Example #1
0
static void ParseArgListDef(FScanner &sc, PClassActor *cls,
	TArray<PType *> &args, TArray<DWORD> &argflags)
{
	if (!sc.CheckToken(')'))
	{
		while (sc.TokenType != ')')
		{
			int flags = 0;
			PType *type = NULL;
			PClass *restrict = NULL;

			// Retrieve flags before type name
			for (;;)
			{
				if (sc.CheckToken(TK_Coerce) || sc.CheckToken(TK_Native))
				{
				}
				else
				{
					break;
				}
			}
			// Read the variable type
			sc.MustGetAnyToken();
			switch (sc.TokenType)
			{
			case TK_Bool:
				type = TypeBool;
				break;

			case TK_Int:
				type = TypeSInt32;
				break;

			case TK_Float:
				type = TypeFloat64;
				break;

			case TK_Sound:		type = TypeSound;		break;
			case TK_String:		type = TypeString;		break;
			case TK_Name:		type = TypeName;		break;
			case TK_State:		type = TypeState;		break;
			case TK_Color:		type = TypeColor;		break;
			case TK_Class:
				sc.MustGetToken('<');
				sc.MustGetToken(TK_Identifier);	// Get class name
				restrict = PClass::FindClass(sc.String);
				if (restrict == NULL)
				{
					sc.ScriptMessage("Unknown class type %s", sc.String);
					FScriptPosition::ErrorCounter++;
				}
				else
				{
					type = NewClassPointer(restrict);
				}
				sc.MustGetToken('>');
				break;
			case TK_Ellipsis:
				// Making the final type NULL signals a varargs function.
				type = NULL;
				sc.MustGetToken(')');
				sc.UnGet();
				break;
			default:
				sc.ScriptMessage ("Unknown variable type %s", sc.TokenName(sc.TokenType, sc.String).GetChars());
				type = TypeSInt32;
				FScriptPosition::ErrorCounter++;
				break;
			}
			// Read the optional variable name
			if (!sc.CheckToken(',') && !sc.CheckToken(')'))
			{
				sc.MustGetToken(TK_Identifier);
			}
			else
			{
				sc.UnGet();
			}

			if (sc.CheckToken('='))
			{
				flags |= VARF_Optional;
				FxExpression *def = ParseParameter(sc, cls, type, true);
				delete def;
			}

			args.Push(type);
			argflags.Push(flags);
			sc.MustGetAnyToken();
			if (sc.TokenType != ',' && sc.TokenType != ')')
			{
				sc.ScriptError ("Expected ',' or ')' but got %s instead", sc.TokenName(sc.TokenType, sc.String).GetChars());
			}
		}
	}
	sc.MustGetToken(';');
}
FCDODiffControl::FCDODiffControl( 
		const UObject* InOldCDO
		, const UObject* InNewCDO
		, TArray< TSharedPtr<FBlueprintDifferenceTreeEntry> >& OutTreeEntries
		, TArray< TSharedPtr<FBlueprintDifferenceTreeEntry> >& OutRealDifferences
		, FOnCDODiffControlChanged SelectionCallback )
	: OldDetails(InOldCDO, FDetailsDiff::FOnDisplayedPropertiesChanged() )
	, NewDetails(InNewCDO, FDetailsDiff::FOnDisplayedPropertiesChanged() )
{
	// @todo: (doc): rename InDifferences
	TArray< FSingleObjectDiffEntry > DifferingProperties;
	OldDetails.DiffAgainst(NewDetails, DifferingProperties);

	// OrderedProperties will contain differences in the order they are displayed:
	TArray< const FSingleObjectDiffEntry* > OrderedProperties;

	// create differing properties list based on what is displayed by the old properties..
	TArray<FPropertySoftPath> OldProperties = OldDetails.GetDisplayedProperties();
	TArray<FPropertySoftPath> NewProperties = NewDetails.GetDisplayedProperties();

	const auto FindDiffering = [](TArray< FSingleObjectDiffEntry > const& InDifferenceEntries, const FPropertySoftPath& PropertyIdentifer) -> const FSingleObjectDiffEntry*
	{
		for (const auto& Difference : InDifferenceEntries)
		{
			if (Difference.Identifier == PropertyIdentifer)
			{
				return &Difference;
			}
		}
		return nullptr;
	};

	// zip the two sets of properties, zip iterators are not trivial to write in c++,
	// so this procedural stuff will have to do:
	int IterOld = 0;
	int IterNew = 0;
	while (IterOld != OldProperties.Num() || IterNew != NewProperties.Num())
	{
		if (IterOld != OldProperties.Num() && IterNew != NewProperties.Num()
			&& OldProperties[IterOld] == NewProperties[IterNew])
		{
			if (const FSingleObjectDiffEntry* Differing = FindDiffering(DifferingProperties, OldProperties[IterOld]))
			{
				OrderedProperties.Push(Differing);
			}
			++IterOld;
			++IterNew;
		}
		else
		{
			if (IterOld != OldProperties.Num())
			{
				bool bFoundDifference = false;
				if (const FSingleObjectDiffEntry* OldDiffering = FindDiffering(DifferingProperties, OldProperties[IterOld]))
				{
					bFoundDifference = true;
					OrderedProperties.Push(OldDiffering);
					++IterOld;
				}
				else if (IterNew != NewProperties.Num())
				{
					if (const FSingleObjectDiffEntry* NewDiffering = FindDiffering(DifferingProperties, NewProperties[IterNew]))
					{
						bFoundDifference = true;
						OrderedProperties.Push(NewDiffering);
						++IterNew;
					}
				}
				if (!bFoundDifference)
				{
					++IterOld;
					++IterNew;
				}
			}
			else
			{
				check(IterNew != NewProperties.Num());
				if (const FSingleObjectDiffEntry* Differing = FindDiffering(DifferingProperties, NewProperties[IterNew]))
				{
					OrderedProperties.Push(Differing);
				}
				++IterNew;
			}
		}
	}

	const auto CreateCDODifferenceWidget = [](FSingleObjectDiffEntry DiffEntry, FText ObjectName) -> TSharedRef<SWidget>
	{
		return SNew(STextBlock)
			.Text(DiffViewUtils::PropertyDiffMessage(DiffEntry, ObjectName))
			.ColorAndOpacity(DiffViewUtils::Differs());
	};

	const auto FocusDetailsDifferenceEntry = [](FPropertySoftPath Identifier, FCDODiffControl* Control, FOnCDODiffControlChanged InSelectionCallback)
	{
		// This allows the owning control to focus the correct tab (or do whatever else it likes):
		InSelectionCallback.ExecuteIfBound();
		Control->HighlightDifference(Identifier);
	};

	TArray< TSharedPtr<FBlueprintDifferenceTreeEntry> > Children;

	for (auto Difference : OrderedProperties)
	{
		auto Entry = TSharedPtr<FBlueprintDifferenceTreeEntry>(
			new FBlueprintDifferenceTreeEntry(
			FOnDiffEntryFocused::CreateStatic(FocusDetailsDifferenceEntry, Difference->Identifier, this, SelectionCallback)
			, FGenerateDiffEntryWidget::CreateStatic(CreateCDODifferenceWidget, *Difference, RightRevision)
			, TArray< TSharedPtr<FBlueprintDifferenceTreeEntry> >()
			)
		);
		Children.Push(Entry);
		OutRealDifferences.Push(Entry);
	}

	const bool bHasDiffferences = Children.Num() != 0;
	FLinearColor Color = bHasDiffferences ? DiffViewUtils::Differs() : DiffViewUtils::Identical();
	if (!bHasDiffferences)
	{
		// make one child informing the user that there are no differences:
		Children.Push(FBlueprintDifferenceTreeEntry::NoDifferencesEntry() );
	}

	const auto ForwardSelection = [](FOnCDODiffControlChanged InSelectionCallback)
	{
		// This allows the owning control to focus the correct tab (or do whatever else it likes):
		InSelectionCallback.ExecuteIfBound();
	};

	OutTreeEntries.Push(FBlueprintDifferenceTreeEntry::CreateDefaultsCategoryEntry(
		FOnDiffEntryFocused::CreateStatic(ForwardSelection, SelectionCallback)
		, Children
		, bHasDiffferences
	));
}
Example #3
0
//*****************************************************************************
//
void LASTMANSTANDING_TimeExpired( void )
{
	LONG				lHighestHealth = 0;
	bool				bTie = false;
	bool				bFoundPlayer = false;
	LONG				lWinner = -1;
	DHUDMessageFadeOut	*pMsg;
	char				szString[64];

	// Don't end the level if we're not in a game.
	if ( LASTMANSTANDING_GetState( ) != LMSS_INPROGRESS )
		return;

	// Try to find the player with the highest health.
	if ( lastmanstanding )
	{
		TArray<ULONG> possibleWinners;
		for ( unsigned int i = 0; i < MAXPLAYERS; ++i )
			possibleWinners.Push ( i );

		// [BB] Find the player with the most lives left.
		PLAYER_SelectPlayersWithHighestValue ( PLAYER_GetLivesLeft, possibleWinners );
		// [BB] If more than one player has the most lives left, select the player with the highest lives.
		if ( possibleWinners.Size() != 1 )
			PLAYER_SelectPlayersWithHighestValue ( PLAYER_GetHealth, possibleWinners );

		// [BB] If more then one player have the most lives and also the same health, then the game it a tie.
		if ( possibleWinners.Size() == 1 )
			lWinner = possibleWinners[0];
		else
		{
			lWinner = MAXPLAYERS;
			bTie = true;
		}
	}
	else if ( teamlms )
	{
		if ( LASTMANSTANDING_TeamsWithAlivePlayersOn( ) == 1 )
		{
			for ( ULONG i = 0; i < teams.Size( ); i++ )
			{
				if ( TEAM_CountLivingAndRespawnablePlayers( i ) )
					lWinner = i;
			}
		}
		else
		{
			lWinner = teams.Size( );
			bTie = true;
		}
	}

	// If for some reason we don't have any players, just end the map like normal.
	if ( lWinner == -1 )
	{
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVER_Printf( PRINT_HIGH, "%s\n", GStrings( "TXT_TIMELIMIT" ));
		else
			Printf( "%s\n", GStrings( "TXT_TIMELIMIT" ));

		GAME_SetEndLevelDelay( 5 * TICRATE );
		return;
	}

	// If there was a tie, then go into sudden death!
	if ( bTie )
	{
		// Only print the message the instant we reach sudden death.
		if ( level.time == (int)( timelimit * TICRATE * 60 ))
		{
			sprintf( szString, "\\cdSUDDEN DEATH!" );
			V_ColorizeString( szString );

			if ( NETWORK_GetState( ) != NETSTATE_SERVER )
			{
				// Display the HUD message.
				pMsg = new DHUDMessageFadeOut( BigFont, szString,
					160.4f,
					75.0f,
					320,
					200,
					CR_RED,
					3.0f,
					2.0f );

				StatusBar->AttachMessage( pMsg, MAKE_ID('C','N','T','R') );
			}
			else
			{
				SERVERCOMMANDS_PrintHUDMessageFadeOut( szString, 160.4f, 75.0f, 320, 200, CR_RED, 3.0f, 2.0f, "BigFont", false, MAKE_ID('C','N','T','R') );
			}
		}

		return;
	}

	// Also, do the win sequence for the player.
	LASTMANSTANDING_DoWinSequence( lWinner );

	// Give the winner a win.
	if ( lastmanstanding )
		PLAYER_SetWins( &players[lWinner], players[lWinner].ulWins + 1 );
	// [BB] In a team game of course give the win to the winning team.
	if ( teamlms )
		TEAM_SetWinCount( lWinner, TEAM_GetWinCount( lWinner ) + 1, false );

	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVER_Printf( PRINT_HIGH, "%s\n", GStrings( "TXT_TIMELIMIT" ));
	else
		Printf( "%s\n", GStrings( "TXT_TIMELIMIT" ));

	GAME_SetEndLevelDelay( 5 * TICRATE );
}
Example #4
0
//*****************************************************************************
//
bool ZANDRONUM_ParseMasterServerResponse( BYTESTREAM_s *pByteStream, TArray<SERVER_s>&aServerInfo, TArray<QUERY_s>&aQueryInfo )
{
	ULONG			i;
	LONG			lCommand;
	SERVER_s	ServerInfo;
	QUERY_s		QueryInfo;
	time_t		tNow;

	lCommand = NETWORK_ReadLong( pByteStream );
	switch ( lCommand )
	{
	case MSC_BEGINSERVERLISTPART:
		const ULONG ulPacketNum = NETWORK_ReadByte( pByteStream );

		if ( ulPacketNum == 0 )
		{
			// Add a new query.
			QueryInfo.qTotal.lNumPlayers = 0;
			QueryInfo.qTotal.lNumServers = 0;
			QueryInfo.qTotal.lNumSpectators = 0;

			for ( unsigned int g = 0; g < NUM_GAMETYPES; g++ )
			{	
				QueryInfo.qByGameMode[g].lNumPlayers = 0;
				QueryInfo.qByGameMode[g].lNumServers = 0;
				QueryInfo.qByGameMode[g].lNumSpectators = 0;
			}

			time( &QueryInfo.tTime );
			aQueryInfo.Push( QueryInfo );

			// Clear out the server list.
			aServerInfo.Clear( );
		}

		time( &tNow );

		while ( true )
		{
			const LONG lCommand = NETWORK_ReadByte( pByteStream );

			switch ( lCommand )
			{
			case MSC_SERVER:
				{
					ServerInfo.ulActiveState = AS_WAITINGFORREPLY;

					// Read in address information.
					ServerInfo.Address.abIP[0] = NETWORK_ReadByte( pByteStream );
					ServerInfo.Address.abIP[1] = NETWORK_ReadByte( pByteStream );
					ServerInfo.Address.abIP[2] = NETWORK_ReadByte( pByteStream );
					ServerInfo.Address.abIP[3] = NETWORK_ReadByte( pByteStream );
					ServerInfo.Address.usPort = htons( NETWORK_ReadShort( pByteStream ));

					ServerInfo.tLastQuery = tNow;

					// Add this server's info to our list, and query it.			
					i = aServerInfo.Push( ServerInfo );
					ZANDRONUM_QueryServer( &aServerInfo[i] );
				}
				break;

			case MSC_SERVERBLOCK:
				{
					// Read in address information.
					ULONG ulPorts = 0;
					while (( ulPorts = NETWORK_ReadByte( pByteStream ) ))
					{
						ServerInfo.Address.abIP[0] = NETWORK_ReadByte( pByteStream );
						ServerInfo.Address.abIP[1] = NETWORK_ReadByte( pByteStream );
						ServerInfo.Address.abIP[2] = NETWORK_ReadByte( pByteStream );
						ServerInfo.Address.abIP[3] = NETWORK_ReadByte( pByteStream );
						for ( ULONG ulIdx = 0; ulIdx < ulPorts; ++ulIdx )
						{
							ServerInfo.ulActiveState = AS_WAITINGFORREPLY;
							ServerInfo.Address.usPort = htons( NETWORK_ReadShort( pByteStream ));

							ServerInfo.tLastQuery = tNow;

							// Add this server's info to our list, and query it.			
							i = aServerInfo.Push( ServerInfo );
							ZANDRONUM_QueryServer( &aServerInfo[i] );
						}
					}

				}
				break;

			case MSC_ENDSERVERLISTPART:
				return false;

			case MSC_ENDSERVERLIST:
				Printf( "Received %d Zandronum servers.\n", aServerInfo.Size( ));

				// Since we got the server list, return true.
				return true;

			default:

				Printf( "Unknown server list command from master server: %d\n", static_cast<int> (lCommand) );
				return false;
			}
		}
	}

	return true;
}
Example #5
0
	void ParseTextMap(MapData *map)
	{
		char *buffer = new char[map->Size(ML_TEXTMAP)];

		isTranslated = true;
		isExtended = false;
		floordrop = false;

		map->Read(ML_TEXTMAP, buffer);
		sc.OpenMem(Wads.GetLumpFullName(map->lumpnum), buffer, map->Size(ML_TEXTMAP));
		delete [] buffer;
		sc.SetCMode(true);
		if (sc.CheckString("namespace"))
		{
			sc.MustGetStringName("=");
			sc.MustGetString();
			namespc = sc.String;
			switch(namespc)
			{
			case NAME_ZDoom:
				namespace_bits = Zd;
				isTranslated = false;
				break;
			case NAME_ZDoomTranslated:
				level.flags2 |= LEVEL2_DUMMYSWITCHES;
				namespace_bits = Zdt;
				break;
			case NAME_Vavoom:
				namespace_bits = Va;
				isTranslated = false;
				break;
			case NAME_Hexen:
				namespace_bits = Hx;
				isTranslated = false;
				break;
			case NAME_Doom:
				namespace_bits = Dm;
				P_LoadTranslator("xlat/doom_base.txt");
				level.flags2 |= LEVEL2_DUMMYSWITCHES;
				floordrop = true;
				break;
			case NAME_Heretic:
				namespace_bits = Ht;
				P_LoadTranslator("xlat/heretic_base.txt");
				level.flags2 |= LEVEL2_DUMMYSWITCHES;
				floordrop = true;
				break;
			case NAME_Strife:
				namespace_bits = St;
				P_LoadTranslator("xlat/strife_base.txt");
				level.flags2 |= LEVEL2_DUMMYSWITCHES|LEVEL2_RAILINGHACK;
				floordrop = true;
				break;
			default:
				Printf("Unknown namespace %s. Using defaults for %s\n", sc.String, GameTypeName());
				switch (gameinfo.gametype)
				{
				default:			// Shh, GCC
				case GAME_Doom:
				case GAME_Chex:
					namespace_bits = Dm;
					P_LoadTranslator("xlat/doom_base.txt");
					break;
				case GAME_Heretic:
					namespace_bits = Ht;
					P_LoadTranslator("xlat/heretic_base.txt");
					break;
				case GAME_Strife:
					namespace_bits = St;
					P_LoadTranslator("xlat/strife_base.txt");
					break;
				case GAME_Hexen:
					namespace_bits = Hx;
					isTranslated = false;
					break;
				}
			}
			sc.MustGetStringName(";");
		}
		else
		{
			Printf("Map does not define a namespace.\n");
		}

		while (sc.GetString())
		{
			if (sc.Compare("thing"))
			{
				FMapThing th;
				unsigned userdatastart = MapThingsUserData.Size();
				ParseThing(&th);
				MapThingsConverted.Push(th);
				if (userdatastart < MapThingsUserData.Size())
				{ // User data added
					MapThingsUserDataIndex[MapThingsConverted.Size()-1] = userdatastart;
					// Mark end of the user data for this map thing
					FMapThingUserData ud;
					ud.Property = NAME_None;
					ud.Value = 0;
					MapThingsUserData.Push(ud);
				}
			}
			else if (sc.Compare("linedef"))
			{
				line_t li;
				ParseLinedef(&li, ParsedLines.Size());
				ParsedLines.Push(li);
			}
			else if (sc.Compare("sidedef"))
			{
				side_t si;
				intmapsidedef_t st;
				ParseSidedef(&si, &st, ParsedSides.Size());
				ParsedSides.Push(si);
				ParsedSideTextures.Push(st);
			}
			else if (sc.Compare("sector"))
			{
				sector_t sec;
				ParseSector(&sec, ParsedSectors.Size());
				ParsedSectors.Push(sec);
			}
			else if (sc.Compare("vertex"))
			{
				vertex_t vt;
				vertexdata_t vd;
				ParseVertex(&vt, &vd);
				ParsedVertices.Push(vt);
				ParsedVertexDatas.Push(vd);
			}
			else
			{
				Skip();
			}
		}

		// Catch bogus maps here rather than during nodebuilding
		if (ParsedVertices.Size() == 0)	I_Error("Map has no vertices.\n");
		if (ParsedSectors.Size() == 0)	I_Error("Map has no sectors. \n");
		if (ParsedLines.Size() == 0)	I_Error("Map has no linedefs.\n");
		if (ParsedSides.Size() == 0)	I_Error("Map has no sidedefs.\n");

		// Create the real vertices
		numvertexes = ParsedVertices.Size();
		vertexes = new vertex_t[numvertexes];
		memcpy(vertexes, &ParsedVertices[0], numvertexes * sizeof(*vertexes));

		// Create the real vertex datas
		numvertexdatas = ParsedVertexDatas.Size();
		vertexdatas = new vertexdata_t[numvertexdatas];
		memcpy(vertexdatas, &ParsedVertexDatas[0], numvertexdatas * sizeof(*vertexdatas));

		// Create the real sectors
		numsectors = ParsedSectors.Size();
		sectors = new sector_t[numsectors];
		memcpy(sectors, &ParsedSectors[0], numsectors * sizeof(*sectors));
		sectors[0].e = new extsector_t[numsectors];
		for(int i = 0; i < numsectors; i++)
		{
			sectors[i].e = &sectors[0].e[i];
		}

		// Create the real linedefs and decompress the sidedefs
		ProcessLineDefs();
	}
