--
--  General Notes
--
--
--  * LuaUI (Spring 0.74b3) is based on Lua 5.0
--
--  * All of the standard lua libraries are available
--    (os, io, math, string, table, coroutine, debug)
--
--  * The Game[], UnitDefs[], and WeaponDefs[] tables are available.
--    These tables can be printed into the infolog.txt by adding
--    "keydebug 2" in the uikeys.txt file. There are example tables at
--    the end of this file.
--
--  * The CMD[] and CMDTYPE[] tables contain bidirectional maps of the
--    known commands type and their names
--
--  * The GL[] table contains a mapping of OpenGL names to constants
--
--  * Screen origin is left-bottom (0, 0)
--    (this is used for both mouse and screen drawing coordinates)
--
--

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
--  CALL-INS
--
--  Call-ins are functions that the lua code can provide that will
--  be called from the Spring executable when appropriate. All of
--  the call-ins are optional.
--

  Shutdown()

  LayoutButtons()

  UpdateLayout()
  ConfigureLayout()

  CommandNotify()

  DrawScreenItems()
  DrawWorldItems()
  DrawWorldShadows() FIXME
  DrawWorldReflection() FIXME
  DrawWorldRefraction() FIXME
  DrawMinimap() FIXME

  KeyPress()
  KeyRelease()
  MouseMove()
  MousePress()
  MouseRelease()

  IsAbove()
  GetTooltip()

  GroupChanged()

  AddConsoleLine()


  GameOver()   FIXME
  TeamDied()   FIXME

  UnitCreated()
  UnitFinished()
  UnitFromFactory()
  UnitDestroyed()
  UnitTaken()
  UnitGiven()
  UnitIdle()     FIXME
  UnitDamaged()  FIXME
  UnitEnteredRadar()
  UnitEnteredLos()
  UnitLeftRadar()
  UnitLeftLos()
  UnitSeismicPing() FIXME

  FeatureCreated() FIXME
  FeatureDestroyed() FIXME


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
--  CALL-OUTS
--
--  Call-outs are the functions which may be used from within the LUA code.
--  They are all placed in the Spring[] table  (ex: use Spring.LoadTextVFS()),
--  except for the OpenGL related call (which are placed in the gl[] table).
--

  KillScript()  FIXME  (not in Spring)

  LoadTextVFS()
  GetDirListVFS()
  GetDirList()

  GetFPS()
  GetGameSpeed()
  GetGameFrame()      FIXME
  GetGameSeconds()
  GetLastUpdateSeconds()

	IsCheatingEnabled() FIXME
  GetGaiaTeamID()     FIXME
  GetRulesInfoMap()   FIXME

  SetActiveCommand()  FIXME
  GetActiveCommand()
  GetDefaultCommand() FIXME
  GetActiveCmdDescs() FIXME
  GetActiveCmdDesc()  FIXME
  GetCmdDescIndex()   FIXME

  GetMouseState()
  GetMouseCursor()
  SetMouseCursor()

  SetCustomCommandDrawLine()

  GetConsoleBuffer()
  GetCurrentTooltip()

  GetKeyState()
  GetModKeyState()
  GetPressedKeys()

  GetKeyCode()
  GetKeySymbol()
  GetKeyBindings()
  GetActionHotKeys()

  GetConfigInt()
  SetConfigInt()
  GetConfigString()
  SetConfigString()

  SetUnitDefIcon()

  GetSelectedGroup()
  GetGroupList()
  GetGroupAIName()
  GetGroupAIList()

  GetSelectedUnits()
  GetSelectedUnitsSorted()
  GetSelectedUnitsCounts()
  GetGroupUnits()
  GetGroupUnitsSorted()
  GetGroupUnitsCounts()
  GetTeamUnits()
  GetTeamUnitsSorted()
  GetTeamUnitsCounts()

  GetUnitsInRectangle()
  GetUnitsInCylinder()
  GetUnitsInPlanes()

  GetFeaturesInRectangle()

  GetUnitDefID()
  GetUnitTeam()
  GetUnitAllyTeam()
  GetUnitGroup()
  GetUnitHealth()
  GetUnitResources()
  GetUnitStates()
  GetUnitStockpile()
  GetUnitPosition()
  GetUnitHeading()
  GetUnitBuildFacing()

  GetFeatureInfo()
  GetFeaturePosition()
  GetFeatureResources()

  GetUnitCommands()    FIXME
  GetFactoryCounts()   FIXME
  GetFactoryCommands() FIXME

  GetCommandQueue()
  GetFullBuildQueue()
  GetRealBuildQueue()

  GetUnitCmdDescs() FIXME

  GetUnitRulesParam() FIXME
  GetUnitRulesParams() FIXME

  GetUnitLosState FIXME

  IsUnitInView()
  IsUnitAllied()

  GetMyAllyTeamID()
  GetMyTeamID()
  GetMyPlayerID()

  GetAllyTeamList()
  GetTeamList()
  GetPlayerList()
  GetPlayerRoster()

  GetTeamInfo()
  GetTeamResources()
  GetTeamUnitStats()
  SetShareLevel()
  ShareResources()

  GetPlayerInfo()

  AreTeamsAllied()
  ArePlayersAllied()

  GetCameraState()
  SetCameraState()
  SetCameraTarget()
  GetCameraPos()
  GetCameraVectors()
  WorldToScreenCoords()
  TraceScreenRay()

  SendCommands()

  GiveOrder()
  GiveOrderToUnit()
  GiveOrderToUnitMap()
  GiveOrderToUnitArray()
  GiveOrderArrayToUnitMap()
  GiveOrderArrayToUnitArray()

  SelectUnitMap()
  SelectUnitArray()

  GetGroundHeight()
  GetGroundNormal()
  GetGroundInfo()  FIXME
  GetGroundExtremes()  FIXME

  TestBuildOrder()
  Pos2BuildPos()

  PlaySoundFile()

  AddWorldIcon()
  AddWorldText()
  AddWorldUnit()

  MarkerAddPoint()   
  MarkerAddLine()     
  MarkerErasePosition()

  gl.ScreenGeometry()
  gl.ResetState()
  gl.ResetMatrices()
  gl.Clear()

  gl.Lighting()
  gl.ShadeModel()

  gl.Scissor()
  gl.ColorMask()
  gl.DepthMask()
  gl.DepthTest()
  gl.Culling()
  gl.LogicOp()
  gl.Blending()
  gl.AlphaTest()
  gl.LineStipple()
  gl.PolygonOffset()
  gl.PolygonMode()
  gl.Texture()
  gl.Material()
  gl.Color()

  gl.FreeTexture()

  gl.Shape()
  gl.Rect()    FIXME
  gl.UnitDef()
  gl.Text()
  gl.GetTextWidth()

  gl.Translate()
  gl.Scale()
  gl.Rotate()

  gl.PushMatrix()
  gl.PopMatrix()

  gl.ListCreate()
  gl.ListRun()
  gl.ListDelete()


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
--  CALL-INS, in detail
--


