in doom_py/src/vizdoom/src/p_udmf.cpp [783:1119]
void ParseLinedef(line_t *ld, int index)
{
bool passuse = false;
bool strifetrans = false;
bool strifetrans2 = false;
FString arg0str, arg1str;
int lineid = -1; // forZDoomTranslated namespace
FString tagstring;
memset(ld, 0, sizeof(*ld));
ld->Alpha = FRACUNIT;
ld->sidedef[0] = ld->sidedef[1] = NULL;
if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
if (level.flags2 & LEVEL2_CHECKSWITCHRANGE) ld->flags |= ML_CHECKSWITCHRANGE;
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{
FName key = ParseKey();
// This switch contains all keys of the UDMF base spec
switch(key)
{
case NAME_V1:
ld->v1 = (vertex_t*)(intptr_t)CheckInt(key); // must be relocated later
continue;
case NAME_V2:
ld->v2 = (vertex_t*)(intptr_t)CheckInt(key); // must be relocated later
continue;
case NAME_Special:
ld->special = CheckInt(key);
if (namespc == NAME_Hexen)
{
if (ld->special < 0 || ld->special > 140 || !HexenLineSpecialOk[ld->special])
ld->special = 0; // NULL all specials which don't exist in Hexen
}
continue;
case NAME_Id:
lineid = CheckInt(key);
tagManager.AddLineID(index, lineid);
continue;
case NAME_Sidefront:
ld->sidedef[0] = (side_t*)(intptr_t)(1 + CheckInt(key));
continue;
case NAME_Sideback:
ld->sidedef[1] = (side_t*)(intptr_t)(1 + CheckInt(key));
continue;
case NAME_Arg0:
case NAME_Arg1:
case NAME_Arg2:
case NAME_Arg3:
case NAME_Arg4:
ld->args[int(key)-int(NAME_Arg0)] = CheckInt(key);
continue;
case NAME_Arg0Str:
CHECK_N(Zd);
arg0str = CheckString(key);
continue;
case NAME_Arg1Str:
CHECK_N(Zd);
arg1str = CheckString(key);
continue;
case NAME_Blocking:
Flag(ld->flags, ML_BLOCKING, key);
continue;
case NAME_Blockmonsters:
Flag(ld->flags, ML_BLOCKMONSTERS, key);
continue;
case NAME_Twosided:
Flag(ld->flags, ML_TWOSIDED, key);
continue;
case NAME_Dontpegtop:
Flag(ld->flags, ML_DONTPEGTOP, key);
continue;
case NAME_Dontpegbottom:
Flag(ld->flags, ML_DONTPEGBOTTOM, key);
continue;
case NAME_Secret:
Flag(ld->flags, ML_SECRET, key);
continue;
case NAME_Blocksound:
Flag(ld->flags, ML_SOUNDBLOCK, key);
continue;
case NAME_Dontdraw:
Flag(ld->flags, ML_DONTDRAW, key);
continue;
case NAME_Mapped:
Flag(ld->flags, ML_MAPPED, key);
continue;
case NAME_Jumpover:
CHECK_N(St | Zd | Zdt | Va)
Flag(ld->flags, ML_RAILING, key);
continue;
case NAME_Blockfloaters:
CHECK_N(St | Zd | Zdt | Va)
Flag(ld->flags, ML_BLOCK_FLOATERS, key);
continue;
case NAME_Translucent:
CHECK_N(St | Zd | Zdt | Va)
strifetrans = CheckBool(key);
continue;
case NAME_Transparent:
CHECK_N(St | Zd | Zdt | Va)
strifetrans2 = CheckBool(key);
continue;
case NAME_Passuse:
CHECK_N(Dm | Zd | Zdt | Va)
passuse = CheckBool(key);
continue;
default:
break;
}
// This switch contains all keys of the UDMF base spec which only apply to Hexen format specials
if (!isTranslated) switch (key)
{
case NAME_Playercross:
Flag(ld->activation, SPAC_Cross, key);
continue;
case NAME_Playeruse:
Flag(ld->activation, SPAC_Use, key);
continue;
case NAME_Playeruseback:
Flag(ld->activation, SPAC_UseBack, key);
continue;
case NAME_Monstercross:
Flag(ld->activation, SPAC_MCross, key);
continue;
case NAME_Impact:
Flag(ld->activation, SPAC_Impact, key);
continue;
case NAME_Playerpush:
Flag(ld->activation, SPAC_Push, key);
continue;
case NAME_Missilecross:
Flag(ld->activation, SPAC_PCross, key);
continue;
case NAME_Monsteruse:
Flag(ld->activation, SPAC_MUse, key);
continue;
case NAME_Monsterpush:
Flag(ld->activation, SPAC_MPush, key);
continue;
case NAME_Repeatspecial:
Flag(ld->flags, ML_REPEAT_SPECIAL, key);
continue;
default:
break;
}
// This switch contains all keys which are ZDoom specific
if (namespace_bits & (Zd|Zdt|Va)) switch(key)
{
case NAME_Alpha:
ld->Alpha = CheckFixed(key);
continue;
case NAME_Renderstyle:
{
const char *str = CheckString(key);
if (!stricmp(str, "translucent")) ld->flags &= ~ML_ADDTRANS;
else if (!stricmp(str, "add")) ld->flags |= ML_ADDTRANS;
else sc.ScriptMessage("Unknown value \"%s\" for 'renderstyle'\n", str);
continue;
}
case NAME_Anycross:
Flag(ld->activation, SPAC_AnyCross, key);
continue;
case NAME_Monsteractivate:
Flag(ld->flags, ML_MONSTERSCANACTIVATE, key);
continue;
case NAME_Blockplayers:
Flag(ld->flags, ML_BLOCK_PLAYERS, key);
continue;
case NAME_Blockeverything:
Flag(ld->flags, ML_BLOCKEVERYTHING, key);
continue;
case NAME_Zoneboundary:
Flag(ld->flags, ML_ZONEBOUNDARY, key);
continue;
case NAME_Clipmidtex:
Flag(ld->flags, ML_CLIP_MIDTEX, key);
continue;
case NAME_Wrapmidtex:
Flag(ld->flags, ML_WRAP_MIDTEX, key);
continue;
case NAME_Midtex3d:
Flag(ld->flags, ML_3DMIDTEX, key);
continue;
case NAME_Checkswitchrange:
Flag(ld->flags, ML_CHECKSWITCHRANGE, key);
continue;
case NAME_Firstsideonly:
Flag(ld->flags, ML_FIRSTSIDEONLY, key);
continue;
case NAME_blockprojectiles:
Flag(ld->flags, ML_BLOCKPROJECTILE, key);
continue;
case NAME_blockuse:
Flag(ld->flags, ML_BLOCKUSE, key);
continue;
case NAME_blocksight:
Flag(ld->flags, ML_BLOCKSIGHT, key);
continue;
case NAME_blockhitscan:
Flag(ld->flags, ML_BLOCKHITSCAN, key);
continue;
// [TP] Locks the special with a key
case NAME_Locknumber:
ld->locknumber = CheckInt(key);
continue;
// [TP] Causes a 3d midtex to behave like an impassible line
case NAME_Midtex3dimpassible:
Flag(ld->flags, ML_3DMIDTEX_IMPASS, key);
continue;
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_Line, 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.AddLineID(index, sc.Number);
}
}
if (isTranslated)
{
int saved = ld->flags;
maplinedef_t mld;
memset(&mld, 0, sizeof(mld));
mld.special = ld->special;
mld.tag = ld->args[0];
P_TranslateLineDef(ld, &mld);
ld->flags = saved | (ld->flags&(ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_FIRSTSIDEONLY));
}
if (passuse && (ld->activation & SPAC_Use))
{
ld->activation = (ld->activation & ~SPAC_Use) | SPAC_UseThrough;
}
if (strifetrans && ld->Alpha == FRACUNIT)
{
ld->Alpha = FRACUNIT * 3/4;
}
if (strifetrans2 && ld->Alpha == FRACUNIT)
{
ld->Alpha = FRACUNIT * 1/4;
}
if (ld->sidedef[0] == NULL)
{
ld->sidedef[0] = (side_t*)(intptr_t)(1);
Printf("Line %d has no first side.\n", index);
}
if (arg0str.IsNotEmpty() && (P_IsACSSpecial(ld->special) || ld->special == 0))
{
ld->args[0] = -FName(arg0str);
}
if (arg1str.IsNotEmpty() && (P_IsThingSpecial(ld->special) || ld->special == 0))
{
ld->args[1] = -FName(arg1str);
}
if ((ld->flags & ML_3DMIDTEX_IMPASS) && !(ld->flags & ML_3DMIDTEX)) // [TP]
{
Printf ("Line %d has midtex3dimpassible without midtex3d.\n", index);
}
}