Minimap mod

FehaFeha Join Date: 2006-11-16 Member: 58633Members
edited August 2011 in Modding
<div class="IPBDescription">For spectators</div>When I first saw the minimap in ns2hd's videos, I figured that I could do something similar in Lua code.
I did it pretty quick, but then build 180 came with a changed GUIMinimap (and a sweet new .tga file for summit).

So I decided to redo the mod now, from build 180's minimap, which I now have (with a few additions, such as location names on the small map, and i moved it to bottom right instead of keeping the position commanders use).

<b>Version 2</b>
I updated the mod, text stays over everything, and as a spectator you see the blips in their teams color, rather than all players being gray and buildings red. I also made the icons scale down slightly when the map is small.

<b>Version 3</b>
Another update, this one makes stuff on your team appear green, and not have same color as all the neutral stuff. The players own icon now use enemy teams color to stay unique. Own teams color couldn't be used for either of them, as its the minimaps color.

<b>Version 4</b>
Fourth version, now you can see normal structures on the minimap! You cant see what structure that thing is, and sadly, I cant fix that. The code that creates data that is later read to make minimap blips, is located serverside, and it simply fills the type field as "Structure". This means that I cant fix this if I want to keep the mod all clientside, which is something I do want.
The minimap will use hydra icons for alien structures, and observatory icons for marine structures.

<b>Version 5</b>
I was asked to make the minimap transparent, so that I did. It is only transparent when its covering whole screen (so not the tiny minimap that commanders and spectators have normally).
To chaneg how transparent it is, go to line 460 "color.a = 0.75" and change the value. 0 makes it invisible, and 1 makes it solid.