--
--  Called whenever LuaUI is being terminated.
--
Shutdown() -> nil


--
--  Called whenever the active commands changed, or if forced
--
LayoutButtons(number xButtons, number yButtons, number cmdCount,
              commands = {  --  the list of commands currently available
                [1] = { id = number,
                        type = number,
                        action = string,
                        hidden = boolean,
                        params = { string "param1", string "param2", etc...}
                      },
                [2] = { ... },
                [3] = { ... },
                etc...
              }) ->
  string menuName,
  number xButtons,
  number yButtons,
  removeCmds = {
    [1] = number cmdIndex1,  etc...
  },
  customCmds = {                 -- all parameters are optional
    [1] = {
      id        = number,
      type      = number,
      action    = string,
      iconname  = string,
      mouseicon = string,
      tooltip   = string,
      nwtext    = string,
      netext    = string,
      swtext    = string,
      setext    = string,
      actions = { string "action1", string "action2",  etc...}
      -- Actions can have a key modifier specification prefix that
      -- will control when they are enabled, and what the effective
      -- key modifiers will be when they are executed. Here's an
      -- example:    actions = { "@-c+s+R-A+M@togglelos" }
      -- The lower case letters control when the action is enabled.
      -- A '+' before the letter means that the modifier key must
      -- be active for the action to execute. A '-' before the letter
      -- means that the modifier key must not be active for the
      -- action to execute. The same pattens holds for the effective
      -- state of the modifiers during execution. A '+' enables the
      -- modifier, and a '-' disables it. Manipulating the effective
      -- state of the modifiers can be useful for actions such as
      -- "group1", "group2", etc...
      --
      --   a/A:  ALT KEY
      --   c/C:  CONTROL KEY
      --   m/M:  META KEY
      --   s/S:  SHIFT KEY
      --   r/R:  RIGHT MOUSE BUTTON
    },
    etc...
  }
  onlyTextureCmds = {
    [1] = number cmdIndex1,  etc...
  },
  reTextureCmds = {
    [number cmdIndex1] = string "texture1",  etc...
  },
  reNamedCmds = {
    [number cmdIndex1] = string "name1",  etc...
  },
  reTooltipCmds = {
    [number cmdIndex1] = string "tooltip1",  etc...
  },
  reParamsCmds = {
    -- paramNum starts at 0
    [number cmdIndex1] = { [number paramNum] = string "value", etc... },  etc...
  },
  buttonList = {
    -- buttonSlots start at 0
    [number buttonSlot] = number cmdIndex1,  etc...
  }


--
--  Called every frame. Return 'true' if you wish to force a re-layout
--  (ex: if you need to change the appearance of a custom button)
--
UpdateLayout(
  boolean commandsChanged,
  number page,
  boolean alt,
  boolean ctrl,
  boolean meta,
  boolean shift
) -> boolean forceLayout


--
--  Called from the "/luaui <command>" in-game command
--
ConfigureLayout(string "command") -> nil


--
--  Called whenever the user produces a new command. If the
--  returned value is true, then the command is not sent.
--
CommandNotify(
  number commandID,
  params  = { string "param1", string "param2", etc... },
  options = { boolean alt, boolean ctrl, boolean shift, boolean right }
) -> boolean takeCommand


--
--  Called every frame
--
DrawWorldItems() -> nil

DrawScreenItems(number width, number height) -> nil


--
--  The following are called when the associated user input is given
--
KeyPress(number key, boolean isRepeat) -> boolean takeEvent

KeyRelease(number key) -> boolean takeEvent


MouseMove(number x, number y, number dx, number dy, number button) ->
  boolean takeEvent

MousePress(number x, number y, number button) -> boolean takeEvent

MouseRelease(number x, number y, number button) ->
  number commandIndex  (-1 for no command)


--
--  Called be Spring to find out if the cursor is over the
--  any part of the user interface. This is used to determine
--  the current tooltip, whether or not to execute a default
--  command, etc...
--
IsAbove(number x, number y) -> boolean above

--
--  Called when Spring thinks the user interface owns the tooltip
--
GetTooltip(number x, number y) -> string "tooltip"


--
--  Called when an allied unit is created
--
UnitCreated(number unitID, number unitDefID, number unitTeam) -> nil

--
--  Called when an allied unit first reaches 100% health
--
UnitFinished(number unitID, number unitDefID, number unitTeam) -> nil

--
--  Called when an allied unit is produced by a factory (after UnitFinished())
--
UnitFromFactory(number unitID, number unitDefID, number unitTeam,
                number factID, number factDefID, boolean userOrders) -> nil

--
--  Called when an allied unit is destroyed
--
UnitDestroyed(number unitID, number unitDefID, number unitTeam) -> nil

--
--  Called just before an allied unit is taken from a team
--
UnitTaken(number unitID, number unitDefID,
          number unitTeam, number newTeam) -> nil

--
--  Called after an allied unit is given to a team
--
UnitGiven(number unitID, number unitDefID,
          number unitTeam, number oldTeam) -> nil

--
--  Called when an enemy unit enter radar
--
UnitEnteredRadar(unitID, unitTeam) -> nil

--
--  Called when an enemy unit enters line of sight
--
UnitEnteredLos(number unitID, number unitDefID, number unitTeam) -> nil

--
--  Called when an enemy unit leaves radar range
--
UnitLeftRadar(number unitID, number unitTeam) -> nil

--
--  Called when an enemy unit leaves line of sight
--
UnitLeftLos(number unitID, number unitDefID, number unitTeam) -> nil

--
--  Called when units are added or removed from
--  a group,or when the group's AI is changed
--
GroupChanged(number groupID) -> nil

--
--  Called when a new line of text is added to the console
--  (or with unviewed lines after LuaUI is initialized)
--
AddConsoleLine(string "text", number priority) -> nil


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
--  CALL-OUTS, in detail
--

--
--  loads archived and unarchived files
--
LoadTextVFS(string "filename") -> nil | string "filecontents"

--
--  only lists archived files
--
GetDirListVFS(string "dir") ->
  vfsFiles = {
    [1] = string "filename",
    etc...
  }

