in doom_py/src/vizdoom/src/p_udmf.cpp [1279:1668]
void ParseSector(sector_t *sec, int index)
{
int lightcolor = -1;
int fadecolor = -1;
int desaturation = -1;
int fplaneflags = 0, cplaneflags = 0;
double fp[4] = { 0 }, cp[4] = { 0 };
FString tagstring;
memset(sec, 0, sizeof(*sec));
sec->lightlevel = 160;
sec->SetXScale(sector_t::floor, FRACUNIT); // [RH] floor and ceiling scaling
sec->SetYScale(sector_t::floor, FRACUNIT);
sec->SetXScale(sector_t::ceiling, FRACUNIT);
sec->SetYScale(sector_t::ceiling, FRACUNIT);
sec->SetAlpha(sector_t::floor, FRACUNIT);
sec->SetAlpha(sector_t::ceiling, FRACUNIT);
sec->thinglist = NULL;
sec->touching_thinglist = NULL; // phares 3/14/98
sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1;
sec->nextsec = -1; //jff 2/26/98 add fields to support locking out
sec->prevsec = -1; // stair retriggering until build completes
sec->heightsec = NULL; // sector used to get floor and ceiling height
sec->sectornum = index;
sec->damageinterval = 32;
sec->terrainnum[sector_t::ceiling] = sec->terrainnum[sector_t::floor] = -1;
if (floordrop) sec->Flags = SECF_FLOORDROP;
// killough 3/7/98: end changes
sec->gravity = 1.f; // [RH] Default sector gravity of 1.0
sec->ZoneNumber = 0xFFFF;
// killough 8/28/98: initialize all sectors to normal friction
sec->friction = ORIG_FRICTION;
sec->movefactor = ORIG_FRICTION_FACTOR;
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{
FName key = ParseKey();
switch(key)
{
case NAME_Heightfloor:
sec->SetPlaneTexZ(sector_t::floor, CheckInt(key) << FRACBITS);
continue;
case NAME_Heightceiling:
sec->SetPlaneTexZ(sector_t::ceiling, CheckInt(key) << FRACBITS);
continue;
case NAME_Texturefloor:
SetTexture(sec, index, sector_t::floor, CheckString(key), missingTex, false);
continue;
case NAME_Textureceiling:
SetTexture(sec, index, sector_t::ceiling, CheckString(key), missingTex, false);
continue;
case NAME_Lightlevel:
sec->lightlevel = sector_t::ClampLight(CheckInt(key));
continue;
case NAME_Special:
sec->special = (short)CheckInt(key);
if (isTranslated) sec->special = P_TranslateSectorSpecial(sec->special);
else if (namespc == NAME_Hexen)
{
if (sec->special < 0 || sec->special > 255 || !HexenSectorSpecialOk[sec->special])
sec->special = 0; // NULL all unknown specials
}
continue;
case NAME_Id:
tagManager.AddSectorTag(index, CheckInt(key));
continue;
default:
break;
}
if (namespace_bits & (Zd|Zdt|Va)) switch(key)
{
case NAME_Xpanningfloor:
sec->SetXOffset(sector_t::floor, CheckFixed(key));
continue;
case NAME_Ypanningfloor:
sec->SetYOffset(sector_t::floor, CheckFixed(key));
continue;
case NAME_Xpanningceiling:
sec->SetXOffset(sector_t::ceiling, CheckFixed(key));
continue;
case NAME_Ypanningceiling:
sec->SetYOffset(sector_t::ceiling, CheckFixed(key));
continue;
case NAME_Xscalefloor:
sec->SetXScale(sector_t::floor, CheckFixed(key));
continue;
case NAME_Yscalefloor:
sec->SetYScale(sector_t::floor, CheckFixed(key));
continue;
case NAME_Xscaleceiling:
sec->SetXScale(sector_t::ceiling, CheckFixed(key));
continue;
case NAME_Yscaleceiling:
sec->SetYScale(sector_t::ceiling, CheckFixed(key));
continue;
case NAME_Rotationfloor:
sec->SetAngle(sector_t::floor, CheckAngle(key));
continue;
case NAME_Rotationceiling:
sec->SetAngle(sector_t::ceiling, CheckAngle(key));
continue;
case NAME_Lightfloor:
sec->SetPlaneLight(sector_t::floor, CheckInt(key));
continue;
case NAME_Lightceiling:
sec->SetPlaneLight(sector_t::ceiling, CheckInt(key));
continue;
case NAME_Alphafloor:
sec->SetAlpha(sector_t::floor, CheckFixed(key));
continue;
case NAME_Alphaceiling:
sec->SetAlpha(sector_t::ceiling, CheckFixed(key));
continue;
case NAME_Renderstylefloor:
{
const char *str = CheckString(key);
if (!stricmp(str, "translucent")) sec->ChangeFlags(sector_t::floor, PLANEF_ADDITIVE, 0);
else if (!stricmp(str, "add")) sec->ChangeFlags(sector_t::floor, 0, PLANEF_ADDITIVE);
else sc.ScriptMessage("Unknown value \"%s\" for 'renderstylefloor'\n", str);
continue;
}
case NAME_Renderstyleceiling:
{
const char *str = CheckString(key);
if (!stricmp(str, "translucent")) sec->ChangeFlags(sector_t::ceiling, PLANEF_ADDITIVE, 0);
else if (!stricmp(str, "add")) sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ADDITIVE);
else sc.ScriptMessage("Unknown value \"%s\" for 'renderstyleceiling'\n", str);
continue;
}
case NAME_Lightfloorabsolute:
if (CheckBool(key)) sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING);
else sec->ChangeFlags(sector_t::floor, PLANEF_ABSLIGHTING, 0);
continue;
case NAME_Lightceilingabsolute:
if (CheckBool(key)) sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING);
else sec->ChangeFlags(sector_t::ceiling, PLANEF_ABSLIGHTING, 0);
continue;
case NAME_Gravity:
sec->gravity = float(CheckFloat(key));
continue;
case NAME_Lightcolor:
lightcolor = CheckInt(key);
continue;
case NAME_Fadecolor:
fadecolor = CheckInt(key);
continue;
case NAME_Desaturation:
desaturation = int(255*CheckFloat(key));
continue;
case NAME_Silent:
Flag(sec->Flags, SECF_SILENT, key);
continue;
case NAME_NoRespawn:
Flag(sec->Flags, SECF_NORESPAWN, key);
continue;
case NAME_Nofallingdamage:
Flag(sec->Flags, SECF_NOFALLINGDAMAGE, key);
continue;
case NAME_Dropactors:
Flag(sec->Flags, SECF_FLOORDROP, key);
continue;
case NAME_SoundSequence:
sec->SeqName = CheckString(key);
sec->seqType = -1;
continue;
case NAME_hidden:
Flag(sec->MoreFlags, SECF_HIDDEN, key);
break;
case NAME_Waterzone:
Flag(sec->MoreFlags, SECF_UNDERWATER, key);
break;
case NAME_floorplane_a:
fplaneflags |= 1;
fp[0] = CheckFloat(key);
break;
case NAME_floorplane_b:
fplaneflags |= 2;
fp[1] = CheckFloat(key);
break;
case NAME_floorplane_c:
fplaneflags |= 4;
fp[2] = CheckFloat(key);
break;
case NAME_floorplane_d:
fplaneflags |= 8;
fp[3] = CheckFloat(key);
break;
case NAME_ceilingplane_a:
cplaneflags |= 1;
cp[0] = CheckFloat(key);
break;
case NAME_ceilingplane_b:
cplaneflags |= 2;
cp[1] = CheckFloat(key);
break;
case NAME_ceilingplane_c:
cplaneflags |= 4;
cp[2] = CheckFloat(key);
break;
case NAME_ceilingplane_d:
cplaneflags |= 8;
cp[3] = CheckFloat(key);
break;
case NAME_damageamount:
sec->damageamount = CheckInt(key);
break;
case NAME_damagetype:
sec->damagetype = CheckString(key);
break;
case NAME_damageinterval:
sec->damageinterval = CheckInt(key);
if (sec->damageinterval < 1) sec->damageinterval = 1;
break;
case NAME_leakiness:
sec->leakydamage = CheckInt(key);
break;
case NAME_damageterraineffect:
Flag(sec->Flags, SECF_DMGTERRAINFX, key);
break;
case NAME_damagehazard:
Flag(sec->Flags, SECF_HAZARD, key);
break;
case NAME_floorterrain:
sec->terrainnum[sector_t::floor] = P_FindTerrain(CheckString(key));
break;
case NAME_ceilingterrain:
sec->terrainnum[sector_t::ceiling] = P_FindTerrain(CheckString(key));
break;
case NAME_MoreIds:
// delay parsing of the tag string until parsing of the sector is complete
// This ensures that the ID is always the first tag in the list.
tagstring = CheckString(key);
break;
default:
break;
}
if ((namespace_bits & (Zd | Zdt)) && !strnicmp("user_", key.GetChars(), 5))
{
AddUserKey(key, UDMF_Sector, index);
}
}
if (tagstring.IsNotEmpty())
{
FScanner sc;
sc.OpenString("tagstring", tagstring);
// scan the string as long as valid numbers can be found
while (sc.CheckNumber())
{
if (sc.Number != 0) tagManager.AddSectorTag(index, sc.Number);
}
}
if (sec->damageamount == 0)
{
// If no damage is set, clear all other related properties so that they do not interfere
// with other means of setting them.
sec->damagetype = NAME_None;
sec->damageinterval = 0;
sec->leakydamage = 0;
sec->Flags &= ~SECF_DAMAGEFLAGS;
}
// Reset the planes to their defaults if not all of the plane equation's parameters were found.
if (fplaneflags != 15)
{
sec->floorplane.a = sec->floorplane.b = 0;
sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor);
sec->floorplane.c = FRACUNIT;
sec->floorplane.ic = FRACUNIT;
}
else
{
double ulen = TVector3<double>(fp[0], fp[1], fp[2]).Length();
// normalize the vector, it must have a length of 1
sec->floorplane.a = FLOAT2FIXED(fp[0] / ulen);
sec->floorplane.b = FLOAT2FIXED(fp[1] / ulen);
sec->floorplane.c = FLOAT2FIXED(fp[2] / ulen);
sec->floorplane.d = FLOAT2FIXED(fp[3] / ulen);
sec->floorplane.ic = FLOAT2FIXED(ulen / fp[2]);
}
if (cplaneflags != 15)
{
sec->ceilingplane.a = sec->ceilingplane.b = 0;
sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling);
sec->ceilingplane.c = -FRACUNIT;
sec->ceilingplane.ic = -FRACUNIT;
}
else
{
double ulen = TVector3<double>(cp[0], cp[1], cp[2]).Length();
// normalize the vector, it must have a length of 1
sec->ceilingplane.a = FLOAT2FIXED(cp[0] / ulen);
sec->ceilingplane.b = FLOAT2FIXED(cp[1] / ulen);
sec->ceilingplane.c = FLOAT2FIXED(cp[2] / ulen);
sec->ceilingplane.d = FLOAT2FIXED(cp[3] / ulen);
sec->ceilingplane.ic = FLOAT2FIXED(ulen / cp[2]);
}
if (lightcolor == -1 && fadecolor == -1 && desaturation == -1)
{
// [RH] Sectors default to white light with the default fade.
// If they are outside (have a sky ceiling), they use the outside fog.
if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special & 0xff) == Sector_Outside))
{
if (fogMap == NULL)
fogMap = GetSpecialLights(PalEntry(255, 255, 255), level.outsidefog, 0);
sec->ColorMap = fogMap;
}
else
{
if (normMap == NULL)
normMap = GetSpecialLights (PalEntry (255,255,255), level.fadeto, NormalLight.Desaturate);
sec->ColorMap = normMap;
}
}
else
{
if (lightcolor == -1) lightcolor = PalEntry(255,255,255);
if (fadecolor == -1)
{
if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special & 0xff) == Sector_Outside))
fadecolor = level.outsidefog;
else
fadecolor = level.fadeto;
}
if (desaturation == -1) desaturation = NormalLight.Desaturate;
sec->ColorMap = GetSpecialLights (lightcolor, fadecolor, desaturation);
}
}