Example #6
0
void R_InitColormaps ()
{
	// [RH] Try and convert BOOM colormaps into blending values.
	//		This is a really rough hack, but it's better than
	//		not doing anything with them at all (right?)

	FakeCmap cm;

	R_DeinitColormaps();

	cm.name[0] = 0;
	cm.blend = 0;
	fakecmaps.Push(cm);

	uint32_t NumLumps = Wads.GetNumLumps();

	for (uint32_t i = 0; i < NumLumps; i++)
	{
		if (Wads.GetLumpNamespace(i) == ns_colormaps)
		{
			char name[9];
			name[8] = 0;
			Wads.GetLumpName (name, i);

			if (Wads.CheckNumForName (name, ns_colormaps) == (int)i)
			{
				strncpy(cm.name, name, 8);
				cm.blend = 0;
				cm.lump = i;
				fakecmaps.Push(cm);
			}
		}
	}

	int rr = 0, gg = 0, bb = 0;
	for(int x=0;x<256;x++)
	{
		rr += GPalette.BaseColors[x].r;
		gg += GPalette.BaseColors[x].g;
		bb += GPalette.BaseColors[x].b;
	}
	rr >>= 8;
	gg >>= 8;
	bb >>= 8;

	int palette_brightness = (rr*77 + gg*143 + bb*35) / 255;

	// To calculate the blend it will just average the colors of the first map
	if (fakecmaps.Size() > 1)
	{
		uint8_t map[256];

		for (unsigned j = 1; j < fakecmaps.Size(); j++)
		{
			if (Wads.LumpLength (fakecmaps[j].lump) >= 256)
			{
				int k, r, g, b;
				FWadLump lump = Wads.OpenLumpNum (fakecmaps[j].lump);
				lump.Read(map, 256);
				r = g = b = 0;

				for (k = 0; k < 256; k++)
				{
					r += GPalette.BaseColors[map[k]].r;
					g += GPalette.BaseColors[map[k]].g;
					b += GPalette.BaseColors[map[k]].b;
				}
				r /= 256;
				g /= 256;
				b /= 256;
				// The calculated average is too dark so brighten it according to the palettes's overall brightness
				int maxcol = MAX<int>(MAX<int>(palette_brightness, r), MAX<int>(g, b));
				
				fakecmaps[j].blend = PalEntry (255, r * 255 / maxcol, g * 255 / maxcol, b * 255 / maxcol);
			}
		}
	}

	// build default special maps (e.g. invulnerability)

	for (unsigned i = 0; i < countof(SpecialColormapParms); ++i)
	{
		AddSpecialColormap(SpecialColormapParms[i].Start[0], SpecialColormapParms[i].Start[1],
			SpecialColormapParms[i].Start[2], SpecialColormapParms[i].End[0],
			SpecialColormapParms[i].End[1], SpecialColormapParms[i].End[2]);
	}
	// desaturated colormaps. These are used for texture composition
	for(int m = 0; m < 31; m++)
	{
		uint8_t *shade = DesaturateColormap[m];
		for (int c = 0; c < 256; c++)
		{
			int intensity = (GPalette.BaseColors[c].r * 77 +
						GPalette.BaseColors[c].g * 143 +
						GPalette.BaseColors[c].b * 37) / 256;

			int r = (GPalette.BaseColors[c].r * (31-m) + intensity *m) / 31;
			int g = (GPalette.BaseColors[c].g * (31-m) + intensity *m) / 31;
			int b = (GPalette.BaseColors[c].b * (31-m) + intensity *m) / 31;
			shade[c] = ColorMatcher.Pick(r, g, b);
		}
	}
}
Example #7
0
void ParseCompatibility()
{
	TArray<FMD5Holder> md5array;
	FMD5Holder md5;
	FCompatValues flags;
	int i, x;
	unsigned int j;

	BCompatMap.Clear();
	CompatParams.Clear();

	// The contents of this file are not cumulative, as it should not
	// be present in user-distributed maps.
	FScanner sc(Wads.GetNumForFullName("compatibility.txt"));

	while (sc.GetString())	// Get MD5 signature
	{
		do
		{
			if (strlen(sc.String) != 32)
			{
				sc.ScriptError("MD5 signature must be exactly 32 characters long");
			}
			for (i = 0; i < 32; ++i)
			{
				if (sc.String[i] >= '0' && sc.String[i] <= '9')
				{
					x = sc.String[i] - '0';
				}
				else
				{
					sc.String[i] |= 'a' ^ 'A';
					if (sc.String[i] >= 'a' && sc.String[i] <= 'f')
					{
						x = sc.String[i] - 'a' + 10;
					}
					else
					{
						x = 0;
						sc.ScriptError("MD5 signature must be a hexadecimal value");
					}
				}
				if (!(i & 1))
				{
					md5.Bytes[i / 2] = x << 4;
				}
				else
				{
					md5.Bytes[i / 2] |= x;
				}
			}
			md5array.Push(md5);
			sc.MustGetString();
		} while (!sc.Compare("{"));
		memset(flags.CompatFlags, 0, sizeof(flags.CompatFlags));
		flags.ExtCommandIndex = ~0u;
		while (sc.GetString())
		{
			if ((i = sc.MatchString(&Options[0].Name, sizeof(*Options))) >= 0)
			{
				flags.CompatFlags[Options[i].WhichSlot] |= Options[i].CompatFlags;
			}
			else if (sc.Compare("clearlineflags"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_CLEARFLAGS);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setlineflags"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETFLAGS);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setlinespecial"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETSPECIAL);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);

				sc.MustGetString();
				CompatParams.Push(P_FindLineSpecial(sc.String, NULL, NULL));
				for (int i = 0; i < 5; i++)
				{
					sc.MustGetNumber();
					CompatParams.Push(sc.Number);
				}
			}
			else if (sc.Compare("clearlinespecial"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_CLEARSPECIAL);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setactivation"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETACTIVATION);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("sectorflooroffset"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SECTORFLOOROFFSET);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetFloat();
				CompatParams.Push(FLOAT2FIXED(sc.Float));
			}
			else if (sc.Compare("setwallyscale"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETWALLYSCALE);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetString();
				CompatParams.Push(sc.MustMatchString(LineSides));
				sc.MustGetString();
				CompatParams.Push(sc.MustMatchString(WallTiers));
				sc.MustGetFloat();
				CompatParams.Push(FLOAT2FIXED(sc.Float));
			}
			else if (sc.Compare("setthingz"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETTHINGZ);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetFloat();
				CompatParams.Push(FLOAT2FIXED(sc.Float));
			}
			else if (sc.Compare("setsectortag"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETTAG);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setthingflags"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETTHINGFLAGS);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else 
			{
				sc.UnGet();
				break;
			}
		}
		if (flags.ExtCommandIndex != ~0u) 
		{
			CompatParams.Push(CP_END);
		}
		sc.MustGetStringName("}");
		for (j = 0; j < md5array.Size(); ++j)
		{
			BCompatMap[md5array[j]] = flags;
		}
		md5array.Clear();
	}
}
/**
 * Assigns a group index to each triangle such that it's the same group as its adjacent triangles.
 * The group indices are between zero and the minimum number of indices needed.
 * @return The number of groups used.
 */