--
--  only lists unarchived files (real files)
--
--  options characters are:
--    "d" - include directories
--    "r" - recursive search
GetDirList(string "dir", string "pattern", string "options") ->
  normalFiles = {
    [1] = string "filename",
    etc...
  }


GetFPS()         -> number fps

GetGameSpeed()   -> number userSpeed, number internalSpeed, boolean paused

GetGameSeconds() -> number seconds

GetLastUpdateSeconds() -> number of seconds since the last update


GetActiveCommand() -> number activeCommand


GetMouseState()  ->
  number x,
  number y,
  boolean leftButton,
  boolean middleButton,
  boolean rightButton

GetMouseCursor() -> string "cursor", number scale

SetMouseCursor(string "cursor"[, number scale]) -> nil


SetCustomCommandDrawLine(int cmdID, int iconCmdID, table color { r, g, b, a})
        -> nil
        iconCmdID is the cmdID which icon is to be used


GetConsoleBuffer([number maxLines]) ->
  lines = {
    [1] = { text = string "text", priority = number priority },
    etc...
  }

GetCurrentTooltip() -> string "tooltip"


GetKeyState(number keycode) -> boolean pressed

GetModKeyState() -> boolean alt, boolean ctrl, boolean meta, boolean shift

GetPressedKeys() -> { [1] = number keycode, etc... }


GetKeyCode(string "keysym") -> number keycode

GetKeySymbol(number keycode) -> string "defKeySym", string "userKeySym"

GetKeyBindings(string "keyset") ->
  bindings = {
    [1] = { string "command" = string "arguments" },
    etc...
  }

GetActionHotKeys(string "command") ->
  hotkeys = {
    [1] = string "hotkey1",
    etc...
  }


GetConfigInt(string varname [,number default])    -> number value

SetConfigInt(string varname, number)              -> nil

GetConfigString(string varname [,string default]) -> string value

SetConfigString(string varname, string value)     -> nil


SetUnitDefIcon(number unitDefID, string "iconName") -> nil


GetSelectedGroup() -> number groupID

GetGroupList() ->
  groups = {
     [number groupID] = number groupCount,
     etc...
  }

GetGroupAIName(number groupID) ->
  nil | string "aiName"

GetGroupAIList() ->
  aiList = {
    [1] = string "aiName",
    etc...
  }


--------------------------------------------------------------------------------
--
--  Unit data call-outs
--
--    MyTeam Unit      : owned by player's team
--    Allied Unit      : only reports for allied units
--    InLos Unit       : only reports for units in los range
--    Visible Unit     : reports on all visible units (in los or radar range)
--    TypeVisible Unit : reports on all units for which the unit type is known,
--                       (in los range or in radar range with prior los)
--
--  NOTE: if /specfullview is greater then 0, all units are considered allies
--

-- MyTeam Units
GetSelectedUnits() -> unitTable = { [1] = number unitID, etc... }

-- MyTeam Units
GetSelectedUnitsCounts() ->
  countTable = { [number unitDefID] = number count, etc... }

-- MyTeam Units
GetSelectedUnitsSorted() ->
  unitDefTable = {
    [number unitDefID] = { [1] = [number unitID], etc...},
    etc...
  }


-- MyTeam Units
GetGroupUnits(groupID) -> nil | unitTable = { [1] = number unitID, etc... }

-- MyTeam Units
GetGroupUnitsCounts(groupID) ->
  nil | countTable = { [number unitDefID] = count, etc... }

-- MyTeam Units
GetGroupUnitsSorted(groupID) -> nil |
  unitDefTable = {
    [number unitDefID] = { [1] = [number unitID], etc... },
    etc...
  }


-- Visible Units
GetTeamUnits(teamID) -> nil | unitTable = { [1] = number unitID, etc... }

-- Visible Units
GetTeamUnitsCounts(teamID) ->
  nil | countTable = { [number unitDefID] = count, etc... }

-- Visible Units
GetTeamUnitsSorted(teamID) -> nil |
  unitDefTable = {
    [number unitDefID] = { [1] = [number unitID], etc... },
    etc...
  }


-- Visible Units
GetUnitsInRectangle(number xmin, number zmin, number xmax, number zmax) ->
  unitTable = { [1] = number unitID, etc... }

-- Visible Units
GetUnitsInCylinder(number x, number z, number radius) ->
  unitTable = { [1] = number unitID, etc... }

-- Visible Units
GetUnitsInPlanes(planes = {
    [1] = { number nx, number ny, number nz, number d },
    etc...
  }) ->
  unitTable = { [1] = number unitID, etc... }
--
-- plane normals point towards accepted space,
-- so the acceptance criteria for each plane is:
--
-- radius     = unit radius
-- px, py, pz = unit position
--
-- [(nx * px) + (ny * py) + (nz * pz) + (d - radius)]  <=  0
--


-- TypeVisible Units
GetUnitDefID(number unitID) ->
  nil | number unitDefID

-- Visible Units
GetUnitTeam(number unitID) ->
  nil | number teamID

-- Visible Units
GetUnitAllyTeam(number unitID) ->
  nil | number allyTeamID

-- MyTeam Units
GetUnitGroup(number unitID) ->
  nil | number groupID  --  (-1 for no group)

-- InLos Units
GetUnitHealth(number unitID) ->
  nil | number health,
        number maxHealth,
        number paralyzeDamage,
        number captureProgress,
        number buildProgress

-- Allied Units
GetUnitResources(number unitID) ->
  nil | number metalMake,
        number metalUse,
        number energyMake,
        number energyUse

-- Allied Units
GetUnitStates(number unitID) ->
  nil | states = {
          firestate  = number,
          movestate  = number,
          repeating  = boolean,
          cloak      = boolean,
          active     = boolean,
          trajectory = boolean
        }

-- Allied Units
GetUnitStockpile(number unitID) ->
  nil | number currentStockpile,
        number queuedStockpile,
        number buildPercent

-- Visible Units (with error offset for enemy units not in los)
GetUnitPosition(number unitID) ->
  nil | number x,
        number y,
        number z

-- InLos Units
GetUnitHeading(number unitID) ->
  nil | number x,
        number y,
        number z

-- InLos Units
GetUnitBuildFacing(number unitID) ->
  nil | number buildFacing

-- Visible Units
IsUnitInView(number unitID) ->
  nil | boolean inview

-- Visible Units
IsUnitAllied(number unitID) ->
  nil | boolean allied


