Public feed #603392

Miscellany

public text v1 · immutable
Raw Edit
·published 2007-07-04 19:15 UTC
rendered paste body
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------


function widget:GetInfo()
  return {
    name      = "Voices",
    desc      = "Unit replies and notifications",
    author    = "quantum",
    date      = "1/7/2007",
    license   = "GNU GPL, v2 or later",
    layer     = -10,
    enabled   = true  --  loaded by default?
  }
end

--TODO:
--unit retreating
--can't reach destination
--chat    'TextCommand'
--captured
--lose
--player exit
--resources/units transferred
--upgrades
--comkill?
--playerdied
--selectsensor
--move plane

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

include("spring.h.lua")

--Speed-ups

local GetTeamUnitStats = Spring.GetTeamUnitStats
local GetSelectedUnits = Spring.GetSelectedUnits
local GetUnitDefID     = Spring.GetUnitDefID
local GetGameSeconds   = Spring.GetGameSeconds
local GetUnitTeam      = Spring.GetUnitTeam
local GetTeamResources = Spring.GetTeamResources
local GetUnitAllyTeam  = Spring.GetUnitAllyTeam
local GetGameSpeed     = Spring.GetGameSpeed
local GetUnitHealth    = Spring.GetUnitHealth
local insert           = table.insert


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


local SOUND_DIRNAME    = LUAUI_DIRNAME .. 'Sounds/'
local VFSMODE          = VFS.RAW_ONLY
local CMD_RETREAT      = 32200

local mySide
local myTeamID
local myAllyTeamID
local saidPaused
local saidStarts
local counter          = 0
local cooldownList     = {}
local selectBuffer     = {}
local cooldown         = {}
local radarList        = {}
local moveState        = {}
local retreatState     = {}
local fireState        = {}
local statsBuffer      = {0, 0, 0, 0, 0, 0}
local energyList = {"corsolar","armsolar","coradvsol","armadvsol","corfus",
                    "armfus", "aafus", "cafus", "cortide", "armtide", "corwin",
                    "armwin"} --FIXME


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
local function rand(x)
  return math.floor(math.random(1,x))
end

local function PlaySound(SOUND_DIRNAME, fileName, ...)
  Spring.PlaySoundFile(SOUND_DIRNAME .. fileName, unpack(arg))
end


local function Play(category)
  fileList = VFS.DirList(SOUND_DIRNAME.."Voices/"..category.."_"..mySide.."/", "*.wav", VFSMODE)
  x = table.getn(fileList)
  if (x > 0) then
    local y = rand(x)
    local dirName = SOUND_DIRNAME.."Voices/"..category.."_"..mySide.."/"
    local fileName = y..".wav"
    --Spring.Echo("Playing "..fileName)
    PlaySound(dirName, fileName)
  else
    --Spring.Echo("no sound found")
  end
end


local function CheckSelected()
  local unitTable = GetSelectedUnits()
  local isTurret  = false
  local isFus     = false
  local isSam     = false
  local isCom     = false
  for _, unitID in ipairs(unitTable) do
    local unitDefID = GetUnitDefID(unitID)
    if ((not UnitDefs[unitDefID].canMove) and
        (UnitDefs[unitDefID].canAttack == 1)) then  --FIXME: canAttack broken?
      isTurret =true
    end
    if ((UnitDefs[unitDefID].name == "corfus") or
        (UnitDefs[unitDefID].name == "armfus") or
        (UnitDefs[unitDefID].name == "cafus") or
        (UnitDefs[unitDefID].name == "aafus")) then --FIXME: sea & cloak
      isFus = true
    end
    if ((UnitDefs[unitDefID].name == "corrl") or
        (UnitDefs[unitDefID].name == "armrl")) then --FIXME: more AA
      isSam = true
    end
    if ((UnitDefs[unitDefID].name == "armcom") or
        (UnitDefs[unitDefID].name == "corcom")) then
      isCom = true
    end

  end
  if (isTurret) then
    Play("turret")
  elseif (isFus) then
    Play("selectfus")
  elseif (isSam) then
    Play("selectsam")
  elseif (isCom) then
    Play("selectcom")
  elseif (table.getn(unitTable) > 1) then
    Play("selectgroup")
  else
    Play("select")
  end
