Exemple #1
0
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);
}
Exemple #3
0
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);
	}
}
Exemple #4
0
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);
}
Exemple #6
0
		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(';');
}
Exemple #8
0
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);
}
Exemple #9
0
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;
}
Exemple #10
0
int SBarInfo::getSignedInteger(FScanner &sc)
{
	if(sc.CheckToken('-'))
	{
		sc.MustGetToken(TK_IntConst);
		return -sc.Number;
	}
	else
	{
		sc.MustGetToken(TK_IntConst);
		return sc.Number;
	}
}
Exemple #11
0
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;
}
Exemple #12
0
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++;
	}
}
Exemple #15
0
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);
}
Exemple #17
0
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++;
	}
}
Exemple #20
0
		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);
}
Exemple #22
0
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)
}
Exemple #26
0
		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);
}
Exemple #30
0
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;
}