|
|
@ -1,4 +1,4 @@
|
|
|
|
-- an experimental lighting engine for df
|
|
|
|
-- an experimental lighting engine for df. param: "static" to not recalc when in game. press "~" to recalculate. "`" to exit
|
|
|
|
local gui = require 'gui'
|
|
|
|
local gui = require 'gui'
|
|
|
|
local guidm = require 'gui.dwarfmode'
|
|
|
|
local guidm = require 'gui.dwarfmode'
|
|
|
|
local render = require 'plugins.rendermax'
|
|
|
|
local render = require 'plugins.rendermax'
|
|
|
@ -36,9 +36,12 @@ end
|
|
|
|
LightOverlay=defclass(LightOverlay,guidm.DwarfOverlay)
|
|
|
|
LightOverlay=defclass(LightOverlay,guidm.DwarfOverlay)
|
|
|
|
LightOverlay.ATTRS {
|
|
|
|
LightOverlay.ATTRS {
|
|
|
|
lightMap={},
|
|
|
|
lightMap={},
|
|
|
|
dynamic=true
|
|
|
|
dynamic=true,
|
|
|
|
|
|
|
|
dirty=false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function LightOverlay.init(args)
|
|
|
|
function LightOverlay:init(args)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.tick=df.global.cur_year_tick_advmode
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function lightPassable(shape)
|
|
|
|
function lightPassable(shape)
|
|
|
@ -102,8 +105,14 @@ function line(x0, y0, x1, y1,plot)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
function LightOverlay:placeLightFov(pos,radius,color,f)
|
|
|
|
function LightOverlay:calculateFovs()
|
|
|
|
f=f or falloff
|
|
|
|
self.fovs=self.fovs or {}
|
|
|
|
|
|
|
|
self.precalc=self.precalc or {}
|
|
|
|
|
|
|
|
for k,v in ipairs(self.fovs) do
|
|
|
|
|
|
|
|
self:calculateFov(v.pos,v.radius,v.color)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function LightOverlay:calculateFov(pos,radius,color)
|
|
|
|
local vp=self:getViewport()
|
|
|
|
local vp=self:getViewport()
|
|
|
|
local map = self.df_layout.map
|
|
|
|
local map = self.df_layout.map
|
|
|
|
local ray=function(tx,ty)
|
|
|
|
local ray=function(tx,ty)
|
|
|
@ -115,9 +124,16 @@ function LightOverlay:placeLightFov(pos,radius,color,f)
|
|
|
|
local dtsq=(lx-x)*(lx-x)+(ly-y)*(ly-y)
|
|
|
|
local dtsq=(lx-x)*(lx-x)+(ly-y)*(ly-y)
|
|
|
|
local dt=math.sqrt(dtsq)
|
|
|
|
local dt=math.sqrt(dtsq)
|
|
|
|
local tile=x+y*map.width
|
|
|
|
local tile=x+y*map.width
|
|
|
|
|
|
|
|
if self.precalc[tile] then
|
|
|
|
|
|
|
|
local tcol=blend(self.precalc[tile],power)
|
|
|
|
|
|
|
|
if tcol.r==self.precalc[tile].r and tcol.g==self.precalc[tile].g and self.precalc[tile].b==self.precalc[tile].b
|
|
|
|
|
|
|
|
and dtsq>0 then
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
local ocol=self.lightMap[tile] or {r=0,g=0,b=0}
|
|
|
|
local ocol=self.lightMap[tile] or {r=0,g=0,b=0}
|
|
|
|
local ncol=blend(power,ocol)
|
|
|
|
local ncol=blend(power,ocol)
|
|
|
|
|
|
|
|
|
|
|
|
self.lightMap[tile]=ncol
|
|
|
|
self.lightMap[tile]=ncol
|
|
|
|
local v=self.ocupancy[tile]
|
|
|
|
local v=self.ocupancy[tile]
|
|
|
|
if dtsq>0 then
|
|
|
|
if dtsq>0 then
|
|
|
@ -136,6 +152,17 @@ function LightOverlay:placeLightFov(pos,radius,color,f)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
circle(pos.x,pos.y,radius,ray)
|
|
|
|
circle(pos.x,pos.y,radius,ray)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function LightOverlay:placeLightFov(pos,radius,color)
|
|
|
|
|
|
|
|
local map = self.df_layout.map
|
|
|
|
|
|
|
|
local tile=pos.x+pos.y*map.width
|
|
|
|
|
|
|
|
local ocol=self.precalc[tile] or {r=0,g=0,b=0}
|
|
|
|
|
|
|
|
local ncol=blend(color,ocol)
|
|
|
|
|
|
|
|
self.precalc[tile]=ncol
|
|
|
|
|
|
|
|
local ocol=self.lightMap[tile] or {r=0,g=0,b=0}
|
|
|
|
|
|
|
|
local ncol=blend(color,ocol)
|
|
|
|
|
|
|
|
self.lightMap[tile]=ncol
|
|
|
|
|
|
|
|
table.insert(self.fovs,{pos=pos,radius=radius,color=color})
|
|
|
|
|
|
|
|
end
|
|
|
|
function LightOverlay:placeLightFov2(pos,radius,color,f,rays)
|
|
|
|
function LightOverlay:placeLightFov2(pos,radius,color,f,rays)
|
|
|
|
f=f or falloff
|
|
|
|
f=f or falloff
|
|
|
|
local raycount=rays or 25
|
|
|
|
local raycount=rays or 25
|
|
|
@ -208,7 +235,7 @@ function LightOverlay:calculateLightLava()
|
|
|
|
if (t1 and t1.liquid_type and t1.flow_size>0) or
|
|
|
|
if (t1 and t1.liquid_type and t1.flow_size>0) or
|
|
|
|
(shape==df.tiletype_shape.EMPTY and t2 and t2.liquid_type and t2.flow_size>0) then
|
|
|
|
(shape==df.tiletype_shape.EMPTY and t2 and t2.liquid_type and t2.flow_size>0) then
|
|
|
|
--self:placeLight({x=i,y=j},5,{r=0.8,g=0.2,b=0.2})
|
|
|
|
--self:placeLight({x=i,y=j},5,{r=0.8,g=0.2,b=0.2})
|
|
|
|
self:placeLightFov({x=i,y=j},5,{r=0.8,g=0.2,b=0.2},nil,5)
|
|
|
|
self:placeLightFov({x=i,y=j},5,{r=0.8,g=0.2,b=0.2},nil)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -225,7 +252,7 @@ function LightOverlay:calculateLightSun()
|
|
|
|
|
|
|
|
|
|
|
|
if (t1 and t1.outside ) then
|
|
|
|
if (t1 and t1.outside ) then
|
|
|
|
|
|
|
|
|
|
|
|
self:placeLightFov({x=i,y=j},7,{r=1,g=1,b=1},nil,3)
|
|
|
|
self:placeLightFov({x=i,y=j},15,{r=1,g=1,b=1},nil)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -267,22 +294,36 @@ function LightOverlay:buildOcupancy()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function LightOverlay:changed()
|
|
|
|
|
|
|
|
if self.dirty or self.tick~=df.global.cur_year_tick_advmode then
|
|
|
|
|
|
|
|
self.dirty=false
|
|
|
|
|
|
|
|
self.tick=df.global.cur_year_tick_advmode
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
end
|
|
|
|
function LightOverlay:makeLightMap()
|
|
|
|
function LightOverlay:makeLightMap()
|
|
|
|
|
|
|
|
if not self:changed() then
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
self.fovs={}
|
|
|
|
|
|
|
|
self.precalc={}
|
|
|
|
self.lightMap={}
|
|
|
|
self.lightMap={}
|
|
|
|
|
|
|
|
|
|
|
|
self:buildOcupancy()
|
|
|
|
self:buildOcupancy()
|
|
|
|
self:calculateLightCursor()
|
|
|
|
self:calculateLightCursor()
|
|
|
|
self:calculateLightLava()
|
|
|
|
self:calculateLightLava()
|
|
|
|
self:calculateLightSun()
|
|
|
|
self:calculateLightSun()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self:calculateFovs()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
function LightOverlay:onIdle()
|
|
|
|
function LightOverlay:onIdle()
|
|
|
|
self._native.parent:logic()
|
|
|
|
self._native.parent:logic()
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function LightOverlay:render(dc)
|
|
|
|
if self.dynamic then
|
|
|
|
if self.dynamic then
|
|
|
|
self:makeLightMap()
|
|
|
|
self:makeLightMap()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function LightOverlay:render(dc)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self:renderParent()
|
|
|
|
self:renderParent()
|
|
|
|
local vp=self:getViewport()
|
|
|
|
local vp=self:getViewport()
|
|
|
|
local map = self.df_layout.map
|
|
|
|
local map = self.df_layout.map
|
|
|
@ -313,7 +354,7 @@ function LightOverlay:onDismiss()
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
function LightOverlay:onInput(keys)
|
|
|
|
function LightOverlay:onInput(keys)
|
|
|
|
if keys.LEAVESCREEN then
|
|
|
|
if keys.STRING_A096 then
|
|
|
|
self:dismiss()
|
|
|
|
self:dismiss()
|
|
|
|
else
|
|
|
|
else
|
|
|
|
self:sendInputToParent(keys)
|
|
|
|
self:sendInputToParent(keys)
|
|
|
@ -324,6 +365,7 @@ function LightOverlay:onInput(keys)
|
|
|
|
if keys.STRING_A126 and not self.dynamic then
|
|
|
|
if keys.STRING_A126 and not self.dynamic then
|
|
|
|
self:makeLightMap()
|
|
|
|
self:makeLightMap()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
self.dirty=true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if not render.isEnabled() then
|
|
|
|
if not render.isEnabled() then
|
|
|
|