-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- --------------------------------------------------------------------------------