end


local function IsStructure(unitID)
  local unitDefID = GetUnitDefID(unitID)
  if (UnitDefs[unitDefID].isBuilding or
      UnitDefs[unitDefID].isFactory) then
    return true
  end
end


local function CoolPlay(category, cooldownTime)
  cooldownTime = cooldownTime or 0
  local t = GetGameSeconds()
  if ((not cooldown[category]) or
      (t - cooldown[category] > cooldownTime)) then
    Play(category)
    cooldown[category] = t
  end
end


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


function widget:Initialize()
  myTeamID = Spring.GetMyTeamID()
  myAllyTeamID = Spring.GetMyAllyTeamID()
  local _, _, _, _, _, side = Spring.GetTeamInfo(myTeamID)
  mySide = side
  --mySide = 'arm'     --DELETEME
  Play("initialized")
  --for i, v in pairs(CMD) do
  --  --Spring.Echo("CMD "..i.." "..v)
  --end
end


function widget:UnitCreated(unitID, unitDefID, unitTeam)
  if (UnitDefs[unitDefID].canMove) then
    moveState[unitID] = 1
    retreatState[unitID] = 0
    fireState[unitID] = 2
  end
  if ((unitTeam == myTeamID) and
      (GetGameSeconds() > 2)) then
    if (IsStructure(unitID)) then
      Play("constructions")
    else
      Play("productions")
    end
  end
end


function widget:UnitFinished(unitID, unitDefID, unitTeam)
  if (unitTeam == myTeamID) then
    if (IsStructure(unitID)) then
      if ((UnitDefs[UnitDedID]) and
          (UnitDefs[UnitDedID].canAttack == 1)) then
        Play("constructiontc")  --FIXME
      else
        Play("constructionc")
      end
    else
      Play("productionc")
    end
  end
end


function widget:UnitGiven(unitID, unitDefID, unitTeam, oldTeam) --not called
  Spring.SendMessage("unitGiven")
  if (oldTeam == myTeamID) then
    CoolPlay("unitsgiven", 1)
  end
end


function widget:UnitDamaged(unitID, unitTeam)
  local unitTeam = GetUnitTeam(unitID)
  if (unitTeam == myTeamID) then
    local unitDefID = GetUnitDefID(unitID)
    if (IsStructure(unitID)) then
      CoolPlay("sdamaged", 10)
    elseif (UnitDefs[unitDefID].isTransport) then
      CoolPlay("tdamaged", 10)
    else
      CoolPlay("udamaged", 10)
    end
    if ((UnitDefs[unitDefID].name == 'armcom') or
        (UnitDefs[unitDefID].name == 'corcom')) then
      health, maxHealth = GetUnitHealth(unitID)
      if health/maxHealth < 0.2 then
        CoolPlay("comdying", 1)
      end
    end
  end
end


function widget:UnitDestroyed(unitID, unitDefID, unitTeam)
  --Spring.Echo('UnitDestroyed')
  moveState[unitID] = nil
  retreatState[unitID] = nil
  fireState[unitID] = nil
  allyTeam = GetUnitAllyTeam(unitID)
  if (allyTeam ~= myAllyTeamID) then
    CoolPlay("destroyedu", 1)
    --for _, energyName in ipairs(energyList) do
      --if (energyName == UnitDefs[unitDefID].name) then
        --CoolPlay("edestroyed", 0)
      --end
    --end
    --if ((UnitDefs[UnitDefID].name == "corcom") or
        --(UnitDefs[UnitDefID].name == "armcom")) then
      --Play("comkill")
    --end
  end
end