static uint32 AssignMinimalAdjacencyGroups(const TArray<uint32>& Adjacency,TArray<int32>& OutTriangleGroups)
{
	const uint32 NumTriangles = Adjacency.Num() / 3;
	check(Adjacency.Num() == NumTriangles * 3);

	// Initialize the triangle group array.
	OutTriangleGroups.Empty(NumTriangles);
	for(uint32 TriangleIndex = 0;TriangleIndex < NumTriangles;TriangleIndex++)
	{
		OutTriangleGroups.Add(INDEX_NONE);
	}

	uint32 NumGroups = 0;
	while(true)
	{
		const uint32 CurrentGroupIndex = NumGroups;
		TArray<uint32> PendingGroupTriangles;

		// Find the next ungrouped triangle to start the group with.
		for(uint32 TriangleIndex = 0;TriangleIndex < NumTriangles;TriangleIndex++)
		{
			if(OutTriangleGroups[TriangleIndex] == INDEX_NONE)
			{
				PendingGroupTriangles.Push(TriangleIndex);
				break;
			}
		}

		if(!PendingGroupTriangles.Num())
		{
			break;
		}
		else
		{
			// Recursively expand the group to include all triangles adjacent to the group's triangles.
			while(PendingGroupTriangles.Num())
			{
				const uint32 TriangleIndex = PendingGroupTriangles.Pop();

				OutTriangleGroups[TriangleIndex] = CurrentGroupIndex;

				for(int32 EdgeIndex = 0;EdgeIndex < 3;EdgeIndex++)
				{
					const int32 AdjacentTriangleIndex = Adjacency[TriangleIndex * 3 + EdgeIndex];
					if(AdjacentTriangleIndex != INDEX_NONE)
					{
						const int32 AdjacentTriangleGroupIndex = OutTriangleGroups[AdjacentTriangleIndex];
						check(AdjacentTriangleGroupIndex == INDEX_NONE || AdjacentTriangleGroupIndex == CurrentGroupIndex);
						if(AdjacentTriangleGroupIndex == INDEX_NONE)
						{
							PendingGroupTriangles.Push(AdjacentTriangleIndex);
						}
					}
				}
			};

			NumGroups++;
		}
	};

	return NumGroups;
}
Example #9
0
static void server_rcon_HandleLogin( int iCandidateIndex, const char *pszHash )
{
	// If there's no slot, the candidate must have timed out, or is hacking. Bye!
	if ( iCandidateIndex == -1 )
		return;

	// Combine the salt and password, and hash it.
	FString fsString, fsCorrectHash;
	fsString.Format( "%s%s", g_Candidates[iCandidateIndex].szSalt, sv_rconpassword.GetGenericRep(CVAR_String).String );	
	CMD5Checksum::GetMD5( reinterpret_cast<const BYTE *>(fsString.GetChars()), fsString.Len(), fsCorrectHash );

	// Compare that to what he sent us.
	// Printf("Mine: %s\nTheirs: %s\n", fsCorrectHash, pszHash );
	NETWORK_ClearBuffer( &g_MessageBuffer );
	// [BB] Do not allow the server to let anybody use RCON in case sv_rconpassword is empty.
	if ( fsCorrectHash.Compare( pszHash ) || ( strlen( sv_rconpassword.GetGenericRep(CVAR_String).String ) == 0 ) )
	{
		// Wrong password.
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_INVALIDPASSWORD );
		NETWORK_LaunchPacket( &g_MessageBuffer, g_Candidates[iCandidateIndex].Address ); // [RC] Note: Be sure to finish any packets before calling Printf(). Otherwise SERVER_RCON_Print will clear your buffer.

		// To prevent mass password flooding, ignore the IP for a few seconds.
		g_BadRequestFloodQueue.addAddress( g_Candidates[iCandidateIndex].Address, gametic / 1000 );

		Printf( "Failed RCON login from %s. Ignoring IP for 10 seconds...\n", NETWORK_AddressToString( g_Candidates[iCandidateIndex].Address ));
	}
	else
	{		
		// [BB] Since we log when RCON clients disconnect, we should also log when they connect.
		// Do this before we do anything else so that this message is sent to the new RCON client
		// with the console history.
		Printf( "RCON client at %s connected.\n", NETWORK_AddressToString( g_Candidates[iCandidateIndex].Address ));

		// Correct password. Promote him to an authed client.
		RCONCLIENT_s Client;
		Client.Address = g_Candidates[iCandidateIndex].Address;
		Client.iLastMessageTic = gametic;
		g_AuthedClients.Push( Client );

		NETWORK_ClearBuffer( &g_MessageBuffer );
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_LOGGEDIN );

		// Tell him some info about the server.
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, PROTOCOL_VERSION );
		NETWORK_WriteString( &g_MessageBuffer.ByteStream, sv_hostname.GetGenericRep( CVAR_String ).String );
		
		// Send updates.
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, NUM_RCON_UPDATES );
		for ( int i = 0; i < NUM_RCON_UPDATES; i++ )
			server_WriteUpdateInfo( &g_MessageBuffer.ByteStream, i );

		// Send the console history.
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, g_RecentConsoleLines.size() );
		for( std::list<FString>::iterator i = g_RecentConsoleLines.begin(); i != g_RecentConsoleLines.end(); ++i )
			NETWORK_WriteString( &g_MessageBuffer.ByteStream, *i );

		NETWORK_LaunchPacket( &g_MessageBuffer, g_Candidates[iCandidateIndex].Address );
		SERVER_RCON_UpdateInfo( SVRCU_ADMINCOUNT );
	}

	// Remove his temporary slot.	
	g_Candidates.Delete( iCandidateIndex );
}
Example #10
0
void InitThingdef()
{
	PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor));

	PStruct *sstruct = NewNativeStruct("Sector", nullptr);
	auto sptr = NewPointer(sstruct);
	sstruct->AddNativeField("soundtarget", TypeActor, myoffsetof(sector_t, SoundTarget));
	
	// expose the global validcount variable.
	PField *vcf = new PField("validcount", TypeSInt32, VARF_Native | VARF_Static, (intptr_t)&validcount);
	GlobalSymbols.AddSymbol(vcf);

	// expose the global Multiplayer variable.
	PField *multif = new PField("multiplayer", TypeBool, VARF_Native | VARF_ReadOnly | VARF_Static, (intptr_t)&multiplayer);
	GlobalSymbols.AddSymbol(multif);

	// set up a variable for the global level data structure
	PStruct *lstruct = NewNativeStruct("LevelLocals", nullptr);
	PField *levelf = new PField("level", lstruct, VARF_Native | VARF_Static, (intptr_t)&level);
	GlobalSymbols.AddSymbol(levelf);

	// set up a variable for the DEH data
	PStruct *dstruct = NewNativeStruct("DehInfo", nullptr);
	PField *dehf = new PField("deh", dstruct, VARF_Native | VARF_Static, (intptr_t)&deh);

	GlobalSymbols.AddSymbol(dehf);

	// set up a variable for the global players array.
	PStruct *pstruct = NewNativeStruct("PlayerInfo", nullptr);
	pstruct->Size = sizeof(player_t);
	pstruct->Align = alignof(player_t);
	PArray *parray = NewArray(pstruct, MAXPLAYERS);
	PField *playerf = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players);
	GlobalSymbols.AddSymbol(playerf);

	// set up the lines array in the sector struct. This is a bit messy because the type system is not prepared to handle a pointer to an array of pointers to a native struct even remotely well...
	// As a result, the size has to be set to something large and arbritrary because it can change between maps. This will need some serious improvement when things get cleaned up.
	pstruct = NewNativeStruct("Sector", nullptr);
	pstruct->AddNativeField("lines", NewPointer(NewArray(NewPointer(NewNativeStruct("line", nullptr), false), 0x40000), false), myoffsetof(sector_t, lines), VARF_Native);

	parray = NewArray(TypeBool, MAXPLAYERS);
	playerf = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame);
	GlobalSymbols.AddSymbol(playerf);

	playerf = new PField("gameaction", TypeUInt8, VARF_Native | VARF_Static, (intptr_t)&gameaction);
	GlobalSymbols.AddSymbol(playerf);

	playerf = new PField("consoleplayer", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&consoleplayer);
	GlobalSymbols.AddSymbol(playerf);

	// Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but it used everywhere as a special flag.
	// It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution'
	// is to create a static variable from it and reference that in the script. Yuck!!!
	static AWeapon *wpnochg = WP_NOCHANGE;
	playerf = new PField("WP_NOCHANGE", NewPointer(RUNTIME_CLASS(AWeapon), false), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&wpnochg);
	GlobalSymbols.AddSymbol(playerf);

	// this needs to be done manually until it can be given a proper type.
	RUNTIME_CLASS(AActor)->AddNativeField("DecalGenerator", NewPointer(TypeVoid), myoffsetof(AActor, DecalGenerator));

	// synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them.
	for (auto &fl : FlagLists)
	{
		if (fl.Use & 2)
		{
			for(int i=0;i<fl.NumDefs;i++)
			{
				if (fl.Defs[i].structoffset > 0) // skip the deprecated entries in this list
				{
					const_cast<PClass*>(*fl.Type)->AddNativeField(FStringf("b%s", fl.Defs[i].name), (fl.Defs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), fl.Defs[i].structoffset, fl.Defs[i].varflags, fl.Defs[i].flagbit);
				}
			}
		}
	}

	FAutoSegIterator probe(CRegHead, CRegTail);

	while (*++probe != NULL)
	{
		if (((ClassReg *)*probe)->InitNatives)
			((ClassReg *)*probe)->InitNatives();
	}

	// Sort the flag lists
	for (size_t i = 0; i < NUM_FLAG_LISTS; ++i)
	{
		qsort (FlagLists[i].Defs, FlagLists[i].NumDefs, sizeof(FFlagDef), flagcmp);
	}

	// Create a sorted list of properties
	if (properties.Size() == 0)
	{
		FAutoSegIterator probe(GRegHead, GRegTail);

		while (*++probe != NULL)
		{
			properties.Push((FPropertyInfo *)*probe);
		}
		properties.ShrinkToFit();
		qsort(&properties[0], properties.Size(), sizeof(properties[0]), propcmp);
	}

	// Create a sorted list of native action functions
	AFTable.Clear();
	if (AFTable.Size() == 0)
	{
		FAutoSegIterator probe(ARegHead, ARegTail);

		while (*++probe != NULL)
		{
			AFuncDesc *afunc = (AFuncDesc *)*probe;
			assert(afunc->VMPointer != NULL);
			*(afunc->VMPointer) = new VMNativeFunction(afunc->Function, afunc->FuncName);
			(*(afunc->VMPointer))->PrintableName.Format("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName);
			AFTable.Push(*afunc);
		}
		AFTable.ShrinkToFit();
		qsort(&AFTable[0], AFTable.Size(), sizeof(AFTable[0]), funccmp);
	}

	FieldTable.Clear();
	if (FieldTable.Size() == 0)
	{
		FAutoSegIterator probe(FRegHead, FRegTail);

		while (*++probe != NULL)
		{
			FieldDesc *afield = (FieldDesc *)*probe;
			FieldTable.Push(*afield);
		}
		FieldTable.ShrinkToFit();
		qsort(&FieldTable[0], FieldTable.Size(), sizeof(FieldTable[0]), fieldcmp);
	}

}
/** Creates a vertex element list for the D3D9MeshUtils vertex format. */
static void GetD3D9MeshVertexDeclarations(TArray<D3DVERTEXELEMENT9>& OutVertexElements)
{
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,Position), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,UVs[0]), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,UVs[1]), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,UVs[2]), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,UVs[3]), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,UVs[4]), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,UVs[5]), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 5));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,UVs[6]), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 6));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,UVs[7]), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 7));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,Color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,SmoothingMask), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,TangentX), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,TangentY), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0));
	OutVertexElements.Push(ConstructD3DVertexElement(0, STRUCT_OFFSET(FUtilVertex,TangentZ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0));
	OutVertexElements.Push(ConstructD3DVertexElement(0xFF,0,D3DDECLTYPE_UNUSED,0,0,0));
}
Example #12
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);
}
Example #13
0
void FMapInfoParser::ParseSkill ()
{
	FSkillInfo skill;

	skill.AmmoFactor = FRACUNIT;
	skill.DoubleAmmoFactor = 2*FRACUNIT;
	skill.DropAmmoFactor = -1;
	skill.DamageFactor = FRACUNIT;
	skill.FastMonsters = false;
	skill.DisableCheats = false;
	skill.EasyBossBrain = false;
	skill.AutoUseHealth = false;
	skill.RespawnCounter = 0;
	skill.RespawnLimit = 0;
	skill.Aggressiveness = FRACUNIT;
	skill.SpawnFilter = 0;
	skill.ACSReturn = AllSkills.Size();
	skill.MenuNameIsLump = false;
	skill.MustConfirm = false;
	skill.Shortcut = 0;
	skill.TextColor = "";

	sc.MustGetString();
	skill.Name = sc.String;

	ParseOpenBrace();

	while (sc.GetString ())
	{
		if (sc.Compare ("ammofactor"))
		{
			ParseAssign();
			sc.MustGetFloat ();
			skill.AmmoFactor = FLOAT2FIXED(sc.Float);
		}
		else if (sc.Compare ("doubleammofactor"))
		{
			ParseAssign();
			sc.MustGetFloat ();
			skill.DoubleAmmoFactor = FLOAT2FIXED(sc.Float);
		}
		else if (sc.Compare ("dropammofactor"))
		{
			ParseAssign();
			sc.MustGetFloat ();
			skill.DropAmmoFactor = FLOAT2FIXED(sc.Float);
		}
		else if (sc.Compare ("damagefactor"))
		{
			ParseAssign();
			sc.MustGetFloat ();
			skill.DamageFactor = FLOAT2FIXED(sc.Float);
		}
		else if (sc.Compare ("fastmonsters"))
		{
			skill.FastMonsters = true;
		}
		else if (sc.Compare ("disablecheats"))
		{
			skill.DisableCheats = true;
		}
		else if (sc.Compare ("easybossbrain"))
		{
			skill.EasyBossBrain = true;
		}
		else if (sc.Compare("autousehealth"))
		{
			skill.AutoUseHealth = true;
		}
		else if (sc.Compare("respawntime"))
		{
			ParseAssign();
			sc.MustGetFloat ();
			skill.RespawnCounter = int(sc.Float*TICRATE);
		}
		else if (sc.Compare("respawnlimit"))
		{
			ParseAssign();
			sc.MustGetNumber ();
			skill.RespawnLimit = sc.Number;
		}
		else if (sc.Compare("Aggressiveness"))
		{
			ParseAssign();
			sc.MustGetFloat ();
			skill.Aggressiveness = FRACUNIT - FLOAT2FIXED(clamp(sc.Float, 0.,1.));
		}
		else if (sc.Compare("SpawnFilter"))
		{
			ParseAssign();
			if (sc.CheckNumber())
			{
				if (sc.Number > 0) skill.SpawnFilter |= (1<<(sc.Number-1));
			}
			else
			{
				sc.MustGetString ();
				if (sc.Compare("baby")) skill.SpawnFilter |= 1;
				else if (sc.Compare("easy")) skill.SpawnFilter |= 2;
				else if (sc.Compare("normal")) skill.SpawnFilter |= 4;
				else if (sc.Compare("hard")) skill.SpawnFilter |= 8;
				else if (sc.Compare("nightmare")) skill.SpawnFilter |= 16;
			}
		}
		else if (sc.Compare("ACSReturn"))
		{
			ParseAssign();
			sc.MustGetNumber ();
			skill.ACSReturn = sc.Number;
		}
		else if (sc.Compare("Name"))
		{
			ParseAssign();
			sc.MustGetString ();
			skill.MenuName = sc.String;
			skill.MenuNameIsLump = false;
		}
		else if (sc.Compare("PlayerClassName"))
		{
			ParseAssign();
			sc.MustGetString ();
			FName pc = sc.String;
			ParseComma();
			sc.MustGetString ();
			skill.MenuNamesForPlayerClass[pc]=sc.String;
		}
		else if (sc.Compare("PicName"))
		{
			ParseAssign();
			sc.MustGetString ();
			skill.MenuName = sc.String;
			skill.MenuNameIsLump = true;
		}
		else if (sc.Compare("MustConfirm"))
		{
			skill.MustConfirm = true;
			if (format_type == FMT_New) 
			{
				if (CheckAssign())
				{
					sc.MustGetString();
					skill.MustConfirmText = sc.String;
				}
			}
			else
			{
				if (sc.CheckToken(TK_StringConst))
				{
					skill.MustConfirmText = sc.String;
				}
			}
		}
		else if (sc.Compare("Key"))
		{
			ParseAssign();
			sc.MustGetString();
			skill.Shortcut = tolower(sc.String[0]);
		}
		else if (sc.Compare("TextColor"))
		{
			ParseAssign();
			sc.MustGetString();
			skill.TextColor.Format("[%s]", sc.String);
		}
		else if (!ParseCloseBrace())
		{
			// Unknown
			sc.ScriptMessage("Unknown property '%s' found in skill definition\n", sc.String);
			SkipToNext();
		}
		else
		{
			break;
		}
	}
	CheckEndOfFile("skill");
	for(unsigned int i = 0; i < AllSkills.Size(); i++)
	{
		if (AllSkills[i].Name == skill.Name)
		{
			AllSkills[i] = skill;
			return;
		}
	}
	AllSkills.Push(skill);
}
Example #14
0
static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defaults, Baggage &bag)
{
	static TArray<FPropParam> params;
	static TArray<FString> strings;

	params.Clear();
	strings.Clear();
	params.Reserve(1);
	params[0].i = 0;
	if (prop->params[0] != '0')
	{
		const char * p = prop->params;
		bool nocomma;
		bool optcomma;
		while (*p)
		{
			FPropParam conv;
			FPropParam pref;

			nocomma = false;
			conv.s = NULL;
			pref.s = NULL;
			pref.i = -1;
			bag.ScriptPosition = sc;
			switch ((*p) & 223)
			{
			case 'X':	// Expression in parentheses or number.
				{
					FxExpression *x = NULL;

					if (sc.CheckString ("("))
					{
						x = new FxDamageValue(new FxIntCast(ParseExpression(sc, bag.Info)), true);
						sc.MustGetStringName(")");
					}
					else
					{
						sc.MustGetNumber();
						if (sc.Number != 0)
						{
							x = new FxDamageValue(new FxConstant(sc.Number, bag.ScriptPosition), false);
						}
					}
					conv.exp = x;
					params.Push(conv);
				}
				break;

			case 'I':
				sc.MustGetNumber();
				conv.i = sc.Number;
				break;

			case 'F':
				sc.MustGetFloat();
				conv.d = sc.Float;
				break;

			case 'Z':	// an optional string. Does not allow any numerical value.
				if (sc.CheckFloat())
				{
					nocomma = true;
					sc.UnGet();
					break;
				}
				// fall through

			case 'S':
				sc.MustGetString();
				conv.s = strings[strings.Reserve(1)] = sc.String;
				break;

			case 'T':
				sc.MustGetString();
				conv.s = strings[strings.Reserve(1)] = strbin1(sc.String);
				break;

			case 'C':
				if (sc.CheckNumber ())
				{
					int R, G, B;
					R = clamp (sc.Number, 0, 255);
					sc.CheckString (",");
					sc.MustGetNumber ();
					G = clamp (sc.Number, 0, 255);
					sc.CheckString (",");
					sc.MustGetNumber ();
					B = clamp (sc.Number, 0, 255);
					conv.i = MAKERGB(R, G, B);
					pref.i = 0;
				}
				else
				{
					sc.MustGetString ();
					conv.s = strings[strings.Reserve(1)] = sc.String;
					pref.i = 1;
				}
				break;

			case 'M':	// special case. An expression-aware parser will not need this.
				conv.i = ParseMorphStyle(sc);
				break;
				
			case 'N':	// special case. An expression-aware parser will not need this.
				conv.i = ParseThingActivation(sc);
				break;

			case 'L':	// Either a number or a list of strings
				if (sc.CheckNumber())
				{
					pref.i = 0;
					conv.i = sc.Number;
				}
				else
				{
					pref.i = 1;
					params.Push(pref);
					params[0].i++;

					do
					{
						sc.MustGetString ();
						conv.s = strings[strings.Reserve(1)] = sc.String;
						params.Push(conv);
						params[0].i++;
					}
					while (sc.CheckString(","));
					goto endofparm;
				}
				break;

			default:
				assert(false);
				break;

			}
			if (pref.i != -1)
			{
				params.Push(pref);
				params[0].i++;
			}
			params.Push(conv);
			params[0].i++;
		endofparm:
			p++;
			// Hack for some properties that have to allow comma less
			// parameter lists for compatibility.
			if ((optcomma = (*p == '_'))) 
				p++;

			if (nocomma) 
			{
				continue;
			}
			else if (*p == 0) 
			{
				break;
			}
			else if (*p >= 'a')
			{
				if (!sc.CheckString(","))
				{
					if (optcomma)
					{
						if (!sc.CheckFloat()) break;
						else sc.UnGet();
					}
					else break;
				}
			}
			else 
			{
				if (!optcomma) sc.MustGetStringName(",");
				else sc.CheckString(",");
			}
		}
	}
	// call the handler
	try
	{
		prop->Handler(defaults, bag.Info, bag, &params[0]);
	}
	catch (CRecoverableError &error)
	{
		sc.ScriptError("%s", error.GetMessage());
	}

	return true;
}
Example #15
0
void gl_InitPortals()
{
	FPortalMap collection;

	if (level.nodes.Size() == 0) return;

	
	CollectPortalSectors(collection);
	glSectorPortals.Clear();

	FPortalMap::Iterator it(collection);
	FPortalMap::Pair *pair;
	int c = 0;
	int planeflags = 0;
	while (it.NextPair(pair))
	{
		for(unsigned i=0;i<pair->Value.Size(); i++)
		{
			if (pair->Value[i].mPlane == sector_t::floor) planeflags |= 1;
			else if (pair->Value[i].mPlane == sector_t::ceiling) planeflags |= 2;
		}
		for (int i=1;i<=2;i<<=1)
		{
			// add separate glSectorPortals for floor and ceiling.
			if (planeflags & i)
			{
				FPortal *portal = new FPortal;
				portal->mDisplacement = pair->Key.mDisplacement;
				portal->plane = (i==1? sector_t::floor : sector_t::ceiling);	/**/
				portal->glportal = NULL;
				glSectorPortals.Push(portal);
				for(unsigned j=0;j<pair->Value.Size(); j++)
				{
					sector_t *sec = pair->Value[j].mSub;
					int plane = pair->Value[j].mPlane;
					if (portal->plane == plane)
					{
						for(int k=0;k<sec->subsectorcount; k++)
						{
							subsector_t *sub = sec->subsectors[k];
							gl_BuildPortalCoverage(&sub->portalcoverage[plane], sub, pair->Key.mDisplacement);
						}
						sec->portals[plane] = portal;
					}
				}
			}
		}
	}

	// Now group the line glSectorPortals (each group must be a continuous set of colinear linedefs with no gaps)
	glLinePortals.Clear();
	linePortalToGL.Clear();
	TArray<int> tempindex;

	tempindex.Reserve(linePortals.Size());
	memset(&tempindex[0], -1, linePortals.Size() * sizeof(int));

	for (unsigned i = 0; i < linePortals.Size(); i++)
	{
		auto port = linePortals[i];
		bool gotsome;

		if (tempindex[i] == -1)
		{
			tempindex[i] = glLinePortals.Size();
			line_t *pSrcLine = linePortals[i].mOrigin;
			line_t *pLine = linePortals[i].mDestination;
			FGLLinePortal &glport = glLinePortals[glLinePortals.Reserve(1)];
			glport.lines.Push(&linePortals[i]);

			// We cannot do this grouping for non-linked glSectorPortals because they can be changed at run time.
			if (linePortals[i].mType == PORTT_LINKED && pLine != nullptr)
			{
				glport.v1 = pLine->v1;
				glport.v2 = pLine->v2;
				do
				{
					// now collect all other colinear lines connected to this one. We run this loop as long as it still finds a match
					gotsome = false;
					for (unsigned j = 0; j < linePortals.Size(); j++)
					{
						if (tempindex[j] == -1)
						{
							line_t *pSrcLine2 = linePortals[j].mOrigin;
							line_t *pLine2 = linePortals[j].mDestination;
							// angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical glSectorPortals aren't found here.)
							unsigned srcang = pSrcLine->Delta().Angle().BAMs();
							unsigned dstang = pLine->Delta().Angle().BAMs();
							if ((pSrcLine->v2 == pSrcLine2->v1 && pLine->v1 == pLine2->v2) ||
								(pSrcLine->v1 == pSrcLine2->v2 && pLine->v2 == pLine2->v1))
							{
								// The line connects, now check the translation
								unsigned srcang2 = pSrcLine2->Delta().Angle().BAMs();
								unsigned dstang2 = pLine2->Delta().Angle().BAMs();
								if (srcang == srcang2 && dstang == dstang2)
								{
									// The lines connect and  both source and destination are colinear, so this is a match
									gotsome = true;
									tempindex[j] = tempindex[i];
									if (pLine->v1 == pLine2->v2) glport.v1 = pLine2->v1;
									else glport.v2 = pLine2->v2;
									glport.lines.Push(&linePortals[j]);
								}
							}
						}
					}
				} while (gotsome);
			}
		}
	}
	linePortalToGL.Resize(linePortals.Size());
	for (unsigned i = 0; i < linePortals.Size(); i++)
	{
		linePortalToGL[i] = &glLinePortals[tempindex[i]];
		/*
		Printf("portal at line %d translates to GL portal %d, range = %f,%f to %f,%f\n",
			int(linePortals[i].mOrigin - lines), tempindex[i], linePortalToGL[i]->v1->fixX() / 65536., linePortalToGL[i]->v1->fixY() / 65536., linePortalToGL[i]->v2->fixX() / 65536., linePortalToGL[i]->v2->fixY() / 65536.);
		*/
	}
}
Example #16
0
void MapLoader::PO_Init (void)
{
	int NumPolyobjs = 0;
	TArray<FMapThing *> polythings;
	for (auto &mthing : MapThingsConverted)
	{
		if (mthing.EdNum == 0 || mthing.EdNum == -1 || mthing.info == nullptr) continue;

		FDoomEdEntry *mentry = mthing.info;
		switch (mentry->Special)
		{
		case SMT_PolyAnchor:
		case SMT_PolySpawn:
		case SMT_PolySpawnCrush:
		case SMT_PolySpawnHurt:
			polythings.Push(&mthing);
			if (mentry->Special != SMT_PolyAnchor)
				NumPolyobjs++;
		}
	}

	int polyIndex;

	// [RH] Make this faster
	InitSideLists ();

	Level->Polyobjects.Resize(NumPolyobjs);
	for (auto &po : Level->Polyobjects) po.Level = Level;	// must be done before the init loop below.

	polyIndex = 0; // index polyobj number
	// Find the startSpot points, and spawn each polyobj
	for (int i=polythings.Size()-1; i >= 0; i--)
	{
		// 9301 (3001) = no crush, 9302 (3002) = crushing, 9303 = hurting touch
		int type = polythings[i]->info->Special;
		if (type >= SMT_PolySpawn && type <= SMT_PolySpawnHurt)
		{ 
			// Polyobj StartSpot Pt.
			Level->Polyobjects[polyIndex].StartSpot.pos = polythings[i]->pos;
			SpawnPolyobj(polyIndex, polythings[i]->angle, type);
			polyIndex++;
		} 
	}
	for (int i = polythings.Size() - 1; i >= 0; i--)
	{
		int type = polythings[i]->info->Special;
		if (type == SMT_PolyAnchor)
		{ 
			// Polyobj Anchor Pt.
			TranslateToStartSpot (polythings[i]->angle, polythings[i]->pos);
		}
	}

	// check for a startspot without an anchor point
	for (auto &poly : Level->Polyobjects)
	{
		if (poly.OriginalPts.Size() == 0)
		{
			Printf (TEXTCOLOR_RED "PO_Init: StartSpot located without an Anchor point: %d\n", poly.tag);
		}
	}
	InitPolyBlockMap();

	// [RH] Don't need the side lists anymore
	KnownPolySides.Reset();

	// mark all subsectors which have a seg belonging to a polyobj
	// These ones should not be rendered on the textured automap.
	for (auto &ss : Level->subsectors)
	{
		for(uint32_t j=0;j<ss.numlines; j++)
		{
			if (ss.firstline[j].sidedef != NULL &&
				ss.firstline[j].sidedef->Flags & WALLF_POLYOBJ)
			{
				ss.flags |= SSECF_POLYORG;
				break;
			}
		}
	}
	// clear all polyobj specials so that they do not obstruct using other lines.
	for (auto &line : Level->lines)
	{
		if (line.special == Polyobj_ExplicitLine || line.special == Polyobj_StartLine)
		{
			line.special = 0;
		}
	}
}
void USoundCue::PostLoad()
{
	Super::PostLoad();

	// Game doesn't care if there are NULL graph nodes
#if WITH_EDITOR
	if (GIsEditor )
	{
		if (SoundCueGraph)
		{
			// Deal with SoundNode types being removed - iterate in reverse as nodes may be removed
			for (int32 idx = SoundCueGraph->Nodes.Num() - 1; idx >= 0; --idx)
			{
				USoundCueGraphNode* Node = Cast<USoundCueGraphNode>(SoundCueGraph->Nodes[idx]);

				if (Node && Node->SoundNode == NULL)
				{
					FBlueprintEditorUtils::RemoveNode(NULL, Node, true);
				}
			}
		}
		else
		{
			// we should have a soundcuegraph unless we are contained in a package which is missing editor only data
			check( GetOutermost()->HasAnyPackageFlags(PKG_FilterEditorOnly) );
		}

		// Always load all sound waves in the editor
		for (USoundNode* SoundNode : AllNodes)
		{
			if (USoundNodeAssetReferencer* AssetReferencerNode = Cast<USoundNodeAssetReferencer>(SoundNode))
			{
				AssetReferencerNode->LoadAsset();
			}
		}
	}
	else
#endif
	{
		TArray<USoundNode*> NodesToEvaluate;
		NodesToEvaluate.Push(FirstNode);

		while (NodesToEvaluate.Num() > 0)
		{
			if (USoundNode* SoundNode = NodesToEvaluate.Pop(false))
			{
				if (USoundNodeAssetReferencer* AssetReferencerNode = Cast<USoundNodeAssetReferencer>(SoundNode))
				{
					AssetReferencerNode->LoadAsset();
				}
				else if (USoundNodeQualityLevel* QualityLevelNode = Cast<USoundNodeQualityLevel>(SoundNode))
				{
					// Only pick the node connected for current quality, currently don't support changing audio quality on the fly
					static const int32 CachedQualityLevel = GEngine->GetGameUserSettings()->GetAudioQualityLevel();
					if (CachedQualityLevel < QualityLevelNode->ChildNodes.Num())
					{
						NodesToEvaluate.Add(QualityLevelNode->ChildNodes[CachedQualityLevel]);
					}
				}
				else
				{
					NodesToEvaluate.Append(SoundNode->ChildNodes);
				}
			}
		}
	}
}
Example #18
0
static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
{
	FScriptPosition scpos(sc);
	if (sc.CheckToken('('))
	{
		FxExpression *data = ParseExpressionM (sc, cls);
		sc.MustGetToken(')');
		return data;
	}
	else if (sc.CheckToken(TK_True))
	{
		return new FxConstant(1, scpos);
	}
	else if (sc.CheckToken(TK_False))
	{
		return new FxConstant(0, scpos);
	}
	else if (sc.CheckToken(TK_IntConst))
	{
		return new FxConstant(sc.Number, scpos);
	}
	else if (sc.CheckToken(TK_FloatConst))
	{
		return new FxConstant(sc.Float, scpos);
	}
	else if (sc.CheckToken(TK_NameConst))
	{
		return new FxConstant(sc.Name, scpos);
	}
	else if (sc.CheckToken(TK_StringConst))
	{
		// String parameters are converted to names. Technically, this should be
		// done at a higher level, as needed, but since no functions take string
		// arguments and ACS_NamedExecuteWithResult/CallACS need names, this is
		// a cheap way to get them working when people use "name" instead of 'name'.
		return new FxConstant(FName(sc.String), scpos);
	}
	else if (sc.CheckToken(TK_Random))
	{
		FRandom *rng;

		if (sc.CheckToken('['))
		{
			sc.MustGetToken(TK_Identifier);
			rng = FRandom::StaticFindRNG(sc.String);
			sc.MustGetToken(']');
		}
		else
		{
			rng = &pr_exrandom;
		}
		sc.MustGetToken('(');

		FxExpression *min = ParseExpressionM (sc, cls);
		sc.MustGetToken(',');
		FxExpression *max = ParseExpressionM (sc, cls);
		sc.MustGetToken(')');

		return new FxRandom(rng, min, max, sc);
	}
	else if (sc.CheckToken(TK_RandomPick) || sc.CheckToken(TK_FRandomPick))
	{
		bool floaty = sc.TokenType == TK_FRandomPick;
		FRandom *rng;
		TArray<FxExpression*> list;
		list.Clear();
		int index = 0;

		if (sc.CheckToken('['))
		{
			sc.MustGetToken(TK_Identifier);
			rng = FRandom::StaticFindRNG(sc.String);
			sc.MustGetToken(']');
		}
		else
		{
			rng = &pr_exrandom;
		}
		sc.MustGetToken('(');

		for (;;)
		{
			FxExpression *expr = ParseExpressionM(sc, cls);
			list.Push(expr);
			if (sc.CheckToken(')'))
				break;
			sc.MustGetToken(',');
		}
		return new FxRandomPick(rng, list, floaty, sc);
	}
	else if (sc.CheckToken(TK_FRandom))
	{
		FRandom *rng;

		if (sc.CheckToken('['))
		{
			sc.MustGetToken(TK_Identifier);
			rng = FRandom::StaticFindRNG(sc.String);
			sc.MustGetToken(']');
		}
		else
		{
			rng = &pr_exrandom;
		}
		sc.MustGetToken('(');

		FxExpression *min = ParseExpressionM (sc, cls);
		sc.MustGetToken(',');
		FxExpression *max = ParseExpressionM (sc, cls);
		sc.MustGetToken(')');

		return new FxFRandom(rng, min, max, sc);
	}
	else if (sc.CheckToken(TK_Random2))
	{
		FRandom *rng;

		if (sc.CheckToken('['))
		{
			sc.MustGetToken(TK_Identifier);
			rng = FRandom::StaticFindRNG(sc.String);
			sc.MustGetToken(']');
		}
		else
		{
			rng = &pr_exrandom;
		}

		sc.MustGetToken('(');

		FxExpression *mask = NULL;

		if (!sc.CheckToken(')'))
		{
			mask = ParseExpressionM(sc, cls);
			sc.MustGetToken(')');
		}
		return new FxRandom2(rng, mask, sc);
	}
	else if (sc.CheckToken(TK_Abs))
	{
		sc.MustGetToken('(');
		FxExpression *x = ParseExpressionM (sc, cls);
		sc.MustGetToken(')');
		return new FxAbs(x); 
	}
	else if (sc.CheckToken(TK_Identifier))
	{
		FName identifier = FName(sc.String);
		if (sc.CheckToken('('))
		{
			FArgumentList *args = new FArgumentList;
			PFunction *func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
			try
			{
				if (func != NULL)
				{
					sc.UnGet();
					ParseFunctionParameters(sc, cls, *args, func, "", NULL);
					return new FxVMFunctionCall(func, args, sc);
				}
				else if (!sc.CheckToken(')'))
				{
					do
					{
						args->Push(ParseExpressionM (sc, cls));
					}
					while (sc.CheckToken(','));
					sc.MustGetToken(')');
				}
				return new FxFunctionCall(NULL, identifier, args, sc);
			}
			catch (...)
			{
				delete args;
				throw;
			}
		}	
		else
		{
			return new FxIdentifier(identifier, sc);
		}
	}
	else
	{
		FString tokname = sc.TokenName(sc.TokenType, sc.String);
		sc.ScriptError ("Unexpected token %s", tokname.GetChars());
	}
	return NULL;
}
Example #19
0
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);
	}
}
	FExpressionResult Evaluate(const TArray<FCompiledToken>& CompiledTokens, const IOperatorEvaluationEnvironment& InEnvironment)
	{
		// Evaluation strategy: the supplied compiled tokens are const. To avoid copying the whole array, we store a separate array of
		// any tokens that are generated at runtime by the evaluator. The operand stack will consist of indices into either the CompiledTokens
		// array, or the RuntimeGeneratedTokens (where Index >= CompiledTokens.Num())
		TArray<FExpressionToken> RuntimeGeneratedTokens;
		TArray<int32> OperandStack;

		/** Get the token pertaining to the specified operand index */
		auto GetToken = [&](int32 Index) -> const FExpressionToken& {
			if (Index < CompiledTokens.Num())
			{
				return CompiledTokens[Index];
			}

			return RuntimeGeneratedTokens[Index - CompiledTokens.Num()];
		};

		/** Add a new token to the runtime generated array */
		auto AddToken = [&](FExpressionToken&& In) -> int32 {
			auto Index = CompiledTokens.Num() + RuntimeGeneratedTokens.Num();
			RuntimeGeneratedTokens.Emplace(MoveTemp(In));
			return Index;
		};


		for (int32 Index = 0; Index < CompiledTokens.Num(); ++Index)
		{
			const auto& Token = CompiledTokens[Index];

			switch(Token.Type)
			{
			case FCompiledToken::Benign:
				continue;

			case FCompiledToken::Operand:
				OperandStack.Push(Index);
				continue;

			case FCompiledToken::BinaryOperator:
				if (OperandStack.Num() >= 2)
				{
					// Binary
					const auto& R = GetToken(OperandStack.Pop());
					const auto& L = GetToken(OperandStack.Pop());

					auto OpResult = InEnvironment.ExecBinary(Token, L, R);
					if (OpResult.IsValid())
					{
						// Inherit the LHS context
						OperandStack.Push(AddToken(FExpressionToken(L.Context, MoveTemp(OpResult.GetValue()))));
					}
					else
					{
						return MakeError(OpResult.GetError());
					}
				}
				else
				{
					FFormatOrderedArguments Args;
					Args.Add(FText::FromString(Token.Context.GetString()));
					return MakeError(FText::Format(LOCTEXT("SyntaxError_NotEnoughOperandsBinary", "Not enough operands for binary operator {0}"), Args));
				}
				break;
			
			case FCompiledToken::PostUnaryOperator:
			case FCompiledToken::PreUnaryOperator:

				if (OperandStack.Num() >= 1)
				{
					const auto& Operand = GetToken(OperandStack.Pop());

					FExpressionResult OpResult = (Token.Type == FCompiledToken::PreUnaryOperator) ?
						InEnvironment.ExecPreUnary(Token, Operand) :
						InEnvironment.ExecPostUnary(Token, Operand);

					if (OpResult.IsValid())
					{
						// Inherit the LHS context
						OperandStack.Push(AddToken(FExpressionToken(Operand.Context, MoveTemp(OpResult.GetValue()))));
					}
					else
					{
						return MakeError(OpResult.GetError());
					}			
				}
				else
				{
					FFormatOrderedArguments Args;
					Args.Add(FText::FromString(Token.Context.GetString()));
					return MakeError(FText::Format(LOCTEXT("SyntaxError_NoUnaryOperand", "No operand for unary operator {0}"), Args));
				}
				break;
			}
		}

		if (OperandStack.Num() == 1)
		{
			return MakeValue(GetToken(OperandStack[0]).Node.Copy());
		}

		return MakeError(LOCTEXT("SyntaxError_InvalidExpression", "Could not evaluate expression"));
	}
