Code: Select all
local versionNumber = "1.34"
function widget:GetInfo()
return {
name = "Map dependant ColourShift",
desc = "Shifts Colours of mapfeatures according to map",
author = "picasso",
date = "April 7, 2015",
license = "GNU GPL v2",
layer = 0,
enabled = true
}
end
-- CONFIGURATION
local debug = false --generates debug message
local updateInt = 1 --seconds for the ::update loop
local dontTrackEnemyWrecks = 0
-- END OF CONFIG
local lastTime
local ColourSchemeFeatures = {}
local ignoreFeature = {}
local HueOffsetByDefID={}
local floor = math.floor
local max = math.max
local udefTab = UnitDefs
local fdefTab = FeatureDefs
local glColor = gl.Color
local glDepthTest = gl.DepthTest
local glRotate = gl.Rotate
local glTexture = gl.Texture
local glTexEnv = gl.TexEnv
local glLineWidth = gl.LineWidth
local glPopMatrix = gl.PopMatrix
local glPushMatrix = gl.PushMatrix
local glTranslate = gl.Translate
local glFeatureShape = gl.FeatureShape
local glUnitShape = gl.UnitShape
local spGetGameSeconds = Spring.GetGameSeconds
local spGetMyPlayerID = Spring.GetMyPlayerID
local spGetPlayerInfo = Spring.GetPlayerInfo
local spGetAllFeatures = Spring.GetAllFeatures
local spGetFeaturePosition = Spring.GetFeaturePosition
local spGetFeatureDefID = Spring.GetFeatureDefID
local spGetMyAllyTeamID = Spring.GetMyAllyTeamID
local spGetFeatureAllyTeam = Spring.GetFeatureAllyTeam
local spGetFeatureTeam = Spring.GetFeatureTeam
local spGetUnitHealth = Spring.GetUnitHealth
local spGetFeatureHealth = Spring.GetFeatureHealth
local spGetFeatureResurrect = Spring.GetFeatureResurrect
local spGetPositionLosState = Spring.GetPositionLosState
local spIsUnitAllied = Spring.IsUnitAllied
local spGetUnitDirection = Spring.GetUnitDirection
local spGetFeatureDirection = Spring.GetFeatureDirection
local spGetUnitBasePosition = Spring.GetUnitBasePosition
local spGetUnitPosition = Spring.GetUnitPosition
local spGetUnitHealth = Spring.GetUnitHealth
local spEcho = Spring.Echo
local spGetUnitDefID = Spring.GetUnitDefID
local spIsSphereInView = Spring.IsSphereInView
local spGetUnitBuildFacing = Spring.GetUnitBuildFacing
local mdeg = math.deg
local matan2 = math.atan2
local DrawColourSchemeFeatures
local ScanFeatures
local DeleteColourSchemeFeatures
local ResetGl
local CheckSpecState
local printDebug
local firstScan = true
function widget:Update()
local timef = spGetGameSeconds()
local time = floor(timef)
-- update timers once every <updateInt> seconds
if (time % updateInt == 0 and time ~= lastTime) then
lastTime = time
--do update stuff:
if ( CheckSpecState() == false ) then
return false
end
ScanFeatures()
DeleteColourSchemeFeatures()
end
end
function widget:DrawWorld()
DrawColourSchemeFeatures()
ResetGl()
end
local HueOffSet={}
--HueOffSet={[FeatureDefID]= 0-255}
function readInHueOffset()
--ReadIn LuaColourOffset by Map file
VFS.Include('Map/MapInfo.lua', nil, VFSMODE)
if not mapinfo.HueOffSet then widgetHandler:RemoveWidget() end
HueOffSet=mapinfo.HueOffSet
return
end
function DrawColourSchemeFeatures()
glColor(1.0, 1.0, 1.0, 0.35 )
glTexture(1,"$units2")
--glTexture(1,"$units1")
glTexEnv( GL.TEXTURE_ENV, GL.TEXTURE_ENV_MODE, 34160 ) --GL_COMBINE_RGB_ARB
--use the alpha given by glColor for the outgoing alpha.
glTexEnv( GL.TEXTURE_ENV, 34162, GL.REPLACE ) --GL_COMBINE_ALPHA
glTexEnv( GL.TEXTURE_ENV, 34184, 34167 ) --GL_SOURCE0_ALPHA_ARB GL_PRIMARY_COLOR_ARB
--------------------------Draw-------------------------------------------------------------
for unitID, ColourScheme in pairs( ColourSchemeFeatures ) do
local x, y, z = ColourScheme.x, ColourScheme.y, ColourScheme.z
local _, losState, _ = spGetPositionLosState(x, y, z)
local udef = fdefTab[ ColourScheme["featDefId"] ]
local radius = max( udef["xsize"], udef["zsize"] ) * 0.5
local inView = spIsSphereInView( x, y, z, radius )
if ( losState == false and inView and HueOffSet[udef] ) then
--glow effect?
--gl.Blending(GL.SRC_ALPHA, GL.ONE)
glPushMatrix()
glTranslate(x, y, z)
glRotate(ColourScheme.angle,0,y,0)
glFeatureShape(ColourScheme["featDefId"], ColourScheme["teamId"] )
glPopMatrix()
end
end
--------------------------Clean up-------------------------------------------------------------
--TODO: Here be atan resolved the hueshift for the features first texture based upon the second textures rgb
--local HueShift = HueOffSet[udef]
--for x=1,#Tex1.X, 1 do
--for y=1,#Tex1.Y, 1 do
-- if Tex2.Blue[x][y] > 0 do
--extract local or, og,ob= Tex1[x][y].r, Tex1[x][y].g, Tex1[x][y].b
-- alpha= (2*or - og - ob)/2
--U = math.cos(HueShift* PI/180);
--W = mathsin(HueShift* PI/180);
--Taken from stackoverflow : http://stackoverflow.com/questions/5007925/using-m-pi-with-c89-standard
-- r = (.299+.701*U+.168*W)*in.r
-- + (.587-.587*U+.330*W)*in.g
-- + (.114-.114*U-.497*W)*in.b;
--
-- g = (.299-.299*U-.328*W)*in.r
-- + (.587+.413*U+.035*W)*in.g
-- + (.114-.114*U+.292*W)*in.b;
--b = (.299-.3*U+1.25*W)*in.r
-- + (.587-.588*U-1.05*W)*in.g
-- + (.114+.886*U-.203*W)*in.b;
--Store it once computated into a cache- yes this produces a texture copy in lua space- but its still cheaper then computating it all again
glTexEnv( GL.TEXTURE_ENV, GL.TEXTURE_ENV_MODE, 8448 ) --GL_MODULATE
--use the alpha given by glColor for the outgoing alpha.
glTexEnv( GL.TEXTURE_ENV, 34162, 8448 ) --GL_MODULATE
----gl.TexEnv( GL.TEXTURE_ENV, 34184, 5890 ) --GL_SOURCE0_ALPHA_ARB GL_TEXTURE
end
function ScanFeatures()
local features = spGetAllFeatures()
if firstScan then
local sfind = string.find
for _, fID in ipairs(features) do
local fDefId = spGetFeatureDefID(fID)
local fName = FeatureDefs[fDefId].name
if sfind(fName, 'tree') or sfind(fName, 'rock') then
ignoreFeature[fDefId] = true
end
end
firstScan = false
return
end
local myAllyID = spGetMyAllyTeamID()
for _, fID in ipairs(features) do
local fDefId = spGetFeatureDefID(fID)
if not ignoreFeature[fDefId] then
local fAllyID = spGetFeatureAllyTeam(fID)
local fTeamID = spGetFeatureTeam( fID )
local resName, _ = spGetFeatureResurrect(fID)
if ( (resName == "" or dontTrackEnemyWrecks == 0) and fAllyID >= 0 and myAllyID ~= fAllyID and ColourSchemeFeatures[fID] == nil ) then
printDebug("ColourScheme Feature added: " .. fDefId )
local x, y, z = spGetFeaturePosition(fID)
local dx,_,dz = spGetFeatureDirection(fID)
local angle = mdeg(matan2(dx,dz))
ColourSchemeFeatures[fID] = { featDefId = fDefId, x=x, y=y, z=z, teamId = fTeamID, angle=angle }
end
end
end
end
function DeleteColourSchemeFeatures()
for featureID, ColourScheme in pairs(ColourSchemeFeatures) do
local a, b, c = spGetPositionLosState(ColourScheme.x, ColourScheme.y, ColourScheme.z)
local losState = b
local featDefID = spGetFeatureDefID(featureID)
--local health,_,_ = spGetFeatureHealth( unitID )
if ( featDefID == nil and losState) then
printDebug("ColourScheme Feature deleted: " .. featureID )
ColourSchemeFeatures[featureID] = nil
end
end
end
function widget:GameStart()
if widgetHandler.widgets then
for i, widget in ipairs(widgetHandler.widgets) do
if (widget:GetInfo().name == 'Defense Range') then
local version = tonumber(string.match(widget:GetInfo().desc,'%d+%.%d+'))
if version and (version < tonumber("6")) then
spEcho("<ColourScheme Site> Old DefenseRange found! Widget removed.")
widgetHandler:RemoveWidget()
end
end
end
end
readInHueOffset()
end
--Commons
function ResetGl()
glColor( { 1.0, 1.0, 1.0, 1.0 } )
glLineWidth( 1.0 )
glDepthTest(false)
glTexture(false)
end
function CheckSpecState()
local playerID = spGetMyPlayerID()
local _, _, spec, _, _, _, _, _ = spGetPlayerInfo(playerID)
if ( spec == true ) then
spEcho("<ColourScheme Site> Spectator mode. Widget removed.")
widgetHandler:RemoveWidget()
return false
end
return true
end
function printDebug( value )
if ( debug ) then
if ( type( value ) == "boolean" ) then
if ( value == true ) then spEcho( "true" )
else spEcho("false") end
elseif ( type(value ) == "table" ) then
spEcho("Dumping table:")
for key,val in pairs(value) do
spEcho(key,val)
end
else
spEcho( value )
end
end
end
A draft based upon the GhostScheme widget - Critique? Suggestions? Caching good, evil, meh?