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);
}
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 gl_ParseFrame(FScanner &sc, FString name)
{
	int type, startDepth;
	FString frameName;

	// get name
	sc.GetString();
	if (strlen(sc.String) > 8)
	{
		sc.ScriptError("Name longer than 8 characters: %s\n", sc.String);
	}
	frameName = sc.String;

	startDepth = ScriptDepth;

	// check for opening brace
	sc.GetString();
	if (sc.Compare("{"))
	{
		ScriptDepth++;
		while (ScriptDepth > startDepth)
		{
			sc.GetString();
			type = sc.MatchString(LightTags);
			switch (type)
			{
			case LIGHTTAG_OPENBRACE:
				ScriptDepth++;
				break;
			case LIGHTTAG_CLOSEBRACE:
				ScriptDepth--;
				break;
			case LIGHTTAG_LIGHT:
				gl_ParseString(sc);
				gl_AddLightAssociation(name, frameName, sc.String);
				break;
			default:
				sc.ScriptError("Unknown tag: %s\n", sc.String);
			}
		}
	}
	else
	{
		sc.ScriptError("Expected '{'.\n");
	}
}
void gl_ParseObject(FScanner &sc)
{
	int type;
	FString name;

	// get name
	sc.GetString();
	name = sc.String;
	if (!PClass::FindClass(name))
		sc.ScriptMessage("Warning: dynamic lights attached to non-existent actor %s\n", name.GetChars());

	// check for opening brace
	sc.GetString();
	if (sc.Compare("{"))
	{
		ScriptDepth++;
		while (ScriptDepth)
		{
			sc.GetString();
			type = sc.MatchString(LightTags);
			switch (type)
			{
			case LIGHTTAG_OPENBRACE:
				ScriptDepth++;
				break;
			case LIGHTTAG_CLOSEBRACE:
				ScriptDepth--;
				break;
			case LIGHTTAG_FRAME:
				gl_ParseFrame(sc, name);
				break;
			default:
				sc.ScriptError("Unknown tag: %s\n", sc.String);
			}
		}
	}
	else
	{
		sc.ScriptError("Expected '{'.\n");
	}
}
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);
}
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);
}
Exemple #7
0
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;
	}
}
Exemple #8
0
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);
}
Exemple #9
0
static void ParseLock(FScanner &sc)
{
	int i,r,g,b;
	int keynum;
	Lock sink;
	Lock *lock = &sink;
	Keygroup *keygroup;
	PClassActor *mi;

	sc.MustGetNumber();
	keynum = sc.Number;

	sc.MustGetString();
	if (!sc.Compare("{"))
	{
		if (!CheckGame(sc.String, false)) keynum = -1;
		sc.MustGetStringName("{");
	}

	ignorekey = true;
	if (keynum > 0 && keynum <= 255) 
	{
		lock = new Lock;
		if (locks[keynum])
		{
			delete locks[keynum];
		}
		locks[keynum] = lock;
		locks[keynum]->locksound.Push("*keytry");
		locks[keynum]->locksound.Push("misc/keytry");
		ignorekey=false;
	}
	else if (keynum != -1)
	{
		sc.ScriptError("Lock index %d out of range", keynum);
	}

	while (!sc.CheckString("}"))
	{
		sc.MustGetString();
		switch(i = sc.MatchString(keywords_lock))
		{
		case 0:	// Any
			keygroup = ParseKeygroup(sc);
			if (keygroup)
			{
				lock->keylist.Push(keygroup);
			}
			break;

		case 1:	// message
			sc.MustGetString();
			lock->Message = sc.String;
			break;

		case 2: // remotemsg
			sc.MustGetString();
			lock->RemoteMsg = sc.String;
			break;

		case 3:	// mapcolor
			sc.MustGetNumber();
			r = sc.Number;
			sc.MustGetNumber();
			g = sc.Number;
			sc.MustGetNumber();
			b = sc.Number;
			lock->rgb = MAKERGB(r,g,b);
			break;

		case 4:	// locksound
			lock->locksound.Clear();
			for (;;)
			{
				sc.MustGetString();
				lock->locksound.Push(sc.String);
				if (!sc.GetString())
				{
					break;
				}
				if (!sc.Compare(","))
				{
					sc.UnGet();
					break;
				}
			}
			break;

		default:
			mi = PClass::FindActor(sc.String);
			if (mi) 
			{
				keygroup = new Keygroup;
				AddOneKey(keygroup, mi, sc);
				if (keygroup) 
				{
					keygroup->anykeylist.ShrinkToFit();
					lock->keylist.Push(keygroup);
				}
			}
			break;
		}
	}
	// copy the messages if the other one does not exist
	if (lock->RemoteMsg.IsEmpty() && lock->Message.IsNotEmpty())
	{
		lock->RemoteMsg = lock->Message;
	}
	if (lock->Message.IsEmpty() && lock->RemoteMsg.IsNotEmpty())
	{
		lock->Message = lock->RemoteMsg;
	}
	lock->keylist.ShrinkToFit();
}
Exemple #10
0
bool FCajunMaster::LoadBots ()
{
    FScanner sc;
    FString tmp;
    bool gotteam = false;
    int loaded_bots = 0;

    bglobal.ForgetBots ();
    tmp = M_GetCajunPath(BOTFILENAME);
    if (tmp.IsEmpty())
    {
        DPrintf ("No " BOTFILENAME ", so no bots\n");
        return false;
    }
    sc.OpenFile(tmp);

    while (sc.GetString ())
    {
        if (!sc.Compare ("{"))
        {
            sc.ScriptError ("Unexpected token '%s'\n", sc.String);
        }

        botinfo_t *newinfo = new botinfo_t;
        bool gotclass = false;

        memset (newinfo, 0, sizeof(*newinfo));

        newinfo->info = copystring ("\\autoaim\\0\\movebob\\.25");

        for (;;)
        {
            sc.MustGetString ();
            if (sc.Compare ("}"))
                break;

            switch (sc.MatchString (BotConfigStrings))
            {
            case BOTCFG_NAME:
                sc.MustGetString ();
                appendinfo (newinfo->info, "name");
                appendinfo (newinfo->info, sc.String);
                newinfo->name = copystring (sc.String);
                break;

            case BOTCFG_AIMING:
                sc.MustGetNumber ();
                newinfo->skill.aiming = sc.Number;
                break;

            case BOTCFG_PERFECTION:
                sc.MustGetNumber ();
                newinfo->skill.perfection = sc.Number;
                break;

            case BOTCFG_REACTION:
                sc.MustGetNumber ();
                newinfo->skill.reaction = sc.Number;
                break;

            case BOTCFG_ISP:
                sc.MustGetNumber ();
                newinfo->skill.isp = sc.Number;
                break;

            case BOTCFG_TEAM:
            {
                char teamstr[16];
                BYTE teamnum;

                sc.MustGetString ();
                if (IsNum (sc.String))
                {
                    teamnum = atoi (sc.String);
                    if (!TeamLibrary.IsValidTeam (teamnum))
                    {
                        teamnum = TEAM_NONE;
                    }
                }
                else
                {
                    teamnum = TEAM_NONE;
                    for (unsigned int i = 0; i < Teams.Size(); ++i)
                    {
                        if (stricmp (Teams[i].GetName (), sc.String) == 0)
                        {
                            teamnum = i;
                            break;
                        }
                    }
                }
                appendinfo (newinfo->info, "team");
                mysnprintf (teamstr, countof(teamstr), "%d", teamnum);
                appendinfo (newinfo->info, teamstr);
                gotteam = true;
                break;
            }

            default:
                if (stricmp (sc.String, "playerclass") == 0)
                {
                    gotclass = true;
                }
                appendinfo (newinfo->info, sc.String);
                sc.MustGetString ();
                appendinfo (newinfo->info, sc.String);
                break;
            }
        }
        if (!gotclass)
        {   // Bots that don't specify a class get a random one
            appendinfo (newinfo->info, "playerclass");
            appendinfo (newinfo->info, "random");
        }
        if (!gotteam)
        {   // Same for bot teams
            appendinfo (newinfo->info, "team");
            appendinfo (newinfo->info, "255");
        }
        newinfo->next = bglobal.botinfo;
        newinfo->lastteam = TEAM_NONE;
        bglobal.botinfo = newinfo;
        loaded_bots++;
    }
    Printf ("%d bots read from %s\n", loaded_bots, BOTFILENAME);
    return true;
}
void gl_ParseSectorLight(FScanner &sc)
{
	int type;
	float floatVal;
	float floatTriple[3];
	FLightDefaults *defaults;

	// get name
	sc.GetString();
	FName name = sc.String;

	// check for opening brace
	sc.GetString();
	if (sc.Compare("{"))
	{
		defaults = new FLightDefaults(name, SectorLight);
		ScriptDepth++;
		while (ScriptDepth)
		{
			sc.GetString();
			type = sc.MatchString(LightTags);
			switch (type)
			{
			case LIGHTTAG_OPENBRACE:
				ScriptDepth++;
				break;
			case LIGHTTAG_CLOSEBRACE:
				ScriptDepth--;
				break;
			case LIGHTTAG_COLOR:
				gl_ParseTriple(sc, floatTriple);
				defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
				defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
				defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
				break;
			case LIGHTTAG_OFFSET:
				gl_ParseTriple(sc, floatTriple);
				defaults->SetOffset(floatTriple);
				break;
			case LIGHTTAG_SCALE:
				floatVal = gl_ParseFloat(sc);
				defaults->SetArg(LIGHT_SCALE, (BYTE)(floatVal * 255));
				break;
			case LIGHTTAG_SUBTRACTIVE:
				defaults->SetSubtractive(gl_ParseInt(sc) != 0);
				break;
			case LIGHTTAG_HALO:
				defaults->SetHalo(gl_ParseInt(sc) != 0);
				break;
			case LIGHTTAG_DONTLIGHTSELF:
				defaults->SetDontLightSelf(gl_ParseInt(sc) != 0);
				break;
			default:
				sc.ScriptError("Unknown tag: %s\n", sc.String);
			}
		}
		gl_AddLightDefaults(defaults);
	}
	else
	{
		sc.ScriptError("Expected '{'.\n");
	}
}
void gl_ParseFlickerLight2(FScanner &sc)
{
	int type;
	float floatVal, floatTriple[3];
	int intVal;
	FLightDefaults *defaults;

	// get name
	sc.GetString();
	FName name = sc.String;

	// check for opening brace
	sc.GetString();
	if (sc.Compare("{"))
	{
		defaults = new FLightDefaults(name, RandomFlickerLight);
		ScriptDepth++;
		while (ScriptDepth)
		{
			sc.GetString();
			type = sc.MatchString(LightTags);
			switch (type)
			{
			case LIGHTTAG_OPENBRACE:
				ScriptDepth++;
				break;
			case LIGHTTAG_CLOSEBRACE:
				ScriptDepth--;
				break;
			case LIGHTTAG_COLOR:
				gl_ParseTriple(sc, floatTriple);
				defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
				defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
				defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
				break;
			case LIGHTTAG_OFFSET:
				gl_ParseTriple(sc, floatTriple);
				defaults->SetOffset(floatTriple);
				break;
			case LIGHTTAG_SIZE:
				intVal = clamp<int>(gl_ParseInt(sc), 0, 255);
				defaults->SetArg(LIGHT_INTENSITY, intVal);
				break;
			case LIGHTTAG_SECSIZE:
				intVal = clamp<int>(gl_ParseInt(sc), 0, 255);
				defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal);
				break;
			case LIGHTTAG_INTERVAL:
				floatVal = gl_ParseFloat(sc);
				defaults->SetAngle((angle_t)(floatVal * ANGLE_MAX));
				break;
			case LIGHTTAG_SUBTRACTIVE:
				defaults->SetSubtractive(gl_ParseInt(sc) != 0);
				break;
			case LIGHTTAG_HALO:
				defaults->SetHalo(gl_ParseInt(sc) != 0);
				break;
			case LIGHTTAG_DONTLIGHTSELF:
				defaults->SetDontLightSelf(gl_ParseInt(sc) != 0);
				break;
			default:
				sc.ScriptError("Unknown tag: %s\n", sc.String);
			}
		}
		if (defaults->GetArg(LIGHT_SECONDARY_INTENSITY) < defaults->GetArg(LIGHT_INTENSITY))
		{
			BYTE v = defaults->GetArg(LIGHT_SECONDARY_INTENSITY);
			defaults->SetArg(LIGHT_SECONDARY_INTENSITY, defaults->GetArg(LIGHT_INTENSITY));
			defaults->SetArg(LIGHT_INTENSITY, v);
		}
		gl_AddLightDefaults(defaults);
	}
	else
	{
		sc.ScriptError("Expected '{'.\n");
	}
}
//==========================================================================
// The actual light def parsing code is there.
// DoParseDefs is no longer called directly by ParseDefs, now it's called
// by LoadDynLightDefs, which wasn't simply integrated into ParseDefs
// because of the way the code needs to load two out of five lumps.
//==========================================================================
void gl_DoParseDefs(FScanner &sc, int workingLump)
{
	int recursion=0;
	int lump, type;

	// Get actor class name.
	while (true)
	{
		sc.SavePos();
		if (!sc.GetToken ())
		{
			return;
		}
		type = sc.MatchString(CoreKeywords);
		switch (type)
		{
		case TAG_INCLUDE:
			{
				sc.MustGetString();
				// This is not using sc.Open because it can print a more useful error message when done here
				lump = Wads.CheckNumForFullName(sc.String, true);
				if (lump==-1)
					sc.ScriptError("Lump '%s' not found", sc.String);

				FScanner newscanner(lump);
				gl_DoParseDefs(newscanner, lump);
				break;
			}
		case LIGHT_POINT:
			gl_ParsePointLight(sc);
			break;
		case LIGHT_PULSE:
			gl_ParsePulseLight(sc);
			break;
		case LIGHT_FLICKER:
			gl_ParseFlickerLight(sc);
			break;
		case LIGHT_FLICKER2:
			gl_ParseFlickerLight2(sc);
			break;
		case LIGHT_SECTOR:
			gl_ParseSectorLight(sc);
			break;
		case LIGHT_OBJECT:
			gl_ParseObject(sc);
			break;
		case LIGHT_CLEAR:
			gl_ReleaseLights();
			break;
		case TAG_SHADER:
			gl_ParseShader(sc);
			break;
		case TAG_CLEARSHADERS:
			break;
		case TAG_SKYBOX:
			gl_ParseSkybox(sc);
			break;
		case TAG_GLOW:
			gl_InitGlow(sc);
			break;
		case TAG_BRIGHTMAP:
			gl_ParseBrightmap(sc, workingLump);
			break;
		case TAG_HARDWARESHADER:
			gl_ParseHardwareShader(sc, workingLump);
			break;
		case TAG_DETAIL:
			gl_ParseDetailTexture(sc);
			break;
		case TAG_DISABLE_FB:
			{
				/* not implemented.
				sc.MustGetString();
				const PClass *cls = PClass::FindClass(sc.String);
				if (cls) GetDefaultByType(cls)->renderflags |= RF_NEVERFULLBRIGHT;
				*/
			}
			break;
		default:
			sc.ScriptError("Error parsing defs.  Unknown tag: %s.\n", sc.String);
			break;
		}
	}
}