Example #21
0
	void CollectNode(void *node, TArray<FCoverageVertex> &shape)
	{
		static TArray<FCoverageLine> lists[2];
		const double COVERAGE_EPSILON = 6.;	// same epsilon as the node builder

		if (!((size_t)node & 1))  // Keep going until found a subsector
		{
			node_t *bsp = (node_t *)node;

			int centerside = R_PointOnSide(center.x, center.y, bsp);

			lists[0].Clear();
			lists[1].Clear();
			for(unsigned i=0;i<shape.Size(); i++)
			{
				FCoverageVertex *v1 = &shape[i];
				FCoverageVertex *v2 = &shape[(i+1) % shape.Size()];
				FCoverageLine vl = {{*v1, *v2}};

				double dist_v1 = PartitionDistance(v1, bsp);
				double dist_v2 = PartitionDistance(v2, bsp);

				if(dist_v1 <= COVERAGE_EPSILON)
				{
					if (dist_v2 <= COVERAGE_EPSILON)
					{
						lists[centerside].Push(vl);
					}
					else
					{
						int side = PointOnSide(v2, bsp);
						lists[side].Push(vl);
					}
				}
				else if (dist_v2 <= COVERAGE_EPSILON)
				{
					int side = PointOnSide(v1, bsp);
					lists[side].Push(vl);
				}
				else 
				{
					int side1 = PointOnSide(v1, bsp);
					int side2 = PointOnSide(v2, bsp);

					if(side1 != side2)
					{
						// if the partition line crosses this seg, we must split it.

						FCoverageVertex vert;

						if (GetIntersection(v1, v2, bsp, &vert))
						{
							lists[0].Push(vl);
							lists[1].Push(vl);
							lists[side1].Last().v[1] = vert;
							lists[side2].Last().v[0] = vert;
						}
						else
						{
							// should never happen
							lists[side1].Push(vl);
						}
					}
					else 
					{
						// both points on the same side.
						lists[side1].Push(vl);
					}
				}
			}
			if (lists[1].Size() == 0)
			{
				CollectNode(bsp->children[0], shape);
			}
			else if (lists[0].Size() == 0)
			{
				CollectNode(bsp->children[1], shape);
			}
			else
			{
				// copy the static arrays into local ones
				TArray<FCoverageVertex> locallists[2];

				for(int l=0;l<2;l++)
				{
					for (unsigned i=0;i<lists[l].Size(); i++)
					{
						locallists[l].Push(lists[l][i].v[0]);
						unsigned i1= (i+1)%lists[l].Size();
						if (lists[l][i1].v[0] != lists[l][i].v[1])
						{
							locallists[l].Push(lists[l][i].v[1]);
						}
					}
				}

				CollectNode(bsp->children[0], locallists[0]);
				CollectNode(bsp->children[1], locallists[1]);
			}
		}
		else
		{
			// we reached a subsector so we can link the node with this subsector
			subsector_t *sub = (subsector_t *)((BYTE *)node - 1);
			collect.Push(int(sub-subsectors));
		}
	}
