|
|
|
@ -434,6 +434,14 @@ matLightDef* lightingEngineViewscreen::getMaterial(int matType,int matIndex)
|
|
|
|
|
else
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
buildingLightDef* lightingEngineViewscreen::getBuilding(df::building* bld)
|
|
|
|
|
{
|
|
|
|
|
auto it=buildingDefs.find(std::make_tuple((int)bld->getType(),(int)bld->getSubtype(),(int)bld->getCustomType()));
|
|
|
|
|
if(it!=buildingDefs.end())
|
|
|
|
|
return &it->second;
|
|
|
|
|
else
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
void lightingEngineViewscreen::applyMaterial(int tileId,const matLightDef& mat,float size, float thickness)
|
|
|
|
|
{
|
|
|
|
|
if(mat.isTransparent)
|
|
|
|
@ -636,6 +644,11 @@ void lightingEngineViewscreen::doOcupancyAndLights()
|
|
|
|
|
|
|
|
|
|
df::tiletype type = b->tiletypeAt(gpos);
|
|
|
|
|
df::tile_designation d = b->DesignationAt(gpos);
|
|
|
|
|
if(d.bits.hidden)
|
|
|
|
|
{
|
|
|
|
|
curCell=lightCell(0,0,0);
|
|
|
|
|
continue; // do not process hidden stuff
|
|
|
|
|
}
|
|
|
|
|
//df::tile_occupancy o = b->OccupancyAt(gpos);
|
|
|
|
|
df::tiletype_shape shape = ENUM_ATTR(tiletype,shape,type);
|
|
|
|
|
df::tiletype_shape_basic basic_shape = ENUM_ATTR(tiletype_shape, basic_shape, shape);
|
|
|
|
@ -646,7 +659,7 @@ void lightingEngineViewscreen::doOcupancyAndLights()
|
|
|
|
|
matLightDef* lightDef=getMaterial(mat.mat_type,mat.mat_index);
|
|
|
|
|
if(!lightDef || !lightDef->isTransparent)
|
|
|
|
|
lightDef=&matWall;
|
|
|
|
|
if(shape==df::tiletype_shape::BROOK_BED || d.bits.hidden )
|
|
|
|
|
if(shape==df::tiletype_shape::BROOK_BED )
|
|
|
|
|
{
|
|
|
|
|
curCell=lightCell(0,0,0);
|
|
|
|
|
}
|
|
|
|
@ -778,34 +791,58 @@ void lightingEngineViewscreen::doOcupancyAndLights()
|
|
|
|
|
for(size_t i = 0; i < df::global::world->buildings.all.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
df::building *bld = df::global::world->buildings.all[i];
|
|
|
|
|
|
|
|
|
|
if(window_z!=bld->z)
|
|
|
|
|
continue;
|
|
|
|
|
if(bld->getBuildStage()<bld->getMaxBuildStage()) //only work if fully built
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
df::coord2d p1(bld->x1,bld->y1);
|
|
|
|
|
df::coord2d p2(bld->x2,bld->y2);
|
|
|
|
|
p1=worldToViewportCoord(p1,vp,window2d);
|
|
|
|
|
p2=worldToViewportCoord(p1,vp,window2d);
|
|
|
|
|
if(isInViewport(p1,vp)||isInViewport(p2,vp))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
int tile=getIndex(p1.x,p1.y); //TODO multitile buildings. How they would work?
|
|
|
|
|
df::building_type type = bld->getType();
|
|
|
|
|
buildingLightDef* def=getBuilding(bld);
|
|
|
|
|
if(!def)
|
|
|
|
|
continue;
|
|
|
|
|
if(def->poweredOnly && bld->isUnpowered())
|
|
|
|
|
continue;
|
|
|
|
|
if(type==df::enums::building_type::Door)
|
|
|
|
|
{
|
|
|
|
|
df::building_doorst* door=static_cast<df::building_doorst*>(bld);
|
|
|
|
|
if(!door->door_flags.bits.closed)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type == df::enums::building_type::WindowGlass || type==df::enums::building_type::WindowGem)
|
|
|
|
|
|
|
|
|
|
if(def->useMaterial)
|
|
|
|
|
{
|
|
|
|
|
matLightDef* mat=getMaterial(bld->mat_type,bld->mat_index);
|
|
|
|
|
if(!mat)mat=&matWall;
|
|
|
|
|
if(def->light.isEmiting)
|
|
|
|
|
{
|
|
|
|
|
applyMaterial(tile,bld->mat_type,bld->mat_index);
|
|
|
|
|
addLight(tile,def->light.makeSource());
|
|
|
|
|
}
|
|
|
|
|
if (type == df::enums::building_type::Table)
|
|
|
|
|
else if(mat->isEmiting)
|
|
|
|
|
{
|
|
|
|
|
addLight(tile,candle);
|
|
|
|
|
addLight(tile,mat->makeSource());
|
|
|
|
|
}
|
|
|
|
|
if (type==df::enums::building_type::Statue)
|
|
|
|
|
if(def->light.isTransparent)
|
|
|
|
|
{
|
|
|
|
|
addLight(tile,torch);
|
|
|
|
|
ocupancy[tile]*=def->light.transparency;
|
|
|
|
|
}
|
|
|
|
|
if(type==df::enums::building_type::Door)
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
df::building_doorst* door=static_cast<df::building_doorst*>(bld);
|
|
|
|
|
if(door->door_flags.bits.closed)
|
|
|
|
|
applyMaterial(tile,bld->mat_type,bld->mat_index,1,&matWall);
|
|
|
|
|
ocupancy[tile]*=mat->transparency;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
applyMaterial(tile,def->light);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -833,6 +870,10 @@ lightCell lua_parseLightCell(lua_State* L)
|
|
|
|
|
//Lua::GetOutput(L)->print("got cell(%f,%f,%f)\n",ret.r,ret.g,ret.b);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
#define GETLUAFLAG(field,name) lua_getfield(L,-1,"flags");\
|
|
|
|
|
if(lua_isnil(L,-1)){field=false;}\
|
|
|
|
|
else{lua_getfield(L,-1,#name);field=lua_isnil(L,-1);lua_pop(L,1);}\
|
|
|
|
|
lua_pop(L,1)
|
|
|
|
|
matLightDef lua_parseMatDef(lua_State* L)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
@ -861,7 +902,10 @@ matLightDef lua_parseMatDef(lua_State* L)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
lua_pop(L,1);
|
|
|
|
|
//todo flags
|
|
|
|
|
GETLUAFLAG(ret.flicker,"flicker");
|
|
|
|
|
GETLUAFLAG(ret.useThickness,"useThickness");
|
|
|
|
|
GETLUAFLAG(ret.sizeModifiesPower,"sizeModifiesPower");
|
|
|
|
|
GETLUAFLAG(ret.sizeModifiesRange,"sizeModifiesRange");
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
int lightingEngineViewscreen::parseMaterials(lua_State* L)
|
|
|
|
@ -918,6 +962,48 @@ int lightingEngineViewscreen::parseSpecial(lua_State* L)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#undef LOAD_SPECIAL
|
|
|
|
|
int lightingEngineViewscreen::parseBuildings(lua_State* L)
|
|
|
|
|
{
|
|
|
|
|
auto engine= (lightingEngineViewscreen*)lua_touserdata(L, 1);
|
|
|
|
|
engine->buildingDefs.clear();
|
|
|
|
|
Lua::StackUnwinder unwinder(L);
|
|
|
|
|
lua_getfield(L,2,"buildings");
|
|
|
|
|
if(!lua_istable(L,-1))
|
|
|
|
|
{
|
|
|
|
|
luaL_error(L,"Buildings table not found.");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
while (lua_next(L, -2) != 0) {
|
|
|
|
|
int type=lua_tonumber(L,-2);
|
|
|
|
|
if(!lua_istable(L,-1))
|
|
|
|
|
{
|
|
|
|
|
luaL_error(L,"Broken building definitions.");
|
|
|
|
|
}
|
|
|
|
|
//os->print("Processing type:%d\n",type);
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
while (lua_next(L, -2) != 0) {
|
|
|
|
|
int subtype=lua_tonumber(L,-2);
|
|
|
|
|
//os->print("\tProcessing subtype:%d\n",index);
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
while (lua_next(L, -2) != 0) {
|
|
|
|
|
int custom=lua_tonumber(L,-2);
|
|
|
|
|
//os->print("\tProcessing custom:%d\n",index);
|
|
|
|
|
buildingLightDef current;
|
|
|
|
|
current.light=lua_parseMatDef(L);
|
|
|
|
|
engine->buildingDefs[std::make_tuple(type,subtype,custom)]=current;
|
|
|
|
|
GETLUAFLAG(current.poweredOnly,"poweredOnly");
|
|
|
|
|
GETLUAFLAG(current.useMaterial,"useMaterial");
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
}
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
}
|
|
|
|
|
lua_pop(L,1);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
void lightingEngineViewscreen::defaultSettings()
|
|
|
|
|
{
|
|
|
|
|
matAmbience=matLightDef(lightCell(0.85f,0.85f,0.85f));
|
|
|
|
@ -968,6 +1054,11 @@ void lightingEngineViewscreen::loadSettings()
|
|
|
|
|
lua_pushvalue(s,env);
|
|
|
|
|
Lua::SafeCall(out,s,2,0);
|
|
|
|
|
|
|
|
|
|
lua_pushcfunction(s, parseBuildings);
|
|
|
|
|
lua_pushlightuserdata(s, this);
|
|
|
|
|
lua_pushvalue(s,env);
|
|
|
|
|
Lua::SafeCall(out,s,2,0);
|
|
|
|
|
out.print("%d buildings loaded\n",buildingDefs.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
@ -978,3 +1069,4 @@ void lightingEngineViewscreen::loadSettings()
|
|
|
|
|
}
|
|
|
|
|
lua_pop(s,1);
|
|
|
|
|
}
|
|
|
|
|
#undef GETLUAFLAG
|
|
|
|
|