diff --git a/LuaUI/Widgets/gui_havens.lua b/LuaUI/Widgets/gui_havens.lua index 1cada8b480..7e21be14da 100644 --- a/LuaUI/Widgets/gui_havens.lua +++ b/LuaUI/Widgets/gui_havens.lua @@ -2,16 +2,16 @@ ------------------------------------------------------------------------------------- function widget:GetInfo() - return { - name = "Haven Handler", - desc = "Haven Handler for Retreat Gadget", - author = "CarRepairer", - date = "2014-04-10", - license = "GNU GPL, v2 or later", - handler = true, - layer = 0, - enabled = true, - } + return { + name = "Haven Handler", + desc = "Haven Handler for Retreat Gadget", + author = "CarRepairer", + date = "2014-04-10", + license = "GNU GPL, v2 or later", + handler = true, + layer = 0, + enabled = true, + } end VFS.Include("LuaRules/Configs/customcmds.h.lua") @@ -20,19 +20,55 @@ VFS.Include("LuaRules/Configs/customcmds.h.lua") ------------------------------------------------------------------------------------- options_path = 'Settings/Interface/Retreat Zones' -options_order = {'onlyShowMyZones', 'cancelRetreat'} +options_order = {'drawNames', 'playerZonesRadio', 'customRetreatCircleColor', 'retreatCircleColor', 'cancelRetreat'} local RETREAT_OFF_TABLE = {0} +local PLAYER_HAVEN_COLOR = {1, 0.1, 0.1, 0.8} +local HavenUpdate options = { - onlyShowMyZones = { - name = 'Only Show My Zones', - desc = 'With this enabled you will only see your retreat zones.', - type = 'bool', - value = true, + playerZonesRadio = { + name = "Display Zone options", + type = 'radioButton', + value = 'player_only_spectator_los', + items = { + { + key = "player_only", + name = "Player Only", + desc = "Only show player's own Retreat Zones", + }, + { + key = "los", + name = "Team", + desc = "Show player's and ally's Retreat Zones", + }, + { + key = "player_only_spectator", + name = "Player Only (Spectator)", + desc = "Only show spectated player's Retreat Zones", + }, + { + key = "los_spectator", + name = "Team (Spectator)", + desc = "Show all Retreat Zones as Spectator", + }, + { + key = "player_only_spectator_los", + name = "Player Only/ Spectator All", + desc = "Only show player's zones when playing, but all zones as spectator", + }, + }, OnChange = function(self) - GetHavens() + HavenUpdate() end, + noHotkey = true, + }, + drawNames = { + name = 'Label Player Names', + desc = "Draws the name of other players' retreat zones", + type = 'bool', + value = false, + noHotkey = true, }, cancelRetreat = { name = 'Cancel Retreat', @@ -44,13 +80,43 @@ options = { Spring.GiveOrder(CMD_RETREAT, RETREAT_OFF_TABLE, CMD.OPT_RIGHT) end, }, + customRetreatCircleColor = { + name = 'Use custom color', + desc = 'Override player Retreat Circle color', + type = 'bool', + value = true, + noHotkey = true, + OnChange = function(self) + HavenUpdate() + end, + }, + retreatCircleColor = { + name = 'Retreat Circle', + type = 'colors', + value = {1, 0.1, 0.1, 0.8}, + OnChange = function (self) + PLAYER_HAVEN_COLOR = self.value + HavenUpdate() + end, + advanced = true + }, } -- speed-ups -local echo = Spring.Echo - local spGetGameFrame = Spring.GetGameFrame +local spGetLocalTeamID = Spring.GetLocalTeamID +local spGetTeamInfo = Spring.GetTeamInfo +local spGetPlayerInfo = Spring.GetPlayerInfo +local spGetTeamRulesParam = Spring.GetTeamRulesParam +local spGetTeamColor = Spring.GetTeamColor +local spGetGroundHeight = Spring.GetGroundHeight +local spGetTeamList = Spring.GetTeamList +local spGetMyPlayerID = Spring.GetMyPlayerID +local spIsGUIHidden = Spring.IsGUIHidden +local spGetSpectatingState = Spring.GetSpectatingState +local spGetGameRulesParam = Spring.GetGameRulesParam +local spSendLuaRulesMsg = Spring.SendLuaRulesMsg local glDepthTest = gl.DepthTest local glAlphaTest = gl.AlphaTest @@ -61,55 +127,63 @@ local glBillboard = gl.Billboard local glColor = gl.Color local GL_GREATER = GL.GREATER -local min = math.min local max = math.max -local floor = math.floor local abs = math.abs local havens = {} -local havenCount = 0 local RADIUS = 0 ---------------------------------------------------------------------------------------- -- functions - -function GetTeamHavens(teamID) - local start = havenCount - local teamHavenCount = Spring.GetTeamRulesParam(teamID, "haven_count") - if teamHavenCount then - havenCount = havenCount + teamHavenCount - if havenCount then - for i = 1, teamHavenCount do - havens[start + i] = { - x = Spring.GetTeamRulesParam(teamID, "haven_x" .. i), - z = Spring.GetTeamRulesParam(teamID, "haven_z" .. i) - } - havens[start + i].y = Spring.GetGroundHeight(havens[start + i].x, havens[start + i].z) - end - end - end +local function GetTeamName(teamID) + local _, leaderID = spGetTeamInfo(teamID, false) + local playerName = spGetPlayerInfo(leaderID, true) + return playerName end -function GetHavens() +HavenUpdate = function () -- local function havens = {} - havenCount = 0 - if options.onlyShowMyZones.value then - local spectating = Spring.GetSpectatingState() - if not spectating then - GetTeamHavens(Spring.GetLocalTeamID()) - end + local spectating = spGetSpectatingState() + local teams + -- how many states can we be in? + -- we can be spectating + -- we can be playing + -- options.drawSpectatorZones.value + -- options.drawAllyZones.value + local opt = options.playerZonesRadio.value + if spectating and (opt == "player_only" or opt == "los") then + -- do not populate havens if option is not spectator option + teams = havens -- empty table else - local teams = Spring.GetTeamList() - for i = 0, #teams-1 do - GetTeamHavens(i) + if opt == "los" or opt == "los_spectator" or (spectating and opt == "player_only_spectator_los") then + teams = spGetTeamList() -- all teams LOS visible + else -- opt is "player_only" or "player_only_spectator" + teams = {spGetLocalTeamID()} -- just my team end end -end + for x = 1, #teams do + local teamID = teams[x] + local teamHavenCount = spGetTeamRulesParam(teamID, "haven_count") + if teamHavenCount then + local teamLeaderName = GetTeamName(teamID) or "???" + local teamcolor = {spGetTeamColor(teamID)} + if teamID == spGetLocalTeamID() and options.customRetreatCircleColor.value then + teamcolor = PLAYER_HAVEN_COLOR + end -function HavenUpdate(teamID, allyTeamID) - local spectating = Spring.GetSpectatingState() - if (not spectating and Spring.GetLocalTeamID() == teamID) or (not options.onlyShowMyZones.value) then - GetHavens() + local start = #havens + for i = 1, teamHavenCount do + local px, pz = spGetTeamRulesParam(teamID, "haven_x" .. i), spGetTeamRulesParam(teamID, "haven_z" .. i) + havens[start + i] = { + x = px, + z = pz, + y = spGetGroundHeight(px, pz), -- strange when height at xz changes + name = teamLeaderName, + color = teamcolor, + team = teamID, + } + end + end end end @@ -117,21 +191,21 @@ end --callins function widget:PlayerChanged(playerID) - if playerID == Spring.GetMyPlayerID() then - GetHavens() + if playerID == spGetMyPlayerID() or spGetSpectatingState() then + HavenUpdate() end end function widget:Initialize() - RADIUS = Spring.GetGameRulesParam('retreatZoneRadius') or 5 + RADIUS = spGetGameRulesParam('retreatZoneRadius') or 5 widgetHandler:RegisterGlobal(widget, "HavenUpdate", HavenUpdate) - GetHavens() + HavenUpdate() end function widget:CommandNotify(cmdID, cmdParams, cmdOptions) if cmdID == CMD_SETHAVEN then local x,y,z = cmdParams[1], cmdParams[2], cmdParams[3] - Spring.SendLuaRulesMsg('sethaven|' .. x .. '|' .. y .. '|' .. z ) + spSendLuaRulesMsg('sethaven|' .. x .. '|' .. y .. '|' .. z ) return true end end @@ -154,47 +228,59 @@ function widget:CommandsChanged() end local function DrawWorldFunc() - local fade = abs((spGetGameFrame() % 40) - 20) / 20 - --Draw ambulance on havens. - if #havens == 0 or Spring.IsGUIHidden() then + if #havens == 0 or spIsGUIHidden() then return end - + + local drawNames = options.drawNames.value + glDepthTest(true) gl.LineWidth(2) - for i = 1, havenCount do + -- iterate over each haven and draw bounding circle and ?playername + for i = 1, #havens do local havenPosition = havens[i] local x, y, z = havenPosition.x, havenPosition.y, havenPosition.z + -- rather not make spring call for height here, but height can do strange things. gl.LineWidth(4) - glColor(1, 1, 1, 0.5) + glColor(1, 1, 1, 0.5) --WHITE gl.DrawGroundCircle(x, y, z, RADIUS, 32) - gl.LineWidth(2) - glColor(1, 0.1, 0.1, 0.8) + glColor(havenPosition.color) gl.DrawGroundCircle(x, y, z, RADIUS, 32) + if drawNames then + gl.PushMatrix() + glTranslate(x, y, z) + glBillboard() + glColor(havenPosition.color) + gl.Text(havenPosition.name, 0, -10, 15, 'noc') + gl.PopMatrix() + end end --for + + --iterate over havens again but this time paint ambulance indicator + local fade = abs((spGetGameFrame() % 40) - 20) / 20 glAlphaTest(GL_GREATER, 0) glColor(1,fade,fade,fade+0.1) glTexture('LuaUI/Images/commands/Bold/retreat.png') - - for i = 1, havenCount do + for i = 1, #havens do local havenPosition = havens[i] local x, y, z = havenPosition.x, max(havenPosition.y, 0.0), havenPosition.z + gl.PushMatrix() glTranslate(x, y, z) glBillboard() glTexRect(-10, 0, 10, 20) gl.PopMatrix() end --for - + glTexture(false) glAlphaTest(false) glDepthTest(false) end - + function widget:DrawWorld() DrawWorldFunc() end --DrawWorld