static TArray<FString> PSR_ReadBaseInstalls(FScanner &sc) { TArray<FString> result; // Get a list of possible install directories. while(sc.GetToken()) { if(sc.TokenType == '}') break; sc.TokenMustBe(TK_StringConst); FString key(sc.String); if(key.Left(18).CompareNoCase("BaseInstallFolder_") == 0) { sc.MustGetToken(TK_StringConst); result.Push(FString(sc.String) + "/steamapps/common"); } else { if(sc.CheckToken('{')) PSR_FindEndBlock(sc); else sc.MustGetToken(TK_StringConst); } } return result; }
bool FIntermissionActionWiper::ParseKey(FScanner &sc) { struct WipeType { const char *Name; gamestate_t Type; } const FT[] = { { "Crossfade", GS_FORCEWIPEFADE }, { "Melt", GS_FORCEWIPEMELT }, { "Burn", GS_FORCEWIPEBURN }, { "Default", GS_FORCEWIPE }, { NULL, GS_FORCEWIPE } }; if (sc.Compare("WipeType")) { sc.MustGetToken('='); sc.MustGetToken(TK_Identifier); int v = sc.MatchString(&FT[0].Name, sizeof(FT[0])); if (v != -1) mWipeType = FT[v].Type; return true; } else return Super::ParseKey(sc); }
void SBarInfo::ParseMugShotBlock(FScanner &sc, FMugShotState &state) { sc.MustGetToken('{'); while(!sc.CheckToken('}')) { FMugShotFrame frame; bool multiframe = false; if(sc.CheckToken('{')) multiframe = true; do { sc.MustGetToken(TK_Identifier); if(strlen(sc.String) > 5) sc.ScriptError("MugShot frames cannot exceed 5 characters."); frame.Graphic.Push(sc.String); } while(multiframe && sc.CheckToken(',')); if(multiframe) sc.MustGetToken('}'); bool negative = sc.CheckToken('-'); sc.MustGetToken(TK_IntConst); frame.Delay = (negative ? -1 : 1)*sc.Number; sc.MustGetToken(';'); state.Frames.Push(frame); } }
static void ParseActionDef (FScanner &sc, PClassActor *cls) { unsigned int error = 0; FName funcname; TArray<PType *> rets; if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0) { sc.ScriptMessage ("Action functions can only be imported by internal class and actor definitions!"); FScriptPosition::ErrorCounter++; } sc.MustGetToken(TK_Native); // check for a return value do { if (sc.CheckToken(TK_Int) || sc.CheckToken(TK_Bool)) { rets.Push(TypeSInt32); } else if (sc.CheckToken(TK_State)) { rets.Push(TypeState); } else if (sc.CheckToken(TK_Float)) { rets.Push(TypeFloat64); } } while (sc.CheckToken(',')); sc.MustGetToken(TK_Identifier); funcname = sc.String; ParseFunctionDef(sc, cls, funcname, rets, VARF_Method | VARF_Action); }
bool FIntermissionActionCast::ParseKey(FScanner &sc) { if (sc.Compare("CastName")) { sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); mName = sc.String; return true; } else if (sc.Compare("CastClass")) { sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); mCastClass = sc.String; return true; } else if (sc.Compare("AttackSound")) { static const char *const seqs[] = {"Missile", "Melee", NULL}; FCastSound *cs = &mCastSounds[mCastSounds.Reserve(1)]; sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); cs->mSequence = (BYTE)sc.MatchString(seqs); sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); cs->mIndex = (BYTE)sc.Number; sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); cs->mSound = sc.String; return true; } else return Super::ParseKey(sc); }
void GetCoordinates(FScanner &sc, bool fullScreenOffsets, SBarInfoCoordinate &x, SBarInfoCoordinate &y) { bool negative = false; bool relCenter = false; SBarInfoCoordinate *coords[2] = {&x, &y}; for(int i = 0;i < 2;i++) { negative = false; relCenter = false; if(i > 0) sc.MustGetToken(','); // [-]INT center negative = sc.CheckToken('-'); sc.MustGetToken(TK_IntConst); coords[i]->Set(negative ? -sc.Number : sc.Number, false); if(sc.CheckToken('+')) { sc.MustGetToken(TK_Identifier); if(!sc.Compare("center")) sc.ScriptError("Expected 'center' but got '%s' instead.", sc.String); relCenter = true; } if(fullScreenOffsets) { coords[i]->SetRelCenter(relCenter); } } //if(!fullScreenOffsets) // y.SetCoord((negative ? -sc.Number : sc.Number) - (200 - script->height)); }
static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClass *cls) { int currvalue = 0; sc.MustGetToken('{'); while (!sc.CheckToken('}')) { sc.MustGetToken(TK_Identifier); FName symname = sc.String; if (sc.CheckToken('=')) { FxExpression *expr = ParseExpression (sc, cls); currvalue = expr->EvalExpression(NULL).GetInt(); delete expr; } PSymbolConst *sym = new PSymbolConst(symname); sym->ValueType = VAL_Int; sym->Value = currvalue; if (symt->AddSymbol (sym) == NULL) { delete sym; sc.ScriptMessage ("'%s' is already defined in '%s'.", symname.GetChars(), cls? cls->TypeName.GetChars() : "Global"); FScriptPosition::ErrorCounter++; } // This allows a comma after the last value but doesn't enforce it. if (sc.CheckToken('}')) break; sc.MustGetToken(','); currvalue++; } sc.MustGetToken(';'); }
void SBarInfo::getCoordinates(FScanner &sc, bool fullScreenOffsets, int &x, int &y) { bool negative = false; bool relCenter = false; int *coords[2] = {&x, &y}; for(int i = 0;i < 2;i++) { negative = false; relCenter = false; if(i > 0) sc.MustGetToken(','); // [-]INT center negative = sc.CheckToken('-'); sc.MustGetToken(TK_IntConst); *coords[i] = negative ? -sc.Number : sc.Number; if(sc.CheckToken('+')) { sc.MustGetToken(TK_Identifier); if(!sc.Compare("center")) sc.ScriptError("Expected 'center' but got '%s' instead.", sc.String); relCenter = true; } if(fullScreenOffsets) { if(relCenter) *coords[i] |= SBarInfoCoordinate::REL_CENTER; else *coords[i] &= ~SBarInfoCoordinate::REL_CENTER; } } if(!fullScreenOffsets) y = (negative ? -sc.Number : sc.Number) - (200 - this->height); }
static int ParseMapEntry(FScanner &scanner, UMapEntry *val) { scanner.MustGetToken(TK_Identifier); val->MapName = scanner.String; scanner.MustGetToken('{'); while(!scanner.CheckToken('}')) { ParseStandardProperty(scanner, val); } return 1; }
int SBarInfo::getSignedInteger(FScanner &sc) { if(sc.CheckToken('-')) { sc.MustGetToken(TK_IntConst); return -sc.Number; } else { sc.MustGetToken(TK_IntConst); return sc.Number; } }
static bool PSR_FindAndEnterBlock(FScanner &sc, const char* keyword) { // Finds a block with a given keyword and then enter it (opening brace) // Should be closed with PSR_FindEndBlock while(sc.GetToken()) { if(sc.TokenType == '}') { sc.UnGet(); return false; } sc.TokenMustBe(TK_StringConst); if(!sc.Compare(keyword)) { if(!sc.CheckToken(TK_StringConst)) PSR_SkipBlock(sc); } else { sc.MustGetToken('{'); return true; } } return false; }
static FString ParseMultiString(FScanner &scanner, int error) { FString build; if (scanner.CheckToken(TK_Identifier)) { if (!stricmp(scanner.String, "clear")) { return "-"; } else { scanner.ScriptError("Either 'clear' or string constant expected"); } } do { scanner.MustGetToken(TK_StringConst); if (build.Len() > 0) build += "\n"; build += scanner.String; } while (scanner.CheckToken(',')); return build; }
void ParseFunctionDef(FScanner &sc, PClassActor *cls, FName funcname, TArray<PType *> &rets, DWORD funcflags) { assert(cls != NULL); const AFuncDesc *afd; TArray<PType *> args; TArray<DWORD> argflags; afd = FindFunction(funcname); if (afd == NULL) { sc.ScriptMessage ("The function '%s' has not been exported from the executable.", funcname.GetChars()); FScriptPosition::ErrorCounter++; } sc.MustGetToken('('); SetImplicitArgs(&args, &argflags, cls, funcflags); ParseArgListDef(sc, cls, args, argflags); if (afd != NULL) { PFunction *sym = new PFunction(funcname); sym->AddVariant(NewPrototype(rets, args), argflags, *(afd->VMPointer)); sym->Flags = funcflags; if (cls->Symbols.AddSymbol(sym) == NULL) { delete sym; sc.ScriptMessage ("'%s' is already defined in class '%s'.", funcname.GetChars(), cls->TypeName.GetChars()); FScriptPosition::ErrorCounter++; } } }
static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls) { // Read the type and make sure it's int or float. if (sc.CheckToken(TK_Int) || sc.CheckToken(TK_Float)) { int type = sc.TokenType; sc.MustGetToken(TK_Identifier); FName symname = sc.String; sc.MustGetToken('='); FxExpression *expr = ParseExpression (sc, cls, true); sc.MustGetToken(';'); if (!expr->isConstant()) { sc.ScriptMessage("Constant definition is not a constant"); FScriptPosition::ErrorCounter++; } else { ExpVal val = static_cast<FxConstant *>(expr)->GetValue(); delete expr; PSymbolConstNumeric *sym; if (type == TK_Int) { sym = new PSymbolConstNumeric(symname, TypeSInt32); sym->Value = val.GetInt(); } else { sym = new PSymbolConstNumeric(symname, TypeFloat64); sym->Float = val.GetFloat(); } if (symt->AddSymbol (sym) == NULL) { delete sym; sc.ScriptMessage ("'%s' is already defined in '%s'.", symname.GetChars(), cls? cls->TypeName.GetChars() : "Global"); FScriptPosition::ErrorCounter++; } } } else { sc.ScriptMessage("Numeric type required for constant"); FScriptPosition::ErrorCounter++; } }
void gl_ParseHardwareShader(FScanner &sc, int deflump) { int type = FTexture::TEX_Any; bool disable_fullbright=false; bool thiswad = false; bool iwad = false; int maplump = -1; FString maplumpname; float speed = 1.f; sc.MustGetString(); if (sc.Compare("texture")) type = FTexture::TEX_Wall; else if (sc.Compare("flat")) type = FTexture::TEX_Flat; else if (sc.Compare("sprite")) type = FTexture::TEX_Sprite; else sc.UnGet(); sc.MustGetString(); FTextureID no = TexMan.CheckForTexture(sc.String, type); FTexture *tex = TexMan[no]; sc.MustGetToken('{'); while (!sc.CheckToken('}')) { sc.MustGetString(); if (sc.Compare("shader")) { sc.MustGetString(); maplumpname = sc.String; } else if (sc.Compare("speed")) { sc.MustGetFloat(); speed = float(sc.Float); } } if (!tex) { return; } if (maplumpname.IsNotEmpty()) { if (tex->bWarped != 0) { Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars()); return; } tex->gl_info.shaderspeed = speed; for(unsigned i=0;i<usershaders.Size();i++) { if (!usershaders[i].CompareNoCase(maplumpname)) { tex->gl_info.shaderindex = i + FIRST_USER_SHADER; return; } } tex->gl_info.shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER; } }
//========================================================================== // // Reads an actor definition // //========================================================================== static void ParseActor(FScanner &sc) { PClassActor *info = NULL; Baggage bag; info = ParseActorHeader(sc, &bag); sc.MustGetToken('{'); while (sc.MustGetAnyToken(), sc.TokenType != '}') { switch (sc.TokenType) { case TK_Action: ParseActionDef (sc, info); break; case TK_Const: ParseConstant (sc, &info->Symbols, info); break; case TK_Enum: ParseEnum (sc, &info->Symbols, info); break; case TK_Native: ParseNativeFunction (sc, info); break; case TK_Var: ParseUserVariable (sc, &info->Symbols, info); break; case TK_Identifier: ParseActorProperty(sc, bag); break; case TK_States: if (bag.StateSet) { sc.ScriptMessage("'%s' contains multiple state declarations", bag.Info->TypeName.GetChars()); FScriptPosition::ErrorCounter++; } ParseStates(sc, bag.Info, (AActor *)bag.Info->Defaults, bag); bag.StateSet = true; break; case '+': case '-': ParseActorFlag(sc, bag, sc.TokenType); break; default: sc.ScriptError("Unexpected '%s' in definition of '%s'", sc.String, bag.Info->TypeName.GetChars()); break; } } FinishActor(sc, info, bag); sc.SetCMode (false); }
static int ParseLumpName(FScanner &scanner, char *buffer) { scanner.MustGetToken(TK_StringConst); if (strlen(scanner.String) > 8) { scanner.ScriptError("String too long. Maximum size is 8 characters."); return 0; } uppercopy(buffer, scanner.String); return 1; }
static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls) { int currvalue = 0; sc.MustGetToken('{'); while (!sc.CheckToken('}')) { sc.MustGetToken(TK_Identifier); FName symname = sc.String; if (sc.CheckToken('=')) { FxExpression *expr = ParseExpression (sc, cls, true); if (!expr->isConstant()) { sc.ScriptMessage("'%s' must be constant", symname.GetChars()); FScriptPosition::ErrorCounter++; } else { currvalue = static_cast<FxConstant *>(expr)->GetValue().GetInt(); } delete expr; } PSymbolConstNumeric *sym = new PSymbolConstNumeric(symname, TypeSInt32); sym->Value = currvalue; if (symt->AddSymbol (sym) == NULL) { delete sym; sc.ScriptMessage ("'%s' is already defined in '%s'.", symname.GetChars(), cls? cls->TypeName.GetChars() : "Global"); FScriptPosition::ErrorCounter++; } // This allows a comma after the last value but doesn't enforce it. if (sc.CheckToken('}')) break; sc.MustGetToken(','); currvalue++; } sc.MustGetToken(';'); }
static void ParseConstant (FScanner &sc, PSymbolTable * symt, PClass *cls) { // Read the type and make sure it's int or float. if (sc.CheckToken(TK_Int) || sc.CheckToken(TK_Float)) { int type = sc.TokenType; sc.MustGetToken(TK_Identifier); FName symname = sc.String; sc.MustGetToken('='); FxExpression *expr = ParseExpression (sc, cls); sc.MustGetToken(';'); ExpVal val = expr->EvalExpression(NULL); delete expr; PSymbolConst *sym = new PSymbolConst(symname); if (type == TK_Int) { sym->ValueType = VAL_Int; sym->Value = val.GetInt(); } else { sym->ValueType = VAL_Float; sym->Float = val.GetFloat(); } if (symt->AddSymbol (sym) == NULL) { delete sym; sc.ScriptMessage ("'%s' is already defined in '%s'.", symname.GetChars(), cls? cls->TypeName.GetChars() : "Global"); FScriptPosition::ErrorCounter++; } } else { sc.ScriptMessage("Numeric type required for constant"); FScriptPosition::ErrorCounter++; } }
EColorRange GetTranslation(FScanner &sc) { if (!sc.CheckToken(TK_Null)) sc.MustGetToken(TK_Identifier); EColorRange returnVal = CR_UNTRANSLATED; FString namedTranslation; //we must send in "[translation]" const BYTE *trans_ptr; namedTranslation.Format("[%s]", sc.String); trans_ptr = (const BYTE *)(&namedTranslation[0]); if((returnVal = V_ParseFontColor(trans_ptr, CR_UNTRANSLATED, CR_UNTRANSLATED)) == CR_UNDEFINED) { sc.ScriptError("Missing definition for color %s.", sc.String); } return returnVal; }
bool FIntermissionActionFader::ParseKey(FScanner &sc) { struct FadeType { const char *Name; EFadeType Type; } const FT[] = { { "FadeIn", FADE_In }, { "FadeOut", FADE_Out }, { NULL, FADE_In } }; if (sc.Compare("FadeType")) { sc.MustGetToken('='); sc.MustGetToken(TK_Identifier); int v = sc.MatchString(&FT[0].Name, sizeof(FT[0])); if (v != -1) mFadeType = FT[v].Type; return true; } else return Super::ParseKey(sc); }
static void ParseNativeFunction(FScanner &sc, PClassActor *cls) { TArray<PType *> rets(1); if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0) { sc.ScriptMessage ("functions can only be declared by native actors!"); FScriptPosition::ErrorCounter++; } // Read the type and make sure it's int or float. sc.MustGetAnyToken(); switch (sc.TokenType) { case TK_Int: case TK_Bool: rets.Push(TypeSInt32); break; case TK_Float: rets.Push(TypeFloat64); break; case TK_Angle_t: rets.Push(TypeAngle); break; case TK_Fixed_t: rets.Push(TypeFixed); break; case TK_State: rets.Push(TypeState); break; case TK_Identifier: rets.Push(NewPointer(RUNTIME_CLASS(DObject))); // Todo: Object type sc.ScriptError("Object type variables not implemented yet!"); break; default: sc.ScriptError("Invalid return type %s", sc.String); return; } sc.MustGetToken(TK_Identifier); ParseFunctionDef(sc, cls, sc.String, rets, VARF_Method); }
//========================================================================== // // Reads an actor definition // //========================================================================== static void ParseActor(FScanner &sc) { FActorInfo * info=NULL; Baggage bag; info = ParseActorHeader(sc, &bag); sc.MustGetToken('{'); while (sc.MustGetAnyToken(), sc.TokenType != '}') { switch (sc.TokenType) { case TK_Action: ParseActionDef (sc, info->Class); break; case TK_Const: ParseConstant (sc, &info->Class->Symbols, info->Class); break; case TK_Enum: ParseEnum (sc, &info->Class->Symbols, info->Class); break; case TK_Native: ParseNativeVariable (sc, &info->Class->Symbols, info->Class); break; case TK_Var: ParseUserVariable (sc, &info->Class->Symbols, info->Class); break; case TK_Identifier: ParseActorProperty(sc, bag); break; case '+': case '-': ParseActorFlag(sc, bag, sc.TokenType); break; default: sc.ScriptError("Unexpected '%s' in definition of '%s'", sc.String, bag.Info->Class->TypeName.GetChars()); break; } } FinishActor(sc, info, bag); sc.SetCMode (false); }
//========================================================================== //*** // DoActionSpecials // handles action specials as code pointers // //========================================================================== bool DoActionSpecials(FScanner &sc, FState & state, Baggage &bag) { int i; int min_args, max_args; FString specname = sc.String; int special = P_FindLineSpecial(sc.String, &min_args, &max_args); if (special > 0 && min_args >= 0) { int paramindex=PrepareStateParameters(&state, 6, bag.Info->Class); StateParams.Set(paramindex, new FxConstant(special, sc)); // Make this consistent with all other parameter parsing if (sc.CheckToken('(')) { for (i = 0; i < 5;) { StateParams.Set(paramindex+i+1, ParseExpression (sc, bag.Info->Class)); i++; if (!sc.CheckToken (',')) break; } sc.MustGetToken (')'); } else i=0; if (i < min_args) { sc.ScriptError ("Too few arguments to %s", specname.GetChars()); } if (i > max_args) { sc.ScriptError ("Too many arguments to %s", specname.GetChars()); } state.SetAction(FindGlobalActionFunction("A_CallSpecial"), false); return true; } return false; }
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) }
void Parse(FScanner &sc, bool fullScreenOffsets) { this->fullScreenOffsets = fullScreenOffsets; if(sc.CheckToken(',')) { while(sc.CheckToken(TK_Identifier)) { if(sc.Compare("forcescaled")) forceScaled = true; else if(sc.Compare("fullscreenoffsets")) this->fullScreenOffsets = true; else sc.ScriptError("Unkown flag '%s'.", sc.String); if(!sc.CheckToken('|') && !sc.CheckToken(',')) { SBarInfoCommandFlowControl::Parse(sc, this->fullScreenOffsets); return; } } sc.MustGetToken(TK_FloatConst); alpha = sc.Float; } SBarInfoCommandFlowControl::Parse(sc, this->fullScreenOffsets); }
bool FIntermissionAction::ParseKey(FScanner &sc) { if (sc.Compare("music")) { sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); mMusic = sc.String; mMusicOrder = 0; if (sc.CheckToken(',')) { sc.MustGetToken(TK_IntConst); mMusicOrder = sc.Number; } return true; } else if (sc.Compare("cdmusic")) { sc.MustGetToken('='); sc.MustGetToken(TK_IntConst); mCdTrack = sc.Number; mCdId = 0; if (sc.CheckToken(',')) { sc.MustGetToken(TK_IntConst); mCdId = sc.Number; } return true; } else if (sc.Compare("Time")) { sc.MustGetToken('='); if (!sc.CheckToken('-')) { sc.MustGetFloat(); mDuration = int(sc.Float*TICRATE); } else { sc.MustGetToken(TK_IntConst); mDuration = sc.Number; } return true; } else if (sc.Compare("Background")) { sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); mBackground = sc.String; mFlatfill = 0; if (sc.CheckToken(',')) { sc.MustGetToken(TK_IntConst); mFlatfill = !!sc.Number; if (sc.CheckToken(',')) { sc.MustGetToken(TK_StringConst); mPalette = sc.String; } } return true; } else if (sc.Compare("Sound")) { sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); mSound = sc.String; return true; } else if (sc.Compare("Draw")) { FIntermissionPatch *pat = &mOverlays[mOverlays.Reserve(1)]; sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); pat->mName = sc.String; sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); pat->x = sc.Number; sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); pat->y = sc.Number; pat->mCondition = NAME_None; return true; } else if (sc.Compare("DrawConditional")) { FIntermissionPatch *pat = &mOverlays[mOverlays.Reserve(1)]; sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); pat->mCondition = sc.String; sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); pat->mName = sc.String; sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); pat->x = sc.Number; sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); pat->y = sc.Number; return true; } else return false; }
bool FIntermissionActionScroller::ParseKey(FScanner &sc) { struct ScrollType { const char *Name; EScrollDir Type; } const ST[] = { { "Left", SCROLL_Left }, { "Right", SCROLL_Right }, { "Up", SCROLL_Up }, { "Down", SCROLL_Down }, { NULL, SCROLL_Left } }; if (sc.Compare("ScrollDirection")) { sc.MustGetToken('='); sc.MustGetToken(TK_Identifier); int v = sc.MatchString(&ST[0].Name, sizeof(ST[0])); if (v != -1) mScrollDir = ST[v].Type; return true; } else if (sc.Compare("InitialDelay")) { sc.MustGetToken('='); if (!sc.CheckToken('-')) { sc.MustGetFloat(); mScrollDelay = int(sc.Float*TICRATE); } else { sc.MustGetToken(TK_IntConst); mScrollDelay = sc.Number; } return true; } else if (sc.Compare("ScrollTime")) { sc.MustGetToken('='); if (!sc.CheckToken('-')) { sc.MustGetFloat(); mScrollTime = int(sc.Float*TICRATE); } else { sc.MustGetToken(TK_IntConst); mScrollTime = sc.Number; } return true; } else if (sc.Compare("Background2")) { sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); mSecondPic = sc.String; return true; } else return Super::ParseKey(sc); }
bool FIntermissionActionTextscreen::ParseKey(FScanner &sc) { if (sc.Compare("Position")) { sc.MustGetToken('='); sc.MustGetToken(TK_IntConst); mTextX = sc.Number; sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); mTextY = sc.Number; return true; } else if (sc.Compare("TextLump")) { sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); int lump = Wads.CheckNumForFullName(sc.String, true); if (lump > 0) { mText = Wads.ReadLump(lump).GetString(); } else { // only print an error if coming from a PWAD if (Wads.GetLumpFile(sc.LumpNum) > 1) sc.ScriptMessage("Unknown text lump '%s'", sc.String); mText.Format("Unknown text lump '%s'", sc.String); } return true; } else if (sc.Compare("Text")) { sc.MustGetToken('='); do { sc.MustGetToken(TK_StringConst); mText << sc.String << '\n'; } while (sc.CheckToken(',')); return true; } else if (sc.Compare("TextColor")) { sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); mTextColor = V_FindFontColor(sc.String); return true; } else if (sc.Compare("TextDelay")) { sc.MustGetToken('='); if (!sc.CheckToken('-')) { sc.MustGetFloat(); mTextDelay = int(sc.Float*TICRATE); } else { sc.MustGetToken(TK_IntConst); mTextDelay = sc.Number; } return true; } else if (sc.Compare("textspeed")) { sc.MustGetToken('='); sc.MustGetToken(TK_IntConst); mTextSpeed = sc.Number; return true; } else return Super::ParseKey(sc); }
static int ParseStandardProperty(FScanner &scanner, UMapEntry *mape) { // find the next line with content. // this line is no property. scanner.MustGetToken(TK_Identifier); FString pname = scanner.String; scanner.MustGetToken('='); if (!pname.CompareNoCase("levelname")) { scanner.MustGetToken(TK_StringConst); mape->LevelName = scanner.String; } else if (!pname.CompareNoCase("next")) { ParseLumpName(scanner, mape->nextmap); } else if (!pname.CompareNoCase("nextsecret")) { ParseLumpName(scanner, mape->nextsecret); } else if (!pname.CompareNoCase("levelpic")) { ParseLumpName(scanner, mape->levelpic); } else if (!pname.CompareNoCase("skytexture")) { ParseLumpName(scanner, mape->skytexture); } else if (!pname.CompareNoCase("music")) { ParseLumpName(scanner, mape->music); } else if (!pname.CompareNoCase("endpic")) { ParseLumpName(scanner, mape->endpic); } else if (!pname.CompareNoCase("endcast")) { scanner.MustGetBoolToken(); if (scanner.Number) strcpy(mape->endpic, "$CAST"); else strcpy(mape->endpic, "-"); } else if (!pname.CompareNoCase("endbunny")) { scanner.MustGetBoolToken(); if (scanner.Number) strcpy(mape->endpic, "$BUNNY"); else strcpy(mape->endpic, "-"); } else if (!pname.CompareNoCase("endgame")) { scanner.MustGetBoolToken(); if (scanner.Number) strcpy(mape->endpic, "!"); else strcpy(mape->endpic, "-"); } else if (!pname.CompareNoCase("exitpic")) { ParseLumpName(scanner, mape->exitpic); } else if (!pname.CompareNoCase("enterpic")) { ParseLumpName(scanner, mape->enterpic); } else if (!pname.CompareNoCase("nointermission")) { scanner.MustGetBoolToken(); mape->nointermission = scanner.Number; } else if (!pname.CompareNoCase("partime")) { scanner.MustGetValue(false); mape->partime = TICRATE * scanner.Number; } else if (!pname.CompareNoCase("intertext")) { mape->InterText = ParseMultiString(scanner, 1); if (mape->InterText.IsEmpty()) return 0; } else if (!pname.CompareNoCase("intertextsecret")) { mape->InterTextSecret = ParseMultiString(scanner, 1); if (mape->InterTextSecret.IsEmpty()) return 0; } else if (!pname.CompareNoCase("interbackdrop")) { ParseLumpName(scanner, mape->interbackdrop); } else if (!pname.CompareNoCase("intermusic")) { ParseLumpName(scanner, mape->intermusic); } else if (!pname.CompareNoCase("episode")) { FString Episode = ParseMultiString(scanner, 1); if (Episode.IsEmpty()) return 0; if (Episode.Compare("-") == 0) { // clear the given episode for (unsigned i = 0; i < AllEpisodes.Size(); i++) { if (AllEpisodes[i].mEpisodeMap.CompareNoCase(mape->MapName) == 0) { AllEpisodes.Delete(i); break; } } } else { auto split = Episode.Split("\n"); // add the given episode FEpisode epi; epi.mEpisodeName = strbin1(split[1]); epi.mEpisodeMap = mape->MapName; epi.mPicName = split[0]; epi.mShortcut = split[2][0]; unsigned i; for (i = 0; i < AllEpisodes.Size(); i++) { if (AllEpisodes[i].mEpisodeMap.CompareNoCase(mape->MapName) == 0) { AllEpisodes[i] = std::move(epi); break; } } if (i == AllEpisodes.Size()) { AllEpisodes.Push(epi); } } } else if (!pname.CompareNoCase("bossaction")) { scanner.MustGetToken(TK_Identifier); int classnum, special, tag; if (!stricmp(scanner.String, "clear")) { // mark level free of boss actions classnum = special = tag = -1; mape->BossActions.Clear(); } else { FName type = scanner.String; scanner.MustGetToken(','); scanner.MustGetValue(false); int special = scanner.Number; scanner.MustGetToken(','); scanner.MustGetValue(false); int tag = scanner.Number; // allow no 0-tag specials here, unless a level exit. if (tag != 0 || special == 11 || special == 51 || special == 52 || special == 124) { // This cannot be evaluated here because this needs to be done in the context of the level being used. FSpecialAction & bossact = mape->BossActions[mape->BossActions.Reserve(1)]; bossact = { type, special | 0x40000000, {tag} }; }; } } else { // Skip over all unknown properties. do { if (!scanner.CheckValue(true)) { scanner.MustGetAnyToken(); if (scanner.TokenType != TK_Identifier && scanner.TokenType != TK_StringConst && scanner.TokenType != TK_True && scanner.TokenType != TK_False) { scanner.ScriptError("Identifier or value expected"); } } } while (scanner.CheckToken(',')); } return 1; }