function widget:Update(dt)
  local selectedUnits = GetSelectedUnits()
  local notEqual = false
  for i, unitID in ipairs(selectedUnits) do
    if (selectBuffer[i] ~= selectedUnits[i]) then
      notEqual = true
    end
  end
  if (notEqual) then
    CheckSelected()
  end
  selectBuffer = selectedUnits
  counter = counter+dt

  if (counter > 1) then
    counter = 0

    if ((GetGameSeconds() > 0) and
        not saidStarts) then
      Play("gamestarts")
      saidStarts = true
    end

    local e = GetTeamResources(myTeamID, "energy")
    if (e and (e < 10)) then
      CoolPlay("energylow", 15)
    end
    local _, _, isPaused = GetGameSpeed()

    if (isPaused and (not saidPause)) then
      Play("paused")
      saidPause = true
    end

    if ((not isPaused) and saidPause) then
      Play("unpaused")
      saidPause = nil
    end
    if (GetGameSeconds() > 0) then
      local killed, died, captured, _, recieved, sent = GetTeamUnitStats(myTeamID)
      if killed and (killed > statsBuffer[1]) then
        Play("kill")
      end
      if captured and(captured > statsBuffer[3]) then
        Play("capturedu")
      end
      if ((recieved and (recieved > statsBuffer[4])) or
          (sent and (sent > statsBuffer[5])))then
        CoolPlay("unitsgiven", 1)
      end
      statsBuffer = {killed, died, captured, recieved, sent}
    end
  end
end


function widget:CommandNotify(commandID, params ,options)
  --PlaySound(LUAUI_DIRNAME.."Voices/", "left.wav")
  --Spring.Echo("CMD "..(CMD[commandID] or "not found"))
  local unitID = GetSelectedUnits()[1]
  local unitDefID = GetUnitDefID(unitID)

  if (commandID == CMD_RETREAT) then
    if (retreatState[unitID] == 0) then
      retreatState[unitID] = 1
      Play("retreath")
    elseif (retreatState[unitID] == 1) then
      retreatState[unitID] = 2
      Play("retreatm")
    else --if retreatState[unitID] == 2 then
      retreatState[unitID] = 0
    end
  end

  if (commandID == CMD_FIRE_STATE) then
    if (fireState[unitID] == 0) then
      fireState[unitID] = 1
    elseif (fireState[unitID] == 1) then
      fireState[unitID] = 2
    else
      fireState[unitID] = 0
      Play("firehold")
    end
  end

  if (commandID == CMD_MOVE_STATE) then
    if (moveState[unitID] == 0) then
      moveState[unitID] = 1
    elseif (moveState[unitID] == 1) then
      moveState[unitID] = 2
      Play("moveroam")
    else
      moveState[unitID] = 0
      Play("movehold")
    end
  end

  if (commandID == CMD_GUARD)   then
    Play("guard")
  end
  if (commandID == CMD_PATROL) then
    Play("patrol")
  end
  if (commandID == CMD_RECLAIM) then
    Play("reclaim")
  end

  if ((commandID == CMD_ATTACK) or
     (commandID == CMD_FIGHT) or
     (commandID == CMD_AREA_ATTACK) or
     (commandID == CMD_DGUN)) then
    if (UnitDefs[unitDefID].canFly) then
      Play("attackp")
    else
      Play("attack")
    end
  end

  if (commandID == CMD_MOVE) then
    if (IsStructure(unitID)) then
      Play("movef")
    else
      Play("move")
    end
  end
  return false
end


function widget:UnitEnteredRadar(unitID, unitTeam)
  CoolPlay("detected",2)
  radarList[unitID] = true
end


function widget:UnitLeftRadar(unitID, unitTeam)
  if radarList[unitID] then
    radarList[unitID] = nil
  end
end


function widget:UnitEnteredLos(unitID, unitDefID, unitTeam)
  if (UnitDefs[unitDefID].isTransport) then
    Play("detectedt")
  elseif (not radarList[unitID]) then
    Play("detected")
  end
end


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