-- Visible Features
GetFeatureInfo(number featureID) ->
  nil | string name,
        string description,
        number radius,
        number mass,
        number xsize,
        number ysize,
        boolean destructable,
        boolean reclaimable,
        boolean blocking,
        boolean burnable,
        boolean floating,
        boolean geoThermal

-- Visible Features
GetFeaturePosition(number featureID) -> nil | number x, number y, number z

-- Allied Features
GetFeatureResources(number featureID) ->
  nil | number metalLeft, number energyLeft


-- Allied Units
GetCommandQueue(number unitID [, number maxCommands]) ->
  nil | commands = {
    [1] = {
            id = number,
            params = { number, number, etc... },
            options = {
              boolean alt,
              boolean ctrl,
              boolean shift,
              boolean right,
              boolean internal
            }
          },
          etc...
        }

-- Allied Units
GetFullBuildQueue(number unitID) ->
  nil | buildOrders = {
          [1] = { [number unitDefID] = number count },  etc...
        }

-- Allied Units
GetRealBuildQueue(number unitID) ->
  nil | buildOrders = {
          [1] = { [number unitDefID] = number count },  etc...
        }


--------------------------------------------------------------------------------

GetMyAllyTeamID() -> number allyTeamID

GetMyTeamID()     -> number teamID

GetMyPlayerID()   -> number playerID


GetAllyTeamList() ->
  allyteamTable = { [1] = number allyTeamID, etc... }

GetTeamList([number allyTeamID]) ->
  nil | teamTable = { [1] = number teamID, etc... }

GetPlayerList([number teamID]) ->
  nil | playerTable = { [1] = number playerID, etc... }

--
-- Sort codes:
--
--   1 = Sort by allies  (the default)
--   2 = Sort by teamID
--   3 = Sort by playerName
--   4 = Sort by CPU usage
--   5 = Sort by ping time
--
GetPlayerRoster([number sortType]) ->
  nil | playerTable = {
          [1] = {
            string  name,
            number  playerID,
            number  teamID,
            number  allyTeamID,
            boolean spectator,
            numebr  cpuUsage,
            number  pingTime
          },
          etc...
        }


GetTeamInfo(number teamID) ->
  nil | number teamNum,
        number leader,
        boolean active,
        boolean isDead,
        boolean isAiTeam,
        string  "side",
        number allyTeam

GetTeamResources(number teamID, string "metal" | "energy") ->
  nil | number currentLevel,
        number storage,
        number pull,
        number income,
        number expense,
        number share,
        number sent,
        number received

GetTeamUnitStats(number teamID) ->
  nil | number killed,
        number died,
        number capturedBy,
        number capturedFrom,
        number received,
        number sent

SetShareLevel(string "metal" | "energy", number fraction) -> nil

