function widget:GetInfo() return { name = "Anti-Comnap v1.2", desc = "tries to prevent comnaps by moving the com and warning points", author = "[]lennart", date = "23 Februar, 2009", license = "GNU GPL v2", layer = -1, enabled = true -- loaded by default? } end local GiveOrderToUnit = Spring.GiveOrderToUnit local GetUnitPosition = Spring.GetUnitPosition local GetCommandQueue = Spring.GetCommandQueue local Echo = Spring.Echo local GetSelectedUnits = Spring.GetSelectedUnits local GetUnitDefID = Spring.GetUnitDefID local GetUnitIsCloaked = Spring.GetUnitIsCloaked local AreTeamsAllied = Spring.AreTeamsAllied local myTeamID = Spring.GetMyTeamID() local GetUnitTeam = Spring.GetUnitTeam local GetTeamUnitsSorted = Spring.GetTeamUnitsSorted local spGetMyPlayerID = Spring.GetMyPlayerID local spGetPlayerInfo = Spring.GetPlayerInfo local MarkerAddPoint = Spring.MarkerAddPoint local GetUnitIsTransporting = Spring.GetUnitIsTransporting local gl_Rect = gl.Rect local gl_Color = gl.Color local GetTextWidth = fontHandler.GetTextWidth local UseFont = fontHandler.UseFont local TextDraw = fontHandler.Draw local TextDrawCentered = fontHandler.DrawCentered local vsx,vsy = gl.GetViewSizes() local px --used to prevent com from "travelling" when escaping naps local py local pz local enemytranslist={} --keep track of enemy transports local allycomlist={} --and of allied coms local lastwarn=0 local disabled=false local buttonXA = 500 local buttonXB = 600 local buttonYA = 500 local buttonYB = 550 local buttonXM local buttonYM local function calcButton() buttonXA= vsx -180 buttonXB= vsx buttonYA= (vsy*0.5) -8 buttonYB= (vsy*0.5) +8 buttonXM= (buttonXA+buttonXB)/2 buttonYM= (buttonYA+buttonYB)/2-3 end local function setUnitToPatrol(unitID, x, y, z) if((px==nil) or (((px-x)^2+(py-y)^2+(pz-z)^2)^0.5>75)) then px=x py=y pz=z -- Echo("setting com to patrol") end local cQueue=GetCommandQueue(unitID) if ((cQueue[0]~=nil) and (cQueue[1]~=nil)) then if ((cQuese[0].id==CMD.MOVE) and (cQueue[1].id==CMD.MOVE)) then return true end end --GiveOrderToUnit(unitID, CMD.MOVE, {(x-50),y,z},{""}) GiveOrderToUnit(unitID, CMD.INSERT, {0,CMD.MOVE,CMD.OPT_SHIFT,(px-35),py,pz}, {"alt"}) GiveOrderToUnit(unitID, CMD.INSERT, {0,CMD.MOVE,CMD.OPT_SHIFT,(px+35),py,pz}, {"alt"}) end function widget:UnitEnteredLos(unitID, unitTeam) local unitDef = GetUnitDefID(unitID) if ((unitDef ~= nil) and UnitDefs[unitDef]["isTransport"] and not(AreTeamsAllied(myTeamID, unitTeam)) and (enemytranslist[unitID]==nil)) then enemytranslist[unitID]=0 -- Echo("spotted enemy trans") end end -- both following functions clear the enemytranslist var, but they are not necessary, -- as will delete any ids where the position is not accessible --[[ function widget:UnitLeftLos(unitID, unitTeam) if (enemytranslist[unitID]~=nil) then enemytranslist[unitID]=nil end end function widget:UnitDestroyed(unitID, unitDefID, unitTeam) if (enemytranslist[unitID]~=nil) then enemytranslist[unitID]=nil end end --]] function widget:UnitCreated(unitID, unitDefID, teamID) if(UnitDefs[unitDefID].isCommander and AreTeamsAllied(myTeamID, teamID)) then allycomlist[unitID]=teamID end end --here the same applies as for the both functions above; if the location is --not accessible the unit will get removed (from the list) anyways --[[ function widget:UnitDestroyed(unitID, unitDefID, teamID) allycomlist[unitID]=nil end --]] local function updateComlist() allycomlist={} local allUnits=Spring.GetAllUnits() if(allUnits~=nil) then for i,unitID in ipairs(allUnits) do unitTeamID=GetUnitTeam(unitID) if(AreTeamsAllied(myTeamID,unitTeamID) and UnitDefs[GetUnitDefID(unitID)].isCommander) then allycomlist[unitID]=unitTeamID end end end -- Echo(" updated commander list.") end function widget:Initialize() --Echo("widget started!!") calcButton() updateComlist() end -- this callin is needed to make the widget work even with cheating (for testing the widget). function widget:PlayerChanged() updateComlist() end local function checkSpecState() local playerID = spGetMyPlayerID() local _, _, spec, _, _, _, _, _ = spGetPlayerInfo(playerID) if ( spec == true ) then spEcho(" Spectator mode. Widget removed.") widgetHandler:RemoveWidget() return false end return true end function widget:ViewResize(viewSizeX, viewSizeY) vsx = viewSizeX vsy = viewSizeY calcButton() end function widget:DrawScreen() if (lastwarn==0) then return true end --draw button with background and text depending on gl_Color(0,0,0,0.2) gl_Rect(buttonXA, buttonYA, buttonXB, buttonYB) if (disabled) then gl_Color(1,1,1,0.5) TextDrawCentered("enable comnap escaping",buttonXM,buttonYM) else gl_Color(1,0.5,0.2,1.0) TextDrawCentered("disable comnap escaping",buttonXM,buttonYM) end gl_Color(1,1,1,1) -- end end function widget:MousePress(x,y,button) if ( (x>=buttonXA) and (x<=buttonXB) and (y>=buttonYA) and (y<=buttonYB) and (lastwarn>0) ) then if(disabled) then disabled=false else disabled=true end end end function widget:GameFrame(frameNum) if ((frameNum%32)==0) then checkSpecState() if(lastwarn>0) then lastwarn=lastwarn-1 if (lastwarn==0) then disabled=false end end for ComUnitID, ComTeamID in pairs(allycomlist) do local shouldescape=true -- prevent multiple commands for multiple transports sighted at once x,y,z=GetUnitPosition(ComUnitID) if(x==nil) then allycomlist[ComUnitID]=nil else for unitID,lastframe in pairs(enemytranslist) do local ex, ey, ez = GetUnitPosition(unitID) if(ex==nil) then if ((frameNum-lastframe)>64) then --delete after three seconds out of sight enemytranslist[unitID]=nil end else local dist = ((x-ex)^2 + (y-ey)^2 +(z-ez)^2)^0.5 if ((frameNum-lastframe)>800) then -- neither GetUnitsInSphere nor GetUnitIsTransporting does work for enemy coms, so.. -- transported=Spring.GetUnitsInSphere(ex,ey,ez,100)--GetUnitIsTransporting(unitID); --[[ for _,transed in ipairs(transported) do if(transed~=unitID) then Echo(transed) end end if (transported~=nil) and (UnitDefs[GetUnitDefID(transported[1])].isCommander) then MarkerAddPoint(ex,ey,ez,"enemy com in transport") enemytranslist[unitID]=frameNum end --]] if (dist<1000) then --1000 is the current warning distance (for allies mostly) MarkerAddPoint(ex,ey,ez,"comnap warning!!") enemytranslist[unitID]=frameNum lastwarn=30 end end --500: the distance at which your com will start moving if ((dist<500) and (ComTeamID==myTeamID) and shouldescape and (not disabled)) then setUnitToPatrol(ComUnitID,x,y,z) shouldescape=false end end end end end -- for testing whether coms are in list: --[[ if((frameNum%1024)==0) then for unitID,_ in pairs(allycomlist) do local x,y,z = GetUnitPosition(unitID) if(x~=nil) then MarkerAddPoint(x,y,z) end end end --]] end end