mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
6cd1e2ce6a
memcpy to copy the player structures. - Fixed compilation with MinGW again and removed most of the new warnings. And following is the log that I forgot to paste in for the previous commit: - Changed the memory management for FString. Instead of using a garbage collected heap, it now uses normal heap calls and reference counting to implement lazy copying. You may now use bitwise operators to move (but not copy!) FStrings around in memory. This means that the CopyForTArray template function is gone, since TArrays can now freely move their contents around without bothering with their specifics. There is one important caveat, however. It is not acceptable to blindly 0 an FString's contents. This necessitated the creation of a proper constructor for player_s so that it can be reset without using memset. I did a quick scan of all memsets in the source and didn't see anything else with a similar problem, but it's possible I missed something. - Fixed: Build tiles were never deallocated. - Fixed: Using Build's palette.dat only got half the palette right. SVN r117 (trunk)
724 lines
16 KiB
C++
724 lines
16 KiB
C++
/*
|
|
** p_terrain.cpp
|
|
** Terrain maintenance
|
|
**
|
|
**---------------------------------------------------------------------------
|
|
** Copyright 1998-2005 Randy Heit
|
|
** All rights reserved.
|
|
**
|
|
** Redistribution and use in source and binary forms, with or without
|
|
** modification, are permitted provided that the following conditions
|
|
** are met:
|
|
**
|
|
** 1. Redistributions of source code must retain the above copyright
|
|
** notice, this list of conditions and the following disclaimer.
|
|
** 2. Redistributions in binary form must reproduce the above copyright
|
|
** notice, this list of conditions and the following disclaimer in the
|
|
** documentation and/or other materials provided with the distribution.
|
|
** 3. The name of the author may not be used to endorse or promote products
|
|
** derived from this software without specific prior written permission.
|
|
**
|
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
**---------------------------------------------------------------------------
|
|
**
|
|
*/
|
|
|
|
// HEADER FILES ------------------------------------------------------------
|
|
|
|
#include <string.h>
|
|
|
|
#include "doomtype.h"
|
|
#include "cmdlib.h"
|
|
#include "p_terrain.h"
|
|
#include "gi.h"
|
|
#include "r_state.h"
|
|
#include "w_wad.h"
|
|
#include "sc_man.h"
|
|
#include "s_sound.h"
|
|
#include "p_local.h"
|
|
#include "templates.h"
|
|
|
|
// MACROS ------------------------------------------------------------------
|
|
|
|
#define SET_FIELD(type,val) *((type*)((byte *)fields + \
|
|
parser[keyword].u.Offset)) = val;
|
|
|
|
// TYPES -------------------------------------------------------------------
|
|
|
|
enum EOuterKeywords
|
|
{
|
|
OUT_SPLASH,
|
|
OUT_TERRAIN,
|
|
OUT_FLOOR,
|
|
OUT_IFDOOM,
|
|
OUT_IFHERETIC,
|
|
OUT_IFHEXEN,
|
|
OUT_IFSTRIFE,
|
|
OUT_ENDIF
|
|
};
|
|
|
|
enum ETerrainKeywords
|
|
{
|
|
TR_CLOSE,
|
|
TR_SPLASH,
|
|
TR_DAMAGEAMOUNT,
|
|
TR_DAMAGETYPE,
|
|
TR_DAMAGETIMEMASK,
|
|
TR_FOOTCLIP,
|
|
TR_STEPVOLUME,
|
|
TR_WALKINGSTEPTIME,
|
|
TR_RUNNINGSTEPTIME,
|
|
TR_LEFTSTEPSOUNDS,
|
|
TR_RIGHTSTEPSOUNDS,
|
|
TR_LIQUID,
|
|
TR_FRICTION
|
|
};
|
|
|
|
enum EDamageKeywords
|
|
{
|
|
DAM_Lava,
|
|
DAM_Ice,
|
|
DAM_Slime
|
|
};
|
|
|
|
enum EGenericType
|
|
{
|
|
GEN_End,
|
|
GEN_Fixed,
|
|
GEN_Sound,
|
|
GEN_Byte,
|
|
GEN_Class,
|
|
GEN_Splash,
|
|
GEN_Float,
|
|
GEN_Time,
|
|
GEN_Bool,
|
|
GEN_Int,
|
|
GEN_Custom,
|
|
};
|
|
|
|
struct FGenericParse
|
|
{
|
|
EGenericType Type;
|
|
union {
|
|
size_t Offset;
|
|
void (*Handler) (int type, void *fields);
|
|
} u;
|
|
};
|
|
|
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
|
|
|
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
|
|
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
|
|
|
static void MakeDefaultTerrain ();
|
|
static void ParseOuter ();
|
|
static void ParseSplash ();
|
|
static void ParseTerrain ();
|
|
static void ParseFloor ();
|
|
static int FindSplash (FName name);
|
|
static int FindTerrain (FName name);
|
|
static void GenericParse (FGenericParse *parser, const char **keywords,
|
|
void *fields, const char *type, FName name);
|
|
static void ParseDamage (int keyword, void *fields);
|
|
static void ParseFriction (int keyword, void *fields);
|
|
|
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
|
|
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
|
|
|
TArray<byte>TerrainTypes;
|
|
TArray<FSplashDef> Splashes;
|
|
TArray<FTerrainDef> Terrains;
|
|
|
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
|
|
|
static const char *OuterKeywords[] =
|
|
{
|
|
"splash",
|
|
"terrain",
|
|
"floor",
|
|
"ifdoom",
|
|
"ifheretic",
|
|
"ifhexen",
|
|
"ifstrife",
|
|
"endif",
|
|
NULL
|
|
};
|
|
|
|
static const char *SplashKeywords[] =
|
|
{
|
|
"}",
|
|
"smallsound",
|
|
"smallclip",
|
|
"sound",
|
|
"smallclass",
|
|
"baseclass",
|
|
"chunkclass",
|
|
"chunkxvelshift",
|
|
"chunkyvelshift",
|
|
"chunkzvelshift",
|
|
"chunkbasezvel",
|
|
"noalert",
|
|
NULL
|
|
};
|
|
|
|
static const char *TerrainKeywords[] =
|
|
{
|
|
"}",
|
|
"splash",
|
|
"damageamount",
|
|
"damagetype",
|
|
"damagetimemask",
|
|
"footclip",
|
|
"stepvolume",
|
|
"walkingsteptime",
|
|
"runningsteptime",
|
|
"leftstepsounds",
|
|
"rightstepsounds",
|
|
"liquid",
|
|
"friction",
|
|
NULL
|
|
};
|
|
|
|
static const char *DamageKeywords[] =
|
|
{
|
|
"lava",
|
|
"ice",
|
|
"slime",
|
|
NULL
|
|
};
|
|
|
|
// Alternate offsetof macro to shut GCC up
|
|
#define theoffsetof(type,field) ((size_t)&((type*)1)->field - 1)
|
|
|
|
static FGenericParse SplashParser[] =
|
|
{
|
|
{ GEN_End, {0} },
|
|
{ GEN_Sound, {theoffsetof(FSplashDef, SmallSplashSound)} },
|
|
{ GEN_Fixed, {theoffsetof(FSplashDef, SmallSplashClip)} },
|
|
{ GEN_Sound, {theoffsetof(FSplashDef, NormalSplashSound)} },
|
|
{ GEN_Class, {theoffsetof(FSplashDef, SmallSplash)} },
|
|
{ GEN_Class, {theoffsetof(FSplashDef, SplashBase)} },
|
|
{ GEN_Class, {theoffsetof(FSplashDef, SplashChunk)} },
|
|
{ GEN_Byte, {theoffsetof(FSplashDef, ChunkXVelShift)} },
|
|
{ GEN_Byte, {theoffsetof(FSplashDef, ChunkYVelShift)} },
|
|
{ GEN_Byte, {theoffsetof(FSplashDef, ChunkZVelShift)} },
|
|
{ GEN_Fixed, {theoffsetof(FSplashDef, ChunkBaseZVel)} },
|
|
{ GEN_Bool, {theoffsetof(FSplashDef, NoAlert)} }
|
|
};
|
|
|
|
static FGenericParse TerrainParser[] =
|
|
{
|
|
{ GEN_End, {0} },
|
|
{ GEN_Splash, {theoffsetof(FTerrainDef, Splash)} },
|
|
{ GEN_Int, {theoffsetof(FTerrainDef, DamageAmount)} },
|
|
{ GEN_Custom, {(size_t)ParseDamage} },
|
|
{ GEN_Int, {theoffsetof(FTerrainDef, DamageTimeMask)} },
|
|
{ GEN_Fixed, {theoffsetof(FTerrainDef, FootClip)} },
|
|
{ GEN_Float, {theoffsetof(FTerrainDef, StepVolume)} },
|
|
{ GEN_Time, {theoffsetof(FTerrainDef, WalkStepTics)} },
|
|
{ GEN_Time, {theoffsetof(FTerrainDef, RunStepTics)} },
|
|
{ GEN_Sound, {theoffsetof(FTerrainDef, LeftStepSound)} },
|
|
{ GEN_Sound, {theoffsetof(FTerrainDef, RightStepSound)} },
|
|
{ GEN_Bool, {theoffsetof(FTerrainDef, IsLiquid)} },
|
|
{ GEN_Custom, {(size_t)ParseFriction} }
|
|
};
|
|
|
|
/*
|
|
struct
|
|
{
|
|
char *name;
|
|
int type;
|
|
bool Heretic;
|
|
}
|
|
TerrainTypeDefs[] =
|
|
{
|
|
{ "FLTWAWA1", FLOOR_WATER, true },
|
|
{ "FLTFLWW1", FLOOR_WATER, true },
|
|
{ "FLTLAVA1", FLOOR_LAVA, true },
|
|
{ "FLATHUH1", FLOOR_LAVA, true },
|
|
{ "FLTSLUD1", FLOOR_SLUDGE, true },
|
|
{ "X_005", FLOOR_WATER, false },
|
|
{ "X_001", FLOOR_LAVA, false },
|
|
{ "X_009", FLOOR_SLUDGE, false },
|
|
{ "F_033", FLOOR_ICE, false },
|
|
{ "END", -1 }
|
|
};
|
|
*/
|
|
|
|
// CODE --------------------------------------------------------------------
|
|
|
|
//==========================================================================
|
|
//
|
|
// P_InitTerrainTypes
|
|
//
|
|
//==========================================================================
|
|
|
|
void P_InitTerrainTypes ()
|
|
{
|
|
int lastlump;
|
|
int lump;
|
|
int size;
|
|
|
|
size = (TexMan.NumTextures()+1)*sizeof(byte);
|
|
TerrainTypes.Resize(size);
|
|
memset (&TerrainTypes[0], 0, size);
|
|
|
|
MakeDefaultTerrain ();
|
|
|
|
lastlump = 0;
|
|
while (-1 != (lump = Wads.FindLump ("TERRAIN", &lastlump)) )
|
|
{
|
|
SC_OpenLumpNum (lump, "TERRAIN");
|
|
ParseOuter ();
|
|
SC_Close ();
|
|
}
|
|
Splashes.ShrinkToFit ();
|
|
Terrains.ShrinkToFit ();
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// MakeDefaultTerrain
|
|
//
|
|
//==========================================================================
|
|
|
|
static void MakeDefaultTerrain ()
|
|
{
|
|
FTerrainDef def;
|
|
|
|
memset (&def, 0, sizeof(def));
|
|
def.Name = "Solid";
|
|
def.Splash = -1;
|
|
Terrains.Push (def);
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// ParseOuter
|
|
//
|
|
//==========================================================================
|
|
|
|
static void ParseOuter ()
|
|
{
|
|
int bracedepth = 0;
|
|
bool ifskip = false;
|
|
|
|
while (SC_GetString ())
|
|
{
|
|
if (ifskip)
|
|
{
|
|
if (bracedepth > 0)
|
|
{
|
|
if (SC_Compare ("}"))
|
|
{
|
|
bracedepth--;
|
|
continue;
|
|
}
|
|
}
|
|
else if (SC_Compare ("endif"))
|
|
{
|
|
ifskip = false;
|
|
continue;
|
|
}
|
|
if (SC_Compare ("{"))
|
|
{
|
|
bracedepth++;
|
|
}
|
|
else if (SC_Compare ("}"))
|
|
{
|
|
SC_ScriptError ("Too many left braces ('}')");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (SC_MustMatchString (OuterKeywords))
|
|
{
|
|
case OUT_SPLASH:
|
|
ParseSplash ();
|
|
break;
|
|
|
|
case OUT_TERRAIN:
|
|
ParseTerrain ();
|
|
break;
|
|
|
|
case OUT_FLOOR:
|
|
ParseFloor ();
|
|
break;
|
|
|
|
case OUT_IFDOOM:
|
|
if (gameinfo.gametype != GAME_Doom)
|
|
{
|
|
ifskip = true;
|
|
}
|
|
break;
|
|
|
|
case OUT_IFHERETIC:
|
|
if (gameinfo.gametype != GAME_Heretic)
|
|
{
|
|
ifskip = true;
|
|
}
|
|
break;
|
|
|
|
case OUT_IFHEXEN:
|
|
if (gameinfo.gametype != GAME_Hexen)
|
|
{
|
|
ifskip = true;
|
|
}
|
|
break;
|
|
|
|
case OUT_IFSTRIFE:
|
|
if (gameinfo.gametype != GAME_Strife)
|
|
{
|
|
ifskip = true;
|
|
}
|
|
break;
|
|
|
|
case OUT_ENDIF:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// ParseSplash
|
|
//
|
|
//==========================================================================
|
|
|
|
void ParseSplash ()
|
|
{
|
|
int splashnum;
|
|
FSplashDef *splashdef;
|
|
bool isnew = false;
|
|
FName name;
|
|
|
|
SC_MustGetString ();
|
|
name = sc_String;
|
|
splashnum = (int)FindSplash (name);
|
|
if (splashnum < 0)
|
|
{
|
|
FSplashDef def;
|
|
def.Name = name;
|
|
splashnum = (int)Splashes.Push (def);
|
|
isnew = true;
|
|
}
|
|
splashdef = &Splashes[splashnum];
|
|
|
|
SC_MustGetString ();
|
|
if (!SC_Compare ("modify") || (SC_MustGetString(), isnew))
|
|
{ // Set defaults
|
|
splashdef->SmallSplashSound =
|
|
splashdef->NormalSplashSound = 0;
|
|
splashdef->SmallSplash =
|
|
splashdef->SplashBase =
|
|
splashdef->SplashChunk = NULL;
|
|
splashdef->ChunkXVelShift =
|
|
splashdef->ChunkYVelShift =
|
|
splashdef->ChunkZVelShift = 8;
|
|
splashdef->ChunkBaseZVel = FRACUNIT;
|
|
splashdef->SmallSplashClip = 12*FRACUNIT;
|
|
splashdef->NoAlert = false;
|
|
}
|
|
if (!SC_Compare ("{"))
|
|
{
|
|
SC_ScriptError ("Expected {");
|
|
}
|
|
else
|
|
{
|
|
GenericParse (SplashParser, SplashKeywords, splashdef, "splash",
|
|
splashdef->Name);
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// ParseTerrain
|
|
//
|
|
//==========================================================================
|
|
|
|
void ParseTerrain ()
|
|
{
|
|
int terrainnum;
|
|
FName name;
|
|
|
|
SC_MustGetString ();
|
|
name = sc_String;
|
|
terrainnum = (int)FindTerrain (name);
|
|
if (terrainnum < 0)
|
|
{
|
|
FTerrainDef def;
|
|
memset (&def, 0, sizeof(def));
|
|
def.Splash = -1;
|
|
def.Name = name;
|
|
terrainnum = (int)Terrains.Push (def);
|
|
}
|
|
|
|
// Set defaults
|
|
SC_MustGetString ();
|
|
if (!SC_Compare ("modify"))
|
|
{
|
|
name = Terrains[terrainnum].Name;
|
|
memset (&Terrains[terrainnum], 0, sizeof(FTerrainDef));
|
|
Terrains[terrainnum].Splash = -1;
|
|
Terrains[terrainnum].Name = name;
|
|
}
|
|
else
|
|
{
|
|
SC_MustGetString ();
|
|
}
|
|
|
|
if (SC_Compare ("{"))
|
|
{
|
|
GenericParse (TerrainParser, TerrainKeywords, &Terrains[terrainnum],
|
|
"terrain", Terrains[terrainnum].Name);
|
|
}
|
|
else
|
|
{
|
|
SC_ScriptError ("Expected {");
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// ParseDamage
|
|
//
|
|
//==========================================================================
|
|
|
|
static void ParseDamage (int keyword, void *fields)
|
|
{
|
|
FTerrainDef *def = (FTerrainDef *)fields;
|
|
|
|
SC_MustGetString ();
|
|
switch (SC_MustMatchString (DamageKeywords))
|
|
{
|
|
case DAM_Lava:
|
|
def->DamageMOD = MOD_FIRE;
|
|
break;
|
|
|
|
case DAM_Ice:
|
|
def->DamageMOD = MOD_ICE;
|
|
break;
|
|
|
|
case DAM_Slime:
|
|
def->DamageMOD = MOD_SLIME;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// ParseFriction
|
|
//
|
|
//==========================================================================
|
|
|
|
static void ParseFriction (int keyword, void *fields)
|
|
{
|
|
FTerrainDef *def = (FTerrainDef *)fields;
|
|
fixed_t friction, movefactor;
|
|
|
|
SC_MustGetFloat ();
|
|
|
|
// These calculations should match those in P_SetSectorFriction().
|
|
// A friction of 1.0 is equivalent to ORIG_FRICTION.
|
|
|
|
friction = (fixed_t)(0x1EB8*(sc_Float*100))/0x80 + 0xD001;
|
|
friction = clamp<fixed_t> (friction, 0, FRACUNIT);
|
|
|
|
if (friction > ORIG_FRICTION) // ice
|
|
movefactor = ((0x10092 - friction) * 1024) / 4352 + 568;
|
|
else
|
|
movefactor = ((friction - 0xDB34)*(0xA))/0x80;
|
|
|
|
if (movefactor < 32)
|
|
movefactor = 32;
|
|
|
|
def->Friction = friction;
|
|
def->MoveFactor = movefactor;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// GenericParse
|
|
//
|
|
//==========================================================================
|
|
|
|
static void GenericParse (FGenericParse *parser, const char **keywords,
|
|
void *fields, const char *type, FName name)
|
|
{
|
|
bool notdone = true;
|
|
int keyword;
|
|
int val;
|
|
const PClass *info;
|
|
|
|
do
|
|
{
|
|
SC_MustGetString ();
|
|
keyword = SC_MustMatchString (keywords);
|
|
switch (parser[keyword].Type)
|
|
{
|
|
case GEN_End:
|
|
notdone = false;
|
|
break;
|
|
|
|
case GEN_Fixed:
|
|
SC_MustGetFloat ();
|
|
SET_FIELD (fixed_t, (fixed_t)(FRACUNIT * sc_Float));
|
|
break;
|
|
|
|
case GEN_Sound:
|
|
SC_MustGetString ();
|
|
val = S_FindSound (sc_String);
|
|
SET_FIELD (int, val);
|
|
if (val == 0)
|
|
{
|
|
Printf ("Unknown sound %s in %s %s\n",
|
|
sc_String, type, name.GetChars());
|
|
}
|
|
break;
|
|
|
|
case GEN_Byte:
|
|
SC_MustGetNumber ();
|
|
SET_FIELD (byte, sc_Number);
|
|
break;
|
|
|
|
case GEN_Class:
|
|
SC_MustGetString ();
|
|
if (SC_Compare ("None"))
|
|
{
|
|
info = NULL;
|
|
}
|
|
else
|
|
{
|
|
info = PClass::FindClass (sc_String);
|
|
if (!info->IsDescendantOf (RUNTIME_CLASS(AActor)))
|
|
{
|
|
Printf ("%s is not an Actor (in %s %s)\n",
|
|
sc_String, type, name.GetChars());
|
|
info = NULL;
|
|
}
|
|
else if (info == NULL)
|
|
{
|
|
Printf ("Unknown actor %s in %s %s\n",
|
|
sc_String, type, name.GetChars());
|
|
}
|
|
}
|
|
SET_FIELD (const PClass *, info);
|
|
break;
|
|
|
|
case GEN_Splash:
|
|
SC_MustGetString ();
|
|
val = FindSplash (sc_String);
|
|
SET_FIELD (int, val);
|
|
if (val == -1)
|
|
{
|
|
Printf ("Splash %s is not defined yet (in %s %s)\n",
|
|
sc_String, type, name.GetChars());
|
|
}
|
|
break;
|
|
|
|
case GEN_Float:
|
|
SC_MustGetFloat ();
|
|
SET_FIELD (float, sc_Float);
|
|
break;
|
|
|
|
case GEN_Time:
|
|
SC_MustGetFloat ();
|
|
SET_FIELD (int, (int)(sc_Float * TICRATE));
|
|
break;
|
|
|
|
case GEN_Bool:
|
|
SET_FIELD (bool, true);
|
|
break;
|
|
|
|
case GEN_Int:
|
|
SC_MustGetNumber ();
|
|
SET_FIELD (int, sc_Number);
|
|
break;
|
|
|
|
case GEN_Custom:
|
|
parser[keyword].u.Handler (keyword, fields);
|
|
break;
|
|
}
|
|
} while (notdone);
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// ParseFloor
|
|
//
|
|
//==========================================================================
|
|
|
|
static void ParseFloor ()
|
|
{
|
|
int picnum;
|
|
int terrain;
|
|
|
|
SC_MustGetString ();
|
|
picnum = TexMan.CheckForTexture (sc_String, FTexture::TEX_Flat);
|
|
if (picnum == -1)
|
|
{
|
|
Printf ("Unknown flat %s\n", sc_String);
|
|
SC_MustGetString ();
|
|
return;
|
|
}
|
|
SC_MustGetString ();
|
|
terrain = FindTerrain (sc_String);
|
|
if (terrain == -1)
|
|
{
|
|
Printf ("Unknown terrain %s\n", sc_String);
|
|
terrain = 0;
|
|
}
|
|
TerrainTypes[picnum] = terrain;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FindSplash
|
|
//
|
|
//==========================================================================
|
|
|
|
int FindSplash (FName name)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < Splashes.Size (); i++)
|
|
{
|
|
if (Splashes[i].Name == name)
|
|
{
|
|
return (int)i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// FindTerrain
|
|
//
|
|
//==========================================================================
|
|
|
|
int FindTerrain (FName name)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < Terrains.Size (); i++)
|
|
{
|
|
if (Terrains[i].Name == name)
|
|
{
|
|
return (int)i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|