Example #22
0
void R_InitSkins (void)
{
	FSoundID playersoundrefs[NUMSKINSOUNDS];
	spritedef_t temp;
	int sndlumps[NUMSKINSOUNDS];
	char key[65];
	DWORD intname, crouchname;
	size_t i;
	int j, k, base;
	int lastlump;
	int aliasid;
	bool remove;
	PClassPlayerPawn *basetype, *transtype;

	key[sizeof(key)-1] = 0;
	i = PlayerClasses.Size () - 1;
	lastlump = 0;

	for (j = 0; j < NUMSKINSOUNDS; ++j)
	{
		playersoundrefs[j] = skinsoundnames[j][1];
	}

	while ((base = Wads.FindLump ("S_SKIN", &lastlump, true)) != -1)
	{
		// The player sprite has 23 frames. This means that the S_SKIN
		// marker needs a minimum of 23 lumps after it.
		if (base >= Wads.GetNumLumps() - 23 || base == -1)
			continue;

		i++;
		for (j = 0; j < NUMSKINSOUNDS; j++)
			sndlumps[j] = -1;
		skins[i].namespc = Wads.GetLumpNamespace (base);

		FScanner sc(base);
		intname = 0;
		crouchname = 0;

		remove = false;
		basetype = NULL;
		transtype = NULL;

		// Data is stored as "key = data".
		while (sc.GetString ())
		{
			strncpy (key, sc.String, sizeof(key)-1);
			if (!sc.GetString() || sc.String[0] != '=')
			{
				Printf (PRINT_BOLD, "Bad format for skin %d: %s\n", (int)i, key);
				break;
			}
			sc.GetString ();
			if (0 == stricmp (key, "name"))
			{
				strncpy (skins[i].name, sc.String, 16);
				for (j = 0; (size_t)j < i; j++)
				{
					if (stricmp (skins[i].name, skins[j].name) == 0)
					{
						mysnprintf (skins[i].name, countof(skins[i].name), "skin%d", (int)i);
						Printf (PRINT_BOLD, "Skin %s duplicated as %s\n",
							skins[j].name, skins[i].name);
						break;
					}
				}
			}
			else if (0 == stricmp (key, "sprite"))
			{
				for (j = 3; j >= 0; j--)
					sc.String[j] = toupper (sc.String[j]);
				intname = *((DWORD *)sc.String);
			}
			else if (0 == stricmp (key, "crouchsprite"))
			{
				for (j = 3; j >= 0; j--)
					sc.String[j] = toupper (sc.String[j]);
				crouchname = *((DWORD *)sc.String);
			}
			else if (0 == stricmp (key, "face"))
			{
				for (j = 2; j >= 0; j--)
					skins[i].face[j] = toupper (sc.String[j]);
				skins[i].face[3] = '\0';
			}
			else if (0 == stricmp (key, "gender"))
			{
				skins[i].gender = D_GenderToInt (sc.String);
			}
			else if (0 == stricmp (key, "scale"))
			{
				skins[i].Scale.X = clamp(atof (sc.String), 1./65536, 256.);
				skins[i].Scale.Y = skins[i].Scale.X;
			}
			else if (0 == stricmp (key, "game"))
			{
				if (gameinfo.gametype == GAME_Heretic)
					basetype = dyn_cast<PClassPlayerPawn>(PClass::FindActor(NAME_HereticPlayer));
				else if (gameinfo.gametype == GAME_Strife)
					basetype = dyn_cast<PClassPlayerPawn>(PClass::FindActor(NAME_StrifePlayer));
				else
					basetype = dyn_cast<PClassPlayerPawn>(PClass::FindActor(NAME_DoomPlayer));

				transtype = basetype;

				if (stricmp (sc.String, "heretic") == 0)
				{
					if (gameinfo.gametype & GAME_DoomChex)
					{
						transtype = dyn_cast<PClassPlayerPawn>(PClass::FindActor(NAME_HereticPlayer));
						skins[i].othergame = true;
					}
					else if (gameinfo.gametype != GAME_Heretic)
					{
						remove = true;
					}
				}
				else if (stricmp (sc.String, "strife") == 0)
				{
					if (gameinfo.gametype != GAME_Strife)
					{
						remove = true;
					}
				}
				else
				{
					if (gameinfo.gametype == GAME_Heretic)
					{
						transtype = dyn_cast<PClassPlayerPawn>(PClass::FindActor(NAME_DoomPlayer));
						skins[i].othergame = true;
					}
					else if (!(gameinfo.gametype & GAME_DoomChex))
					{
						remove = true;
					}
				}

				if (remove)
					break;
			}
			else if (0 == stricmp (key, "class"))
			{ // [GRB] Define the skin for a specific player class
				int pclass = D_PlayerClassToInt (sc.String);

				if (pclass < 0)
				{
					remove = true;
					break;
				}

				basetype = transtype = PlayerClasses[pclass].Type;
			}
			else if (key[0] == '*')
			{ // Player sound replacment (ZDoom extension)
				int lump = Wads.CheckNumForName (sc.String, skins[i].namespc);
				if (lump == -1)
				{
					lump = Wads.CheckNumForFullName (sc.String, true, ns_sounds);
				}
				if (lump != -1)
				{
					if (stricmp (key, "*pain") == 0)
					{ // Replace all pain sounds in one go
						aliasid = S_AddPlayerSound (skins[i].name, skins[i].gender,
							playersoundrefs[0], lump, true);
						for (int l = 3; l > 0; --l)
						{
							S_AddPlayerSoundExisting (skins[i].name, skins[i].gender,
								playersoundrefs[l], aliasid, true);
						}
					}
					else
					{
						int sndref = S_FindSoundNoHash (key);
						if (sndref != 0)
						{
							S_AddPlayerSound (skins[i].name, skins[i].gender, sndref, lump, true);
						}
					}
				}
			}
			else
			{
				for (j = 0; j < NUMSKINSOUNDS; j++)
				{
					if (stricmp (key, skinsoundnames[j][0]) == 0)
					{
						sndlumps[j] = Wads.CheckNumForName (sc.String, skins[i].namespc);
						if (sndlumps[j] == -1)
						{ // Replacement not found, try finding it in the global namespace
							sndlumps[j] = Wads.CheckNumForFullName (sc.String, true, ns_sounds);
						}
					}
				}
				//if (j == 8)
				//	Printf ("Funny info for skin %i: %s = %s\n", i, key, sc.String);
			}
		}

		// [GRB] Assume Doom skin by default
		if (!remove && basetype == NULL)
		{
			if (gameinfo.gametype & GAME_DoomChex)
			{
				basetype = transtype = dyn_cast<PClassPlayerPawn>(PClass::FindActor(NAME_DoomPlayer));
			}
			else if (gameinfo.gametype == GAME_Heretic)
			{
				basetype = dyn_cast<PClassPlayerPawn>(PClass::FindActor(NAME_HereticPlayer));
				transtype = dyn_cast<PClassPlayerPawn>(PClass::FindActor(NAME_DoomPlayer));
				skins[i].othergame = true;
			}
			else
			{
				remove = true;
			}
		}

		if (!remove)
		{
			skins[i].range0start = transtype->ColorRangeStart;
			skins[i].range0end = transtype->ColorRangeEnd;

			remove = true;
			for (j = 0; j < (int)PlayerClasses.Size (); j++)
			{
				PClassPlayerPawn *type = PlayerClasses[j].Type;

				if (type->IsDescendantOf (basetype) &&
					GetDefaultByType(type)->SpawnState->sprite == GetDefaultByType(basetype)->SpawnState->sprite &&
					type->ColorRangeStart == basetype->ColorRangeStart &&
					type->ColorRangeEnd == basetype->ColorRangeEnd)
				{
					PlayerClasses[j].Skins.Push ((int)i);
					remove = false;
				}
			}
		}

		if (!remove)
		{
			if (skins[i].name[0] == 0)
				mysnprintf (skins[i].name, countof(skins[i].name), "skin%d", (int)i);

			// Now collect the sprite frames for this skin. If the sprite name was not
			// specified, use whatever immediately follows the specifier lump.
			if (intname == 0)
			{
				char name[9];
				Wads.GetLumpName (name, base+1);
				memcpy(&intname, name, 4);
			}

			int basens = Wads.GetLumpNamespace(base);

			for(int spr = 0; spr<2; spr++)
			{
				spriteframewithrotate sprtemp[MAX_SPRITE_FRAMES];
				memset (sprtemp, 0xFFFF, sizeof(sprtemp));
				for (k = 0; k < MAX_SPRITE_FRAMES; ++k)
				{
					sprtemp[k].Flip = 0;
					sprtemp[k].Voxel = NULL;
				}
				int maxframe = -1;

				if (spr == 1)
				{
					if (crouchname !=0 && crouchname != intname)
					{
						intname = crouchname;
					}
					else
					{
						skins[i].crouchsprite = -1;
						break;
					}
				}

				for (k = base + 1; Wads.GetLumpNamespace(k) == basens; k++)
				{
					char lname[9];
					DWORD lnameint;
					Wads.GetLumpName (lname, k);
					memcpy(&lnameint, lname, 4);
					if (lnameint == intname)
					{
						FTextureID picnum = TexMan.CreateTexture(k, FTexture::TEX_SkinSprite);
						bool res = R_InstallSpriteLump (picnum, lname[4] - 'A', lname[5], false, sprtemp, maxframe);

						if (lname[6] && res)
							R_InstallSpriteLump (picnum, lname[6] - 'A', lname[7], true, sprtemp, maxframe);
					}
				}

				if (spr == 0 && maxframe <= 0)
				{
					Printf (PRINT_BOLD, "Skin %s (#%d) has no frames. Removing.\n", skins[i].name, (int)i);
					remove = true;
					break;
				}

				Wads.GetLumpName (temp.name, base+1);
				temp.name[4] = 0;
				int sprno = (int)sprites.Push (temp);
				if (spr==0)	skins[i].sprite = sprno;
				else skins[i].crouchsprite = sprno;
				R_InstallSprite (sprno, sprtemp, maxframe);
			}
		}

		if (remove)
		{
			if (i < numskins-1)
				memmove (&skins[i], &skins[i+1], sizeof(skins[0])*(numskins-i-1));
			i--;
			continue;
		}

		// Register any sounds this skin provides
		aliasid = 0;
		for (j = 0; j < NUMSKINSOUNDS; j++)
		{
			if (sndlumps[j] != -1)
			{
				if (j == 0 || sndlumps[j] != sndlumps[j-1])
				{
					aliasid = S_AddPlayerSound (skins[i].name, skins[i].gender,
						playersoundrefs[j], sndlumps[j], true);
				}
				else
				{
					S_AddPlayerSoundExisting (skins[i].name, skins[i].gender,
						playersoundrefs[j], aliasid, true);
				}
			}
		}

		// Make sure face prefix is a full 3 chars
		if (skins[i].face[1] == 0 || skins[i].face[2] == 0)
		{
			skins[i].face[0] = 0;
		}
	}

	if (numskins > PlayerClasses.Size ())
	{ // The sound table may have changed, so rehash it.
		S_HashSounds ();
		S_ShrinkPlayerSoundLists ();
	}
}
Example #23
0
	void ProcessLineDefs()
	{
		int sidecount = 0;
		for(unsigned i = 0, skipped = 0; i < ParsedLines.Size();)
		{
			// Relocate the vertices
			intptr_t v1i = intptr_t(ParsedLines[i].v1);
			intptr_t v2i = intptr_t(ParsedLines[i].v2);

			if (v1i >= numvertexes || v2i >= numvertexes || v1i < 0 || v2i < 0)
			{
				I_Error ("Line %d has invalid vertices: %zd and/or %zd.\nThe map only contains %d vertices.", i+skipped, v1i, v2i, numvertexes);
			}
			else if (v1i == v2i ||
				(vertexes[v1i].x == vertexes[v2i].x && vertexes[v1i].y == vertexes[v2i].y))
			{
				Printf ("Removing 0-length line %d\n", i+skipped);
				ParsedLines.Delete(i);
				ForceNodeBuild = true;
				skipped++;
			}
			else
			{
				ParsedLines[i].v1 = &vertexes[v1i];
				ParsedLines[i].v2 = &vertexes[v2i];

				if (ParsedLines[i].sidedef[0] != NULL)
					sidecount++;
				if (ParsedLines[i].sidedef[1] != NULL)
					sidecount++;
				linemap.Push(i+skipped);
				i++;
			}
		}
		numlines = ParsedLines.Size();
		numsides = sidecount;
		lines = new line_t[numlines];
		sides = new side_t[numsides];
		int line, side;

		for(line = 0, side = 0; line < numlines; line++)
		{
			short tempalpha[2] = { SHRT_MIN, SHRT_MIN };

			lines[line] = ParsedLines[line];

			for(int sd = 0; sd < 2; sd++)
			{
				if (lines[line].sidedef[sd] != NULL)
				{
					int mapside = int(intptr_t(lines[line].sidedef[sd]))-1;
					if (mapside < sidecount)
					{
						sides[side] = ParsedSides[mapside];
						sides[side].linedef = &lines[line];
						sides[side].sector = &sectors[intptr_t(sides[side].sector)];
						lines[line].sidedef[sd] = &sides[side];

						P_ProcessSideTextures(!isExtended, &sides[side], sides[side].sector, &ParsedSideTextures[mapside],
							lines[line].special, lines[line].args[0], &tempalpha[sd], missingTex);

						side++;
					}
					else
					{
						lines[line].sidedef[sd] = NULL;
					}
				}
			}

			P_AdjustLine(&lines[line]);
			P_FinishLoadingLineDef(&lines[line], tempalpha[0]);
		}
		assert(side <= numsides);
		if (side < numsides)
		{
			Printf("Map had %d invalid side references\n", numsides - side);
			numsides = side;
		}
	}
Example #24
0
void InitThingdef()
{
	// Sort the flag lists
	for (size_t i = 0; i < NUM_FLAG_LISTS; ++i)
	{
		qsort (FlagLists[i].Defs, FlagLists[i].NumDefs, sizeof(FFlagDef), flagcmp);
	}

	// Create a sorted list of properties
	if (properties.Size() == 0)
	{
		FAutoSegIterator probe(GRegHead, GRegTail);

		while (*++probe != NULL)
		{
			properties.Push((FPropertyInfo *)*probe);
		}
		properties.ShrinkToFit();
		qsort(&properties[0], properties.Size(), sizeof(properties[0]), propcmp);
	}

	// Create a sorted list of native action functions
	AFTable.Clear();
	if (AFTable.Size() == 0)
	{
		FAutoSegIterator probe(ARegHead, ARegTail);

		while (*++probe != NULL)
		{
			AFuncDesc *afunc = (AFuncDesc *)*probe;
			assert(afunc->VMPointer != NULL);
			*(afunc->VMPointer) = new VMNativeFunction(afunc->Function, afunc->Name);
			AFTable.Push(*afunc);
		}
		AFTable.ShrinkToFit();
		qsort(&AFTable[0], AFTable.Size(), sizeof(AFTable[0]), funccmp);
	}

	// Define some member variables we feel like exposing to the user
	PSymbolTable &symt = RUNTIME_CLASS(AActor)->Symbols;
	PType *array5 = NewArray(TypeSInt32, 5);
	symt.AddSymbol(new PField(NAME_Alpha,		TypeFloat64,	VARF_Native, myoffsetof(AActor,Alpha)));
	symt.AddSymbol(new PField(NAME_Angle,		TypeFloat64,	VARF_Native, myoffsetof(AActor,Angles.Yaw)));
	symt.AddSymbol(new PField(NAME_Args,		array5,			VARF_Native, myoffsetof(AActor,args)));
	symt.AddSymbol(new PField(NAME_CeilingZ,	TypeFloat64,	VARF_Native, myoffsetof(AActor,ceilingz)));
	symt.AddSymbol(new PField(NAME_FloorZ,		TypeFloat64,	VARF_Native, myoffsetof(AActor,floorz)));
	symt.AddSymbol(new PField(NAME_Health,		TypeSInt32,		VARF_Native, myoffsetof(AActor,health)));
	symt.AddSymbol(new PField(NAME_Mass,		TypeSInt32,		VARF_Native, myoffsetof(AActor,Mass)));
	symt.AddSymbol(new PField(NAME_Pitch,		TypeFloat64,	VARF_Native, myoffsetof(AActor,Angles.Pitch)));
	symt.AddSymbol(new PField(NAME_Roll,		TypeFloat64,	VARF_Native, myoffsetof(AActor,Angles.Roll)));
	symt.AddSymbol(new PField(NAME_Special,		TypeSInt32,		VARF_Native, myoffsetof(AActor,special)));
	symt.AddSymbol(new PField(NAME_TID,			TypeSInt32,		VARF_Native, myoffsetof(AActor,tid)));
	symt.AddSymbol(new PField(NAME_TIDtoHate,	TypeSInt32,		VARF_Native, myoffsetof(AActor,TIDtoHate)));
	symt.AddSymbol(new PField(NAME_WaterLevel,	TypeSInt32,		VARF_Native, myoffsetof(AActor,waterlevel)));
	symt.AddSymbol(new PField(NAME_X,			TypeFloat64,	VARF_Native, myoffsetof(AActor,__Pos.X)));	// must remain read-only!
	symt.AddSymbol(new PField(NAME_Y,			TypeFloat64,	VARF_Native, myoffsetof(AActor,__Pos.Y)));	// must remain read-only!
	symt.AddSymbol(new PField(NAME_Z,			TypeFloat64,	VARF_Native, myoffsetof(AActor,__Pos.Z)));	// must remain read-only!
	symt.AddSymbol(new PField(NAME_VelX,		TypeFloat64,	VARF_Native, myoffsetof(AActor,Vel.X)));
	symt.AddSymbol(new PField(NAME_VelY,		TypeFloat64,	VARF_Native, myoffsetof(AActor, Vel.Y)));
	symt.AddSymbol(new PField(NAME_VelZ,		TypeFloat64,	VARF_Native, myoffsetof(AActor, Vel.Z)));
	symt.AddSymbol(new PField(NAME_MomX,		TypeFloat64,	VARF_Native, myoffsetof(AActor, Vel.X)));
	symt.AddSymbol(new PField(NAME_MomY,		TypeFloat64,	VARF_Native, myoffsetof(AActor, Vel.Y)));
	symt.AddSymbol(new PField(NAME_MomZ,		TypeFloat64,	VARF_Native, myoffsetof(AActor, Vel.Z)));
	symt.AddSymbol(new PField(NAME_ScaleX,		TypeFloat64,	VARF_Native, myoffsetof(AActor, Scale.X)));
	symt.AddSymbol(new PField(NAME_ScaleY,		TypeFloat64,	VARF_Native, myoffsetof(AActor, Scale.Y)));
	symt.AddSymbol(new PField(NAME_Score,		TypeSInt32,		VARF_Native, myoffsetof(AActor,Score)));
	symt.AddSymbol(new PField(NAME_Accuracy,	TypeSInt32,		VARF_Native, myoffsetof(AActor,accuracy)));
	symt.AddSymbol(new PField(NAME_Stamina,		TypeSInt32,		VARF_Native, myoffsetof(AActor,stamina)));
	symt.AddSymbol(new PField(NAME_Height,		TypeFloat64,	VARF_Native, myoffsetof(AActor,Height)));
	symt.AddSymbol(new PField(NAME_Radius,		TypeFloat64,	VARF_Native, myoffsetof(AActor,radius)));
	symt.AddSymbol(new PField(NAME_ReactionTime,TypeSInt32,		VARF_Native, myoffsetof(AActor,reactiontime)));
	symt.AddSymbol(new PField(NAME_MeleeRange,	TypeFloat64,	VARF_Native, myoffsetof(AActor,meleerange)));
	symt.AddSymbol(new PField(NAME_Speed,		TypeFloat64,	VARF_Native, myoffsetof(AActor,Speed)));
	symt.AddSymbol(new PField(NAME_Threshold,	TypeSInt32,		VARF_Native, myoffsetof(AActor,threshold)));
	symt.AddSymbol(new PField(NAME_DefThreshold,TypeSInt32,		VARF_Native, myoffsetof(AActor,DefThreshold)));
}
Example #25
0
void ParseCompatibility()
{
	TArray<FMD5Holder> md5array;
	FMD5Holder md5;
	FCompatValues flags;
	int i, x;
	unsigned int j;

	BCompatMap.Clear();
	CompatParams.Clear();

	// The contents of this file are not cumulative, as it should not
	// be present in user-distributed maps.
	FScanner sc(Wads.GetNumForFullName("compatibility.txt"));

	while (sc.GetString())	// Get MD5 signature
	{
		do
		{
			if (strlen(sc.String) != 32)
			{
				sc.ScriptError("MD5 signature must be exactly 32 characters long");
			}
			for (i = 0; i < 32; ++i)
			{
				if (sc.String[i] >= '0' && sc.String[i] <= '9')
				{
					x = sc.String[i] - '0';
				}
				else
				{
					sc.String[i] |= 'a' ^ 'A';
					if (sc.String[i] >= 'a' && sc.String[i] <= 'f')
					{
						x = sc.String[i] - 'a' + 10;
					}
					else
					{
						x = 0;
						sc.ScriptError("MD5 signature must be a hexadecimal value");
					}
				}
				if (!(i & 1))
				{
					md5.Bytes[i / 2] = x << 4;
				}
				else
				{
					md5.Bytes[i / 2] |= x;
				}
			}
			md5array.Push(md5);
			sc.MustGetString();
		} while (!sc.Compare("{"));
		memset(flags.CompatFlags, 0, sizeof(flags.CompatFlags));
		flags.ExtCommandIndex = ~0u;
		while (sc.GetString())
		{
			if ((i = sc.MatchString(&Options[0].Name, sizeof(*Options))) >= 0)
			{
				flags.CompatFlags[Options[i].WhichSlot] |= Options[i].CompatFlags;
			}
			else if (sc.Compare("clearlineflags"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_CLEARFLAGS);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setlineflags"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETFLAGS);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setlinespecial"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETSPECIAL);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);

				sc.MustGetString();
				CompatParams.Push(P_FindLineSpecial(sc.String, NULL, NULL));
				for (int i = 0; i < 5; i++)
				{
					sc.MustGetNumber();
					CompatParams.Push(sc.Number);
				}
			}
			else if (sc.Compare("clearlinespecial"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_CLEARSPECIAL);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setactivation"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETACTIVATION);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setsectoroffset"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETSECTOROFFSET);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetString();
				CompatParams.Push(sc.MustMatchString(SectorPlanes));
				sc.MustGetFloat();
				CompatParams.Push(int(sc.Float*65536.));
			}
			else if (sc.Compare("setsectorspecial"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETSECTORSPECIAL);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setwallyscale"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETWALLYSCALE);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetString();
				CompatParams.Push(sc.MustMatchString(LineSides));
				sc.MustGetString();
				CompatParams.Push(sc.MustMatchString(WallTiers));
				sc.MustGetFloat();
				CompatParams.Push(int(sc.Float*65536.));
			}
			else if (sc.Compare("setwalltexture"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETWALLTEXTURE);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetString();
				CompatParams.Push(sc.MustMatchString(LineSides));
				sc.MustGetString();
				CompatParams.Push(sc.MustMatchString(WallTiers));
				sc.MustGetString();
				const FString texName = sc.String;
				const unsigned int texIndex = TexNames.Find(texName);
				const unsigned int texCount = TexNames.Size();
				if (texIndex == texCount)
				{
					TexNames.Push(texName);
				}
				CompatParams.Push(texIndex);
			}
			else if (sc.Compare("setthingz"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETTHINGZ);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetFloat();
				CompatParams.Push(int(sc.Float*256));	// do not use full fixed here so that it can eventually handle larger levels
			}
			else if (sc.Compare("setsectortag"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETTAG);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setthingflags"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETTHINGFLAGS);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setvertex"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETVERTEX);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetFloat();
				CompatParams.Push(int(sc.Float * 256));	// do not use full fixed here so that it can eventually handle larger levels
				sc.MustGetFloat();
				CompatParams.Push(int(sc.Float * 256));	// do not use full fixed here so that it can eventually handle larger levels
				flags.CompatFlags[SLOT_BCOMPAT] |= BCOMPATF_REBUILDNODES;
			}
			else if (sc.Compare("setthingskills"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETTHINGSKILLS);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else if (sc.Compare("setsectortexture"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETSECTORTEXTURE);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetString();
				CompatParams.Push(sc.MustMatchString(SectorPlanes));
				sc.MustGetString();
				const FString texName = sc.String;
				const unsigned int texIndex = TexNames.Find(texName);
				const unsigned int texCount = TexNames.Size();
				if (texIndex == texCount)
				{
					TexNames.Push(texName);
				}
				CompatParams.Push(texIndex);
			}
			else if (sc.Compare("setsectorlight"))
			{
				if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
				CompatParams.Push(CP_SETSECTORLIGHT);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
				sc.MustGetNumber();
				CompatParams.Push(sc.Number);
			}
			else
			{
				sc.UnGet();
				break;
			}
		}
		if (flags.ExtCommandIndex != ~0u) 
		{
			CompatParams.Push(CP_END);
		}
		sc.MustGetStringName("}");
		for (j = 0; j < md5array.Size(); ++j)
		{
			BCompatMap[md5array[j]] = flags;
		}
		md5array.Clear();
	}
}
Example #26
0
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);
}
FSCSDiffControl::FSCSDiffControl(
		const UBlueprint* InOldBlueprint
		, const UBlueprint* InNewBlueprint
		, TArray< TSharedPtr<FBlueprintDifferenceTreeEntry> >& OutTreeEntries
		, TArray< TSharedPtr<FBlueprintDifferenceTreeEntry> >& OutRealDifferences
		, FOnSCSDiffControlChanged SelectionCallback
	)
	: DifferingProperties()
	, OldSCS( InOldBlueprint )
	, NewSCS( InNewBlueprint )
{
	TArray< FSCSResolvedIdentifier > OldHierarchy = OldSCS.GetDisplayedHierarchy();
	TArray< FSCSResolvedIdentifier > NewHierarchy = NewSCS.GetDisplayedHierarchy();
	DiffUtils::CompareUnrelatedSCS(InOldBlueprint, OldHierarchy, InNewBlueprint, NewHierarchy, DifferingProperties);

	const auto FocusSCSDifferenceEntry = [](FSCSDiffEntry Entry, FOnSCSDiffControlChanged InSelectionCallback, FSCSDiffControl* Owner)
	{
		InSelectionCallback.ExecuteIfBound();
		if (Entry.TreeIdentifier.Name != NAME_None)
		{
			Owner->OldSCS.HighlightProperty(Entry.TreeIdentifier.Name, FPropertyPath());
			Owner->NewSCS.HighlightProperty(Entry.TreeIdentifier.Name, FPropertyPath());
		}
	};

	const auto CreateSCSDifferenceWidget = [](FSCSDiffEntry Entry, FText ObjectName) -> TSharedRef<SWidget>
	{
		return SNew(STextBlock)
			.Text(DiffViewUtils::SCSDiffMessage(Entry,ObjectName))
			.ColorAndOpacity(DiffViewUtils::Differs());
	};

	TArray< TSharedPtr<FBlueprintDifferenceTreeEntry> > Children;
	for( auto Difference : DifferingProperties.Entries )
	{
		auto Entry = TSharedPtr<FBlueprintDifferenceTreeEntry>(
			new FBlueprintDifferenceTreeEntry(
				FOnDiffEntryFocused::CreateStatic(FocusSCSDifferenceEntry, Difference, SelectionCallback, this)
				, FGenerateDiffEntryWidget::CreateStatic(CreateSCSDifferenceWidget, Difference, RightRevision)
				, TArray< TSharedPtr<FBlueprintDifferenceTreeEntry> >()
			)
		);
		Children.Push(Entry);
		OutRealDifferences.Push(Entry);
	}

	const bool bHasDiffferences = Children.Num() != 0;
	if (!bHasDiffferences)
	{
		// make one child informing the user that there are no differences:
		Children.Push(FBlueprintDifferenceTreeEntry::NoDifferencesEntry());
	}

	const auto ForwardSelection = [](FOnSCSDiffControlChanged InSelectionCallback)
	{
		// This allows the owning control to focus the correct tab (or do whatever else it likes):
		InSelectionCallback.ExecuteIfBound();
	};

	OutTreeEntries.Push(FBlueprintDifferenceTreeEntry::CreateComponentsCategoryEntry(
		FOnDiffEntryFocused::CreateStatic(ForwardSelection, SelectionCallback),
		Children,
		bHasDiffferences
	));
}
Example #28
0
static bool LoadScriptFile(int lumpnum, FileReader *lump, int numnodes, bool include, int type)
{
	int i;
	DWORD prevSpeakerType;
	FStrifeDialogueNode *node;
	char buffer[4];

	lump->Read(buffer, 4);
	lump->Seek(-4, SEEK_CUR);

	// The binary format is so primitive that this check is enough to detect it.
	bool isbinary = (buffer[0] == 0 || buffer[1] == 0 || buffer[2] == 0 || buffer[3] == 0);

	if ((type == 1 && !isbinary) || (type == 2 && isbinary))
	{
		DPrintf("Incorrect data format for %s.", Wads.GetLumpFullName(lumpnum));
		return false;
	}

	if (!isbinary)
	{
		P_ParseUSDF(lumpnum, lump, numnodes);
	}
	else 
	{
		if (!include)
		{
			LoadScriptFile("SCRIPT00", true, 1);
		}
		if (!(gameinfo.flags & GI_SHAREWARE))
		{
			// Strife scripts are always a multiple of 1516 bytes because each entry
			// is exactly 1516 bytes long.
			if (numnodes % 1516 != 0)
			{
				DPrintf("Incorrect data format for %s.", Wads.GetLumpFullName(lumpnum));
				return false;
			}
			numnodes /= 1516;
		}
		else
		{
			// And the teaser version has 1488-byte entries.
			if (numnodes % 1488 != 0)
			{
				DPrintf("Incorrect data format for %s.", Wads.GetLumpFullName(lumpnum));
				return false;
			}
			numnodes /= 1488;
		}

		prevSpeakerType = 0;

		for (i = 0; i < numnodes; ++i)
		{
			if (!(gameinfo.flags & GI_SHAREWARE))
			{
				node = ReadRetailNode (lump, prevSpeakerType);
			}
			else
			{
				node = ReadTeaserNode (lump, prevSpeakerType);
			}
			node->ThisNodeNum = StrifeDialogues.Push(node);
		}
	}
	return true;
}
Example #29
0
void gl_InitModels()
{
	int Lump, lastLump;
	FString path;
	int index, surface;
	int i;

	FSpriteModelFrame smf;

	lastLump = 0;

	for(unsigned i=0;i<Models.Size();i++)
	{
		delete Models[i];
	}
	Models.Clear();
	SpriteModelFrames.Clear();
	DeleteModelHash();

	// First, create models for each voxel
	for (unsigned i = 0; i < Voxels.Size(); i++)
	{
		FVoxelModel *md = new FVoxelModel(Voxels[i], false);
		Voxels[i]->VoxelIndex = Models.Push(md);
	}
	// now create GL model frames for the voxeldefs
	for (unsigned i = 0; i < VoxelDefs.Size(); i++)
	{
		FVoxelModel *md = (FVoxelModel*)Models[VoxelDefs[i]->Voxel->VoxelIndex];
		memset(&smf, 0, sizeof(smf));
		smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
		smf.modelIDs[0] = VoxelDefs[i]->Voxel->VoxelIndex;
		smf.skinIDs[0] = md->GetPaletteTexture();
		smf.xscale = smf.yscale = smf.zscale = VoxelDefs[i]->Scale;
		smf.angleoffset = VoxelDefs[i]->AngleOffset.Degrees;
		if (VoxelDefs[i]->PlacedSpin != 0)
		{
			smf.yrotate = 1.f;
			smf.rotationSpeed = VoxelDefs[i]->PlacedSpin / 55.55f;
			smf.flags |= MDL_ROTATING;
		}
		VoxelDefs[i]->VoxeldefIndex = SpriteModelFrames.Push(smf);
		if (VoxelDefs[i]->PlacedSpin != VoxelDefs[i]->DroppedSpin)
		{
			if (VoxelDefs[i]->DroppedSpin != 0)
			{
				smf.yrotate = 1.f;
				smf.rotationSpeed = VoxelDefs[i]->DroppedSpin / 55.55f;
				smf.flags |= MDL_ROTATING;
			}
			else
			{
				smf.yrotate = 0;
				smf.rotationSpeed = 0;
				smf.flags &= ~MDL_ROTATING;
			}
			SpriteModelFrames.Push(smf);
		}
	}

	memset(&smf, 0, sizeof(smf));
	smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
	while ((Lump = Wads.FindLump("MODELDEF", &lastLump)) != -1)
	{
		FScanner sc(Lump);
		while (sc.GetString())
		{
			if (sc.Compare("model"))
			{
				path = "";
				sc.MustGetString();
				memset(&smf, 0, sizeof(smf));
				smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
				smf.xscale=smf.yscale=smf.zscale=1.f;

				smf.type = PClass::FindClass(sc.String);
				if (!smf.type || smf.type->Defaults == nullptr) 
				{
					sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String);
				}
				sc.MustGetStringName("{");
				while (!sc.CheckString("}"))
				{
					sc.MustGetString();
					if (sc.Compare("path"))
					{
						sc.MustGetString();
						FixPathSeperator(sc.String);
						path = sc.String;
						if (path[(int)path.Len()-1]!='/') path+='/';
					}
					else if (sc.Compare("model"))
					{
						sc.MustGetNumber();
						index = sc.Number;
						if (index < 0 || index >= MAX_MODELS_PER_FRAME)
						{
							sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
						}
						sc.MustGetString();
						FixPathSeperator(sc.String);
						smf.modelIDs[index] = FindModel(path.GetChars(), sc.String);
						if (smf.modelIDs[index] == -1)
						{
							Printf("%s: model not found in %s\n", sc.String, path.GetChars());
						}
					}
					else if (sc.Compare("scale"))
					{
						sc.MustGetFloat();
						smf.xscale = sc.Float;
						sc.MustGetFloat();
						smf.yscale = sc.Float;
						sc.MustGetFloat();
						smf.zscale = sc.Float;
					}
					// [BB] Added zoffset reading. 
					// Now it must be considered deprecated.
					else if (sc.Compare("zoffset"))
					{
						sc.MustGetFloat();
						smf.zoffset=sc.Float;
					}
					// Offset reading.
					else if (sc.Compare("offset"))
					{
						sc.MustGetFloat();
						smf.xoffset = sc.Float;
						sc.MustGetFloat();
						smf.yoffset = sc.Float;
						sc.MustGetFloat();
						smf.zoffset = sc.Float;
					}
					// angleoffset, pitchoffset and rolloffset reading.
					else if (sc.Compare("angleoffset"))
					{
						sc.MustGetFloat();
						smf.angleoffset = sc.Float;
					}
					else if (sc.Compare("pitchoffset"))
					{
						sc.MustGetFloat();
						smf.pitchoffset = sc.Float;
					}
					else if (sc.Compare("rolloffset"))
					{
						sc.MustGetFloat();
						smf.rolloffset = sc.Float;
					}
					// [BB] Added model flags reading.
					else if (sc.Compare("ignoretranslation"))
					{
						smf.flags |= MDL_IGNORETRANSLATION;
					}
					else if (sc.Compare("pitchfrommomentum"))
					{
						smf.flags |= MDL_PITCHFROMMOMENTUM;
					}
					else if (sc.Compare("inheritactorpitch"))
					{
						smf.flags |= MDL_USEACTORPITCH | MDL_BADROTATION;
					}
					else if (sc.Compare("inheritactorroll"))
					{
						smf.flags |= MDL_USEACTORROLL;
					}
					else if (sc.Compare("useactorpitch"))
					{
						smf.flags |= MDL_USEACTORPITCH;
					}
					else if (sc.Compare("useactorroll"))
					{
						smf.flags |= MDL_USEACTORROLL;
					}
					else if (sc.Compare("rotating"))
					{
						smf.flags |= MDL_ROTATING;
						smf.xrotate = 0.;
						smf.yrotate = 1.;
						smf.zrotate = 0.;
						smf.rotationCenterX = 0.;
						smf.rotationCenterY = 0.;
						smf.rotationCenterZ = 0.;
						smf.rotationSpeed = 1.;
					}
					else if (sc.Compare("rotation-speed"))
					{
						sc.MustGetFloat();
						smf.rotationSpeed = sc.Float;
					}
					else if (sc.Compare("rotation-vector"))
					{
						sc.MustGetFloat();
						smf.xrotate = sc.Float;
						sc.MustGetFloat();
						smf.yrotate = sc.Float;
						sc.MustGetFloat();
						smf.zrotate = sc.Float;
					}
					else if (sc.Compare("rotation-center"))
					{
						sc.MustGetFloat();
						smf.rotationCenterX = sc.Float;
						sc.MustGetFloat();
						smf.rotationCenterY = sc.Float;
						sc.MustGetFloat();
						smf.rotationCenterZ = sc.Float;
					}
					else if (sc.Compare("interpolatedoubledframes"))
					{
						smf.flags |= MDL_INTERPOLATEDOUBLEDFRAMES;
					}
					else if (sc.Compare("nointerpolation"))
					{
						smf.flags |= MDL_NOINTERPOLATION;
					}
					else if (sc.Compare("skin"))
					{
						sc.MustGetNumber();
						index=sc.Number;
						if (index<0 || index>=MAX_MODELS_PER_FRAME)
						{
							sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
						}
						sc.MustGetString();
						FixPathSeperator(sc.String);
						if (sc.Compare(""))
						{
							smf.skinIDs[index]=FNullTextureID();
						}
						else
						{
							smf.skinIDs[index] = LoadSkin(path.GetChars(), sc.String);
							if (!smf.skinIDs[index].isValid())
							{
								Printf("Skin '%s' not found in '%s'\n",
									sc.String, smf.type->TypeName.GetChars());
							}
						}
					}
					else if (sc.Compare("surfaceskin"))
					{
						sc.MustGetNumber();
						index = sc.Number;
						sc.MustGetNumber();
						surface = sc.Number;

						if (index<0 || index >= MAX_MODELS_PER_FRAME)
						{
							sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
						}

						if (surface<0 || surface >= MD3_MAX_SURFACES)
						{
							sc.ScriptError("Invalid MD3 Surface %d in %s", MD3_MAX_SURFACES, smf.type->TypeName.GetChars());
						}

						sc.MustGetString();
						FixPathSeperator(sc.String);
						if (sc.Compare(""))
						{
							smf.surfaceskinIDs[index][surface] = FNullTextureID();
						}
						else
						{
							smf.surfaceskinIDs[index][surface] = LoadSkin(path.GetChars(), sc.String);
							if (!smf.surfaceskinIDs[index][surface].isValid())
							{
								Printf("Surface Skin '%s' not found in '%s'\n",
									sc.String, smf.type->TypeName.GetChars());
							}
						}
					}
					else if (sc.Compare("frameindex") || sc.Compare("frame"))
					{
						bool isframe=!!sc.Compare("frame");

						sc.MustGetString();
						smf.sprite = -1;
						for (i = 0; i < (int)sprites.Size (); ++i)
						{
							if (strnicmp (sprites[i].name, sc.String, 4) == 0)
							{
								if (sprites[i].numframes==0)
								{
									//sc.ScriptError("Sprite %s has no frames", sc.String);
								}
								smf.sprite = i;
								break;
							}
						}
						if (smf.sprite==-1)
						{
							sc.ScriptError("Unknown sprite %s in model definition for %s", sc.String, smf.type->TypeName.GetChars());
						}

						sc.MustGetString();
						FString framechars = sc.String;

						sc.MustGetNumber();
						index=sc.Number;
						if (index<0 || index>=MAX_MODELS_PER_FRAME)
						{
							sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
						}
						if (isframe)
						{
							sc.MustGetString();
							if (smf.modelIDs[index] != -1)
							{
								FModel *model = Models[smf.modelIDs[index]];
								smf.modelframes[index] = model->FindFrame(sc.String);
								if (smf.modelframes[index]==-1) sc.ScriptError("Unknown frame '%s' in %s", sc.String, smf.type->TypeName.GetChars());
							}
							else smf.modelframes[index] = -1;
						}
						else
						{
							sc.MustGetNumber();
							smf.modelframes[index] = sc.Number;
						}

						for(i=0; framechars[i]>0; i++)
						{
							char map[29]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
							int c = toupper(framechars[i])-'A';

							if (c<0 || c>=29)
							{
								sc.ScriptError("Invalid frame character %c found", c+'A');
							}
							if (map[c]) continue;
							smf.frame=c;
							SpriteModelFrames.Push(smf);
							GetDefaultByType(smf.type)->hasmodel = true;
							map[c]=1;
						}
					}
					else
					{
						sc.ScriptMessage("Unrecognized string \"%s\"", sc.String);
					}
				}
			}
		}
	}

	// create a hash table for quick access
	SpriteModelHash = new int[SpriteModelFrames.Size ()];
	atterm(DeleteModelHash);
	memset(SpriteModelHash, 0xff, SpriteModelFrames.Size () * sizeof(int));

	for (i = 0; i < (int)SpriteModelFrames.Size (); i++)
	{
		int j = ModelFrameHash(&SpriteModelFrames[i]) % SpriteModelFrames.Size ();

		SpriteModelFrames[i].hashnext = SpriteModelHash[j];
		SpriteModelHash[j]=i;
	}
}
Example #30
0
TArray<FString> I_GetSteamPath()
{
	TArray<FString> result;
	TArray<FString> SteamInstallFolders;

	// Linux and OS X actually allow the user to install to any location, so
	// we need to figure out on an app-by-app basis where the game is installed.
	// To do so, we read the virtual registry.
#ifdef __APPLE__
	const FString appSupportPath = M_GetMacAppSupportPath();
	FString regPath = appSupportPath + "/Steam/config/config.vdf";
	try
	{
		SteamInstallFolders = ParseSteamRegistry(regPath);
	}
	catch(class CDoomError &error)
	{
		// If we can't parse for some reason just pretend we can't find anything.
		return result;
	}

	SteamInstallFolders.Push(appSupportPath + "/Steam/SteamApps/common");
#else
	char* home = getenv("HOME");
	if(home != NULL && *home != '\0')
	{
		FString regPath;
		regPath.Format("%s/.steam/config/config.vdf", home);
		// [BL] The config seems to have moved from the more modern .local to
		// .steam at some point. Not sure if it's just my setup so I guess we
		// can fall back on it?
		if(!FileExists(regPath))
			regPath.Format("%s/.local/share/Steam/config/config.vdf", home);

		try
		{
			SteamInstallFolders = ParseSteamRegistry(regPath);
		}
		catch(class CDoomError &error)
		{
			// If we can't parse for some reason just pretend we can't find anything.
			return result;
		}

		regPath.Format("%s/.local/share/Steam/SteamApps/common", home);
		SteamInstallFolders.Push(regPath);
	}
#endif

	for(unsigned int i = 0;i < SteamInstallFolders.Size();++i)
	{
		for(unsigned int app = 0;app < countof(AppInfo);++app)
		{
			struct stat st;
			FString candidate(SteamInstallFolders[i] + "/" + AppInfo[app].BasePath);
			if(DirExists(candidate))
				result.Push(candidate);
		}
	}

	return result;
}