<b>Version 6</b>
NS2HD asked me if I could make the small minimap for spectators 50% bigger. I did that, but sort of fail. Sure the result worked without problems, but the code was not as good. I suspect it had to do with me being sleep deprived, as I now after a good nights sleep managed to do what I wanted (I wanted it easy to customize even if you don't know coding).
I now made the minimap scalable, just use a variable called GUIMinimap.kSmallSpectatorSizeScale at line 33 (That is near the top, together with a bunch of other variables I surrounded with "-" symbols).
The value is percent of how big you want the small map for spectators be. A value of 1.5 is 50% bigger than commanders map, a value of 1 is same size. A value of 2 is twice the size, which means it is same size as the normal "big" minimap.
I will leave it at a value of 1 as a default, but if you want to re-size it, just change it.
I moved all my other constants to the same area near the top, such as spectators map color and transparency, and surrounded them with "-" symbols to make it easy to find.

<b>Version 7</b>
Very minor update, simply added a variable to make it easy for people to customize if they want the self-icon for spectators to be visible.

<b>Version 8</b>
I fixed the rotation of the FOV icon and made it visible, as was requested by jimbob

<b>Version 9</b>
I made waypoints appear on the minimap. Only the actual destination, as I don't see the use for displaying where the next point on your path is. Would just be confusing if you saw both of them on the minimap, as you might mistake one for the other.
The waypoints are opposite teams color, just like the self-icon, and I also made them have a pulsing size (simple sine wave added to the size).

<b>Version 10</b>
Merged with build 181 and improved some stuff I didn't like.


<b>Version 11</b>
Fixed some bugs and stuff. I am not even sure what I fixed compared to last version, as I slacked behind a little in updating this thread.


You can easily change:
<ul><li>The <b>size</b> of the small minimap for spectator at line 34, "GUIMinimap.kSmallSpectatorSizeScale = 1". It is in percent, so a value of 1 equals 100% of default, while a value of 2 would be 200% (same size as the big minimap)</li><li>The <b>color </b>of the minimap at line 39, "GUIMinimap.kSpectatorTeamColor = kNeutralTeamColor". You can make it equal a number in the form of 0xRRGGBB, or use some global colors like I do. maybe kMarineTeamColor?</li><li>The <b>transparency </b>of the big minimap at line 41, "GUIMinimap.kBigSizeAlpha = 0.5". The lower, the more transparent.</li><li>The visibility of the<b> self-icon</b> on the minimap at line 45, by changing "GUIMinimap.kSpectatorShowSelfIcon = true". The value can be true or false.</li></ul>


The code (does anyone know how to get a codebox with fixed width?):
<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>// ======= Copyright © 2003-2011, Unknown Worlds Entertainment, Inc. All rights reserved. =======
//
// lua\GUIMinimap.lua
//
// Created by: Brian Cronin (brianc@unknownworlds.com)
// Modded by: feha
//
// Manages displaying the minimap and icons on the minimap.
//
// ========= For more information, visit us at <a href="http://www.unknownworlds.com" target="_blank">http://www.unknownworlds.com</a> =====================

Script.Load("lua/GUIScanlines.lua")
Script.Load("lua/FunctionContracts.lua")

class 'GUIMinimap' (GUIScript)

GUIMinimap.kModeMini = 0
GUIMinimap.kModeBig = 1

GUIMinimap.kMapBackgroundXOffset = 10
GUIMinimap.kMapBackgroundYOffset = 10

GUIMinimap.kBackgroundTextureAlien = "ui/alien_commander_background.dds"
GUIMinimap.kBackgroundTextureMarine = "ui/marine_commander_background.dds"
GUIMinimap.kBackgroundTextureCoords = { X1 = 473, Y1 = 0, X2 = 793, Y2 = 333 }

GUIMinimap.kBigSizeScale = 2
GUIMinimap.kBackgroundSize = GUIScale(300)
GUIMinimap.kBackgroundWidth = GUIMinimap.kBackgroundSize
GUIMinimap.kBackgroundHeight = GUIMinimap.kBackgroundSize

//------------------------------------------------------------------------------------------------
// A variable to be able to scale the minmap easyer for spectators
GUIMinimap.kSmallSpectatorSizeScale = 1
// The blips are very small on the small minimap, so I want them slightly bigger
GUIMinimap.kSpectatorSmallBlipScale = GUIMinimap.kSmallSpectatorSizeScale * 1.15
// This is the variable for minimaps small size as spectator
GUIMinimap.kMinimapSmallSpectatorSize = Vector(GUIMinimap.kBackgroundWidth * GUIMinimap.kSmallSpectatorSizeScale, GUIMinimap.kBackgroundHeight * GUIMinimap.kSmallSpectatorSizeScale, 0)
// Spectator team dont have its own color sadly, lets give it one temporary
GUIMinimap.kSpectatorTeamColor = kNeutralTeamColor
// How transparent do you want the map? A value of 1 is solid, and 0 isinvisible
GUIMinimap.kBigSizeAlpha = 0.5
GUIMinimap.kSmallSpectatorSizeAlpha = 1
// Should the self-icon show for spectators? NS2HD didnt want it, but I prefer it. True/False
GUIMinimap.kSpectatorShowSelfIcon = true
//------------------------------------------------------------------------------------------------

local kStaticPriorityBlips = {}

kStaticPriorityBlips["CommandStation"] = true
kStaticPriorityBlips["Extractor"] = true
kStaticPriorityBlips["Hive"] = true
kStaticPriorityBlips["Harvester"] = true

GUIMinimap.kMapMinMax = 55
GUIMinimap.kMapRatio = function() return ConditionalValue(Client.minimapExtentScale.z > Client.minimapExtentScale.x, Client.minimapExtentScale.z / Client.minimapExtentScale.x, Client.minimapExtentScale.x / Client.minimapExtentScale.z) end

GUIMinimap.kMinimapSmallSize = Vector(GUIMinimap.kBackgroundWidth, GUIMinimap.kBackgroundHeight, 0)
GUIMinimap.kMinimapBigSize = Vector(GUIMinimap.kBackgroundWidth * GUIMinimap.kBigSizeScale, GUIMinimap.kBackgroundHeight * GUIMinimap.kBigSizeScale, 0)

GUIMinimap.kBlipSize = GUIScale(30)
GUIMinimap.kUnpoweredNodeBlipSize = GUIScale(32)

GUIMinimap.kTeamColors = { }
GUIMinimap.kTeamColors[kMinimapBlipTeam.Friendly] = Color(0, 1, 0, 1)
GUIMinimap.kTeamColors[kMinimapBlipTeam.Enemy] = Color(1, 0, 0, 1)
GUIMinimap.kTeamColors[kMinimapBlipTeam.Neutral] = Color(0.5, 0.5, 0.5, 1)
GUIMinimap.kTeamColors[4] = ColorIntToColor(kMarineTeamColor)
GUIMinimap.kTeamColors[5] = ColorIntToColor(kAlienTeamColor)

GUIMinimap.kUnpoweredNodeColor = Color(1, 0, 0)

GUIMinimap.kIconFileName = "ui/minimap_blip.dds"
GUIMinimap.kIconWidth = 32
GUIMinimap.kIconHeight = 32

GUIMinimap.kUnpoweredNodeFileName = "ui/power_node_off.dds"
GUIMinimap.kUnpoweredNodeIconWidth = 32
GUIMinimap.kUnpoweredNodeIconHeight = 32

GUIMinimap.kStaticBlipsLayer = 0
GUIMinimap.kStaticBlipsLayerPriority = 1 // Sometimes some important blips get drawn below stuff
GUIMinimap.kPlayerIconLayer = 2
GUIMinimap.kDynamicBlipsLayer = 3
GUIMinimap.kTextLayer = 4 // We want text to be drawn over everything else (I think)

GUIMinimap.kBlipTexture = "ui/blip.dds"

GUIMinimap.kBlipTextureCoordinates = { }
GUIMinimap.kBlipTextureCoordinates[kAlertType.Attack] = { X1 = 0, Y1 = 0, X2 = 64, Y2 = 64 }

GUIMinimap.kAttackBlipMinSize = Vector(GUIScale(25), GUIScale(25), 0)
GUIMinimap.kAttackBlipMaxSize = Vector(GUIScale(100), GUIScale(100), 0)
GUIMinimap.kAttackBlipPulseSpeed = 6
GUIMinimap.kAttackBlipTime = 5
GUIMinimap.kAttackBlipFadeInTime = 4.5
GUIMinimap.kAttackBlipFadeOutTime = 1

// The different font-sizes for the big and the small minimap
GUIMinimap.kLocationFontSize = 12
GUIMinimap.kLocationFontSizeSmall = 10

local ClassToGrid = { }

ClassToGrid["TechPoint"] = { 1, 1 }
ClassToGrid["ResourcePoint"] = { 2, 1 }
ClassToGrid["Door"] = { 3, 1 }
ClassToGrid["DoorLocked"] = { 4, 1 }
ClassToGrid["DoorWelded"] = { 5, 1 }
ClassToGrid["Grenade"] = { 6, 1 }
ClassToGrid["PowerPoint"] = { 7, 1 }

ClassToGrid["ReadyRoomPlayer"] = { 1, 2 }
ClassToGrid["Marine"] = { 1, 2 }
ClassToGrid["Heavy"] = { 2, 2 }
ClassToGrid["Jetpack"] = { 3, 2 }
ClassToGrid["MAC"] = { 4, 2 }
ClassToGrid["CommandStationOccupied"] = { 5, 2 }
ClassToGrid["CommandStationL2Occupied"] = { 6, 2 }
ClassToGrid["CommandStationL3Occupied"] = { 7, 2 }
ClassToGrid["Death"] = { 8, 2 }

ClassToGrid["Skulk"] = { 1, 3 }
ClassToGrid["Gorge"] = { 2, 3 }
ClassToGrid["Lerk"] = { 3, 3 }
ClassToGrid["Fade"] = { 4, 3 }
ClassToGrid["Onos"] = { 5, 3 }
ClassToGrid["Drifter"] = { 6, 3 }
ClassToGrid["HiveOccupied"] = { 7, 3 }
ClassToGrid["Kill"] = { 8, 3 }

ClassToGrid["CommandStation"] = ClassToGrid["TechPoint"] //{ 1, 4 }
ClassToGrid["CommandStationL2"] = { 2, 4 }
ClassToGrid["CommandStationL3"] = { 3, 4 }
ClassToGrid["Extractor"] = ClassToGrid["ResourcePoint"] //{ 4, 4 }
ClassToGrid["Sentry"] = { 5, 4 }
ClassToGrid["ARC"] = { 6, 4 }
ClassToGrid["ARCDeployed"] = { 7, 4 }

ClassToGrid["InfantryPortal"] = { 1, 5 }
ClassToGrid["Armory"] = { 2, 5 }
ClassToGrid["AdvancedArmory"] = { 3, 5 }
ClassToGrid["AdvancedArmoryModule"] = { 4, 5 }
ClassToGrid["Observatory"] = { 6, 5 }

ClassToGrid["HiveBuilding"] = { 1, 6 }
ClassToGrid["Hive"] = ClassToGrid["TechPoint"] //{ 2, 6 }
ClassToGrid["HiveL2"] = { 3, 6 }
ClassToGrid["HiveL3"] = { 4, 6 }
ClassToGrid["Harvester"] = ClassToGrid["ResourcePoint"] //{ 5, 6 }
ClassToGrid["Hydra"] = { 6, 6 }
ClassToGrid["Egg"] = { 7, 6 }

ClassToGrid["Crag"] = { 1, 7 }
ClassToGrid["MatureCrag"] = { 2, 7 }
ClassToGrid["Whip"] = { 3, 7 }
ClassToGrid["MatureWhip"] = { 4, 7 }

ClassToGrid["WaypointMove"] = { 1, 8 }
ClassToGrid["WaypointDefend"] = { 2, 8 }
ClassToGrid["PlayerFOV"] = { 4, 8 }

/**
* Returns Column and Row to find the minimap icon for the passed in class.
*/
local function GetSpriteGridByClass(class)

// This really shouldn't happen but lets return something just in case.
if not ClassToGrid[class] then
return 8, 1
end

return unpack(ClassToGrid[class])

end
AddFunctionContract(GetSpriteGridByClass, { Arguments = { "string" }, Returns = { "number", "number" } })

local function PlotToMap(posX, posZ, comMode)

local adjustedX = posX - Client.minimapExtentOrigin.x
local adjustedZ = posZ - Client.minimapExtentOrigin.z

local xFactor = 4
local zFactor = xFactor / GUIMinimap.kMapRatio()

local plottedX = (adjustedX / (Client.minimapExtentScale.x / xFactor)) * GUIMinimap.kBackgroundSize
local plottedY = (adjustedZ / (Client.minimapExtentScale.z / zFactor)) * GUIMinimap.kBackgroundSize

// The X/Y is currently for a minimap with a scale of 2, lets divide it by 2 for a scale of 1
// Dividing with kBigSizeScale is the wrong way to do it UWE, try it your way with it set to 3
plottedX = plottedX / 2
plottedY = plottedY / 2

// This makes it rescale to another size if
local sizeScale = GUIMinimap:GetSizeScale(comMode)
plottedX = plottedX * sizeScale
plottedY = plottedY * sizeScale

// The world space is oriented differently from the GUI space, adjust for that here.
// Return 0 as the third parameter so the results can easily be added to a Vector.
return plottedY, -plottedX, 0

end
AddFunctionContract(PlotToMap, { Arguments = { "number", "number", "number" }, Returns = { "number", "number", "number" } })

function GUIMinimap:Initialize()

self:InitializeBackground()
self:InitializeScanlines()

self.minimap = GUIManager:CreateGraphicItem()

self:InitializeLocationNames()

self.comMode = nil
self:SetBackgroundMode(GUIMinimap.kModeMini)
self.minimap:SetTexture("maps/overviews/" .. Shared.GetMapName() .. ".tga")
self.minimap:SetColor(PlayerUI_GetTeamColor())

self.background:AddChild(self.minimap)

// Used for commander.
self:InitializeCameraLines()

// Used for normal players.
self:InitializePlayerIcon()

//Used for waypoints
self:InitializeWaypointIcon()

self.staticBlips = { }

self.reuseDynamicBlips = { }
self.inuseDynamicBlips = { }

self.mousePressed = { LMB = { Down = nil, X = 0, Y = 0 }, RMB = { Down = nil, X = 0, Y = 0 } }

end

function GUIMinimap:InitializeBackground()

self.background = GUIManager:CreateGraphicItem()
self.background:SetSize(Vector(GUIMinimap.kBackgroundWidth, GUIMinimap.kBackgroundHeight, 0))
self.background:SetPosition(Vector(0, -GUIMinimap.kBackgroundHeight, 0))
GUISetTextureCoordinatesTable(self.background, GUIMinimap.kBackgroundTextureCoords)

self.background:SetAnchor(GUIItem.Left, GUIItem.Top)
self.background:SetLayer(kGUILayerMinimap)

// Non-commander players assume the map isn't visible by default.
if not PlayerUI_IsACommander() then
self.background:SetIsVisible(false)
end

end

function GUIMinimap:InitializeScanlines()

local settingsTable = { }
settingsTable.Width = GUIMinimap.kBackgroundWidth
settingsTable.Height = GUIMinimap.kBackgroundHeight
// The amount of extra scanline space that should be above the minimap.
settingsTable.ExtraHeight = 0
self.scanlines = GUIScanlines()
self.scanlines:Initialize(settingsTable)
self.scanlines:GetBackground():SetInheritsParentAlpha(true)
self.background:AddChild(self.scanlines:GetBackground())

end

function GUIMinimap:InitializeCameraLines()

self.cameraLines = GUIManager:CreateLinesItem()
self.cameraLines:SetAnchor(GUIItem.Center, GUIItem.Middle)
self.cameraLines:SetLayer(GUIMinimap.kPlayerIconLayer)
self.minimap:AddChild(self.cameraLines)

end

function GUIMinimap:InitializePlayerIcon()

self.playerIcon = GUIManager:CreateGraphicItem()
self.playerIcon:SetSize(Vector(GUIMinimap.kBlipSize, GUIMinimap.kBlipSize, 0))
self.playerIcon:SetAnchor(GUIItem.Middle, GUIItem.Center)
self.playerIcon:SetTexture(GUIMinimap.kIconFileName)
iconCol, iconRow = GetSpriteGridByClass(PlayerUI_GetPlayerClass())
self.playerIcon:SetTexturePixelCoordinates(GUIGetSprite(iconCol, iconRow, GUIMinimap.kIconWidth, GUIMinimap.kIconHeight))
self.playerIcon:SetIsVisible(false)
self.playerIcon:SetLayer(GUIMinimap.kPlayerIconLayer)
self.playerIcon:SetColor(Color(0, 1, 0, 1))
self.minimap:AddChild(self.playerIcon)

self.playerIconFov = GUIManager:CreateGraphicItem()
self.playerIconFov:SetSize(Vector(GUIMinimap.kBlipSize*2, GUIMinimap.kBlipSize, 0))
self.playerIconFov:SetAnchor(GUIItem.Middle, GUIItem.Top)
self.playerIconFov:SetPosition(Vector(-GUIMinimap.kBlipSize, -GUIMinimap.kBlipSize, 0))
self.playerIconFov:SetTexture(GUIMinimap.kIconFileName)
local iconCol, iconRow = GetSpriteGridByClass('PlayerFOV')
local gridPosX, gridPosY, gridWidth, gridHeight = GUIGetSprite(iconCol, iconRow, GUIMinimap.kIconWidth, GUIMinimap.kIconHeight)
self.playerIconFov:SetTexturePixelCoordinates(gridPosX-GUIMinimap.kIconWidth, gridPosY, gridWidth, gridHeight)
self.playerIconFov:SetIsVisible(false)
self.playerIconFov:SetLayer(GUIMinimap.kPlayerIconLayer)
self.playerIcon:AddChild(self.playerIconFov)

end

function GUIMinimap:InitializeWaypointIcon()

self.waypoint = GUIManager:CreateGraphicItem()
self.waypoint:SetSize(Vector(GUIMinimap.kBlipSize, GUIMinimap.kBlipSize, 0))
self.waypoint:SetAnchor(GUIItem.Middle, GUIItem.Center)
self.waypoint:SetTexture(GUIMinimap.kIconFileName)
iconCol, iconRow = GetSpriteGridByClass("WaypointMove")
self.waypoint:SetTexturePixelCoordinates(GUIGetSprite(iconCol, iconRow, GUIMinimap.kIconWidth, GUIMinimap.kIconHeight))
self.waypoint:SetIsVisible(false)
self.waypoint:SetLayer(GUIMinimap.kPlayerIconLayer)
self.waypoint:SetColor(Color(1, 1, 1, 1))
self.minimap:AddChild(self.waypoint)

end

function GUIMinimap:InitializeLocationNames()

self.locationItems = { }
local locationData = PlayerUI_GetLocationData()

// Average the position of same named locations so they don't display
// multiple times.
local multipleLocationsData = { }
for i, location in ipairs(locationData) do

// Filter out the ready room.
if location.Name ~= "Ready Room" then

local locationTable = multipleLocationsData[location.Name]
if locationTable == nil then

locationTable = { }
multipleLocationsData[location.Name] = locationTable

end
table.insert(locationTable, location.Origin)

end

end

self.uniqueLocationsData = { }
for name, origins in pairs(multipleLocationsData) do

local averageOrigin = Vector(0, 0, 0)
table.foreachfunctor(origins, function (origin) averageOrigin = averageOrigin + origin end)
table.insert(self.uniqueLocationsData, { Name = name, Origin = averageOrigin / table.count(origins) })

end

for i, location in ipairs(self.uniqueLocationsData) do

local locationItem = GUIManager:CreateTextItem()
locationItem:SetFontSize(GUIMinimap.kLocationFontSize)
locationItem:SetFontIsBold(true)
locationItem:SetAnchor(GUIItem.Middle, GUIItem.Center)
locationItem:SetTextAlignmentX(GUIItem.Align_Center)
locationItem:SetTextAlignmentY(GUIItem.Align_Center)

local posX, posY = PlotToMap(location.Origin.x, location.Origin.z, self.comMode)

// Locations only supported on the big mode.
locationItem:SetPosition(Vector(posX, posY, 0))
locationItem:SetColor(Color(1, 1, 1, 1))
locationItem:SetText(location.Name)
locationItem:SetLayer(GUIMinimap.kTextLayer)
self.minimap:AddChild(locationItem)
table.insert(self.locationItems, locationItem)

end

end

function GUIMinimap:Uninitialize()

// The ItemMask is the parent of the Item so this will destroy both.
for i, blip in ipairs(self.reuseDynamicBlips) do
GUI.DestroyItem(blip["ItemMask"])
end
self.reuseDynamicBlips = { }
for i, blip in ipairs(self.inuseDynamicBlips) do
GUI.DestroyItem(blip["ItemMask"])
end
self.inuseDynamicBlips = { }

if self.scanlines then
self.scanlines:Uninitialize()
self.scanlines = nil
end

if self.minimap then
GUI.DestroyItem(self.minimap)
end
self.minimap = nil

if self.background then
GUI.DestroyItem(self.background)
self.background = nil
end

// The staticBlips are children of the background so will be cleaned up with it.
self.staticBlips = { }

end

function GUIMinimap:SetButtonsScript(setButtonsScript)

self.buttonsScript = setButtonsScript

end

// We need to make a function to see if a player is spectator, as player_client.lua doesnt.
local function PlayerUI_IsASpectator()

local player = Client.GetLocalPlayer()
if player ~= nil then
return player:GetTeamNumber() == kSpectatorIndex
end

return false

end

// We need a function to see if player changed team
function GUIMinimap:PlayerChangedTeam()

local player = Client.GetLocalPlayer()
if player ~= nil then
local team = player:GetTeamNumber()
if team ~= self.lastTeam then
self.lastTeam = team
return team
end
end

return

end

function GUIMinimap:Update(deltaTime)

// Commander always sees the minimap.
if PlayerUI_IsACommander() then
self.background:SetIsVisible(true)
if CommanderUI_IsAlienCommander() then
self.background:SetTexture(GUIMinimap.kBackgroundTextureAlien)
else
self.background:SetTexture(GUIMinimap.kBackgroundTextureMarine)
end
elseif PlayerUI_IsASpectator() then
// We want spectators to always see minimap, like a commander can.
self.background:SetIsVisible(true)
elseif self.comMode == GUIMinimap.kModeMini then
// No minimap for non-commaders
self.background:SetIsVisible(false)
end

// if the players change team, we want to update some stuff for the minimap
local changedTeam = self:PlayerChangedTeam()
if changedTeam then
// We make sure comMode is not same as current size, so SetBackgroundMode actually runs
local currentMode = self.comMode
self.comMode = nil
self:SetBackgroundMode(currentMode)

// Set color for the own player icon to be opposite teams color as we want contrast with the
// minimaps bg, which is own teams color, and as we want a color no other blip uses.
local color = 1 // This makes it green if player is not in a normal team
if changedTeam == kTeam1Index then
color = 5
elseif changedTeam == kTeam2Index then
color = 4
end
self.playerIcon:SetColor(GUIMinimap.kTeamColors[color])
self.waypoint:SetColor(GUIMinimap.kTeamColors[color])
end

self:UpdateIcon()

self:UpdateWaypoint()

self:UpdateStaticBlips(deltaTime)

self:UpdateDynamicBlips(deltaTime)

self:UpdateInput()

if self.minimap:GetIsVisible() then
// The color cannot be attained right away in some cases so
// we need to make sure it is the correct color.

if PlayerUI_IsASpectator() then
// Colors the minimap itself, not the bg
self.minimap:SetColor(ColorIntToColor(GUIMinimap.kSpectatorTeamColor))
else
self.minimap:SetColor(PlayerUI_GetTeamColor())
end

local color = self.minimap:GetColor()
if self.comMode == GUIMinimap.kModeBig then
color.a = GUIMinimap.kBigSizeAlpha
elseif PlayerUI_IsASpectator() then
color.a = GUIMinimap.kSmallSpectatorSizeAlpha
end
self.minimap:SetColor(color)
end

if self.scanlines then
self.scanlines:Update(deltaTime)
end

end

function GUIMinimap:UpdateIcon()

if PlayerUI_IsACommander() then

self.playerIcon:SetIsVisible(false)
self.playerIconFov:SetIsVisible(false)
self.cameraLines:SetIsVisible(true)

local topLeftPoint, topRightPoint, bottomLeftPoint, bottomRightPoint = CommanderUI_ViewFarPlanePoints()
if topLeftPoint == nil then
return
end

topLeftPoint = Vector(PlotToMap(topLeftPoint.x, topLeftPoint.z, self.comMode))
topRightPoint = Vector(PlotToMap(topRightPoint.x, topRightPoint.z, self.comMode))
bottomLeftPoint = Vector(PlotToMap(bottomLeftPoint.x, bottomLeftPoint.z, self.comMode))
bottomRightPoint = Vector(PlotToMap(bottomRightPoint.x, bottomRightPoint.z, self.comMode))

self.cameraLines:ClearLines()
local lineColor = Color(1, 1, 1, 1)
self.cameraLines:AddLine(topLeftPoint, topRightPoint, lineColor)
self.cameraLines:AddLine(topRightPoint, bottomRightPoint, lineColor)
self.cameraLines:AddLine(bottomRightPoint, bottomLeftPoint, lineColor)
self.cameraLines:AddLine(bottomLeftPoint, topLeftPoint, lineColor)

elseif PlayerUI_IsAReadyRoomPlayer() or (not self.kSpectatorShowSelfIcon and PlayerUI_IsASpectator()) then

// No icons for ready room players.
self.cameraLines:SetIsVisible(false)
self.playerIcon:SetIsVisible(false)
self.playerIconFov:SetIsVisible(false)

else

// Draw a player icon representing this player's position.
local playerOrigin = PlayerUI_GetOrigin()
local playerRotation = PlayerUI_GetMinimapPlayerDirection()
local posX, posY = PlotToMap(playerOrigin.x, playerOrigin.z, self.comMode)

self.cameraLines:SetIsVisible(false)
self.playerIcon:SetIsVisible(true)
// Disabled until rotation is correct.
self.playerIconFov:SetIsVisible(true)

local sizeScale = GUIMinimap:GetSizeScale(self.comMode)

// kIconWidth and such are bigger than kBlipSize for some reason
// GUIMinimap.kIconWidth
// GUIMinimap.kIconHeight
local blipSize = GUIMinimap.kBlipSize
local width = (GUIMinimap.kBlipSize/2)*sizeScale
local height = (GUIMinimap.kBlipSize/2)*sizeScale

posX = posX - (width / 2)
posY = posY - (height / 2)

self.playerIcon:SetSize(Vector(width, height, 0))
self.playerIcon:SetPosition(Vector(posX, posY, 0))
self.playerIcon:SetRotation(Vector(0, 0, playerRotation))

/*
* UWE decided that the XZ-plane is the horizontal plane, but just like in
* games where the XY-plane is horizontal, they decided to keep the screen
* in a XY-plane. This means you can't imagine the screen as a sheet of paper
* lying on the table, where rotations happen around an upwards axis (the
* yaw component of 3D angles). Instead, as the screen is the XY-plane like
* in many other games, but the XY-plane is vertical in spark engine, we have
* to imagine the paper beign vertical, with its thin edge directed towards us,
* and the rotations happening around the z-axis (pitch in 3D angles).
*
* BUT, it seems as if angles is different in spark engine as well, as pitching
* seemed to rotate around the forward axis, which should be roll. Rolling
* however worked like I expected pitching to work, except that playerRotation
* goes counterclockwise, and rolling seems to rotate clockwise. That means I
* had to invert playerRotation for the rolling.
*
* I think I understand now, Z is the forward-vector, not X, which seems to be
* the right-vector. This means the screen can actually be imagined as a
* screen like the one in front of you, where the Z-axis apparently is the
* forward/depth axis. As said in the first paragraph, rotation on the XY
* plane happens around the Z-axis, but now we know that means a rotation
* around the forward-axis, not right-axis (roll in 3D-angles, not pitch or yaw).
*/
// I imagine the screen like mentioned above, and rotate x-dir around z to get eyeDir.
local eyeDir = Angles(0,0,-playerRotation):GetCoords().xAxis

// As the rotation seems to be bugged, I have to align the rotation-anchors of the icons.
// Then I move FOV in the direction you look as far as it was moved to align the anchors.
self.playerIconFov:SetPosition(Vector(-height, 0, 0) + eyeDir * height)
self.playerIconFov:SetRotation(Vector(0, 0, playerRotation))
self.playerIconFov:SetSize(Vector(2*width, height, 0))

local playerClass = PlayerUI_GetPlayerClass()
if (PlayerUI_IsASpectator()) then playerClass = "Marine" end //Spectators dont have an icon for their class
if GUIMinimap.playerClass ~= playerClass then

local iconCol, iconRow = GetSpriteGridByClass(playerClass)
self.playerIcon:SetTexturePixelCoordinates(GUIGetSprite(iconCol, iconRow, GUIMinimap.kIconWidth, GUIMinimap.kIconHeight))

GUIMinimap.playerClass = playerClass

end

end

end

function GUIMinimap:UpdateWaypoint()

local nextWaypointActive = PlayerUI_GetNextWaypointActive()

if not nextWaypointActive then

self.waypoint:SetIsVisible(false)

else

local waypointOrigin = Vector(player:GetVisibleWaypoint())
local waypointSize = GUIMinimap.kBlipSize/2
// Sin goes from -1 to 1, so lets add 1 to get 0-2 instead
local sine = (1+math.sin(Shared.GetTime()*math.pi))
waypointSize = waypointSize * (1+sine/10)

local screenX, screenY = PlotToMap(waypointOrigin.x, waypointOrigin.z, self.comMode)

local sizeScale = GUIMinimap:GetSizeScale(self.comMode)
waypointSize = waypointSize * sizeScale

screenX = screenX - (waypointSize / 2)
screenY = screenY - (waypointSize / 2)

self.waypoint:SetIsVisible(true)
self.waypoint:SetSize(Vector(waypointSize, waypointSize, 0))
self.waypoint:SetPosition(Vector(screenX, screenY, 0))

end

end

function GUIMinimap:UpdateStaticBlips(deltaTime)

// First hide all previous static blips.
for index, oldBlip in ipairs(self.staticBlips) do
oldBlip:SetIsVisible(false)
end

//I dont want to edit Player_Client, so to keep all edits in this file, I get the blips
local blips = Shared.GetEntitiesWithClassname("MapBlip")

local staticBlips = PlayerUI_GetStaticMapBlips()
local blipItemCount = 7
local numBlips = table.count(staticBlips) / blipItemCount
local currentIndex = 1
while numBlips > 0 do
local xPos, yPos = PlotToMap(staticBlips[currentIndex], staticBlips[currentIndex + 1], self.comMode)
local rotation = staticBlips[currentIndex + 2]
local xTexture = staticBlips[currentIndex + 3]
local yTexture = staticBlips[currentIndex + 4]
local blipType = staticBlips[currentIndex + 5]
local blipTeam = staticBlips[currentIndex + 6]

//We want spectators to see what team the blips belong to
local blipTeamColor = blipTeam
blipTeam = blips:GetEntityAtIndex(currentIndex/blipItemCount):GetTeamNumber()
if (PlayerUI_IsASpectator() or PlayerUI_IsAReadyRoomPlayer()) then
if blipTeam == kTeam1Index then
blipTeamColor = 4
elseif blipTeam == kTeam2Index then
blipTeamColor = 5
else
blipTeamColor = kMinimapBlipTeam.Neutral
end
end

self:SetStaticBlip(xPos, yPos, rotation, xTexture, yTexture, blipType, blipTeamColor)
currentIndex = currentIndex + blipItemCount
numBlips = numBlips - 1
end

end

function GUIMinimap:SetStaticBlip(xPos, yPos, rotation, xTexture, yTexture, blipType, blipTeamColor)

// Find a free static blip to reuse or create a new one.
local foundBlip = nil
for index, oldBlip in ipairs(self.staticBlips) do
if not oldBlip:GetIsVisible() then
foundBlip = oldBlip
break
end
end

if not foundBlip then
foundBlip = self:AddStaticBlip()
end

local textureName = GUIMinimap.kIconFileName
local iconWidth = GUIMinimap.kIconWidth
local iconHeight = GUIMinimap.kIconHeight
local iconCol = 0
local iconRow = 0
local blipColor = GUIMinimap.kTeamColors[blipTeamColor]
local blendTechnique = GUIItem.Default
local blipSize = GUIMinimap.kBlipSize

// Special case for PowerPoint.
if blipType == kMinimapBlipType.PowerPoint then

// Only unpowered node blips are sent.
blipColor = GUIMinimap.kUnpoweredNodeColor
local pulseAmount = (math.sin(Shared.GetTime()) + 1) / 2
blipColor.a = 0.5 + (pulseAmount * 0.5)

iconCol, iconRow = GetSpriteGridByClass('PowerPoint')

// Ignore eggs
elseif blipType == kMinimapBlipType.Egg then
return

// Everything else is handled here.
elseif table.contains(kMinimapBlipType, blipType) ~= nil then

iconCol, iconRow = GetSpriteGridByClass(EnumToString(kMinimapBlipType, blipType))

end

local sizeScale = GUIMinimap:GetSizeScale(self.comMode)
blipSize = (blipSize/2) * sizeScale

foundBlip:SetTexture(textureName)
foundBlip:SetTexturePixelCoordinates(GUIGetSprite(iconCol, iconRow, iconWidth, iconHeight))
foundBlip:SetIsVisible(true)
foundBlip:SetSize(Vector(blipSize, blipSize, 0))
foundBlip:SetPosition(Vector(xPos - (blipSize / 2), yPos - (blipSize / 2), 0))
foundBlip:SetRotation(Vector(0, 0, rotation))
foundBlip:SetColor(blipColor)
foundBlip:SetBlendTechnique(blendTechnique)


local layer = GUIMinimap.kStaticBlipsLayer
if kStaticPriorityBlips[blipType] == true then
layer = GUIMinimap.kStaticBlipsLayerPriority
end
foundBlip:SetLayer(layer)



end

function GUIMinimap:AddStaticBlip()

addedBlip = GUIManager:CreateGraphicItem()
addedBlip:SetAnchor(GUIItem.Center, GUIItem.Middle)
addedBlip:SetLayer(GUIMinimap.kStaticBlipsLayer)
self.minimap:AddChild(addedBlip)
table.insert(self.staticBlips, addedBlip)
return addedBlip

end

function GUIMinimap:UpdateDynamicBlips(deltaTime)

if PlayerUI_IsACommander() then
local newDynamicBlips = CommanderUI_GetDynamicMapBlips()
local blipItemCount = 3
local numBlips = table.count(newDynamicBlips) / blipItemCount
local currentIndex = 1
while numBlips > 0 do
local blipType = newDynamicBlips[currentIndex + 2]
self:AddDynamicBlip(newDynamicBlips[currentIndex], newDynamicBlips[currentIndex + 1], blipType)

currentIndex = currentIndex + blipItemCount
numBlips = numBlips - 1
end
end

local removeBlips = { }
for i, blip in ipairs(self.inuseDynamicBlips) do
if blip["Type"] == kAlertType.Attack then
if self:UpdateAttackBlip(blip, deltaTime) then
table.insert(removeBlips, blip)
end
end
end
for i, blip in ipairs(removeBlips) do
self:RemoveDynamicBlip(blip)
end

end

function GUIMinimap:UpdateAttackBlip(blip, deltaTime)

blip["Time"] = blip["Time"] - deltaTime

// Fade in.
if blip["Time"] >= GUIMinimap.kAttackBlipFadeInTime then
local fadeInAmount = ((GUIMinimap.kAttackBlipTime - blip["Time"]) / (GUIMinimap.kAttackBlipTime - GUIMinimap.kAttackBlipFadeInTime))
blip["Item"]:SetColor(Color(1, 1, 1, fadeInAmount))
else
blip["Item"]:SetColor(Color(1, 1, 1, 1))
end

// Fade out.
if blip["Time"] <= GUIMinimap.kAttackBlipFadeOutTime then
if blip["Time"] <= 0 then
// Done animating.
return true
end
blip["Item"]:SetColor(Color(1, 1, 1, blip["Time"] / GUIMinimap.kAttackBlipFadeOutTime))
end

local timeLeft = GUIMinimap.kAttackBlipTime - blip["Time"]
local pulseAmount = (math.sin(timeLeft * GUIMinimap.kAttackBlipPulseSpeed) + 1) / 2
local blipSize = LerpGeneric(GUIMinimap.kAttackBlipMinSize, GUIMinimap.kAttackBlipMaxSize / 2, pulseAmount)

blip["Item"]:SetSize(blipSize)
// Make sure it is always centered.
local sizeDifference = GUIMinimap.kAttackBlipMaxSize - blipSize
local minimapSize = self:GetMinimapSize()
local xOffset = (sizeDifference.x / 2) - GUIMinimap.kAttackBlipMaxSize.x / 2
local yOffset = (sizeDifference.y / 2) - GUIMinimap.kAttackBlipMaxSize.y / 2
local plotX, plotY = PlotToMap(blip["X"], blip["Y"], self.comMode)
blip["Item"]:SetPosition(Vector(plotX + xOffset, plotY + yOffset, 0))

// Not done yet.
return false

end

function GUIMinimap:AddDynamicBlip(xPos, yPos, blipType)

/**
* Blip types - kAlertType
*
* 0 - Attack
* Attention-getting spinning squares that start outside the minimap and spin down to converge to point
* on map, continuing to draw at point for a few seconds).
*
* 1 - Info
* Research complete, area blocked, structure couldn't be built, etc. White effect, not as important to
* grab your attention right away).
*
* 2 - Request
* Soldier needs ammo, asking for order, etc. Should be yellow or green effect that isn't as
* attention-getting as the under attack. Should draw for a couple seconds.)
*/

if blipType == kAlertType.Attack then
if self.scanlines then
// Disrupt should probably be a global function that disrupts all scanlines at the same time.
self.scanlines:Disrupt()
end
addedBlip = self:GetFreeDynamicBlip(xPos, yPos, blipType)
addedBlip["Item"]:SetSize(Vector(0, 0, 0))
addedBlip["Time"] = GUIMinimap.kAttackBlipTime
end

end

function GUIMinimap:RemoveDynamicBlip(blip)

blip["Item"]:SetIsVisible(false)
table.removevalue(self.inuseDynamicBlips, blip)
table.insert(self.reuseDynamicBlips, blip)

end

function GUIMinimap:GetFreeDynamicBlip(xPos, yPos, blipType)

local returnBlip = nil
if table.count(self.reuseDynamicBlips) > 0 then

returnBlip = self.reuseDynamicBlips[1]
table.removevalue(self.reuseDynamicBlips, returnBlip)
table.insert(self.inuseDynamicBlips, returnBlip)

else

returnBlip = { }
returnBlip["Item"] = GUIManager:CreateGraphicItem()
// Make sure these draw a layer above the minimap so they are on top.
returnBlip["Item"]:SetLayer(GUIMinimap.kDynamicBlipsLayer)
returnBlip["Item"]:SetTexture(GUIMinimap.kBlipTexture)
returnBlip["Item"]:SetBlendTechnique(GUIItem.Add)
returnBlip["Item"]:SetAnchor(GUIItem.Center, GUIItem.Middle)
self.minimap:AddChild(returnBlip["Item"])
table.insert(self.inuseDynamicBlips, returnBlip)

end

returnBlip["X"] = xPos
returnBlip["Y"] = yPos

returnBlip["Type"] = blipType
returnBlip["Item"]:SetIsVisible(true)
returnBlip["Item"]:SetColor(Color(1, 1, 1, 1))
local minimapSize = self:GetMinimapSize()
local plotX, plotY = PlotToMap(xPos, yPos, self.comMode)
returnBlip["Item"]:SetPosition(Vector(plotX, plotY, 0))
GUISetTextureCoordinatesTable(returnBlip["Item"], GUIMinimap.kBlipTextureCoordinates[blipType])
return returnBlip

end

function GUIMinimap:UpdateInput()

if PlayerUI_IsACommander() then
local mouseX, mouseY = Client.GetCursorPosScreen()
if self.mousePressed["LMB"]["Down"] then
local containsPoint, withinX, withinY = GUIItemContainsPoint(self.minimap, mouseX, mouseY)
if containsPoint then
local minimapSize = self:GetMinimapSize()
local backgroundScreenPosition = self.minimap:GetScreenPosition(Client.GetScreenWidth(), Client.GetScreenHeight())

local cameraPosition = Vector(mouseX, mouseY, 0)

cameraPosition.x = cameraPosition.x - backgroundScreenPosition.x
cameraPosition.y = cameraPosition.y - backgroundScreenPosition.y

local horizontalScale = CommanderUI_MapLayoutHorizontalScale()
local verticalScale = CommanderUI_MapLayoutVerticalScale()

local moveX = (cameraPosition.x / minimapSize.x) * horizontalScale
local moveY = (cameraPosition.y / minimapSize.y) * verticalScale

CommanderUI_MapMoveView(moveX, moveY)
end
end
end

end

function GUIMinimap:UpdateLocationNames(modeIsMini)

for i, location in ipairs(self.uniqueLocationsData) do

local posX, posY = PlotToMap(location.Origin.x, location.Origin.z, self.comMode)

local locationItem = self.locationItems[i]

// "Locations only supported on the big mode." NOT CORRECT ANYMORE!!! mwahaha :P
if modeIsMini then
locationItem:SetFontSize(self.kLocationFontSizeSmall)
else
locationItem:SetFontSize(self.kLocationFontSize)
end

locationItem:SetPosition(Vector(posX, posY, 0))

end

end

function GUIMinimap:SetBackgroundMode(setMode)

if self.comMode ~= setMode then

self.comMode = setMode
local modeIsMini = self.comMode == GUIMinimap.kModeMini

// Locations only visible in the big mode (or as spectator)
self:UpdateLocationNames(modeIsMini)
table.foreachfunctor(self.locationItems, function (item) item:SetIsVisible(PlayerUI_IsASpectator() or not modeIsMini) end)

local modeSize = self:GetMinimapSize()

if self.background then
if modeIsMini then
self.background:SetAnchor(GUIItem.Left, GUIItem.Bottom)
self.background:SetPosition(Vector(GUIMinimap.kMapBackgroundXOffset, -GUIMinimap.kBackgroundHeight - GUIMinimap.kMapBackgroundYOffset, 0))

if PlayerUI_IsASpectator() then
// Make the bg transparent for spectators, so you only see the minimap
self.background:SetColor(Color(1, 1, 1, 0))
// We want the minimap in bottom right corner as a spectator (i think)
self.background:SetPosition(Vector(Client.GetScreenWidth() - GUIMinimap.kBackgroundWidth * GUIMinimap.kSmallSpectatorSizeScale - GUIMinimap.kMapBackgroundXOffset, 0-GUIMinimap.kBackgroundHeight * GUIMinimap.kSmallSpectatorSizeScale - GUIMinimap.kMapBackgroundYOffset, 0))
else
// If player is not a spectator, they may see the bg
self.background:SetColor(Color(1, 1, 1, 1))
end
else
self.background:SetAnchor(GUIItem.Center, GUIItem.Middle)
self.background:SetPosition(Vector(-modeSize.x / 2, -modeSize.y / 2, 0))
self.background:SetColor(Color(1, 1, 1, 0))
end
end
self.minimap:SetSize(modeSize)

// We want the background to sit "inside" the border so move it up and to the right a bit.
local borderExtraWidth = ConditionalValue(self.background, GUIMinimap.kBackgroundWidth - self:GetMinimapSize().x, 0)
local borderExtraHeight = ConditionalValue(self.background, GUIMinimap.kBackgroundHeight - self:GetMinimapSize().y, 0)
local defaultPosition = Vector(borderExtraWidth / 2, borderExtraHeight / 2, 0)
local modePosition = ConditionalValue(modeIsMini, defaultPosition, Vector(0, 0, 0))
self.minimap:SetPosition(Vector(0, 0, 0))

end

end

function GUIMinimap:GetMinimapSize()

return ConditionalValue(self.comMode == GUIMinimap.kModeMini, ConditionalValue(PlayerUI_IsASpectator(),GUIMinimap.kMinimapSmallSpectatorSize,G
UIMinimap.kMinimapSmallSize), GUIMinimap.kMinimapBigSize)

end

function GUIMinimap:GetSizeScale(comMode)

// For some reason, GUIMinimap.comMode is nil in this function. No idea why.
if comMode == self.kModeBig then
return self.kBigSizeScale
elseif PlayerUI_IsASpectator() then
return self.kSmallSpectatorSizeScale
end
return 1

end

function GUIMinimap:GetPositionOnBackground(xPos, yPos, currentSize)

local backgroundScreenPosition = self.minimap:GetScreenPosition(Client.GetScreenWidth(), Client.GetScreenHeight())
local inBackgroundPosition = Vector((xPos * self:GetMinimapSize().x) - (currentSize.x / 2), (yPos * self:GetMinimapSize().y) - (currentSize.y / 2), 0)
return backgroundScreenPosition + inBackgroundPosition

end

// Shows or hides the big map.
function GUIMinimap:ShowMap(showMap)

// Non-commander/spectator players only see the map when the key is held down.
if not PlayerUI_IsACommander() and not PlayerUI_IsASpectator() then
self.background:SetIsVisible(showMap)
end

local previousComMode = self.comMode

self:SetBackgroundMode(ConditionalValue(showMap, GUIMinimap.kModeBig, GUIMinimap.kModeMini))

// Only call Update when the state changes
if previousComMode ~= self.comMode then
// Make sure everything is in sync in case this function is called after GUIMinimap:Update() is called.
self:Update(0)
end

end

function GUIMinimap:SendKeyEvent(key, down)

if PlayerUI_IsACommander() then
if key == InputKey.MouseButton0 and self.mousePressed["LMB"]["Down"] ~= down then
self.mousePressed["LMB"]["Down"] = down
local mouseX, mouseY = Client.GetCursorPosScreen()
local containsPoint, withinX, withinY = GUIItemContainsPoint(self.minimap, mouseX, mouseY)
if down and containsPoint then
local buttonIndex = nil
if self.buttonsScript then
buttonIndex = self.buttonsScript:GetTargetedButton()
end
if buttonIndex then
CommanderUI_ActionCancelled()
self.buttonsScript:SetTargetedButton(nil)
CommanderUI_MapClicked(withinX / self:GetMinimapSize().x, withinY / self:GetMinimapSize().y, 0, buttonIndex)
// The down event is considered "captured" at this point and shouldn't be processed in UpdateInput().
self.mousePressed["LMB"]["Down"] = false
end
return true
end
elseif key == InputKey.MouseButton1 and self.mousePressed["RMB"]["Down"] ~= down then
self.mousePressed["RMB"]["Down"] = down
local mouseX, mouseY = Client.GetCursorPosScreen()
local containsPoint, withinX, withinY = GUIItemContainsPoint(self.minimap, mouseX, mouseY)
if down and containsPoint then
if self.buttonsScript then
// Cancel just in case the user had a targeted action selected before this press.
CommanderUI_ActionCancelled()
self.buttonsScript:SetTargetedButton(nil)
end
CommanderUI_MapClicked(withinX / self:GetMinimapSize().x, withinY / self:GetMinimapSize().y, 1, nil)
return true
end
end
end

return false

end

function GUIMinimap:GetBackground()

return self.background

end

function GUIMinimap:ContainsPoint(pointX, pointY)

return GUIItemContainsPoint(self:GetBackground(), pointX, pointY) or GUIItemContainsPoint(self.minimap, pointX, pointY)

end</div>
Or download the file here:
<a href="http://dl.dropbox.com/u/25164097/GUIMinimap.lua" target="_blank">http://dl.dropbox.com/u/25164097/GUIMinimap.lua</a>

Here is a screen, hope you can view it, steam dont like displaying screens of non-public games.
And this forum doesn't like links to steam-screens placed within [img] tags
<a href="http://cloud.steampowered.com/ugc/576675927167572233/B3FD02EDDD994ECE21AB198F5E583B69827E268B/" target="_blank">http://cloud.steampowered.com/ugc/57667592...583B69827E268B/</a>

<b>Screens for version 2</b>
<a href="http://cloud.steampowered.com/ugc/576675927172340429/18D9296EFA274CE4B1515D3570AF22689A5938CB/" target="_blank">http://cloud.steampowered.com/ugc/57667592...AF22689A5938CB/</a>
<a href="http://cloud.steampowered.com/ugc/576675927172338032/5552AA7A87DB7E7AB7CBE72F7402B0EE6590A7DE/" target="_blank">http://cloud.steampowered.com/ugc/57667592...02B0EE6590A7DE/</a>

<b>Screens for version 10</b>
<a href="http://cloud.steampowered.com/ugc/576677340145265233/2F70B1C075CB61962EAFC110B6DCB16BA68F11EB/" target="_blank">Screen 1</a>
<a href="http://cloud.steampowered.com/ugc/576677340145263865/147CA5B60FD55B5D81B9108AB300E27A416926E3/" target="_blank">Screen 2</a>
<a href="http://cloud.steampowered.com/ugc/576677340145266027/C82DAF7F49FD9E8750C8AB48EB45BBBA1BE14B0E/" target="_blank">Screen 2</a>
«1

Comments

  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    *bump*
    An update, the map looks better now. and such.
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    edited July 2011
    *bump*
    Another update, fixed a bug pointed out by scardybob (thanks!), where own teams structure show up as neutral structures. Turned out that the color for friendly units was same as color for neutral units :P

    I could not find out why enemy techpoints and such do not show up on minimap until you can see them.
    At first I thought the code handling hiding enemy players also affected structures, but I couldnt find any such code, so now I am starting to suspect that it has to do with a bug in the spark engine.
    Clients doesnt seem to be sent data for entities with same team number as GetEnemyTeamNumber(player:GetTeamNumber(), or atleast Shared.GetEntitiesWithClassname(classname) does not seem to have those entities. Wierd bug is wierd...
    If I am mistaken, and anyone is able to help me, please post a reply!


    I would love feedback on what should be changed, or what other bugs the minimap has.
    Or any other feedback at all ;)
  • twilitebluetwiliteblue bug stalker Join Date: 2003-02-04 Member: 13116Members, NS2 Playtester, Squad Five Blue
    Nice work! Could you please upload it as a file, so it's easier to download? I'm sure NS2HD will love it!
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    edited July 2011
    I suppose I could if I ever could get the forums attachement system to cooperate with me.
    Actually, I think I can try using dropbox for that, it doesnt seem to hate me :P

    EDIT:
    Added a link to a download now
  • TrCTrC Join Date: 2008-11-30 Member: 65612Members
    Its nice, good work.
  • ObraxisObraxis Subnautica Animator & Generalist, NS2 Person Join Date: 2004-07-24 Member: 30071Super Administrators, Forum Admins, NS1 Playtester, Forum Moderators, NS2 Developer, Constellation, NS2 Playtester, Squad Five Silver, WC 2013 - Supporter, Subnautica Developer, Pistachionauts
    This is great work, I'm sure NS2HD will appreciate it! :-)
  • JimBob_UKJimBob_UK Join Date: 2010-04-09 Member: 71233Members
    Love it mate. Keep up the good work.
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    edited July 2011
    *bump*
    Updated
    Now you can see normal structures as well, but sadly not what kind that would be. There is code serverside I would have to edit (which I wont as I want to keep this mod clientside only), cause all the clients know, is that they are a "Structure". I made the minimap display hydra icons for alien buildings, and observatory icons for marine buildings.
  • HughHugh Cameraman San Francisco, CA Join Date: 2010-04-18 Member: 71444NS2 Developer, NS2 Playtester, Reinforced - Silver, Reinforced - Onos, WC 2013 - Shadow, Subnautica Developer, Pistachionauts
    Feha you are a god among men. I wil put this mod through its glorious paces this weekend in Cyd v Team 156!
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    Thanks xD

    And another bump, welcome the fifth update. A tiny update I made when JimBob requested that I made the minimap transparent. Only applies to the big minimap (the one you have to hold a key to see).
  • BJHBnade_spammerBJHBnade_spammer Join Date: 2005-02-25 Member: 42431Members
    edited July 2011
    i say if ns2hd approves of it devs should put this in the next build!!!

    thats the great thing about lua anyone can edit it. knowing what to do though is a whole other story.
  • ScardyBobScardyBob ScardyBob Join Date: 2009-11-25 Member: 69528Forum Admins, Forum Moderators, NS2 Playtester, Squad Five Blue, Reinforced - Shadow, WC 2013 - Shadow
    edited July 2011
    Love the mod. Makes some much needed fixes to the minimap. Definitely think UWE should incorporate this into the next build. Here are some picks I took of it in action.

    <a href="http://imgur.com/fy3Dn" target="_blank"><img src="http://i.imgur.com/fy3Dns.jpg" border="0" class="linked-image" /></a>
    <a href="http://imgur.com/ri3u2" target="_blank"><img src="http://i.imgur.com/ri3u2s.jpg" border="0" class="linked-image" /></a>
    <a href="http://imgur.com/NvCyH" target="_blank"><img src="http://i.imgur.com/NvCyHs.jpg" border="0" class="linked-image" /></a>
    <a href="http://imgur.com/ySSYF" target="_blank"><img src="http://i.imgur.com/ySSYFs.jpg" border="0" class="linked-image" /></a>
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    *Bump*
    Yet another version, as always I wrote about it in the first post
  • RokiyoRokiyo A.K.A. .::FeX::. Revenge Join Date: 2002-10-10 Member: 1471Members, Constellation
    edited July 2011
    Wow, very nice. The colours are a great addition.

    Would you be able to make it a bit bigger? I found it a little difficult to make out during video <a href="http://www.youtube.com/watch?v=qqwfhH97k_w" target="_blank">NS2HD[241]</a>.

    Edit: Oops, I just realised that's exactly what went into update 6!
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    Heh, ns2hd asked me the very same question when he tried it, which is why I did it. I got sort of surprised at first, but looking at the vid I would agree, he actually needed the ability to make it bigger (probably got a bigger game window or resolution).

    He also asked me to get rid of the green self-icon for spectators, which I did in update six. But I decided today to add a variable for that as well, so at the same area all my other customizable variables is locates (inside the "-" symbol wrapping), where you can now easily turn it on/off.
    I made it default to be visible.
    <!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->// Should the self-icon show for spectators? NS2HD didnt want it, but I prefer it. True/False
    GUIMinimap.kSpectatorShowSelfIcon = true<!--c2--></div><!--ec2-->

    So again bumpedibump for a seventh update (altough extremely minor XD).
    update six had the icon hidden for spectators, so if you dont want it visible, there is no need to update.
  • JimBob_UKJimBob_UK Join Date: 2010-04-09 Member: 71233Members
    Do you remeber the cone icon that was apart of the player location icon when the icons first appeared. Could you make that the spectator icon?
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    edited July 2011
    Yeah, I messed a lil bit with it at the beginning, it seemed to rotate oddly, as is stated in a comment in the default minimaps file.
    <!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->// Disabled until rotation is correct.
    //self.playerIconFov:SetIsVisible(true)<!--c2--></div><!--ec2-->

    I suppose I could mess a bit more with it, maybe make some hacky fix for it or something. :P
  • JimBob_UKJimBob_UK Join Date: 2010-04-09 Member: 71233Members
    Thats the one. Ye have a play with it, i think it will look good for spec mode.
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    edited July 2011
    Ok, I managed to do it, but then I decided to re-do it immediately, as what I had done was handle it as if the screen was lying down. Due to how sparks XY plane is not the horizontal one, when I handled the screen like that, I had to convert the directional vector to Vector(dir.x,dir.z,0). simple, but I figured I should get used to sparks XY plane. so I decided to handle the screen as if it was sparks XY plane, which it is. Took some time, as I am not used to think on that sort of plane. As I said, I am more used to horizontal XY planes :P

    <div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>/*
    * UWE decided that the XZ-plane is the horizontal plane, but just like in games where the
    * XY-plane is horizontal, they decided to keep the screen in a XY-plane.
    * This means you can't imagine the screen as a sheet of paper lying on the table, where
    * rotations happen around an upwards axis (the yaw component of 3D angles).
    * Instead, as the screen is the XY-plane like in many other games, but the plane is vertical
    * in spark engine, we have to imagine the paper beign vertical, with its thin edge directed
    * towards us, and the rotations happening around the z-axis (pitch in 3D angles).
    *
    * BUT, it seems as if angles is different in spark engine as well, as pitching seemed to
    * rotate around the forward axis, which should be roll. Rolling however worked like I
    * expected pitching to work, except that playerRotation goes counterclockwise, and rolling
    * seems to rotate clockwise. That means I had to invert playerRotation for the rolling.
    */
    // I imagine the screen like mentioned above, except roll what should have been pitch
    local forward = Angles(0,0,-playerRotation):GetCoords().xAxis

    // As the rotation seems to be bugged, I have to align the rotation-anchors of the icons
    // Then I move it in the direction you look as far as it was moved to align the anchors
    self.playerIconFov:SetPosition(Vector(-playerSize, 0, 0) + forward * playerSize)
    self.playerIconFov:SetRotation(Vector(0, 0, playerRotation))
    self.playerIconFov:SetSize(Vector(2*playerSize, playerSize, 0))</div>

    Anyone got more insight in spark engine? Cause it looks a bit as if Z is the forward-axis in spark, and not X as I assumed, which instead appears to be the right-axis. Roll, which is the angle around forward-axis, rotates around Z, pitch, which is the angle around right-axis, rotates around X. Can it possibly really be like that?

    EDIT:
    Ok, so I am pretty sure that it is the case. Seeing as rolling seem to happen around the Z-axis, it seems like Z is the forward-axis, not X. A vector ([x,y,z]) in gmod is [forward,right,up], but in ns2 it would be [right, up, forward]. This means that NS2 vectors is like gmod vectors, where the directions shifted 1 step to the left. I suppose that is pretty good to know. :P


    tl;dr
    I fixed the rotation of the FOV icon and made it visible, as requested by jimbob
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    edited July 2011
    I am now at version number nine. One more version and I will need to use 2 digits!

    I made waypoints visible on the minimap, they use same color as the self-icon, and they got a pulsing size to easily grab your attention (sine ways ftw!).

    I suppose this update only benefit marines, cause afaik you never get any waypoints if you are an alien, a spectator or a ready-room player.


    EDIT:
    I also just got 2 pages in this thread!
  • ScardyBobScardyBob ScardyBob Join Date: 2009-11-25 Member: 69528Forum Admins, Forum Moderators, NS2 Playtester, Squad Five Blue, Reinforced - Shadow, WC 2013 - Shadow
    Is there a chance you could fix some of the structure icon issues? Many structures on the marines show up as sentries on the minimap and hydras for the aliens (especially the cysts).
  • twilitebluetwiliteblue bug stalker Join Date: 2003-02-04 Member: 13116Members, NS2 Playtester, Squad Five Blue
    Awesome work Feha! I love you for adding waypoints on the minimap. It has been a needed feature.
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    edited July 2011
    Thanks! xD

    @ scardybob, as I said in the bump for when I added structure icons to the minimap, the marine icons are observatories, not sentries. :P
    Also, no, I can't "fix" the icons.
    <!--quoteo(post=1860481:date=Jul 14 2011, 12:20 AM:name=Feha)--><div class='quotetop'>QUOTE (Feha @ Jul 14 2011, 12:20 AM) <a href="index.php?act=findpost&pid=1860481"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->*bump*
    Updated
    Now you can see normal structures as well, but sadly not what kind that would be. <b>There is code serverside I would have to edit</b> (which I wont as I want to keep this mod clientside only), cause all the clients know, is that they are a <b>"Structure"</b>. I made the minimap display hydra icons for alien buildings, and <b>observatory </b>icons for marine buildings.<!--QuoteEnd--></div><!--QuoteEEnd-->
    And I can't just get all entities as a client, as for some reason, spark does not send you all the entities. Although I am not sure, maybe it actually sends all friendly buildings, and all enemy buildings you can see.
    I'm not sure, last time I messed around with it was when locations in chat was just added (when it always displayed your own location, no matter who talked). I tried getting a table of players back then, and it worked dodgy at best. At times it was empty, did not even find my own player (I used that Shared.GetEntitiesByClassname(string) function) :S.
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    My internet works properly again (its been lousy the last week), so I decided to post here now.
    I merged the code with 181, and improved some stuff (such as got rid of the ugly harvester and hive icons, and use the resource point and tech point icons like last build.

    Have fun! xD
  • SewlekSewlek The programmer previously known as Schimmel Join Date: 2003-05-13 Member: 16247Members, NS2 Developer, NS2 Playtester, Squad Five Gold, Subnautica Developer
    very nice :D
    could you remove the eggs from the minimap? its really not necessary to display them and they disturb a little bit
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    edited July 2011
    I can yes, and it is a good idea to at least try out, but I think I will do that tomorrow. should go to bed :P

    If you want to do it yourself for now, just go to function function GUIMinimap:SetStaticBlip (line 693)
    Just like there is
    "// Special case for PowerPoint.
    if blipType == kMinimapBlipType.PowerPoint then"
    you should be able to do something similar using Egg.

    EDIT:
    You answered so fast, that I am not sure if I updated my dropbox file in time. Just log in as comm and see if your camera is a rectangle, or a polygon with 4 corners (if its the latter, its the correct version).
  • aeroripperaeroripper Join Date: 2005-02-25 Member: 42471NS1 Playtester, Forum Moderators, Constellation
    Thank you for this mod! Is it possible to change the minimap colors to be like NS1?

    <a href="http://imageshack.us/photo/my-images/638/ns1minimap.png/" target="_blank">http://imageshack.us/photo/my-images/638/ns1minimap.png/</a>
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    Not exactly sure what you mean, the minimap is already blue for marines :S

    And as I said in the first mod, changing colors is easy. Sure, what I tell you how to change is the spectators color, but if you want to change the other teams color, just edit this part (around line 490):
    <!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->if PlayerUI_IsASpectator() then
        // Colors the minimap itself, not the bg
        self.minimap:SetColor(ColorIntToColor(GUIMinimap.kSpectatorTeamColor))
    else
        self.minimap:SetColor(PlayerUI_GetTeamColor())
    end<!--c2--></div><!--ec2-->
    You would change self.minimap:SetColor(PlayerUI_GetTeamColor()) with whatever color you want it to be, if you want it to be certain colors depending on team, class or whatever, just add if statements. if you need help with that, ask me ;).

    If there is anything else you want to be able to customize, feel free to ask me.
  • BJHBnade_spammerBJHBnade_spammer Join Date: 2005-02-25 Member: 42431Members
    i still like this mini map the best developers just need to implement more icons for the mini maps so we can have a better view of whats going on.
  • FehaFeha Join Date: 2006-11-16 Member: 58633Members
    I updated it, not sure exactly what is the difference since the last version, as I slaked behind on updating this thread.
    The latest thing I did was fix a bug where the hive icons (and cc + extractors and such) sometimes got drawn beneath the techpoint. Now some blips get a priority setting to always get drawn over other blips. Tell me if there is any other blips you think needs to get visibility priority.
    I also made eggs not visible, when shimmel asked me to. Not sure if I already updated thread with that or if it is news coming with this update.
Sign In or Register to comment.