diff --git a/scripts/devel/light.lua b/scripts/devel/light.lua index f3d39e4db..48324d797 100644 --- a/scripts/devel/light.lua +++ b/scripts/devel/light.lua @@ -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 guidm = require 'gui.dwarfmode' local render = require 'plugins.rendermax' @@ -36,9 +36,12 @@ end LightOverlay=defclass(LightOverlay,guidm.DwarfOverlay) LightOverlay.ATTRS { lightMap={}, - dynamic=true + dynamic=true, + dirty=false, } -function LightOverlay.init(args) +function LightOverlay:init(args) + + self.tick=df.global.cur_year_tick_advmode end function lightPassable(shape) @@ -102,8 +105,14 @@ function line(x0, y0, x1, y1,plot) end end end -function LightOverlay:placeLightFov(pos,radius,color,f) - f=f or falloff +function LightOverlay:calculateFovs() + 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 map = self.df_layout.map 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 dt=math.sqrt(dtsq) 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 ncol=blend(power,ocol) + self.lightMap[tile]=ncol local v=self.ocupancy[tile] if dtsq>0 then @@ -136,6 +152,17 @@ function LightOverlay:placeLightFov(pos,radius,color,f) end circle(pos.x,pos.y,radius,ray) 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) f=f or falloff local raycount=rays or 25 @@ -208,7 +235,7 @@ function LightOverlay:calculateLightLava() 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 --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 @@ -225,7 +252,7 @@ function LightOverlay:calculateLightSun() 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 @@ -267,22 +294,36 @@ function LightOverlay:buildOcupancy() 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() + if not self:changed() then + return + end + self.fovs={} + self.precalc={} self.lightMap={} + self:buildOcupancy() self:calculateLightCursor() self:calculateLightLava() self:calculateLightSun() + + self:calculateFovs() end function LightOverlay:onIdle() self._native.parent:logic() +end +function LightOverlay:render(dc) if self.dynamic then self:makeLightMap() end -end -function LightOverlay:render(dc) - - self:renderParent() local vp=self:getViewport() local map = self.df_layout.map @@ -313,7 +354,7 @@ function LightOverlay:onDismiss() end function LightOverlay:onInput(keys) - if keys.LEAVESCREEN then + if keys.STRING_A096 then self:dismiss() else self:sendInputToParent(keys) @@ -324,6 +365,7 @@ function LightOverlay:onInput(keys) if keys.STRING_A126 and not self.dynamic then self:makeLightMap() end + self.dirty=true end end if not render.isEnabled() then