ShareResources(number team,
               string "units" | "metal" | "energy"[, number amount) -> nil


GetPlayerInfo(number playerID) ->
  nil | string  "name",
        boolean active,
        boolean spectator,
        number  teamID,
        number  allyTeamID,
        number  pingTime,
        number  cpuUsage


AreTeamsAllied(number teamID1, number teamID2) -> nil | boolean allied

ArePlayersAllied(number playerID1, number playerID2) -> nil | boolean allied


GetCameraState() -> table[] camstate  (opaque handle)

SetCameraState(table[] camstate, number camTime) -> nil

GetCameraPos() -> number x, number y, number z

GetCameraVectors() ->
  vectorTable = {
    forward   = { [1] = number x, [2] = number y, [3] = number z },
    up        = { [1] = number x, [2] = number y, [3] = number z },
    right     = { [1] = number x, [2] = number y, [3] = number z },
    top       = { [1] = number x, [2] = number y, [3] = number z },
    bottom    = { [1] = number x, [2] = number y, [3] = number z },
    leftside  = { [1] = number x, [2] = number y, [3] = number z },
    rightside = { [1] = number x, [2] = number y, [3] = number z }
  }

WorldToScreenCoords(number x, number y, number z) ->
  number x, number y, number z

TraceScreenRay(number mouseX, number mouseY[, boolean onlyCoords]) ->
  nil |
  string "unit",    number unitID    |
  string "feature", number featureID |
  string "ground",  { [1] = number x, [2] = number y, [3] = number z }


SendCommands(commands = { string "cmd1", string "cmd2", ... }) -> nil


GiveOrder(number cmdID,
          params = {number, etc...},
          options = {"alt", "ctrl", "shift", "right"}) -> nil

GiveOrderToUnit(number unitID,
                number cmdID,
                params = {number, etc...},
                options = {"alt", "ctrl", "shift", "right"}) -> nil

GiveOrderToUnitMap(unitMap = { [unitID] = dontCare, etc... },
                   number cmdID,
                   params = {number, etc...},
                   options = {"alt", "ctrl", "shift", "right"}) -> nil

GiveOrderToUnitArray(unitArray = { [1] = unitID, etc... },
                     number cmdID,
                     params = {number, etc...},
                     options = {"alt", "ctrl", "shift", "right"}) -> nil

GiveOrderArrayToUnitMap(
  unitMap = { [number unitID] = dontCare, etc... },
  orderArray = {
    { number cmdID,
      params = {number, etc...},
      options = {"alt", "ctrl", "shift", "right"}
    },
    etc...
  }) -> nil

GiveOrderArrayToUnitArray(
  unitArray = { [1] = number unitID, etc... },
  orderArray = {
    { number cmdID,
      params = {number, etc...},
      options = {"alt", "ctrl", "shift", "right"}
    },
    etc...
  }) -> nil


SelectUnitMap(unitIDs = { [unitID1] = x1 , [unitID2] = x2 , ...}) -> nil

SelectUnitArray(unitIDs = { [1] = unitID1 , [2] = unitID2 , ...}) -> nil


GetGroundHeight(number x, number y) -> number z

GetGroundNormal(number x, number y) -> number x, number y, number z


TestBuildOrder(number unitDefID,
               number x, number y, number z
               number facing) -> boolean willBuild

Pos2BuildPos(number unitDefID, number x, number y, number z) ->
  nil | number x,
        number y,
        number z


PlaySoundFile(string "filename"
              [, number volume
              [, number x, number y, number z]]) -> nil  -- 1.0 = maxVolume


AddWorldIcon(number cmdID, number x, number y, number z) -> nil

AddWorldText(string "text", number x, number y, number z) -> nil

AddWorldUnit(number unitDefID,
             number x, number y, number z,
             number team, number facing) -> nil


MarkerAddPoint(number x, number y, number z[, string "text"]) -> nil

MarkerAddLine(number x1, number y1, number z1,
              number x2, number y2, number z2)    -> nil

MarkerErasePosition(number x, number y, number z) -> nil


--------------------------------------------------------------------------------
--
--  gl[] table
--
--  The calls in the gl[] table are based on OpenGL functions.
--  You may wish to read the documentation for the following OpenGL
--  functions to better understand them:
--    * glBegin()
--    * glEnable()
--    * glVertex()
--    * glNormal()
--    * glTexCoord()
--    * glAlphaFunc()
--    * glBlendFunc()
--    * glDepthFunc()
--    * glLogicOp()
--    * glCullFace()
--    * glShadeModel()
--    * glScissor()
--    * glGenLists()
--    * glNewList()
--    * glDeleteLists()
--

gl.ScreenGeometry(number width, number dist) -> nil


gl.ResetState() -> nil
-- ShadeModel = GL_SMOOTH
-- Scissor    = false
-- Texture    = false
-- ColorMask  = true, true, true, true
-- DepthMask  = false
-- DepthTest  = false  (GL_LEQUAL)
-- Culling    = false  (GL_BACK)
-- LogicOp    = false  (GL_INVERT)
-- AlphaTest  = false  (GL_GREATER, 0.5f)
-- Blending   = GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA


gl.ResetMatrices() -> nil
-- Resets GL_TEXTURE matrix stack
-- Resets GL_MODELVIEW matrix stack
-- Resets GL_PROJECTION matrix stack


gl.Clear(number bits[, number v1[, number v2, number v3, number v4]]) -> nil
-- bits:
--   GL_COLOR_BUFFER_BIT    (4 values)
--   GL_ACCUM_BUFFER_BIT    (4 values)
--   GL_DEPTH_BUFFER_BIT    (1 value)
--   GL_STENCIL_BUFFER_BIT  (1 value)


gl.ShadeModel(number mode) -> nil
gl.Scissor      (boolean enable | number x, number y, number w, number h) -> nil
gl.Lighting     (boolean enable) -> nil
gl.ColorMask    (boolean enable/red
                 [, boolean green, boolean blue, boolean alpha]) -> nil
gl.DepthMask    (boolean enable) -> nil
gl.DepthTest    (boolean enable | number func) -> nil
gl.Culling      (boolean enable | number face) -> nil
gl.LogicOp      (boolean enable | number func) -> nil
gl.AlphaTest    (boolean enable | number func, number threshold) -> nil
gl.Blending     (boolean enable | number srcmode, number dstmode) -> nil
gl.LineStipple  (boolean enable | string "" | number f, number pattern) -> nil
gl.PolygonOffset(boolean enable | number factor, number units) -> nil
gl.PolygonMode  (number face, number mode) -> nil

gl.Texture(boolean enable | string "filename") -> boolean success

gl.Material({
    ambient   = {number r, number g, number b[, number a]},
    diffuse   = {number r, number g, number b[, number a]},
    ambidiff  = {number r, number g, number b[, number a]},
    emission  = {number r, number g, number b[, number a]},
    specular  = {number r, number g, number b[, number a]},
    shininess = number specularExponent
  }) -> nil

gl.Color({ number r, number g, number b[, number a] } |
             number r, number g, number b[, number a]) -> nil

gl.FreeTexture(string "texname") -> boolean success

gl.Shape(
  number GLtype,
  elements = {
    [1] = { v | vertex   = { number x, number y, number z },           -- required
            n | normal   = { number x, number y, number z },           -- optional
            t | texcoord = { number x, number y },                     -- optional
            c | color    = { number r, number g, number b, number a }  -- optional
    },
    etc ...
  }
) -> nil

gl.UnitDef(number unitDefID, number teamID) -> nil

-- the text option characters are:
--
--   "o" - outline with black
--   "O" - outline with white
--   "r" - right justify
--   "c" - center justify
--   "n" - ignore embedded color codes  (enables gl.Color() for text)
--
gl.Text(string "text", number x, number y, number size, string "options") -> nil
gl.GetTextWidth(string "text") -> number width  --  in pixels, with a font size of 1.0


gl.MatrixMode(number mode) -> nil

gl.PushMatrix()   -> nil
gl.PopMatrix()    -> nil
gl.LoadIdentity() -> nil

gl.Translate(number x, number y, number z)            -> nil
gl.Scale(number x, number y, number z)                -> nil
gl.Rotate(number angle, number x, number y, number z) -> nil


gl.ListCreate(function [,arg1 [,arg2...]]) -> number listID  -- 0 is an invalid list
gl.ListRun(number listID)    -> nil
gl.ListDelete(number listID) -> nil


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--
--  Examples of Game[], WeaponDefs[], and UnitDefs[] tables
--

Game = {}
Game.version = "0.74b3+"
Game.commEnds = false
Game.gravity = 100.000000
Game.tidal = 60.000000
Game.windMin = 10.000000
Game.windMax = 20.000000
Game.mapX = 16
Game.mapY = 16
Game.mapName = "Castles.smf"
Game.modName = "BA461.sd7"
Game.modHumanName = "Balanced Annihilation V4.61"
Game.limitDGun = false
Game.diminishingMetal = false
Game.springCategories = { ["vtol"] = true, ["special"] = true, ["noweapon"] = true, ["notair"] = true, ["notsub"] = true, ["all"] = true, ["weapon"] = true, ["notship"] = true, ["notland"] = true, ["mobile"] = true, ["kbot"] = true, ["plant"] = true, ["ship"] = true, ["antiemg"] = true, ["antigator"] = true, ["antilaser"] = true, ["antiflame"] = true, ["underwater"] = true, ["tank"] = true, ["hover"] = true, ["phib"] = true, ["constr"] = true, ["strategic"] = true, ["commander"] = true, ["mine"] = true, ["kamikaze"] = true, ["jam"] = true, ["minelayer"] = true, ["notstructure"] = true, ["tport"] = true, ["fort"] = true, ["notspace"] = true }


WeaponDefs = {}
WeaponDefs[39] = {}
WeaponDefs[39].name = "armcomlaser"
WeaponDefs[39].id = 39
WeaponDefs[39].onlyTargetCategory = { ["vtol"] = true, ["special"] = true, ["noweapon"] = true, ["notair"] = true, ["notsub"] = true, ["all"] = true, ["weapon"] = true, ["notship"] = true, ["notland"] = true, ["mobile"] = true, ["kbot"] = true, ["plant"] = true, ["ship"] = true, ["antiemg"] = true, ["antigator"] = true, ["antilaser"] = true, ["antiflame"] = true, ["underwater"] = true, ["tank"] = true, ["hover"] = true, ["phib"] = true, ["constr"] = true, ["strategic"] = true, ["commander"] = true, ["mine"] = true, ["kamikaze"] = true, ["jam"] = true, ["minelayer"] = true, ["notstructure"] = true, ["tport"] = true, ["fort"] = true, ["notspace"] = true }
WeaponDefs[39].type = "BeamLaser"
WeaponDefs[39].isAircraftBomb = false
WeaponDefs[39].isStarburstLauncher = false
WeaponDefs[39].isBeamLaser = true
WeaponDefs[39].isShield = false
WeaponDefs[39].isTorpedoLauncher = false
WeaponDefs[39].isDGun = false
WeaponDefs[39].isLightingCannon = false
WeaponDefs[39].isLaserCannon = false
WeaponDefs[39].isMissileLauncher = false
WeaponDefs[39].isEmgCannon = false
WeaponDefs[39].isFlame = false
WeaponDefs[39].isCannon = false
WeaponDefs[39].range = 300.000000
WeaponDefs[39].heightmod = 0.200000
WeaponDefs[39].accuracy = 0.000000
WeaponDefs[39].sprayangle = 0.000000
WeaponDefs[39].movingAccuracy = 0.000000
WeaponDefs[39].targetMoveError = 0.050000
WeaponDefs[39].damages = { ["amphibious"] = 75.000000, ["anniddm"] = 75.000000, ["antibomber"] = 75.000000, ["antifighter"] = 75.000000, ["antiraider"] = 75.000000, ["atl"] = 75.000000, ["blackhydra"] = 75.000000, ["commanders"] = 75.000000, ["crawlingbombs"] = 75.000000, ["dl"] = 75.000000, ["else"] = 75.000000, ["flakboats"] = 75.000000, ["flaks"] = 75.000000, ["flamethrowers"] = 75.000000, ["gunships"] = 75.000000, ["heavyunits"] = 75.000000, ["hgunships"] = 75.000000, ["jammerboats"] = 75.000000, ["krogoth"] = 75.000000, ["l1bombers"] = 75.000000, ["l1fighters"] = 75.000000, ["l1subs"] = 5.000000, ["l2bombers"] = 75.000000, ["l2fighters"] = 75.000000, ["l2subs"] = 5.000000, ["l3subs"] = 5.000000, ["mechs"] = 75.000000, ["minelayers"] = 75.000000, ["mines"] = 75.000000, ["nanos"] = 75.000000, ["orcone"] = 75.000000, ["otherboats"] = 75.000000, ["plasmaguns"] = 75.000000, ["radar"] = 75.000000, ["seadragon"] = 75.000000, ["spies"] = 75.000000, ["tl"] = 75.000000, ["vradar"] = 75.000000, ["vtol"] = 75.000000, ["vtrans"] = 180.000000, ["vulcbuzz"] = 75.000000 }
WeaponDefs[39].paralyzeDamageTime = 0
WeaponDefs[39].impulseFactor = 0.123000
WeaponDefs[39].impulseBoost = 0.123000
WeaponDefs[39].craterMult = 0.000000
WeaponDefs[39].craterBoost = 0.000000
WeaponDefs[39].noSelfDamage = true
WeaponDefs[39].areaOfEffect = 6.000000
WeaponDefs[39].fireStarter = 0.700000
WeaponDefs[39].edgeEffectiveness = 0.990000
WeaponDefs[39].size = 2.187500
WeaponDefs[39].sizeGrowth = 0.200000
WeaponDefs[39].collisionSize = 0.050000
WeaponDefs[39].salvoSize = 1
WeaponDefs[39].salvoDelay = 0.100000
WeaponDefs[39].reload = 0.400000
WeaponDefs[39].beamTime = 0.100000
WeaponDefs[39].maxAngle = 54.933315
WeaponDefs[39].restTime = 0.000000
WeaponDefs[39].uptime = 0.000000
WeaponDefs[39].metalCost = 0.000000
WeaponDefs[39].energyCost = 0.000000
WeaponDefs[39].supplyCost = 0.000000
WeaponDefs[39].turret = true
WeaponDefs[39].onlyForward = false
WeaponDefs[39].waterweapon = false
WeaponDefs[39].tracks = false
WeaponDefs[39].dropped = false
WeaponDefs[39].paralyzer = false
WeaponDefs[39].canAttackGround = true
WeaponDefs[39].noAutoTarget = false
WeaponDefs[39].manualFire = false
WeaponDefs[39].interceptor = 0
WeaponDefs[39].targetable = 0
WeaponDefs[39].stockpile = false
WeaponDefs[39].coverageRange = 0.000000
WeaponDefs[39].intensity = 0.900000
WeaponDefs[39].thickness = 2.000000
WeaponDefs[39].laserFlareSize = 7.000000
WeaponDefs[39].coreThickness = 0.100000
WeaponDefs[39].duration = 0.050000
WeaponDefs[39].graphicsType = 1330073426
WeaponDefs[39].soundTrigger = true
WeaponDefs[39].selfExplode = false
WeaponDefs[39].gravityAffected = false
WeaponDefs[39].twoPhase = false
WeaponDefs[39].guided = false
WeaponDefs[39].vlaunch = false
WeaponDefs[39].selfProp = false
WeaponDefs[39].noExplode = false
WeaponDefs[39].startVelocity = 0.010000
WeaponDefs[39].weaponAcceleration = 0.000000
WeaponDefs[39].turnRate = 0.000000
WeaponDefs[39].maxVelocity = 900.000000
WeaponDefs[39].projectileSpeed = 30.000000
WeaponDefs[39].explosionSpeed = 3.233584
WeaponDefs[39].wobble = 0.000000
WeaponDefs[39].trajectoryHeight = 0.000000
WeaponDefs[39].largeBeamLaser = false
WeaponDefs[39].isShield = false
WeaponDefs[39].shieldRepulser = false
WeaponDefs[39].smartShield = false
WeaponDefs[39].exteriorShield = false
WeaponDefs[39].visibleShield = false
WeaponDefs[39].visibleShieldRepulse = false
WeaponDefs[39].shieldEnergyUse = 0.000000
WeaponDefs[39].shieldRadius = 0.000000
WeaponDefs[39].shieldForce = 0.000000
WeaponDefs[39].shieldMaxSpeed = 0.000000
WeaponDefs[39].shieldPower = 0.000000
WeaponDefs[39].shieldPowerRegen = 0.000000
WeaponDefs[39].shieldPowerRegenEnergy = 0.000000
WeaponDefs[39].shieldAlpha = 0.200000
WeaponDefs[39].shieldInterceptType = 0
WeaponDefs[39].interceptedByShieldType = 2
WeaponDefs[39].collisionNoFeature = true
WeaponDefs[39].collisionNoFriendly = true
WeaponDefs[39].avoidFriendly = true


UnitDefs = {}
UnitDefs[43] = {}
UnitDefs[43].id = 43
UnitDefs[43].name = "armcom"
UnitDefs[43].humanName = "Commander"
UnitDefs[43].filename = "units/armcom.fbi"
UnitDefs[43].techLevel = 0
UnitDefs[43].maxThisUnit = 5000
UnitDefs[43].TEDClass = "COMMANDER"
UnitDefs[43].iconType = "armcommander"
UnitDefs[43].modCategories = { ["arm"] = true, ["commander"] = true, ["weapon"] = true, ["notair"] = true, ["notsub"] = true, ["ctrl_c"] = true, ["notship"] = true, ["level10"] = true, ["all"] = true }
UnitDefs[43].springCategories = { ["notair"] = true, ["notsub"] = true, ["all"] = true, ["weapon"] = true, ["notship"] = true, ["commander"] = true }
UnitDefs[43].armorType = "commanders"
UnitDefs[43].type = "Builder"
UnitDefs[43].isBomber = false
UnitDefs[43].isFighter = false
UnitDefs[43].isBuilder = true
UnitDefs[43].isFactory = false
UnitDefs[43].isBuilding = false
UnitDefs[43].isTransport = false
UnitDefs[43].isGroundUnit = false
UnitDefs[43].isMetalExtractor = false
UnitDefs[43].isFeature = false
UnitDefs[43].weaponCount = 3
UnitDefs[43].weapons = {}
UnitDefs[43].weapons[0] = {}
UnitDefs[43].weapons[0].weaponDef = WeaponDefs[39]
UnitDefs[43].weapons[0].fuelUsage = 0.000000
UnitDefs[43].weapons[0].badTargets = { ["antilaser"] = true }
UnitDefs[43].weapons[0].onlyTargets = { ["vtol"] = true, ["special"] = true, ["noweapon"] = true, ["notair"] = true, ["notsub"] = true, ["all"] = true, ["weapon"] = true, ["notship"] = true, ["notland"] = true, ["mobile"] = true, ["kbot"] = true, ["plant"] = true, ["ship"] = true, ["antiemg"] = true, ["antigator"] = true, ["antilaser"] = true, ["antiflame"] = true, ["underwater"] = true, ["tank"] = true, ["hover"] = true, ["phib"] = true, ["constr"] = true, ["strategic"] = true, ["commander"] = true, ["mine"] = true, ["kamikaze"] = true, ["jam"] = true, ["minelayer"] = true, ["notstructure"] = true, ["tport"] = true, ["fort"] = true, ["notspace"] = true }
UnitDefs[43].weapons[1] = {}
UnitDefs[43].weapons[1].weaponDef = WeaponDefs[195]
UnitDefs[43].weapons[1].fuelUsage = 0.000000
UnitDefs[43].weapons[1].badTargets = {}
UnitDefs[43].weapons[1].onlyTargets = {}
UnitDefs[43].weapons[2] = {}
UnitDefs[43].weapons[2].weaponDef = WeaponDefs[13]
UnitDefs[43].weapons[2].fuelUsage = 0.000000
UnitDefs[43].weapons[2].badTargets = { ["vtol"] = true }
UnitDefs[43].weapons[2].onlyTargets = { ["vtol"] = true, ["special"] = true, ["noweapon"] = true, ["notair"] = true, ["notsub"] = true, ["all"] = true, ["weapon"] = true, ["notship"] = true, ["notland"] = true, ["mobile"] = true, ["kbot"] = true, ["plant"] = true, ["ship"] = true, ["antiemg"] = true, ["antigator"] = true, ["antilaser"] = true, ["antiflame"] = true, ["underwater"] = true, ["tank"] = true, ["hover"] = true, ["phib"] = true, ["constr"] = true, ["strategic"] = true, ["commander"] = true, ["mine"] = true, ["kamikaze"] = true, ["jam"] = true, ["minelayer"] = true, ["notstructure"] = true, ["tport"] = true, ["fort"] = true, ["notspace"] = true }
UnitDefs[43].maxRange = 300.000000
UnitDefs[43].hasShield = false
UnitDefs[43].canParalyze = false
UnitDefs[43].canStockpile = false
UnitDefs[43].canAttackWater = false
UnitDefs[43].deathExplosion = WeaponDefs[88]
UnitDefs[43].selfDExplosion = WeaponDefs[88]
UnitDefs[43].builder = true
UnitDefs[43].buildSpeed = 300.000000
UnitDefs[43].buildDistance = 128.000000
UnitDefs[43].buildOptionsCount = 25
UnitDefs[43].buildOptions = {}
UnitDefs[43].buildOptions[0] = UnitDefs[143]
UnitDefs[43].buildOptions[1] = UnitDefs[156]
UnitDefs[43].buildOptions[2] = UnitDefs[172]
UnitDefs[43].buildOptions[3] = UnitDefs[110]
UnitDefs[43].buildOptions[4] = UnitDefs[56]
UnitDefs[43].buildOptions[5] = UnitDefs[166]
UnitDefs[43].buildOptions[6] = UnitDefs[161]
UnitDefs[43].buildOptions[7] = UnitDefs[99]
UnitDefs[43].buildOptions[8] = UnitDefs[163]
UnitDefs[43].buildOptions[9] = UnitDefs[94]
UnitDefs[43].buildOptions[10] = UnitDefs[73]
UnitDefs[43].buildOptions[11] = UnitDefs[90]
UnitDefs[43].buildOptions[12] = UnitDefs[169]
UnitDefs[43].buildOptions[13] = UnitDefs[20]
UnitDefs[43].buildOptions[14] = UnitDefs[152]
UnitDefs[43].buildOptions[15] = UnitDefs[57]
UnitDefs[43].buildOptions[16] = UnitDefs[119]
UnitDefs[43].buildOptions[17] = UnitDefs[144]
UnitDefs[43].buildOptions[18] = UnitDefs[54]
UnitDefs[43].buildOptions[19] = UnitDefs[63]
UnitDefs[43].buildOptions[20] = UnitDefs[93]
UnitDefs[43].buildOptions[21] = UnitDefs[157]
UnitDefs[43].buildOptions[22] = UnitDefs[124]
UnitDefs[43].buildOptions[23] = UnitDefs[76]
UnitDefs[43].buildOptions[24] = UnitDefs[53]
UnitDefs[43].selfDCountdown = 10
UnitDefs[43].buildTime = 75000.000000
UnitDefs[43].energyCost = 2500.000000
UnitDefs[43].metalCost = 2500.000000
UnitDefs[43].energyMake = 25.000000
UnitDefs[43].windGenerator = 0.000000
UnitDefs[43].tidalGenerator = 0.000000
UnitDefs[43].extractRange = 0.000000
UnitDefs[43].extractsMetal = 0.000000
UnitDefs[43].metalMake = 1.500000
UnitDefs[43].makesMetal = 0.000000
UnitDefs[43].energyStorage = 0.000000
UnitDefs[43].metalStorage = 0.000000
UnitDefs[43].energyUpkeep = 0.000000
UnitDefs[43].metalUpkeep = 0.000000
UnitDefs[43].needGeo = false
UnitDefs[43].isMetalMaker = false
UnitDefs[43].totalEnergyOut = 25.000000
UnitDefs[43].autoHeal = 2.666667
UnitDefs[43].idleAutoHeal = 2.666667
UnitDefs[43].idleTime = 1800
UnitDefs[43].power = 2541.666748
UnitDefs[43].health = 3000.000000
UnitDefs[43].speed = 37.500000
UnitDefs[43].turnRate = 1148.000000
UnitDefs[43].moveType = 0
UnitDefs[43].upright = true
UnitDefs[43].canAssist = true
UnitDefs[43].canAttack = true
UnitDefs[43].canBuild = true
UnitDefs[43].canCapture = true
UnitDefs[43].canCloak = true
UnitDefs[43].canDGun = true
UnitDefs[43].canFly = false
UnitDefs[43].canGuard = true
UnitDefs[43].canHover = false
UnitDefs[43].canKamikaze = false
UnitDefs[43].canMove = true
UnitDefs[43].canPatrol = true
UnitDefs[43].canReclaim = true
UnitDefs[43].canRepair = true
UnitDefs[43].canRestore = true
UnitDefs[43].canResurrect = false
UnitDefs[43].noAutoFire = false
UnitDefs[43].reclaimable = false
UnitDefs[43].onOffable = false
UnitDefs[43].floater = false
UnitDefs[43].activateWhenBuilt = true
UnitDefs[43].mass = 5000.000000
UnitDefs[43].xSize = 4
UnitDefs[43].ySize = 4
UnitDefs[43].buildAngle = 0
UnitDefs[43].radarRadius = 700
UnitDefs[43].sonarRadius = 300
UnitDefs[43].jammerRadius = 0
UnitDefs[43].sonarJamRadius = 0
UnitDefs[43].seismicRadius = 0
UnitDefs[43].seismicSignature = 0.000000
UnitDefs[43].stealth = false
UnitDefs[43].controlRadius = 32.000000
UnitDefs[43].losRadius = 28.125000
UnitDefs[43].airLosRadius = 21.093750
UnitDefs[43].losHeight = 20.000000
UnitDefs[43].maxSlope = 0.939693
UnitDefs[43].maxHeightDif = 14.558809
UnitDefs[43].minWaterDepth = -10000000.000000
UnitDefs[43].waterline = 0.000000
UnitDefs[43].maxWaterDepth = 35.000000
UnitDefs[43].armoredMultiple = 1.000000
UnitDefs[43].wingDrag = 0.070000
UnitDefs[43].wingAngle = 0.080000
UnitDefs[43].drag = 0.130461
UnitDefs[43].frontToSpeed = 0.100000
UnitDefs[43].speedToFront = 0.070000
UnitDefs[43].myGravity = 0.400000
UnitDefs[43].maxBank = 0.800000
UnitDefs[43].maxPitch = 0.450000
UnitDefs[43].turnRadius = 500.000000
UnitDefs[43].wantedHeight = 0.000000
UnitDefs[43].hoverAttack = false
UnitDefs[43].dlHoverFactor = -1.000000
UnitDefs[43].dontLand = false
UnitDefs[43].maxAcc = 0.180000
UnitDefs[43].maxDec = 0.037500
UnitDefs[43].maxAileron = 0.015000
UnitDefs[43].maxElevator = 0.010000
UnitDefs[43].maxRudder = 0.004000
UnitDefs[43].maxFuel = 0.000000
UnitDefs[43].refuelTime = 5.000000
UnitDefs[43].minAirBasePower = 0.000000
UnitDefs[43].loadingRadius = 220.000000
UnitDefs[43].transportCapacity = 0
UnitDefs[43].transportSize = 0
UnitDefs[43].isAirBase = false
UnitDefs[43].transportMass = 100000.000000
UnitDefs[43].startCloaked = false
UnitDefs[43].cloakCost = 100.000000
UnitDefs[43].cloakCostMoving = 1000.000000
UnitDefs[43].decloakDistance = 50.000000
UnitDefs[43].kamikazeDist = 0.000000
UnitDefs[43].targfac = false
UnitDefs[43].hideDamage = true
UnitDefs[43].isCommander = true
UnitDefs[43].showPlayerName = true
UnitDefs[43].highTrajectoryType = 0
UnitDefs[43].noChaseCategory = { ["all"] = true }
UnitDefs[43].canDropFlare = false
UnitDefs[43].flareReloadTime = 5.000000
UnitDefs[43].flareEfficieny = 0.500000
UnitDefs[43].flareDelay = 0.300000
UnitDefs[43].flareDropVectorX = 0.000000
UnitDefs[43].flareDropVectorY = 0.000000
UnitDefs[43].flareDropVectorZ = 0.000000
UnitDefs[43].flareTime = 90
UnitDefs[43].flareSalvoSize = 4
UnitDefs[43].flareSalvoDelay = 0
UnitDefs[43].smoothAnim = true
UnitDefs[43].canLoopbackAttack = false
UnitDefs[43].levelGround = true
UnitDefs[43].useBuildingGroundDecal = false
UnitDefs[43].buildingDecalType = 1801678674
UnitDefs[43].buildingDecalSizeX = 4
UnitDefs[43].buildingDecalSizeY = 4
UnitDefs[43].buildingDecalDecaySpeed = 0.100000
UnitDefs[43].isFirePlatform = false
UnitDefs[43].showNanoFrame = true
UnitDefs[43].showNanoSpray = true
UnitDefs[43].nanoColorR = 0.200000
UnitDefs[43].nanoColorG = 0.700000
UnitDefs[43].nanoColorB = 0.200000
