void FTextureManager::ParseCameraTexture(FScanner &sc) { const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny | TEXMAN_ShortNameOnly; int width, height; int fitwidth, fitheight; FString picname; sc.MustGetString (); picname = sc.String; sc.MustGetNumber (); width = sc.Number; sc.MustGetNumber (); height = sc.Number; FTextureID picnum = CheckForTexture (picname, FTexture::TEX_Flat, texflags); FTexture *viewer = new FCanvasTexture (picname, width, height); if (picnum.Exists()) { FTexture *oldtex = Texture(picnum); fitwidth = oldtex->GetScaledWidth (); fitheight = oldtex->GetScaledHeight (); viewer->UseType = oldtex->UseType; ReplaceTexture (picnum, viewer, true); } else { fitwidth = width; fitheight = height; // [GRB] No need for oldtex viewer->UseType = FTexture::TEX_Wall; AddTexture (viewer); } if (sc.GetString()) { if (sc.Compare ("fit")) { sc.MustGetNumber (); fitwidth = sc.Number; sc.MustGetNumber (); fitheight = sc.Number; } else { sc.UnGet (); } } if (sc.GetString()) { if (sc.Compare("WorldPanning")) { viewer->bWorldPanning = true; } else { sc.UnGet(); } } viewer->SetScaledSize(fitwidth, fitheight); }
static void ParseStatistics(const char *fn, TArray<FStatistics> &statlist) { statlist.Clear(); try { FScanner sc; sc.OpenFile(fn); while (sc.GetString()) { FStatistics &ep_entry = statlist[statlist.Reserve(1)]; ep_entry.epi_header = sc.String; sc.MustGetString(); ep_entry.epi_name = sc.String; sc.MustGetStringName("{"); while (!sc.CheckString("}")) { FSessionStatistics &session = ep_entry.stats[ep_entry.stats.Reserve(1)]; sc.MustGetString(); sc.MustGetString(); strncpy(session.name, sc.String, 12); sc.MustGetString(); strncpy(session.info, sc.String, 30); int h,m,s; sc.MustGetString(); sscanf(sc.String, "%d:%d:%d", &h, &m, &s); session.timeneeded= ((((h*60)+m)*60)+s)*TICRATE; sc.MustGetNumber(); session.skill=sc.Number; if (sc.CheckString("{")) { while (!sc.CheckString("}")) { FLevelStatistics &lstats = session.levelstats[session.levelstats.Reserve(1)]; sc.MustGetString(); strncpy(lstats.name, sc.String, 12); sc.MustGetString(); strncpy(lstats.info, sc.String, 30); int h,m,s; sc.MustGetString(); sscanf(sc.String, "%d:%d:%d", &h, &m, &s); lstats.timeneeded= ((((h*60)+m)*60)+s)*TICRATE; lstats.skill = 0; } } } } } catch(CRecoverableError &) { } }
static void ParseDamage (FScanner &sc, int keyword, void *fields) { FTerrainDef *def = (FTerrainDef *)fields; sc.MustGetString (); // Lava is synonymous with Fire here! if (sc.Compare("Lava")) def->DamageMOD=NAME_Fire; else def->DamageMOD=sc.String; }
//========================================================================== //*** // Reads a state label that may contain '.'s. // processes a state block // //========================================================================== static FString ParseStateString(FScanner &sc) { FString statestring; sc.MustGetString(); statestring = sc.String; if (sc.CheckString("::")) { sc.MustGetString (); statestring << "::" << sc.String; } while (sc.CheckString (".")) { sc.MustGetString (); statestring << "." << sc.String; } return statestring; }
static void ParseActorProperty(FScanner &sc, Baggage &bag) { static const char *statenames[] = { "Spawn", "See", "Melee", "Missile", "Pain", "Death", "XDeath", "Burn", "Ice", "Raise", "Crash", "Crush", "Wound", "Disintegrate", "Heal", NULL }; strlwr (sc.String); FString propname = sc.String; if (sc.CheckString (".")) { sc.MustGetString (); propname += '.'; strlwr (sc.String); propname += sc.String; } else { sc.UnGet (); } FPropertyInfo *prop = FindProperty(propname); if (prop != NULL) { if (bag.Info->Class->IsDescendantOf(prop->cls)) { ParsePropertyParams(sc, prop, (AActor *)bag.Info->Class->Defaults, bag); } else { sc.ScriptMessage("\"%s\" requires an actor of type \"%s\"\n", propname.GetChars(), prop->cls->TypeName.GetChars()); FScriptPosition::ErrorCounter++; } } else if (!propname.CompareNoCase("States")) { if (bag.StateSet) { sc.ScriptMessage("'%s' contains multiple state declarations", bag.Info->Class->TypeName.GetChars()); FScriptPosition::ErrorCounter++; } ParseStates(sc, bag.Info, (AActor *)bag.Info->Class->Defaults, bag); bag.StateSet=true; } else if (MatchString(propname, statenames) != -1) { bag.statedef.SetStateLabel(propname, CheckState (sc, bag.Info->Class)); } else { sc.ScriptError("\"%s\" is an unknown actor property\n", propname.GetChars()); } }
void ParseSplash (FScanner &sc) { int splashnum; FSplashDef *splashdef; bool isnew = false; FName name; sc.MustGetString (); name = sc.String; splashnum = (int)FindSplash (name); if (splashnum < 0) { FSplashDef def; SetSplashDefaults (&def); def.Name = name; splashnum = (int)Splashes.Push (def); isnew = true; } splashdef = &Splashes[splashnum]; sc.MustGetString (); if (!sc.Compare ("modify")) { // Set defaults if (!isnew) { // New ones already have their defaults set before they're pushed. SetSplashDefaults (splashdef); } } else { sc.MustGetString(); } if (!sc.Compare ("{")) { sc.ScriptError ("Expected {"); } else { GenericParse (sc, SplashParser, SplashKeywords, splashdef, "splash", splashdef->Name); } }
static void SkipSubBlock(FScanner &sc) { sc.MustGetStringName("{"); int depth = 1; while (depth > 0) { sc.MustGetString(); if (sc.Compare("{")) depth++; if (sc.Compare("}")) depth--; } }
void ParseTerrain (FScanner &sc) { int terrainnum; FName name; sc.MustGetString (); name = sc.String; terrainnum = (int)P_FindTerrain (name); if (terrainnum < 0) { FTerrainDef def; memset (&def, 0, sizeof(def)); def.Splash = -1; def.Name = name; terrainnum = (int)Terrains.Push (def); } // Set defaults sc.MustGetString (); if (!sc.Compare ("modify")) { name = Terrains[terrainnum].Name; memset (&Terrains[terrainnum], 0, sizeof(FTerrainDef)); Terrains[terrainnum].Splash = -1; Terrains[terrainnum].Name = name; } else { sc.MustGetString (); } if (sc.Compare ("{")) { GenericParse (sc, TerrainParser, TerrainKeywords, &Terrains[terrainnum], "terrain", Terrains[terrainnum].Name); } else { sc.ScriptError ("Expected {"); } }
static void ParseDefault (FScanner &sc) { int terrain; sc.MustGetString (); terrain = P_FindTerrain (sc.String); if (terrain == -1) { Printf ("Unknown terrain %s\n", sc.String); terrain = 0; } DefaultTerrainType = terrain; }
static void ParseFloor (FScanner &sc) { FTextureID picnum; int terrain; sc.MustGetString (); picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny); if (!picnum.Exists()) { Printf ("Unknown flat %s\n", sc.String); sc.MustGetString (); return; } sc.MustGetString (); terrain = P_FindTerrain (sc.String); if (terrain == -1) { Printf ("Unknown terrain %s\n", sc.String); terrain = 0; } TerrainTypes.Set(picnum.GetIndex(), terrain); }
static void ParseOptionValue(FScanner &sc) { FName optname; FOptionValues *val = new FOptionValues; sc.MustGetString(); optname = sc.String; sc.MustGetStringName("{"); while (!sc.CheckString("}")) { FOptionValues::Pair &pair = val->mValues[val->mValues.Reserve(1)]; sc.MustGetFloat(); pair.Value = sc.Float; sc.MustGetStringName(","); sc.MustGetString(); pair.Text = strbin1(sc.String); } FOptionValues **pOld = OptionValues.CheckKey(optname); if (pOld != NULL && *pOld != NULL) { delete *pOld; } OptionValues[optname] = val; }
static bool CheckSkipOptionBlock(FScanner &sc) { bool filter = false; sc.MustGetStringName("("); do { sc.MustGetString(); if (sc.Compare("ReadThis")) filter |= gameinfo.drawreadthis; else if (sc.Compare("Swapmenu")) filter |= gameinfo.swapmenu; else if (sc.Compare("Windows")) { #ifdef _WIN32 filter = true; #endif } else if (sc.Compare("unix")) { #ifdef __unix__ filter = true; #endif } else if (sc.Compare("Mac")) { #ifdef __APPLE__ filter = true; #endif } else if (sc.Compare("OpenAL")) { filter |= IsOpenALPresent(); } else if (sc.Compare("FModEx")) { filter |= IsFModExPresent(); } } while (sc.CheckString(",")); sc.MustGetStringName(")"); if (!filter) { SkipSubBlock(sc); return !sc.CheckString("else"); } return false; }
static void ParseSpawnMap(FScanner &sc, SpawnMap & themap, const char *descript) { TMap<int, bool> defined; int error = 0; MapinfoSpawnItem editem; editem.filename = sc.ScriptName; while (true) { if (sc.CheckString("}")) return; else if (sc.CheckNumber()) { int ednum = sc.Number; sc.MustGetStringName("="); sc.MustGetString(); bool *def = defined.CheckKey(ednum); if (def != NULL) { sc.ScriptMessage("%s %d defined more than once", descript, ednum); error++; } else if (ednum < 0) { sc.ScriptMessage("%s must be positive, got %d", descript, ednum); error++; } defined[ednum] = true; editem.classname = sc.String; editem.linenum = sc.Line; themap.Insert(ednum, editem); } else { sc.ScriptError("Number expected"); } } if (error > 0) { sc.ScriptError("%d errors encountered in %s definition", error, descript); } }
static bool CheckSkipGameBlock(FScanner &sc) { bool filter = false; sc.MustGetStringName("("); do { sc.MustGetString(); filter |= CheckGame(sc.String, false); } while (sc.CheckString(",")); sc.MustGetStringName(")"); if (!filter) { SkipSubBlock(sc); return true; } return false; }
FTextureID FTextureManager::ParseFramenum (FScanner &sc, FTextureID basepicnum, int usetype, bool allowMissing) { const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; FTextureID framenum; sc.MustGetString (); if (IsNum (sc.String)) { framenum = basepicnum + (atoi(sc.String) - 1); } else { framenum = CheckForTexture (sc.String, usetype, texflags); if (!framenum.Exists() && !allowMissing) { sc.ScriptError ("Unknown texture %s", sc.String); } } return framenum; }
static void ParseTime (FScanner &sc, DWORD &min, DWORD &max) { sc.MustGetString (); if (sc.Compare ("tics")) { sc.MustGetFloat (); min = max = DWORD(sc.Float * 1000 / 35); } else if (sc.Compare ("rand")) { sc.MustGetFloat (); min = DWORD(sc.Float * 1000 / 35); sc.MustGetFloat (); max = DWORD(sc.Float * 1000 / 35); } else { sc.ScriptError ("Must specify a duration for animation frame"); } }
static void ParseOptionMenu(FScanner &sc) { sc.MustGetString(); FOptionMenuDescriptor *desc = new FOptionMenuDescriptor; desc->mType = MDESC_OptionsMenu; desc->mMenuName = sc.String; desc->mSelectedItem = -1; desc->mScrollPos = 0; desc->mClass = NULL; desc->mPosition = DefaultOptionMenuSettings.mPosition; desc->mScrollTop = DefaultOptionMenuSettings.mScrollTop; desc->mIndent = DefaultOptionMenuSettings.mIndent; desc->mDontDim = DefaultOptionMenuSettings.mDontDim; ParseOptionMenuBody(sc, desc); bool scratch = ReplaceMenu(sc, desc); if (desc->mIndent == 0) desc->CalcIndent(); if (scratch) delete desc; }
void FTextureManager::ParseTime (FScanner &sc, uint32_t &min, uint32_t &max) { sc.MustGetString (); if (sc.Compare ("tics")) { sc.MustGetFloat (); min = max = uint32_t(sc.Float * 1000 / 35); } else if (sc.Compare ("rand")) { sc.MustGetFloat (); min = uint32_t(sc.Float * 1000 / 35); sc.MustGetFloat (); max = uint32_t(sc.Float * 1000 / 35); } else { min = max = 1; sc.ScriptError ("Must specify a duration for animation frame"); } }
static void ParseDamageDefinition(FScanner &sc) { sc.SetCMode (true); // This may be 100% irrelevant for such a simple syntax, but I don't know // Get DamageType sc.MustGetString(); FName damageType = sc.String; DamageTypeDefinition dtd; sc.MustGetToken('{'); while (sc.MustGetAnyToken(), sc.TokenType != '}') { if (sc.Compare("FACTOR")) { sc.MustGetFloat(); dtd.DefaultFactor = sc.Float; if (dtd.DefaultFactor == 0) dtd.ReplaceFactor = true; } else if (sc.Compare("REPLACEFACTOR")) { dtd.ReplaceFactor = true; } else if (sc.Compare("NOARMOR")) { dtd.NoArmor = true; } else { sc.ScriptError("Unexpected data (%s) in damagetype definition.", sc.String); } } dtd.Apply(damageType); sc.SetCMode (false); // (set to true earlier in function) }
//=========================================================================== // // Reads glow definitions from GLDEFS // //=========================================================================== void gl_InitGlow(FScanner &sc) { sc.MustGetStringName("{"); while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("FLATS")) { sc.MustGetStringName("{"); while (!sc.CheckString("}")) { sc.MustGetString(); FTextureID flump=TexMan.CheckForTexture(sc.String, FTexture::TEX_Flat,FTextureManager::TEXMAN_TryAny); FTexture *tex = TexMan[flump]; if (tex) tex->gl_info.bGlowing = tex->gl_info.bFullbright = true; } } else if (sc.Compare("WALLS")) { sc.MustGetStringName("{"); while (!sc.CheckString("}")) { sc.MustGetString(); FTextureID flump=TexMan.CheckForTexture(sc.String, FTexture::TEX_Wall,FTextureManager::TEXMAN_TryAny); FTexture *tex = TexMan[flump]; if (tex) tex->gl_info.bGlowing = tex->gl_info.bFullbright = true; } } else if (sc.Compare("TEXTURE")) { sc.SetCMode(true); sc.MustGetString(); FTextureID flump=TexMan.CheckForTexture(sc.String, FTexture::TEX_Flat,FTextureManager::TEXMAN_TryAny); FTexture *tex = TexMan[flump]; sc.MustGetStringName(","); sc.MustGetString(); PalEntry color = V_GetColor(NULL, sc.String); //sc.MustGetStringName(","); //sc.MustGetNumber(); if (sc.CheckString(",")) { if (sc.CheckNumber()) { if (tex) tex->gl_info.GlowHeight = sc.Number; if (!sc.CheckString(",")) goto skip_fb; } sc.MustGetStringName("fullbright"); if (tex) tex->gl_info.bFullbright = true; } skip_fb: sc.SetCMode(false); if (tex && color != 0) { tex->gl_info.bGlowing = true; tex->gl_info.GlowColor = color; } } } }
void FTextureManager::ParseAnimatedDoor(FScanner &sc) { const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; FDoorAnimation anim; TArray<FTextureID> frames; bool error = false; FTextureID v; sc.MustGetString(); anim.BaseTexture = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); if (!anim.BaseTexture.Exists()) { error = true; } else { Texture(anim.BaseTexture)->bNoDecals = true; } while (sc.GetString()) { if (sc.Compare ("opensound")) { sc.MustGetString (); anim.OpenSound = sc.String; } else if (sc.Compare ("closesound")) { sc.MustGetString (); anim.CloseSound = sc.String; } else if (sc.Compare ("pic")) { sc.MustGetString (); if (IsNum (sc.String)) { v = anim.BaseTexture + (atoi(sc.String) - 1); } else { v = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); if (!v.Exists() && anim.BaseTexture.Exists() && !error) { sc.ScriptError ("Unknown texture %s", sc.String); } } frames.Push(v); } else if (sc.Compare("allowdecals")) { if (anim.BaseTexture.Exists()) Texture(anim.BaseTexture)->bNoDecals = false; } else { sc.UnGet (); break; } } if (!error) { anim.TextureFrames = new FTextureID[frames.Size()]; memcpy (anim.TextureFrames, &frames[0], sizeof(FTextureID) * frames.Size()); anim.NumTextureFrames = frames.Size(); mAnimatedDoors.Push (anim); } }
void FTextureManager::ParseAnim (FScanner &sc, int usetype) { const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; TArray<FAnimDef::FAnimFrame> frames (32); FTextureID picnum; int defined = 0; bool optional = false, missing = false; sc.MustGetString (); if (sc.Compare ("optional")) { optional = true; sc.MustGetString (); } picnum = CheckForTexture (sc.String, usetype, texflags); if (!picnum.Exists()) { if (optional) { missing = true; } else { Printf (PRINT_BOLD, "ANIMDEFS: Can't find %s\n", sc.String); } } // no decals on animating textures, by default if (picnum.isValid()) { Texture(picnum)->bNoDecals = true; } while (sc.GetString ()) { if (sc.Compare ("allowdecals")) { if (picnum.isValid()) { Texture(picnum)->bNoDecals = false; } continue; } else if (sc.Compare ("range")) { if (defined == 2) { sc.ScriptError ("You cannot use \"pic\" and \"range\" together in a single animation."); } if (defined == 1) { sc.ScriptError ("You can only use one \"range\" per animation."); } defined = 1; ParseRangeAnim (sc, picnum, usetype, missing); } else if (sc.Compare ("pic")) { if (defined == 1) { sc.ScriptError ("You cannot use \"pic\" and \"range\" together in a single animation."); } defined = 2; ParsePicAnim (sc, picnum, usetype, missing, frames); } else { sc.UnGet (); break; } } // If base pic is not present, don't add this anim // ParseRangeAnim adds the anim itself, but ParsePicAnim does not. if (picnum.isValid() && defined == 2) { if (frames.Size() < 2) { sc.ScriptError ("Animation needs at least 2 frames"); } AddComplexAnim (picnum, frames); } }
void MapLoader::parseEDLinedef(FScanner &sc, TMap<int, EDLinedef> &EDLines) { EDLinedef ld; bool argsset = false; memset(&ld, 0, sizeof(ld)); ld.alpha = 1.; sc.MustGetStringName("{"); while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("recordnum")) { sc.CheckString("="); sc.MustGetNumber(); ld.recordnum = sc.Number; } else if (sc.Compare("tag")) { sc.CheckString("="); sc.MustGetNumber(); ld.tag = sc.Number; } else if (sc.Compare("id")) { sc.CheckString("="); sc.MustGetNumber(); ld.id = sc.Number; } else if (sc.Compare("special")) { sc.CheckString("="); if (sc.CheckNumber()) { // Oh joy, this is going to be fun... // Here we cannot do anything because we need the tag to make this work. // For now just store a negative number and resolve this later. ld.special = -sc.Number; } else { sc.MustGetString(); ld.special = P_FindLineSpecial(sc.String); } } else if (sc.Compare("args")) { sc.CheckString("="); sc.MustGetStringName("{"); int c = 0; while (true) { sc.MustGetNumber(); ld.args[c++] = sc.Number; if (sc.CheckString("}")) break; sc.MustGetStringName(","); } argsset = true; } else if (sc.Compare("alpha")) { sc.CheckString("="); sc.MustGetFloat(); ld.alpha = sc.Float; } else if (sc.Compare("extflags")) { // these are needed to build the proper activation mask out of the possible flags which do not match ZDoom 1:1. uint32_t actmethod = 0; uint32_t acttype = 0; do { sc.CheckString("="); sc.MustGetString(); for (const char *tok = strtok(sc.String, ",+ \t"); tok != nullptr; tok = strtok(nullptr, ",+ \t")) { if (!stricmp(tok, "USE")) actmethod |= SPAC_Use | SPAC_MUse; else if (!stricmp(tok, "CROSS")) actmethod |= SPAC_Cross | SPAC_MCross | SPAC_PCross; else if (!stricmp(tok, "IMPACT")) ld.activation |= SPAC_Impact; else if (!stricmp(tok, "PUSH")) actmethod |= SPAC_Push; else if (!stricmp(tok, "PLAYER")) acttype |= SPAC_Use | SPAC_Cross | SPAC_Push; else if (!stricmp(tok, "MONSTER")) acttype |= SPAC_MUse | SPAC_MCross | SPAC_MPush; else if (!stricmp(tok, "MISSILE")) acttype |= SPAC_PCross; else if (!stricmp(tok, "REPEAT")) ld.flags |= ML_REPEAT_SPECIAL; else if (!stricmp(tok, "1SONLY")) ld.flags |= ML_FIRSTSIDEONLY; else if (!stricmp(tok, "ADDITIVE")) ld.flags |= ML_ADDTRANS; else if (!stricmp(tok, "BLOCKALL")) ld.flags |= ML_BLOCKEVERYTHING; else if (!stricmp(tok, "ZONEBOUNDARY")) ld.flags |= ML_ZONEBOUNDARY; else if (!stricmp(tok, "CLIPMIDTEX")) ld.flags |= ML_CLIP_MIDTEX; else sc.ScriptError("Unknown option '%s'", tok); } } while (sc.CheckString("|")); // Unquoted strings with '|' separator - parse as a separate string in the loop. // and finally we must mask in the activation method ld.activation |= (actmethod & acttype); } else { sc.ScriptError("Unknown property '%s'", sc.String); } } if (ld.tag == 0) ld.tag = ld.id; // urgh... if (ld.special < 0) // translate numeric specials. { line_t line; maplinedef_t mld; mld.special = -ld.special; mld.tag = ld.tag; Level->TranslateLineDef(&line, &mld); ld.special = line.special; ld.activation = line.activation; ld.flags = (ld.flags & ~(ML_REPEAT_SPECIAL | ML_FIRSTSIDEONLY)) | (line.flags & (ML_REPEAT_SPECIAL | ML_FIRSTSIDEONLY)); if (!argsset) memcpy(ld.args, line.args, sizeof(ld.args)); } EDLines[ld.recordnum] = ld; }
static void parseMapthing(FScanner &sc, TMap<int, EDMapthing> &EDThings) { EDMapthing mt; memset(&mt, 0, sizeof(mt)); mt.flags |= MTF_SINGLE | MTF_COOPERATIVE | MTF_DEATHMATCH; // Extradata uses inverse logic, like Doom.exe sc.MustGetStringName("{"); while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("recordnum")) { sc.CheckString("="); sc.MustGetNumber(); mt.recordnum = sc.Number; } else if (sc.Compare("tid")) { sc.CheckString("="); sc.MustGetNumber(); mt.tid = sc.Number; } else if (sc.Compare("type")) { sc.CheckString("="); if (sc.CheckNumber()) { mt.type = sc.Number; } else { // Class name. sc.MustGetString(); // According to the Eternity Wiki a name may be prefixed with 'thing:'. const char *pos = strchr(sc.String, ':'); // Eternity never checks if the prefix actually is 'thing'. if (pos) pos++; else pos = sc.String; const PClass *cls = PClass::FindClass(pos); if (cls != nullptr) { FDoomEdMap::Iterator it(DoomEdMap); FDoomEdMap::Pair *pair; while (it.NextPair(pair)) { if (pair->Value.Type == cls) { mt.type = pair->Key; break; } } } else { // Let's hope this isn't an internal Eternity name. // If so, a name mapping needs to be defined... sc.ScriptError("Unknown type '%s'", sc.String); } } } else if (sc.Compare("args")) { sc.CheckString("="); sc.MustGetStringName("{"); int c = 0; while (!sc.CheckString("}")) { sc.MustGetNumber(); mt.args[c++] = sc.Number; } } else if (sc.Compare("height")) { sc.CheckString("="); sc.MustGetFloat(); // no idea if Eternity allows fractional numbers. Better be safe and do it anyway. mt.height = sc.Float; } else if (sc.Compare("options")) { sc.CheckString("="); do { sc.MustGetString(); for (const char *tok = strtok(sc.String, ",+ \t"); tok != nullptr; tok = strtok(nullptr, ",+ \t")) { if (!stricmp(tok, "EASY")) mt.skillfilter |= 3; else if (!stricmp(tok, "NORMAL")) mt.skillfilter |= 4; else if (!stricmp(tok, "HARD")) mt.skillfilter |= 24; else if (!stricmp(tok, "AMBUSH")) mt.flags |= MTF_AMBUSH; else if (!stricmp(tok, "NOTSINGLE")) mt.flags &= ~MTF_SINGLE; else if (!stricmp(tok, "NOTDM")) mt.flags &= ~MTF_DEATHMATCH; else if (!stricmp(tok, "NOTCOOP")) mt.flags &= ~MTF_COOPERATIVE; else if (!stricmp(tok, "FRIEND")) mt.flags |= MTF_FRIENDLY; else if (!stricmp(tok, "DORMANT")) mt.flags |= MTF_DORMANT; else sc.ScriptError("Unknown option '%s'", tok); } } while (sc.CheckString("|")); // Unquoted strings with '|' separator - parse as a separate string in the loop. } else { sc.ScriptError("Unknown property '%s'", sc.String); } } EDThings[mt.recordnum] = mt; }
static void parseSector(FScanner &sc, TMap<int, EDSector> &EDSectors) { EDSector sec; memset(&sec, 0, sizeof(sec)); sec.Overlayalpha[sector_t::floor] = sec.Overlayalpha[sector_t::ceiling] = 1.; sec.floorterrain = sec.ceilingterrain = -1; sc.MustGetStringName("{"); while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("recordnum")) { sc.CheckString("="); sc.MustGetNumber(); sec.recordnum = sc.Number; } else if (sc.Compare("flags")) { uint32_t *flagvar = nullptr; if (sc.CheckString(".")) { sc.MustGetString(); if (sc.Compare("add")) { flagvar = &sec.flagsAdd; } else if (sc.Compare("remove")) { flagvar = &sec.flagsRemove; } else { sc.ScriptError("Invalid property 'flags.%s'", sc.String); } } else { sec.flagsSet = true; flagvar = &sec.flags; } sc.CheckString("="); do { sc.MustGetString(); for (const char *tok = strtok(sc.String, ",+ \t"); tok != nullptr; tok = strtok(nullptr, ",+ \t")) { if (!stricmp(tok, "SECRET")) *flagvar |= SECF_SECRET | SECF_WASSECRET; else if (!stricmp(tok, "FRICTION")) *flagvar |= SECF_FRICTION; else if (!stricmp(tok, "PUSH")) *flagvar |= SECF_PUSH; else if (!stricmp(tok, "KILLSOUND")) *flagvar |= SECF_SILENT; else if (!stricmp(tok, "KILLMOVESOUND")) *flagvar |= SECF_SILENTMOVE; else sc.ScriptError("Unknown option '%s'", tok); } } while (sc.CheckString("|")); // Unquoted strings with '|' separator - parse as a separate string in the loop. } else if (sc.Compare("damage")) { sc.CheckString("="); sc.MustGetNumber(); sec.damageamount = sc.Number; } else if (sc.Compare("damagemod")) { sc.CheckString("="); sc.MustGetString(); sec.damagetype = sc.String; } else if (sc.Compare("damagemask")) { sc.CheckString("="); sc.MustGetNumber(); sec.damageinterval = sc.Number; } else if (sc.Compare("damageflags")) { uint32_t *flagvar = nullptr; uint8_t *leakvar = nullptr; if (sc.CheckString(".")) { sc.MustGetString(); if (sc.Compare("add")) { flagvar = &sec.damageflagsAdd; leakvar = &sec.leakyadd; } else if (sc.Compare("remove")) { flagvar = &sec.damageflagsRemove; leakvar = &sec.leakyremove; } else { sc.ScriptError("Invalid property 'flags.%s'", sc.String); } } else { sec.damageflagsSet = true; flagvar = &sec.damageflags; leakvar = &sec.leaky; } sc.CheckString("="); do { sc.MustGetString(); for (const char *tok = strtok(sc.String, ",+ \t"); tok != nullptr; tok = strtok(nullptr, ",+ \t")) { if (!stricmp(tok, "LEAKYSUIT")) *leakvar |= 1; else if (!stricmp(tok, "IGNORESUIT")) *leakvar |= 2; // these 2 bits will be used to set 'leakychance', but this can only be done when the sector gets initialized else if (!stricmp(tok, "ENDGODMODE")) *flagvar |= SECF_ENDGODMODE; else if (!stricmp(tok, "ENDLEVEL")) *flagvar |= SECF_ENDLEVEL; else if (!stricmp(tok, "TERRAINHIT")) *flagvar |= SECF_DMGTERRAINFX; else sc.ScriptError("Unknown option '%s'", tok); } } while (sc.CheckString("|")); // Unquoted strings with '|' separator - parse as a separate string in the loop. } else if (sc.Compare("floorterrain")) { sc.CheckString("="); sc.MustGetString(); sec.floorterrain = P_FindTerrain(sc.String); } else if (sc.Compare("floorangle")) { sc.CheckString("="); sc.MustGetFloat(); sec.angle[sector_t::floor] = sc.Float; } else if (sc.Compare("flooroffsetx")) { sc.CheckString("="); sc.MustGetFloat(); sec.xoffs[sector_t::floor] = sc.Float; } else if (sc.Compare("flooroffsety")) { sc.CheckString("="); sc.MustGetFloat(); sec.yoffs[sector_t::floor] = sc.Float; } else if (sc.Compare("ceilingterrain")) { sc.CheckString("="); sc.MustGetString(); sec.ceilingterrain = P_FindTerrain(sc.String); } else if (sc.Compare("ceilingangle")) { sc.CheckString("="); sc.MustGetFloat(); sec.angle[sector_t::ceiling] = sc.Float; } else if (sc.Compare("ceilingoffsetx")) { sc.CheckString("="); sc.MustGetFloat(); sec.xoffs[sector_t::ceiling] = sc.Float; } else if (sc.Compare("ceilingoffsety")) { sc.CheckString("="); sc.MustGetFloat(); sec.yoffs[sector_t::ceiling] = sc.Float; } else if (sc.Compare("colormaptop") || sc.Compare("colormapbottom")) { sc.CheckString("="); sc.MustGetString(); // these properties are not implemented by ZDoom } else if (sc.Compare("colormapmid")) { sc.CheckString("="); sc.MustGetString(); // Eternity is based on SMMU and uses colormaps differently than all other ports. // The only solution here is to convert the colormap to an RGB value and set it as the sector's color. uint32_t cmap = R_ColormapNumForName(sc.String); if (cmap != 0) { sec.color = R_BlendForColormap(cmap) & 0xff000000; sec.colorSet = true; } } else if (sc.Compare("overlayalpha")) { sc.MustGetStringName("."); sc.MustGetString(); if (sc.Compare("floor")) { sc.MustGetNumber(); if (sc.CheckString("%")) sc.Float = sc.Number / 100.f; else sc.Float = sc.Number / 255.f; sec.Overlayalpha[sector_t::floor] = sc.Float; } else if (sc.Compare("ceiling")) { sc.MustGetFloat(); if (sc.CheckString("%")) sc.Float = sc.Number / 100.f; else sc.Float = sc.Number / 255.f; sec.Overlayalpha[sector_t::floor] = sc.Float; } } else if (sc.Compare("portalflags")) { int dest = 0; sc.MustGetStringName("."); sc.MustGetString(); if (sc.Compare("floor")) dest = sector_t::floor; else if (sc.Compare("ceiling")) dest = sector_t::ceiling; else sc.ScriptError("Unknown portal type '%s'", sc.String); sc.CheckString("="); do { sc.MustGetString(); for (const char *tok = strtok(sc.String, ",+ \t"); tok != nullptr; tok = strtok(nullptr, ",+ \t")) { if (!stricmp(tok, "DISABLED")) sec.portalflags[dest] |= PLANEF_DISABLED; else if (!stricmp(tok, "NORENDER")) sec.portalflags[dest] |= PLANEF_NORENDER; else if (!stricmp(tok, "NOPASS")) sec.portalflags[dest] |= PLANEF_NOPASS; else if (!stricmp(tok, "BLOCKSOUND")) sec.portalflags[dest] |= PLANEF_BLOCKSOUND; else if (!stricmp(tok, "OVERLAY")) sec.portalflags[dest] |= 0; // we do not use this. Alpha is the sole determinant for overlay drawing else if (!stricmp(tok, "ADDITIVE")) sec.portalflags[dest] |= PLANEF_ADDITIVE; else if (!stricmp(tok, "USEGLOBALTEX")) {} // not implemented else sc.ScriptError("Unknown option '%s'", tok); } } while (sc.CheckString("|")); // Unquoted strings with '|' separator - parse as a separate string in the loop. } else { sc.ScriptError("Unknown property '%s'", sc.String); } } EDSectors[sec.recordnum] = sec; }
void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init) { FString patchname; int Mirror = 0; sc.MustGetString(); init.TexName = sc.String; sc.MustGetStringName(","); sc.MustGetNumber(); part.OriginX = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); part.OriginY = sc.Number; if (sc.CheckString("{")) { while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("flipx")) { Mirror |= 1; } else if (sc.Compare("flipy")) { Mirror |= 2; } else if (sc.Compare("rotate")) { sc.MustGetNumber(); sc.Number = (((sc.Number + 90)%360)-90); if (sc.Number != 0 && sc.Number !=90 && sc.Number != 180 && sc.Number != -90) { sc.ScriptError("Rotation must be a multiple of 90 degrees."); } part.Rotate = (sc.Number / 90) & 3; } else if (sc.Compare("Translation")) { int match; bComplex = true; if (part.Translation != NULL) delete part.Translation; part.Translation = NULL; part.Blend = 0; static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; sc.MustGetString(); match = sc.MatchString(maps); if (match >= 0) { part.Blend = BLEND_SPECIALCOLORMAP1 + match; } else if (sc.Compare("ICE")) { part.Blend = BLEND_ICEMAP; } else if (sc.Compare("DESATURATE")) { sc.MustGetStringName(","); sc.MustGetNumber(); part.Blend = BLEND_DESATURATE1 + clamp(sc.Number-1, 0, 30); } else { sc.UnGet(); part.Translation = new FRemapTable; part.Translation->MakeIdentity(); do { sc.MustGetString(); part.Translation->AddToTranslation(sc.String); } while (sc.CheckString(",")); } } else if (sc.Compare("Colormap")) { float r1,g1,b1; float r2,g2,b2; sc.MustGetFloat(); r1 = (float)sc.Float; sc.MustGetStringName(","); sc.MustGetFloat(); g1 = (float)sc.Float; sc.MustGetStringName(","); sc.MustGetFloat(); b1 = (float)sc.Float; if (!sc.CheckString(",")) { part.Blend = AddSpecialColormap(0,0,0, r1, g1, b1); } else { sc.MustGetFloat(); r2 = (float)sc.Float; sc.MustGetStringName(","); sc.MustGetFloat(); g2 = (float)sc.Float; sc.MustGetStringName(","); sc.MustGetFloat(); b2 = (float)sc.Float; part.Blend = AddSpecialColormap(r1, g1, b1, r2, g2, b2); } } else if (sc.Compare("Blend")) { bComplex = true; if (part.Translation != NULL) delete part.Translation; part.Translation = NULL; part.Blend = 0; if (!sc.CheckNumber()) { sc.MustGetString(); part.Blend = V_GetColor(NULL, sc); } else { int r,g,b; r = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); g = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); b = sc.Number; //sc.MustGetStringName(","); This was never supposed to be here. part.Blend = MAKERGB(r, g, b); } // Blend.a may never be 0 here. if (sc.CheckString(",")) { sc.MustGetFloat(); if (sc.Float > 0.f) part.Blend.a = clamp<int>(int(sc.Float*255), 1, 254); else part.Blend = 0; } else part.Blend.a = 255; } else if (sc.Compare("alpha")) { sc.MustGetFloat(); part.Alpha = clamp<blend_t>(int(sc.Float * BLENDUNIT), 0, BLENDUNIT); // bComplex is not set because it is only needed when the style is not OP_COPY. } else if (sc.Compare("style")) { static const char *styles[] = {"copy", "translucent", "add", "subtract", "reversesubtract", "modulate", "copyalpha", "copynewalpha", "overlay", NULL }; sc.MustGetString(); part.op = sc.MustMatchString(styles); bComplex |= (part.op != OP_COPY); bTranslucentPatches = bComplex; } else if (sc.Compare("useoffsets")) { init.UseOffsets = true; } } } if (Mirror & 2) { part.Rotate = (part.Rotate + 2) & 3; Mirror ^= 1; } if (Mirror & 1) { part.Rotate |= 4; } }
FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype) : Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) { TArray<TexPart> parts; TArray<TexInit> inits; bool bSilent = false; bMultiPatch = true; sc.SetCMode(true); sc.MustGetString(); const char* textureName = NULL; if (sc.Compare("optional")) { bSilent = true; sc.MustGetString(); if (sc.Compare(",")) { // this is not right. Apparently a texture named 'optional' is being defined right now... sc.UnGet(); textureName = "optional"; bSilent = false; } } Name = !textureName ? sc.String : textureName; Name.ToUpper(); sc.MustGetStringName(","); sc.MustGetNumber(); Width = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); Height = sc.Number; UseType = usetype; bool offset2set = false; if (sc.CheckString("{")) { while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("XScale")) { sc.MustGetFloat(); Scale.X = sc.Float; if (Scale.X == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name.GetChars()); } else if (sc.Compare("YScale")) { sc.MustGetFloat(); Scale.Y = sc.Float; if (Scale.Y == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name.GetChars()); } else if (sc.Compare("WorldPanning")) { bWorldPanning = true; } else if (sc.Compare("NullTexture")) { UseType = ETextureType::Null; } else if (sc.Compare("NoDecals")) { bNoDecals = true; } else if (sc.Compare("Patch")) { TexPart part; TexInit init; ParsePatch(sc, part, init); if (init.TexName.IsNotEmpty()) { parts.Push(part); init.UseType = ETextureType::WallPatch; init.Silent = bSilent; init.HasLine = true; init.sc = sc; inits.Push(init); } part.Texture = NULL; part.Translation = NULL; } else if (sc.Compare("Sprite")) { TexPart part; TexInit init; ParsePatch(sc, part, init); if (init.TexName.IsNotEmpty()) { parts.Push(part); init.UseType = ETextureType::Sprite; init.Silent = bSilent; init.HasLine = true; init.sc = sc; inits.Push(init); } part.Texture = NULL; part.Translation = NULL; } else if (sc.Compare("Graphic")) { TexPart part; TexInit init; ParsePatch(sc, part, init); if (init.TexName.IsNotEmpty()) { parts.Push(part); init.UseType = ETextureType::MiscPatch; init.Silent = bSilent; init.HasLine = true; init.sc = sc; inits.Push(init); } part.Texture = NULL; part.Translation = NULL; } else if (sc.Compare("Offset")) { sc.MustGetNumber(); _LeftOffset[0] = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); _TopOffset[0] = sc.Number; if (!offset2set) { _LeftOffset[1] = _LeftOffset[0]; _TopOffset[1] = _TopOffset[0]; } } else if (sc.Compare("Offset2")) { sc.MustGetNumber(); _LeftOffset[1] = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); _TopOffset[1] = sc.Number; offset2set = true; } else { sc.ScriptError("Unknown texture property '%s'", sc.String); } } NumParts = parts.Size(); Parts = new TexPart[NumParts]; memcpy(Parts, &parts[0], NumParts * sizeof(*Parts)); Inits = new TexInit[NumParts]; for (int i = 0; i < NumParts; i++) { Inits[i] = inits[i]; } } if (Width <= 0 || Height <= 0) { UseType = ETextureType::Null; Printf("Texture %s has invalid dimensions (%d, %d)\n", Name.GetChars(), Width, Height); Width = Height = 1; } CalcBitSize (); sc.SetCMode(false); }
static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) { sc.MustGetStringName("{"); while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("ifgame")) { if (!CheckSkipGameBlock(sc)) { // recursively parse sub-block ParseOptionMenuBody(sc, desc); } } else if (sc.Compare("ifoption")) { if (!CheckSkipOptionBlock(sc)) { // recursively parse sub-block ParseOptionMenuBody(sc, desc); } } else if (sc.Compare("Class")) { sc.MustGetString(); const PClass *cls = PClass::FindClass(sc.String); if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DOptionMenu))) { sc.ScriptError("Unknown menu class '%s'", sc.String); } desc->mClass = cls; } else if (sc.Compare("Title")) { sc.MustGetString(); desc->mTitle = sc.String; } else if (sc.Compare("Position")) { sc.MustGetNumber(); desc->mPosition = sc.Number; } else if (sc.Compare("DefaultSelection")) { sc.MustGetNumber(); desc->mSelectedItem = sc.Number; } else if (sc.Compare("ScrollTop")) { sc.MustGetNumber(); desc->mScrollTop = sc.Number; } else if (sc.Compare("Indent")) { sc.MustGetNumber(); desc->mIndent = sc.Number; } else if (sc.Compare("Submenu")) { sc.MustGetString(); FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FOptionMenuItem *it = new FOptionMenuItemSubmenu(label, sc.String); desc->mItems.Push(it); } else if (sc.Compare("Option")) { sc.MustGetString(); FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FString cvar = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FString values = sc.String; FString check; int center = 0; if (sc.CheckString(",")) { sc.MustGetString(); if (*sc.String != 0) check = sc.String; if (sc.CheckString(",")) { sc.MustGetNumber(); center = sc.Number; } } FOptionMenuItem *it = new FOptionMenuItemOption(label, cvar, values, check, center); desc->mItems.Push(it); } else if (sc.Compare("Command")) { sc.MustGetString(); FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FOptionMenuItem *it = new FOptionMenuItemCommand(label, sc.String); desc->mItems.Push(it); } else if (sc.Compare("SafeCommand")) { sc.MustGetString(); FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FOptionMenuItem *it = new FOptionMenuItemSafeCommand(label, sc.String); desc->mItems.Push(it); } else if (sc.Compare("Control") || sc.Compare("MapControl")) { bool map = sc.Compare("MapControl"); sc.MustGetString(); FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FOptionMenuItem *it = new FOptionMenuItemControl(label, sc.String, map? &AutomapBindings : &Bindings); desc->mItems.Push(it); } else if (sc.Compare("ColorPicker")) { sc.MustGetString(); FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FOptionMenuItem *it = new FOptionMenuItemColorPicker(label, sc.String); desc->mItems.Push(it); } else if (sc.Compare("StaticText")) { sc.MustGetString(); FString label = sc.String; bool cr = false; if (sc.CheckString(",")) { sc.MustGetNumber(); cr = !!sc.Number; } FOptionMenuItem *it = new FOptionMenuItemStaticText(label, cr); desc->mItems.Push(it); } else if (sc.Compare("StaticTextSwitchable")) { sc.MustGetString(); FString label = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FString label2 = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FName action = sc.String; bool cr = false; if (sc.CheckString(",")) { sc.MustGetNumber(); cr = !!sc.Number; } FOptionMenuItem *it = new FOptionMenuItemStaticTextSwitchable(label, label2, action, cr); desc->mItems.Push(it); } else if (sc.Compare("Slider")) { sc.MustGetString(); FString text = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FString action = sc.String; sc.MustGetStringName(","); sc.MustGetFloat(); double min = sc.Float; sc.MustGetStringName(","); sc.MustGetFloat(); double max = sc.Float; sc.MustGetStringName(","); sc.MustGetFloat(); double step = sc.Float; int showvalue = 1; if (sc.CheckString(",")) { sc.MustGetNumber(); showvalue = sc.Number; } FOptionMenuItem *it = new FOptionMenuSliderCVar(text, action, min, max, step, showvalue); desc->mItems.Push(it); } else if (sc.Compare("screenresolution")) { sc.MustGetString(); FOptionMenuItem *it = new FOptionMenuScreenResolutionLine(sc.String); desc->mItems.Push(it); } else { sc.ScriptError("Unknown keyword '%s'", sc.String); } } }
static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) { sc.MustGetStringName("{"); while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("else")) { SkipSubBlock(sc); } else if (sc.Compare("ifgame")) { if (!CheckSkipGameBlock(sc)) { // recursively parse sub-block ParseListMenuBody(sc, desc); } } else if (sc.Compare("ifoption")) { if (!CheckSkipOptionBlock(sc)) { // recursively parse sub-block ParseListMenuBody(sc, desc); } } else if (sc.Compare("Class")) { sc.MustGetString(); const PClass *cls = PClass::FindClass(sc.String); if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DListMenu))) { sc.ScriptError("Unknown menu class '%s'", sc.String); } desc->mClass = cls; } else if (sc.Compare("Selector")) { sc.MustGetString(); desc->mSelector = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch); sc.MustGetStringName(","); sc.MustGetNumber(); desc->mSelectOfsX = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); desc->mSelectOfsY = sc.Number; } else if (sc.Compare("Linespacing")) { sc.MustGetNumber(); desc->mLinespacing = sc.Number; } else if (sc.Compare("Position")) { sc.MustGetNumber(); desc->mXpos = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); desc->mYpos = sc.Number; } else if (sc.Compare("Centermenu")) { desc->mCenter = true; } else if (sc.Compare("MouseWindow")) { sc.MustGetNumber(); desc->mWLeft = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); desc->mWRight = sc.Number; } else if (sc.Compare("StaticPatch") || sc.Compare("StaticPatchCentered")) { bool centered = sc.Compare("StaticPatchCentered"); sc.MustGetNumber(); int x = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); int y = sc.Number; sc.MustGetStringName(","); sc.MustGetString(); FTextureID tex = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch); FListMenuItem *it = new FListMenuItemStaticPatch(x, y, tex, centered); desc->mItems.Push(it); } else if (sc.Compare("StaticText") || sc.Compare("StaticTextCentered")) { bool centered = sc.Compare("StaticTextCentered"); sc.MustGetNumber(); int x = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); int y = sc.Number; sc.MustGetStringName(","); sc.MustGetString(); FListMenuItem *it = new FListMenuItemStaticText(x, y, sc.String, desc->mFont, desc->mFontColor, centered); desc->mItems.Push(it); } else if (sc.Compare("PatchItem")) { sc.MustGetString(); FTextureID tex = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch); sc.MustGetStringName(","); sc.MustGetString(); int hotkey = sc.String[0]; sc.MustGetStringName(","); sc.MustGetString(); FName action = sc.String; int param = 0; if (sc.CheckString(",")) { sc.MustGetNumber(); param = sc.Number; } FListMenuItem *it = new FListMenuItemPatch(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, tex, action, param); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } else if (sc.Compare("TextItem")) { sc.MustGetString(); FString text = sc.String; sc.MustGetStringName(","); sc.MustGetString(); int hotkey = sc.String[0]; sc.MustGetStringName(","); sc.MustGetString(); FName action = sc.String; int param = 0; if (sc.CheckString(",")) { sc.MustGetNumber(); param = sc.Number; } FListMenuItem *it = new FListMenuItemText(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, param); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } else if (sc.Compare("Font")) { sc.MustGetString(); FFont *newfont = V_GetFont(sc.String); if (newfont != NULL) desc->mFont = newfont; if (sc.CheckString(",")) { sc.MustGetString(); desc->mFontColor2 = desc->mFontColor = V_FindFontColor((FName)sc.String); if (sc.CheckString(",")) { sc.MustGetString(); desc->mFontColor2 = V_FindFontColor((FName)sc.String); } } else { desc->mFontColor = OptionSettings.mFontColor; desc->mFontColor2 = OptionSettings.mFontColorValue; } } else if (sc.Compare("NetgameMessage")) { sc.MustGetString(); desc->mNetgameMessage = sc.String; } else if (sc.Compare("PlayerDisplay")) { bool noportrait = false; FName action = NAME_None; sc.MustGetNumber(); int x = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); int y = sc.Number; sc.MustGetStringName(","); sc.MustGetString(); PalEntry c1 = V_GetColor(NULL, sc.String); sc.MustGetStringName(","); sc.MustGetString(); PalEntry c2 = V_GetColor(NULL, sc.String); if (sc.CheckString(",")) { sc.MustGetNumber(); noportrait = !!sc.Number; if (sc.CheckString(",")) { sc.MustGetString(); action = sc.String; } } FListMenuItemPlayerDisplay *it = new FListMenuItemPlayerDisplay(desc, x, y, c1, c2, noportrait, action); desc->mItems.Push(it); } else if (sc.Compare("PlayerNameBox")) { sc.MustGetString(); FString text = sc.String; sc.MustGetStringName(","); sc.MustGetNumber(); int ofs = sc.Number; sc.MustGetStringName(","); sc.MustGetString(); FListMenuItem *it = new FPlayerNameBox(desc->mXpos, desc->mYpos, desc->mLinespacing, ofs, text, desc->mFont, desc->mFontColor, sc.String); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } else if (sc.Compare("ValueText")) { sc.MustGetString(); FString text = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FName action = sc.String; FName values; if (sc.CheckString(",")) { sc.MustGetString(); values = sc.String; } FListMenuItem *it = new FValueTextItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, values); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } else if (sc.Compare("Slider")) { sc.MustGetString(); FString text = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FString action = sc.String; sc.MustGetStringName(","); sc.MustGetNumber(); int min = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); int max = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); int step = sc.Number; FListMenuItem *it = new FSliderItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, action, min, max, step); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } else { sc.ScriptError("Unknown keyword '%s'", sc.String); } } }
void FTeam::ParseTeamDefinition (FScanner &Scan) { FTeam Team; int valid = -1; Scan.MustGetString (); Team.m_Name = Scan.String; Scan.MustGetStringName ("{"); while (!Scan.CheckString ("}")) { Scan.MustGetString (); switch (Scan.MatchString (TeamInfoOptions)) { case TEAMINFO_Game: Scan.MustGetString (); if (Scan.Compare("Any")) valid = 1; else if (CheckGame(Scan.String, false)) valid = 1; else if (valid == -1) valid = 0; break; case TEAMINFO_PlayerColor: Scan.MustGetString (); Team.m_iPlayerColor = V_GetColor (NULL, Scan.String); break; case TEAMINFO_TextColor: Scan.MustGetString (); Team.m_TextColor.AppendFormat ("[%s]", Scan.String); break; case TEAMINFO_Logo: Scan.MustGetString (); Team.m_Logo = Scan.String; break; case TEAMINFO_AllowCustomPlayerColor: Team.m_bAllowCustomPlayerColor = true; break; case TEAMINFO_PlayerStartThingNumber: Scan.MustGetNumber (); break; case TEAMINFO_RailColor: case TEAMINFO_FlagItem: case TEAMINFO_SkullItem: case TEAMINFO_SmallFlagHUDIcon: case TEAMINFO_SmallSkullHUDIcon: case TEAMINFO_LargeFlagHUDIcon: case TEAMINFO_LargeSkullHUDIcon: case TEAMINFO_WinnerPic: case TEAMINFO_LoserPic: case TEAMINFO_WinnerTheme: case TEAMINFO_LoserTheme: Scan.MustGetString (); break; default: Scan.ScriptError ("ParseTeamDefinition: Unknown team option '%s'.\n", Scan.String); break; } } if (valid) Teams.Push (Team); }