|  |  |  | @ -1,6 +1,7 @@ | 
		
	
		
			
				|  |  |  |  | #include "renderer_light.hpp" | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #include <functional> | 
		
	
		
			
				|  |  |  |  | #include <string> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #include "Types.h" | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -13,7 +14,9 @@ | 
		
	
		
			
				|  |  |  |  | #include "df/flow_info.h" | 
		
	
		
			
				|  |  |  |  | #include "df/world.h" | 
		
	
		
			
				|  |  |  |  | #include "df/building.h" | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #include "df/building_doorst.h" | 
		
	
		
			
				|  |  |  |  | #include "df/plant.h" | 
		
	
		
			
				|  |  |  |  | #include "df/plant_raw.h" | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | using df::global::gps; | 
		
	
		
			
				|  |  |  |  | using namespace DFHack; | 
		
	
	
		
			
				
					|  |  |  | @ -54,6 +57,7 @@ rect2d getMapViewport() | 
		
	
		
			
				|  |  |  |  | lightingEngineViewscreen::lightingEngineViewscreen(renderer_light* target):lightingEngine(target) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     reinit(); | 
		
	
		
			
				|  |  |  |  |     initRawSpecific(); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void lightingEngineViewscreen::reinit() | 
		
	
	
		
			
				
					|  |  |  | @ -65,6 +69,7 @@ void lightingEngineViewscreen::reinit() | 
		
	
		
			
				|  |  |  |  |     size_t size=w*h; | 
		
	
		
			
				|  |  |  |  |     lightMap.resize(size,lightCell(1,1,1)); | 
		
	
		
			
				|  |  |  |  |     ocupancy.resize(size); | 
		
	
		
			
				|  |  |  |  |     lights.resize(size); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void plotCircle(int xm, int ym, int r,std::function<void(int,int)> setPixel) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
	
		
			
				
					|  |  |  | @ -107,18 +112,23 @@ bool lightingEngineViewscreen::lightUpCell(lightCell& power,int dx,int dy,int tx | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         size_t tile=getIndex(tx,ty); | 
		
	
		
			
				|  |  |  |  |         float dsq=dx*dx+dy*dy; | 
		
	
		
			
				|  |  |  |  |         float dt=sqrt(dsq); | 
		
	
		
			
				|  |  |  |  |         lightCell& v=ocupancy[tile]; | 
		
	
		
			
				|  |  |  |  |         lightSource& ls=lights[tile]; | 
		
	
		
			
				|  |  |  |  |         bool wallhack=false; | 
		
	
		
			
				|  |  |  |  |         bool outsidehack=false; | 
		
	
		
			
				|  |  |  |  |         if(v.r+v.g+v.b==0) | 
		
	
		
			
				|  |  |  |  |             wallhack=true; | 
		
	
		
			
				|  |  |  |  |         if(v.r<0) | 
		
	
		
			
				|  |  |  |  |             outsidehack=true; | 
		
	
		
			
				|  |  |  |  |         if (dsq>0 && !wallhack && !outsidehack) | 
		
	
		
			
				|  |  |  |  |          | 
		
	
		
			
				|  |  |  |  |         if (dsq>0 && !wallhack) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             power.r=power.r*(pow(v.r,dt)); | 
		
	
		
			
				|  |  |  |  |             power.g=power.g*(pow(v.g,dt)); | 
		
	
		
			
				|  |  |  |  |             power.b=power.b*(pow(v.b,dt)); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         if(ls.radius>0 && dsq>0) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             power.r=power.r*(pow(v.r,dsq)); | 
		
	
		
			
				|  |  |  |  |             power.g=power.g*(pow(v.g,dsq)); | 
		
	
		
			
				|  |  |  |  |             power.b=power.b*(pow(v.b,dsq)); | 
		
	
		
			
				|  |  |  |  |             if(power<ls.power) | 
		
	
		
			
				|  |  |  |  |                 return false; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         //float dt=sqrt(dsq);
 | 
		
	
		
			
				|  |  |  |  |         lightCell oldCol=lightMap[tile]; | 
		
	
	
		
			
				
					|  |  |  | @ -127,8 +137,6 @@ bool lightingEngineViewscreen::lightUpCell(lightCell& power,int dx,int dy,int tx | 
		
	
		
			
				|  |  |  |  |          | 
		
	
		
			
				|  |  |  |  |         if(wallhack) | 
		
	
		
			
				|  |  |  |  |             return false; | 
		
	
		
			
				|  |  |  |  |         if(dsq>0 && outsidehack) | 
		
	
		
			
				|  |  |  |  |             return false; | 
		
	
		
			
				|  |  |  |  |         float pwsq=power.r*power.r+power.g*power.g+power.b*power.b; | 
		
	
		
			
				|  |  |  |  |         return pwsq>levelDim*levelDim; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					|  |  |  | @ -145,17 +153,32 @@ void lightingEngineViewscreen::doFovs() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     mapPort=getMapViewport(); | 
		
	
		
			
				|  |  |  |  |     using namespace std::placeholders; | 
		
	
		
			
				|  |  |  |  |     for(size_t i=0;i<lights.size();i++) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         lightSource& csource=lights[i]; | 
		
	
		
			
				|  |  |  |  |         plotCircle(csource.pos.x,csource.pos.y,csource.radius,std::bind(&lightingEngineViewscreen::doRay,this,csource.power,csource.pos.x,csource.pos.y,_1,_2)); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     for(int i=mapPort.first.x;i<mapPort.second.x;i++) | 
		
	
		
			
				|  |  |  |  |         for(int j=mapPort.first.y;j<mapPort.second.y;j++) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             lightSource& csource=lights[getIndex(i,j)]; | 
		
	
		
			
				|  |  |  |  |             if(csource.radius>0) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 lightCell power=csource.power; | 
		
	
		
			
				|  |  |  |  |                 int radius =csource.radius; | 
		
	
		
			
				|  |  |  |  |                 if(csource.flicker) | 
		
	
		
			
				|  |  |  |  |                 { | 
		
	
		
			
				|  |  |  |  |                     float flicker=(rand()/(float)RAND_MAX)/2.0f+0.5f; | 
		
	
		
			
				|  |  |  |  |                     radius*=flicker; | 
		
	
		
			
				|  |  |  |  |                     power=power*flicker; | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |                 plotCircle(i,j,radius, | 
		
	
		
			
				|  |  |  |  |                 std::bind(&lightingEngineViewscreen::doRay,this,power,i,j,_1,_2)); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void lightingEngineViewscreen::calculate() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     rect2d vp=getMapViewport(); | 
		
	
		
			
				|  |  |  |  |     const lightCell dim(levelDim,levelDim,levelDim); | 
		
	
		
			
				|  |  |  |  |     lightMap.assign(lightMap.size(),lightCell(1,1,1)); | 
		
	
		
			
				|  |  |  |  |     lights.assign(lights.size(),lightSource()); | 
		
	
		
			
				|  |  |  |  |     for(int i=vp.first.x;i<vp.second.x;i++) | 
		
	
		
			
				|  |  |  |  |     for(int j=vp.first.y;j<vp.second.y;j++) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
	
		
			
				
					|  |  |  | @ -171,6 +194,7 @@ void lightingEngineViewscreen::updateWindow() | 
		
	
		
			
				|  |  |  |  |     if(lightMap.size()!=myRenderer->lightGrid.size()) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         reinit(); | 
		
	
		
			
				|  |  |  |  |         myRenderer->invalidate(); | 
		
	
		
			
				|  |  |  |  |         return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     std::swap(lightMap,myRenderer->lightGrid); | 
		
	
	
		
			
				
					|  |  |  | @ -180,14 +204,60 @@ void lightingEngineViewscreen::updateWindow() | 
		
	
		
			
				|  |  |  |  |     myRenderer->invalidate(); | 
		
	
		
			
				|  |  |  |  |     //std::copy(lightMap.begin(),lightMap.end(),myRenderer->lightGrid.begin());
 | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void lightSource::combine(const lightSource& other) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     power=blend(power,other.power); | 
		
	
		
			
				|  |  |  |  |     radius=std::max(other.radius,radius);//hack... but who cares
 | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | bool lightingEngineViewscreen::addLight(int tileId,const lightSource& light) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     bool wasLight=lights[tileId].radius>0; | 
		
	
		
			
				|  |  |  |  |     lights[tileId].combine(light); | 
		
	
		
			
				|  |  |  |  |     if(light.flicker) | 
		
	
		
			
				|  |  |  |  |         lights[tileId].flicker=true; | 
		
	
		
			
				|  |  |  |  |     return wasLight; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | lightCell getStandartColor(int colorId) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     return lightCell(df::global::enabler->ccolor[colorId][0]/255.0f, | 
		
	
		
			
				|  |  |  |  |         df::global::enabler->ccolor[colorId][1]/255.0f, | 
		
	
		
			
				|  |  |  |  |         df::global::enabler->ccolor[colorId][2]/255.0f); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | int getPlantNumber(const std::string& id) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     std::vector<df::plant_raw*>& vec=df::plant_raw::get_vector(); | 
		
	
		
			
				|  |  |  |  |     for(int i=0;i<vec.size();i++) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         if(vec[i]->id==id) | 
		
	
		
			
				|  |  |  |  |             return i; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     return -1; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void addPlant(const std::string& id,std::map<int,lightSource>& map,const lightSource& v) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     int nId=getPlantNumber(id); | 
		
	
		
			
				|  |  |  |  |     if(nId>0) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         map[nId]=v; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void lightingEngineViewscreen::initRawSpecific() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     addPlant("TOWER_CAP",glowPlants,lightSource(lightCell(0.65,0.65,0.65),6)); | 
		
	
		
			
				|  |  |  |  |     addPlant("MUSHROOM_CUP_DIMPLE",glowPlants,lightSource(lightCell(0.03,0.03,0.5),3)); | 
		
	
		
			
				|  |  |  |  |     addPlant("CAVE MOSS",glowPlants,lightSource(lightCell(0.1,0.1,0.4),2)); | 
		
	
		
			
				|  |  |  |  |     addPlant("MUSHROOM_HELMET_PLUMP",glowPlants,lightSource(lightCell(0.2,0.1,0.6),2)); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | static size_t max_list_size = 100000; // Avoid iterating over huge lists
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void lightingEngineViewscreen::doOcupancyAndLights() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     lights.clear(); | 
		
	
		
			
				|  |  |  |  |     lightSource sun(lightCell(1,1,1),15); | 
		
	
		
			
				|  |  |  |  |     lightSource lava(lightCell(0.8f,0.2f,0.2f),5); | 
		
	
		
			
				|  |  |  |  |     lightSource candle(lightCell(0.96f,0.84f,0.03f),5); | 
		
	
		
			
				|  |  |  |  |     lightSource torch(lightCell(0.9f,0.75f,0.3f),8); | 
		
	
		
			
				|  |  |  |  |     rect2d vp=getMapViewport(); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     int window_x=*df::global::window_x; | 
		
	
		
			
				|  |  |  |  |     int window_y=*df::global::window_y; | 
		
	
		
			
				|  |  |  |  |     int window_z=*df::global::window_z; | 
		
	
	
		
			
				
					|  |  |  | @ -259,8 +329,9 @@ void lightingEngineViewscreen::doOcupancyAndLights() | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if(cellArray[block_x][block_y].r >= 0.003f && cellArray[block_x][block_y].g >= 0.003f && cellArray[block_x][block_y].b >= 0.003f) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 lightSource sun={cellArray[block_x][block_y],25,coord2d(wx,wy)}; | 
		
	
		
			
				|  |  |  |  |                 lights.push_back(sun); | 
		
	
		
			
				|  |  |  |  |                 int tile=getIndex(wx,wy); | 
		
	
		
			
				|  |  |  |  |                 lightSource sun(cellArray[block_x][block_y],25); | 
		
	
		
			
				|  |  |  |  |                 addLight(tile,sun); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -270,19 +341,23 @@ void lightingEngineViewscreen::doOcupancyAndLights() | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         int wx=x-window_x+vp.first.x; | 
		
	
		
			
				|  |  |  |  |         int wy=y-window_y+vp.first.y; | 
		
	
		
			
				|  |  |  |  |         lightCell& curCell=ocupancy[getIndex(wx,wy)]; | 
		
	
		
			
				|  |  |  |  |         curCell=lightCell(0.8f,0.8f,0.8f); | 
		
	
		
			
				|  |  |  |  |         int tile=getIndex(wx,wy); | 
		
	
		
			
				|  |  |  |  |         lightCell& curCell=ocupancy[tile]; | 
		
	
		
			
				|  |  |  |  |         curCell=lightCell(0.85f,0.85f,0.85f); | 
		
	
		
			
				|  |  |  |  |         df::tiletype* type = Maps::getTileType(x,y,window_z); | 
		
	
		
			
				|  |  |  |  |         if(!type) | 
		
	
		
			
				|  |  |  |  |             continue; | 
		
	
		
			
				|  |  |  |  |         //if(!type)
 | 
		
	
		
			
				|  |  |  |  |         //{
 | 
		
	
		
			
				|  |  |  |  |         //    //unallocated, do sky
 | 
		
	
		
			
				|  |  |  |  |         //        addLight(tile,sun);
 | 
		
	
		
			
				|  |  |  |  |         //    continue;
 | 
		
	
		
			
				|  |  |  |  |         //}
 | 
		
	
		
			
				|  |  |  |  |         df::tiletype_shape shape = ENUM_ATTR(tiletype,shape,*type); | 
		
	
		
			
				|  |  |  |  |         df::tile_designation* d=Maps::getTileDesignation(x,y,window_z); | 
		
	
		
			
				|  |  |  |  |         df::tile_designation* d2=Maps::getTileDesignation(x,y,window_z-1); | 
		
	
		
			
				|  |  |  |  |         df::tile_occupancy* o=Maps::getTileOccupancy(x,y,window_z); | 
		
	
		
			
				|  |  |  |  |         if(!o || !d ) | 
		
	
		
			
				|  |  |  |  |             continue; | 
		
	
		
			
				|  |  |  |  |          | 
		
	
		
			
				|  |  |  |  |         if(shape==df::tiletype_shape::BROOK_BED || shape==df::tiletype_shape::WALL || shape==df::tiletype_shape::TREE /*|| o->bits.building*/) | 
		
	
		
			
				|  |  |  |  |         if(shape==df::tiletype_shape::BROOK_BED || shape==df::tiletype_shape::WALL || shape==df::tiletype_shape::TREE || d->bits.hidden ) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             curCell=lightCell(0,0,0); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
	
		
			
				
					|  |  |  | @ -317,33 +392,55 @@ void lightingEngineViewscreen::doOcupancyAndLights() | 
		
	
		
			
				|  |  |  |  |                                 curCell*=lightCell(0.75f,0.95f,0.95f); | 
		
	
		
			
				|  |  |  |  |                             } | 
		
	
		
			
				|  |  |  |  |                         } | 
		
	
		
			
				|  |  |  |  |                         if (type == df::enums::building_type::Table) | 
		
	
		
			
				|  |  |  |  |                         { | 
		
	
		
			
				|  |  |  |  |                             addLight(tile,candle); | 
		
	
		
			
				|  |  |  |  |                         } | 
		
	
		
			
				|  |  |  |  |                         if (type==df::enums::building_type::Statue) | 
		
	
		
			
				|  |  |  |  |                         { | 
		
	
		
			
				|  |  |  |  |                             addLight(tile,torch); | 
		
	
		
			
				|  |  |  |  |                         } | 
		
	
		
			
				|  |  |  |  |                         if (type==df::enums::building_type::WindowGem) | 
		
	
		
			
				|  |  |  |  |                         { | 
		
	
		
			
				|  |  |  |  |                             DFHack::MaterialInfo mat(bld->mat_index,bld->mat_type); | 
		
	
		
			
				|  |  |  |  |                             if(mat.isInorganic()) | 
		
	
		
			
				|  |  |  |  |                             { | 
		
	
		
			
				|  |  |  |  |                                 int color=mat.inorganic->material.basic_color[0]+8*mat.inorganic->material.basic_color[2]; | 
		
	
		
			
				|  |  |  |  |                                 curCell*=getStandartColor(color); | 
		
	
		
			
				|  |  |  |  |                             } | 
		
	
		
			
				|  |  |  |  |                         } | 
		
	
		
			
				|  |  |  |  |                         if(type==df::enums::building_type::Door) | 
		
	
		
			
				|  |  |  |  |                         { | 
		
	
		
			
				|  |  |  |  |                             df::building_doorst* door=static_cast<df::building_doorst*>(bld); | 
		
	
		
			
				|  |  |  |  |                             if(door->door_flags.bits.closed) | 
		
	
		
			
				|  |  |  |  |                                 curCell*=lightCell(0,0,0); | 
		
	
		
			
				|  |  |  |  |                         } | 
		
	
		
			
				|  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if(!d->bits.liquid_type && d->bits.flow_size>3 ) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             curCell=lightCell(0.5f,0.5f,0.6f); | 
		
	
		
			
				|  |  |  |  |             curCell*=lightCell(0.7f,0.7f,0.8f); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         //todo constructions
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         //lights
 | 
		
	
		
			
				|  |  |  |  |         if((d->bits.liquid_type && d->bits.flow_size>0)|| (d2 && d2->bits.liquid_type && d2->bits.flow_size>0)) | 
		
	
		
			
				|  |  |  |  |         if((d->bits.liquid_type && d->bits.flow_size>0)||  | 
		
	
		
			
				|  |  |  |  |             ( | 
		
	
		
			
				|  |  |  |  |             (shape==df::tiletype_shape::EMPTY || shape==df::tiletype_shape::RAMP_TOP || shape==df::tiletype_shape::STAIR_DOWN || shape==df::tiletype_shape::STAIR_UPDOWN ) | 
		
	
		
			
				|  |  |  |  |             && d2 && d2->bits.liquid_type && d2->bits.flow_size>0) | 
		
	
		
			
				|  |  |  |  |             ) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             lightSource lava={lightCell(0.8f,0.2f,0.2f),5,coord2d(wx,wy)}; | 
		
	
		
			
				|  |  |  |  |             lights.push_back(lava); | 
		
	
		
			
				|  |  |  |  |              | 
		
	
		
			
				|  |  |  |  |             addLight(tile,lava); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         if(d->bits.outside && d->bits.flow_size==0) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             curCell=lightCell(-1,-1,-1);//Marking as outside so no calculation is done on it
 | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |          | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     for(int blockx=window_x/16;blockx<=endBlockx;blockx++) | 
		
	
		
			
				|  |  |  |  |     for(int blocky=window_y/16;blocky<=endBlocky;blocky++) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         df::map_block* block=Maps::getBlock(blockx,blocky,window_z); | 
		
	
		
			
				|  |  |  |  |          | 
		
	
		
			
				|  |  |  |  |         if(!block) | 
		
	
		
			
				|  |  |  |  |             continue; | 
		
	
		
			
				|  |  |  |  |         for(int i=0;i<block->flows.size();i++) | 
		
	
	
		
			
				
					|  |  |  | @ -354,6 +451,7 @@ void lightingEngineViewscreen::doOcupancyAndLights() | 
		
	
		
			
				|  |  |  |  |                 df::coord2d pos=f->pos; | 
		
	
		
			
				|  |  |  |  |                 int wx=pos.x-window_x+vp.first.x; | 
		
	
		
			
				|  |  |  |  |                 int wy=pos.y-window_y+vp.first.y; | 
		
	
		
			
				|  |  |  |  |                 int tile=getIndex(wx,wy); | 
		
	
		
			
				|  |  |  |  |                 if(wx>=vp.first.x && wy>=vp.first.y && wx<=vp.second.x && wy<=vp.second.y) | 
		
	
		
			
				|  |  |  |  |                 { | 
		
	
		
			
				|  |  |  |  |                     lightCell fireColor; | 
		
	
	
		
			
				
					|  |  |  | @ -369,10 +467,36 @@ void lightingEngineViewscreen::doOcupancyAndLights() | 
		
	
		
			
				|  |  |  |  |                     { | 
		
	
		
			
				|  |  |  |  |                         fireColor=lightCell(0.64f,0.0f,0.0f); | 
		
	
		
			
				|  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |                     lightSource fire={fireColor,f->density/5,coord2d(wx,wy)}; | 
		
	
		
			
				|  |  |  |  |                     lights.push_back(fire); | 
		
	
		
			
				|  |  |  |  |                     lightSource fire(fireColor,f->density/5); | 
		
	
		
			
				|  |  |  |  |                     addLight(tile,fire); | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         for(int i=0;i<block->plants.size();i++) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             df::plant* cPlant=block->plants[i]; | 
		
	
		
			
				|  |  |  |  |              | 
		
	
		
			
				|  |  |  |  |             df::coord2d pos=cPlant->pos; | 
		
	
		
			
				|  |  |  |  |             int wx=pos.x-window_x+vp.first.x; | 
		
	
		
			
				|  |  |  |  |             int wy=pos.y-window_y+vp.first.y; | 
		
	
		
			
				|  |  |  |  |             int tile=getIndex(wx,wy); | 
		
	
		
			
				|  |  |  |  |             if(wx>=vp.first.x && wy>=vp.first.y && wx<=vp.second.x && wy<=vp.second.y) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 auto it=glowPlants.find(cPlant->material); | 
		
	
		
			
				|  |  |  |  |                 if(it!=glowPlants.end()) | 
		
	
		
			
				|  |  |  |  |                 { | 
		
	
		
			
				|  |  |  |  |                     addLight(tile,it->second); | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     if(df::global::cursor->x>-30000) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         lightSource cursor(lightCell(0.96f,0.84f,0.03f),11); | 
		
	
		
			
				|  |  |  |  |         cursor.flicker=true; | 
		
	
		
			
				|  |  |  |  |         int wx=df::global::cursor->x-window_x+vp.first.x; | 
		
	
		
			
				|  |  |  |  |         int wy=df::global::cursor->y-window_y+vp.first.y; | 
		
	
		
			
				|  |  |  |  |         int tile=getIndex(wx,wy); | 
		
	
		
			
				|  |  |  |  |         addLight(tile,cursor); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } |