light.lua: more help, changed screen exit key to '`'. Made it recalculate only when needed.

develop
Warmist 2013-06-23 13:28:22 +03:00
parent 1ce43c6cc4
commit 4ce951f5b9
1 changed files with 55 additions and 13 deletions

@ -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