void ParseLinedef(line_t *ld, int index) { bool passuse = false; bool strifetrans = false; bool strifetrans2 = false; FString arg0str, arg1str; memset(ld, 0, sizeof(*ld)); ld->Alpha = FRACUNIT; ld->id = -1; 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: ld->id = CheckInt(key); 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; // [Dusk] lock number case NAME_Locknumber: ld->locknumber = CheckInt(key); continue; default: break; } if (!strnicmp("user_", key.GetChars(), 5)) { AddUserKey(key, UDMF_Line, index); } } if (isTranslated) { int saved = ld->flags; maplinedef_t mld; memset(&mld, 0, sizeof(mld)); mld.special = ld->special; mld.tag = ld->id; 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); } }
// // P_ArchiveWorld // void P_SerializeWorld (FArchive &arc) { int i, j; sector_t *sec; line_t *li; zone_t *zn; // do sectors for (i = 0, sec = sectors; i < numsectors; i++, sec++) { arc << sec->floorplane << sec->ceilingplane; if (SaveVersion < 3223) { BYTE bytelight; arc << bytelight; sec->lightlevel = bytelight; } else { arc << sec->lightlevel; } arc << sec->special << sec->tag << sec->soundtraversed << sec->seqType << sec->friction << sec->movefactor << sec->floordata << sec->ceilingdata << sec->lightingdata << sec->stairlock << sec->prevsec << sec->nextsec << sec->planes[sector_t::floor] << sec->planes[sector_t::ceiling] << sec->heightsec << sec->bottommap << sec->midmap << sec->topmap << sec->gravity << sec->damage << sec->mod << sec->SoundTarget << sec->SecActTarget << sec->sky << sec->MoreFlags << sec->Flags << sec->FloorSkyBox << sec->CeilingSkyBox << sec->ZoneNumber << sec->secretsector << sec->interpolations[0] << sec->interpolations[1] << sec->interpolations[2] << sec->interpolations[3] << sec->SeqName; sec->e->Serialize(arc); if (arc.IsStoring ()) { arc << sec->ColorMap->Color << sec->ColorMap->Fade; BYTE sat = sec->ColorMap->Desaturate; arc << sat; } else { PalEntry color, fade; BYTE desaturate; arc << color << fade << desaturate; sec->ColorMap = GetSpecialLights (color, fade, desaturate); } // begin of GZDoom additions arc << sec->reflect[sector_t::ceiling] << sec->reflect[sector_t::floor]; // end of GZDoom additions } // do lines for (i = 0, li = lines; i < numlines; i++, li++) { arc << li->flags << li->activation << li->special << li->Alpha << li->id; if (P_IsACSSpecial(li->special)) { P_SerializeACSScriptNumber(arc, li->args[0], false); } else { arc << li->args[0]; } arc << li->args[1] << li->args[2] << li->args[3] << li->args[4]; for (j = 0; j < 2; j++) { if (li->sidedef[j] == NULL) continue; side_t *si = li->sidedef[j]; arc << si->textures[side_t::top] << si->textures[side_t::mid] << si->textures[side_t::bottom] << si->Light << si->Flags << si->LeftSide << si->RightSide << si->Index; DBaseDecal::SerializeChain (arc, &si->AttachedDecals); } } // do zones arc << numzones; if (arc.IsLoading()) { if (zones != NULL) { delete[] zones; } zones = new zone_t[numzones]; } for (i = 0, zn = zones; i < numzones; ++i, ++zn) { arc << zn->Environment; } }
void ParseThing(FMapThing *th) { FString arg0str, arg1str; memset(th, 0, sizeof(*th)); th->gravity = FRACUNIT; th->RenderStyle = STYLE_Count; th->alpha = -1; th->health = 1; sc.MustGetToken('{'); while (!sc.CheckToken('}')) { FName key = ParseKey(); switch(key) { case NAME_Id: th->thingid = CheckInt(key); break; case NAME_X: th->x = CheckFixed(key); break; case NAME_Y: th->y = CheckFixed(key); break; case NAME_Height: th->z = CheckFixed(key); break; case NAME_Angle: th->angle = (short)CheckInt(key); break; case NAME_Type: th->type = (short)CheckInt(key); break; case NAME_Conversation: CHECK_N(Zd | Zdt) th->Conversation = CheckInt(key); break; case NAME_Special: CHECK_N(Hx | Zd | Zdt | Va) th->special = CheckInt(key); break; case NAME_Gravity: CHECK_N(Zd | Zdt) th->gravity = CheckFixed(key); break; case NAME_Arg0: case NAME_Arg1: case NAME_Arg2: case NAME_Arg3: case NAME_Arg4: CHECK_N(Hx | Zd | Zdt | Va) th->args[int(key)-int(NAME_Arg0)] = CheckInt(key); break; case NAME_Arg0Str: CHECK_N(Zd); arg0str = CheckString(key); break; case NAME_Arg1Str: CHECK_N(Zd); arg1str = CheckString(key); break; case NAME_Skill1: case NAME_Skill2: case NAME_Skill3: case NAME_Skill4: case NAME_Skill5: case NAME_Skill6: case NAME_Skill7: case NAME_Skill8: case NAME_Skill9: case NAME_Skill10: case NAME_Skill11: case NAME_Skill12: case NAME_Skill13: case NAME_Skill14: case NAME_Skill15: case NAME_Skill16: if (CheckBool(key)) th->SkillFilter |= (1<<(int(key)-NAME_Skill1)); else th->SkillFilter &= ~(1<<(int(key)-NAME_Skill1)); break; case NAME_Class1: case NAME_Class2: case NAME_Class3: case NAME_Class4: case NAME_Class5: case NAME_Class6: case NAME_Class7: case NAME_Class8: case NAME_Class9: case NAME_Class10: case NAME_Class11: case NAME_Class12: case NAME_Class13: case NAME_Class14: case NAME_Class15: case NAME_Class16: CHECK_N(Hx | Zd | Zdt | Va) if (CheckBool(key)) th->ClassFilter |= (1<<(int(key)-NAME_Class1)); else th->ClassFilter &= ~(1<<(int(key)-NAME_Class1)); break; case NAME_Ambush: Flag(th->flags, MTF_AMBUSH, key); break; case NAME_Dormant: CHECK_N(Hx | Zd | Zdt | Va) Flag(th->flags, MTF_DORMANT, key); break; case NAME_Single: Flag(th->flags, MTF_SINGLE, key); break; case NAME_Coop: Flag(th->flags, MTF_COOPERATIVE, key); break; case NAME_Dm: Flag(th->flags, MTF_DEATHMATCH, key); break; case NAME_Translucent: CHECK_N(St | Zd | Zdt | Va) Flag(th->flags, MTF_SHADOW, key); break; case NAME_Invisible: CHECK_N(St | Zd | Zdt | Va) Flag(th->flags, MTF_ALTSHADOW, key); break; case NAME_Friend: // This maps to Strife's friendly flag CHECK_N(Dm | Zd | Zdt | Va) Flag(th->flags, MTF_FRIENDLY, key); break; case NAME_Strifeally: CHECK_N(St | Zd | Zdt | Va) Flag(th->flags, MTF_FRIENDLY, key); break; case NAME_Standing: CHECK_N(St | Zd | Zdt | Va) Flag(th->flags, MTF_STANDSTILL, key); break; case NAME_Countsecret: CHECK_N(Zd | Zdt | Va) Flag(th->flags, MTF_SECRET, key); break; case NAME_Renderstyle: { FName style = CheckString(key); switch (style) { case NAME_None: th->RenderStyle = STYLE_None; break; case NAME_Normal: th->RenderStyle = STYLE_Normal; break; case NAME_Fuzzy: th->RenderStyle = STYLE_Fuzzy; break; case NAME_SoulTrans: th->RenderStyle = STYLE_SoulTrans; break; case NAME_OptFuzzy: th->RenderStyle = STYLE_OptFuzzy; break; case NAME_Stencil: th->RenderStyle = STYLE_Stencil; break; case NAME_AddStencil: th->RenderStyle = STYLE_AddStencil; break; case NAME_Translucent: th->RenderStyle = STYLE_Translucent; break; case NAME_Add: case NAME_Additive: th->RenderStyle = STYLE_Add; break; case NAME_Shaded: th->RenderStyle = STYLE_Shaded; break; case NAME_AddShaded: th->RenderStyle = STYLE_AddShaded; break; case NAME_TranslucentStencil: th->RenderStyle = STYLE_TranslucentStencil; break; case NAME_Shadow: th->RenderStyle = STYLE_Shadow; break; case NAME_Subtract: case NAME_Subtractive: th->RenderStyle = STYLE_Subtract; break; default: break; } } break; case NAME_Alpha: th->alpha = CheckFixed(key); break; case NAME_FillColor: th->fillcolor = CheckInt(key); case NAME_Health: th->health = CheckInt(key); break; case NAME_Score: th->score = CheckInt(key); break; case NAME_Pitch: th->pitch = (short)CheckInt(key); break; case NAME_Roll: th->roll = (short)CheckInt(key); break; case NAME_ScaleX: th->scaleX = CheckFixed(key); break; case NAME_ScaleY: th->scaleY = CheckFixed(key); break; case NAME_Scale: th->scaleX = th->scaleY = CheckFixed(key); break; default: if (0 == strnicmp("user_", key.GetChars(), 5)) { // Custom user key - Sets an actor's user variable directly FMapThingUserData ud; ud.Property = key; ud.Value = CheckInt(key); MapThingsUserData.Push(ud); } break; } } if (arg0str.IsNotEmpty() && (P_IsACSSpecial(th->special) || th->special == 0)) { th->args[0] = -FName(arg0str); } if (arg1str.IsNotEmpty() && (P_IsThingSpecial(th->special) || th->special == 0)) { th->args[1] = -FName(arg1str); } // Thing specials are only valid in namespaces with Hexen-type specials // and in ZDoomTranslated - which will use the translator on them. if (namespc == NAME_ZDoomTranslated) { maplinedef_t mld; line_t ld; if (th->special != 0) // if special is 0, keep the args (e.g. for bridge things) { // The trigger type is ignored here. mld.flags = 0; mld.special = th->special; mld.tag = th->args[0]; P_TranslateLineDef(&ld, &mld); th->special = ld.special; memcpy(th->args, ld.args, sizeof (ld.args)); } } else if (isTranslated) { th->special = 0; memset(th->args, 0, sizeof (th->args)); } }
// // P_ArchiveWorld // void P_SerializeWorld (FArchive &arc) { int i, j; sector_t *sec; line_t *li; zone_t *zn; // do sectors for (i = 0, sec = sectors; i < numsectors; i++, sec++) { arc << sec->floorplane << sec->ceilingplane; if (SaveVersion < 3223) { BYTE bytelight; arc << bytelight; sec->lightlevel = bytelight; } else { arc << sec->lightlevel; } arc << sec->special; if (SaveVersion < 4523) { short tag; arc << tag; } arc << sec->soundtraversed << sec->seqType << sec->friction << sec->movefactor << sec->floordata << sec->ceilingdata << sec->lightingdata << sec->stairlock << sec->prevsec << sec->nextsec << sec->planes[sector_t::floor] << sec->planes[sector_t::ceiling] << sec->heightsec << sec->bottommap << sec->midmap << sec->topmap << sec->gravity; if (SaveVersion >= 4530) { P_SerializeTerrain(arc, sec->terrainnum[0]); P_SerializeTerrain(arc, sec->terrainnum[1]); } if (SaveVersion >= 4529) { arc << sec->damageamount; } else { short dmg; arc << dmg; sec->damageamount = dmg; } if (SaveVersion >= 4528) { arc << sec->damageinterval << sec->leakydamage << sec->damagetype; } else { short damagemod; arc << damagemod; sec->damagetype = MODtoDamageType(damagemod); if (sec->damageamount < 20) { sec->leakydamage = 0; sec->damageinterval = 32; } else if (sec->damageamount < 50) { sec->leakydamage = 5; sec->damageinterval = 32; } else { sec->leakydamage = 256; sec->damageinterval = 1; } } arc << sec->SoundTarget << sec->SecActTarget << sec->sky << sec->MoreFlags << sec->Flags << sec->SkyBoxes[sector_t::floor] << sec->SkyBoxes[sector_t::ceiling] << sec->ZoneNumber; if (SaveVersion < 4529) { short secretsector; arc << secretsector; if (secretsector) sec->Flags |= SECF_WASSECRET; sec->special &= ~(SECRET_MASK|FRICTION_MASK|PUSH_MASK); P_InitSectorSpecial(sec, sec->special, true); } arc << sec->interpolations[0] << sec->interpolations[1] << sec->interpolations[2] << sec->interpolations[3] << sec->SeqName; sec->e->Serialize(arc); if (arc.IsStoring ()) { arc << sec->ColorMap->Color << sec->ColorMap->Fade; BYTE sat = sec->ColorMap->Desaturate; arc << sat; } else { PalEntry color, fade; BYTE desaturate; arc << color << fade << desaturate; sec->ColorMap = GetSpecialLights (color, fade, desaturate); } // begin of GZDoom additions arc << sec->reflect[sector_t::ceiling] << sec->reflect[sector_t::floor]; // end of GZDoom additions } // do lines for (i = 0, li = lines; i < numlines; i++, li++) { arc << li->flags << li->activation << li->special << li->Alpha; if (SaveVersion < 4523) { int id; arc << id; } if (P_IsACSSpecial(li->special)) { P_SerializeACSScriptNumber(arc, li->args[0], false); } else { arc << li->args[0]; } arc << li->args[1] << li->args[2] << li->args[3] << li->args[4]; if (SaveVersion >= 4531) { arc << li->skybox; } for (j = 0; j < 2; j++) { if (li->sidedef[j] == NULL) continue; side_t *si = li->sidedef[j]; arc << si->textures[side_t::top] << si->textures[side_t::mid] << si->textures[side_t::bottom] << si->Light << si->Flags << si->LeftSide << si->RightSide << si->Index; DBaseDecal::SerializeChain (arc, &si->AttachedDecals); } } // do zones arc << numzones; if (arc.IsLoading()) { if (zones != NULL) { delete[] zones; } zones = new zone_t[numzones]; } for (i = 0, zn = zones; i < numzones; ++i, ++zn) { arc << zn->Environment; } }