mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 23:01:59 +00:00
- made most of the player spawn spot handliing functions members of FLevelLocals.
This commit is contained in:
parent
0ef0698d24
commit
66695ac6a0
11 changed files with 84 additions and 70 deletions
|
@ -417,7 +417,7 @@ bool FCajunMaster::DoAddBot (uint8_t *info, botskill_t skill)
|
|||
else
|
||||
Printf ("%s joined the game\n", players[bnum].userinfo.GetName());
|
||||
|
||||
G_DoReborn (bnum, true);
|
||||
level.DoReborn (bnum, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -667,6 +667,6 @@ CCMD(fpuke)
|
|||
}
|
||||
else
|
||||
{
|
||||
T_RunScript(currentUILevel, atoi(argv[1]), players[consoleplayer].mo);
|
||||
T_RunScript(players[consoleplayer].mo->Level, atoi(argv[1]), players[consoleplayer].mo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1014,7 +1014,7 @@ void G_Ticker ()
|
|||
}
|
||||
if (players[i].playerstate == PST_REBORN || players[i].playerstate == PST_ENTER)
|
||||
{
|
||||
G_DoReborn(i, false);
|
||||
level.DoReborn(i, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1241,7 +1241,7 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags)
|
|||
// Called after a player dies
|
||||
// almost everything is cleared and initialized
|
||||
//
|
||||
void G_PlayerReborn (int player)
|
||||
void FLevelLocals::PlayerReborn (int player)
|
||||
{
|
||||
player_t* p;
|
||||
int frags[MAXPLAYERS];
|
||||
|
@ -1325,7 +1325,7 @@ void G_PlayerReborn (int player)
|
|||
// because something is occupying it
|
||||
//
|
||||
|
||||
bool G_CheckSpot (int playernum, FPlayerStart *mthing)
|
||||
bool FLevelLocals::CheckSpot (int playernum, FPlayerStart *mthing)
|
||||
{
|
||||
DVector3 spot;
|
||||
double oldz;
|
||||
|
@ -1335,7 +1335,7 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing)
|
|||
|
||||
spot = mthing->pos;
|
||||
|
||||
if (!(level.flags & LEVEL_USEPLAYERSTARTZ))
|
||||
if (!(flags & LEVEL_USEPLAYERSTARTZ))
|
||||
{
|
||||
spot.Z = 0;
|
||||
}
|
||||
|
@ -1377,7 +1377,7 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing)
|
|||
//
|
||||
|
||||
// [RH] Returns the distance of the closest player to the given mapthing
|
||||
static double PlayersRangeFromSpot (FPlayerStart *spot)
|
||||
double FLevelLocals::PlayersRangeFromSpot (FPlayerStart *spot)
|
||||
{
|
||||
double closest = INT_MAX;
|
||||
double distance;
|
||||
|
@ -1398,7 +1398,7 @@ static double PlayersRangeFromSpot (FPlayerStart *spot)
|
|||
}
|
||||
|
||||
// [RH] Select the deathmatch spawn spot farthest from everyone.
|
||||
static FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections)
|
||||
FPlayerStart *FLevelLocals::SelectFarthestDeathmatchSpot (size_t selections)
|
||||
{
|
||||
double bestdistance = 0;
|
||||
FPlayerStart *bestspot = NULL;
|
||||
|
@ -1406,7 +1406,7 @@ static FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections)
|
|||
|
||||
for (i = 0; i < selections; i++)
|
||||
{
|
||||
double distance = PlayersRangeFromSpot (&level.deathmatchstarts[i]);
|
||||
double distance = PlayersRangeFromSpot (&deathmatchstarts[i]);
|
||||
|
||||
if (distance > bestdistance)
|
||||
{
|
||||
|
@ -1419,27 +1419,27 @@ static FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections)
|
|||
}
|
||||
|
||||
// [RH] Select a deathmatch spawn spot at random (original mechanism)
|
||||
static FPlayerStart *SelectRandomDeathmatchSpot (int playernum, unsigned int selections)
|
||||
FPlayerStart *FLevelLocals::SelectRandomDeathmatchSpot (int playernum, unsigned int selections)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (j = 0; j < 20; j++)
|
||||
{
|
||||
i = pr_dmspawn() % selections;
|
||||
if (G_CheckSpot (playernum, &level.deathmatchstarts[i]) )
|
||||
if (CheckSpot (playernum, &level.deathmatchstarts[i]) )
|
||||
{
|
||||
return &level.deathmatchstarts[i];
|
||||
return &deathmatchstarts[i];
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] return a spot anyway, since we allow telefragging when a player spawns
|
||||
return &level.deathmatchstarts[i];
|
||||
return &deathmatchstarts[i];
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DObject, G_PickDeathmatchStart)
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, PickDeathmatchStart)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
unsigned int selections = level.deathmatchstarts.Size();
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
unsigned int selections = self->deathmatchstarts.Size();
|
||||
DVector3 pos;
|
||||
int angle;
|
||||
if (selections == 0)
|
||||
|
@ -1450,8 +1450,8 @@ DEFINE_ACTION_FUNCTION(DObject, G_PickDeathmatchStart)
|
|||
else
|
||||
{
|
||||
unsigned int i = pr_dmspawn() % selections;
|
||||
angle = level.deathmatchstarts[i].angle;
|
||||
pos = level.deathmatchstarts[i].pos;
|
||||
angle = self->deathmatchstarts[i].angle;
|
||||
pos = self->deathmatchstarts[i].pos;
|
||||
}
|
||||
|
||||
if (numret > 1)
|
||||
|
@ -1466,12 +1466,12 @@ DEFINE_ACTION_FUNCTION(DObject, G_PickDeathmatchStart)
|
|||
return numret;
|
||||
}
|
||||
|
||||
void G_DeathMatchSpawnPlayer (int playernum)
|
||||
void FLevelLocals::DeathMatchSpawnPlayer (int playernum)
|
||||
{
|
||||
unsigned int selections;
|
||||
FPlayerStart *spot;
|
||||
|
||||
selections = level.deathmatchstarts.Size ();
|
||||
selections = deathmatchstarts.Size ();
|
||||
// [RH] We can get by with just 1 deathmatch start
|
||||
if (selections < 1)
|
||||
I_Error ("No deathmatch starts");
|
||||
|
@ -1488,17 +1488,17 @@ void G_DeathMatchSpawnPlayer (int playernum)
|
|||
{ // No good spot, so the player will probably get stuck.
|
||||
// We were probably using select farthest above, and all
|
||||
// the spots were taken.
|
||||
spot = G_PickPlayerStart(playernum, PPS_FORCERANDOM);
|
||||
if (!G_CheckSpot(playernum, spot))
|
||||
spot = PickPlayerStart(playernum, PPS_FORCERANDOM);
|
||||
if (!CheckSpot(playernum, spot))
|
||||
{ // This map doesn't have enough coop spots for this player
|
||||
// to use one.
|
||||
spot = SelectRandomDeathmatchSpot(playernum, selections);
|
||||
if (spot == NULL)
|
||||
{ // We have a player 1 start, right?
|
||||
spot = &level.playerstarts[0];
|
||||
spot = &playerstarts[0];
|
||||
if (spot->type == 0)
|
||||
{ // Fine, whatever.
|
||||
spot = &level.deathmatchstarts[0];
|
||||
spot = &deathmatchstarts[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1511,15 +1511,15 @@ void G_DeathMatchSpawnPlayer (int playernum)
|
|||
//
|
||||
// G_PickPlayerStart
|
||||
//
|
||||
FPlayerStart *G_PickPlayerStart(int playernum, int flags)
|
||||
FPlayerStart *FLevelLocals::PickPlayerStart(int playernum, int flags)
|
||||
{
|
||||
if (level.AllPlayerStarts.Size() == 0) // No starts to pick
|
||||
if (AllPlayerStarts.Size() == 0) // No starts to pick
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM) ||
|
||||
level.playerstarts[playernum].type == 0)
|
||||
if ((flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM) ||
|
||||
playerstarts[playernum].type == 0)
|
||||
{
|
||||
if (!(flags & PPS_NOBLOCKINGCHECK))
|
||||
{
|
||||
|
@ -1529,9 +1529,9 @@ FPlayerStart *G_PickPlayerStart(int playernum, int flags)
|
|||
// Find all unblocked player starts.
|
||||
for (i = 0; i < level.AllPlayerStarts.Size(); ++i)
|
||||
{
|
||||
if (G_CheckSpot(playernum, &level.AllPlayerStarts[i]))
|
||||
if (CheckSpot(playernum, &AllPlayerStarts[i]))
|
||||
{
|
||||
good_starts.Push(&level.AllPlayerStarts[i]);
|
||||
good_starts.Push(&AllPlayerStarts[i]);
|
||||
}
|
||||
}
|
||||
if (good_starts.Size() > 0)
|
||||
|
@ -1540,17 +1540,17 @@ FPlayerStart *G_PickPlayerStart(int playernum, int flags)
|
|||
}
|
||||
}
|
||||
// Pick a spot at random, whether it's open or not.
|
||||
return &level.AllPlayerStarts[pr_pspawn(level.AllPlayerStarts.Size())];
|
||||
return &level.AllPlayerStarts[pr_pspawn(AllPlayerStarts.Size())];
|
||||
}
|
||||
return &level.playerstarts[playernum];
|
||||
return &playerstarts[playernum];
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DObject, G_PickPlayerStart)
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, PickPlayerStart)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_INT(playernum);
|
||||
PARAM_INT(flags);
|
||||
auto ps = G_PickPlayerStart(playernum, flags);
|
||||
auto ps = self->PickPlayerStart(playernum, flags);
|
||||
if (numret > 1)
|
||||
{
|
||||
ret[1].SetInt(ps? ps->angle : 0);
|
||||
|
@ -1566,23 +1566,24 @@ DEFINE_ACTION_FUNCTION(DObject, G_PickPlayerStart)
|
|||
//
|
||||
// G_QueueBody
|
||||
//
|
||||
static void G_QueueBody (AActor *body)
|
||||
void FLevelLocals::QueueBody (AActor *body)
|
||||
{
|
||||
// flush an old corpse if needed
|
||||
int modslot = level.bodyqueslot%level.BODYQUESIZE;
|
||||
level.bodyqueslot = modslot + 1;
|
||||
int modslot = bodyqueslot%level.BODYQUESIZE;
|
||||
bodyqueslot = modslot + 1;
|
||||
|
||||
if (level.bodyqueslot >= level.BODYQUESIZE && level.bodyque[modslot] != NULL)
|
||||
if (bodyqueslot >= BODYQUESIZE && bodyque[modslot] != NULL)
|
||||
{
|
||||
level.bodyque[modslot]->Destroy ();
|
||||
bodyque[modslot]->Destroy ();
|
||||
}
|
||||
level.bodyque[modslot] = body;
|
||||
bodyque[modslot] = body;
|
||||
|
||||
// Copy the player's translation, so that if they change their color later, only
|
||||
// their current body will change and not all their old corpses.
|
||||
if (GetTranslationType(body->Translation) == TRANSLATION_Players ||
|
||||
GetTranslationType(body->Translation) == TRANSLATION_PlayersExtra)
|
||||
{
|
||||
// This needs to be able to handle multiple levels, in case a level with dead players is used as a secondary one later.
|
||||
*translationtables[TRANSLATION_PlayerCorpses][modslot] = *TranslationToTable(body->Translation);
|
||||
body->Translation = TRANSLATION(TRANSLATION_PlayerCorpses,modslot);
|
||||
translationtables[TRANSLATION_PlayerCorpses][modslot]->UpdateNative();
|
||||
|
@ -1606,9 +1607,9 @@ static void G_QueueBody (AActor *body)
|
|||
// G_DoReborn
|
||||
//
|
||||
EXTERN_CVAR(Bool, sv_singleplayerrespawn)
|
||||
void G_DoReborn (int playernum, bool freshbot)
|
||||
void FLevelLocals::DoReborn (int playernum, bool freshbot)
|
||||
{
|
||||
if (!multiplayer && !(level.flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn &&
|
||||
if (!multiplayer && !(flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn &&
|
||||
!G_SkillProperty(SKILLP_PlayerRespawn))
|
||||
{
|
||||
if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars()))
|
||||
|
@ -1633,27 +1634,27 @@ void G_DoReborn (int playernum, bool freshbot)
|
|||
// first disassociate the corpse
|
||||
if (players[playernum].mo)
|
||||
{
|
||||
G_QueueBody (players[playernum].mo);
|
||||
QueueBody (players[playernum].mo);
|
||||
players[playernum].mo->player = NULL;
|
||||
}
|
||||
|
||||
// spawn at random spot if in deathmatch
|
||||
if ((deathmatch || isUnfriendly) && (level.deathmatchstarts.Size () > 0))
|
||||
if ((deathmatch || isUnfriendly) && (deathmatchstarts.Size () > 0))
|
||||
{
|
||||
G_DeathMatchSpawnPlayer (playernum);
|
||||
DeathMatchSpawnPlayer (playernum);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) &&
|
||||
level.playerstarts[playernum].type != 0 &&
|
||||
G_CheckSpot (playernum, &level.playerstarts[playernum]))
|
||||
if (!(flags2 & LEVEL2_RANDOMPLAYERSTARTS) &&
|
||||
playerstarts[playernum].type != 0 &&
|
||||
CheckSpot (playernum, &playerstarts[playernum]))
|
||||
{
|
||||
AActor *mo = P_SpawnPlayer(&level.playerstarts[playernum], playernum);
|
||||
AActor *mo = P_SpawnPlayer(&playerstarts[playernum], playernum);
|
||||
if (mo != NULL) P_PlayerStartStomp(mo, true);
|
||||
}
|
||||
else
|
||||
{ // try to spawn at any random player's spot
|
||||
FPlayerStart *start = G_PickPlayerStart(playernum, PPS_FORCERANDOM);
|
||||
FPlayerStart *start = PickPlayerStart(playernum, PPS_FORCERANDOM);
|
||||
AActor *mo = P_SpawnPlayer(start, playernum);
|
||||
if (mo != NULL) P_PlayerStartStomp(mo, true);
|
||||
}
|
||||
|
|
|
@ -38,9 +38,6 @@ class AActor;
|
|||
//
|
||||
// GAME
|
||||
//
|
||||
void G_DeathMatchSpawnPlayer (int playernum);
|
||||
|
||||
struct FPlayerStart *G_PickPlayerStart (int playernum, int flags = 0);
|
||||
enum
|
||||
{
|
||||
PPS_FORCERANDOM = 1,
|
||||
|
@ -89,7 +86,6 @@ enum EFinishLevelType
|
|||
|
||||
void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags);
|
||||
|
||||
void G_DoReborn (int playernum, bool freshbot);
|
||||
void G_DoPlayerPop(int playernum);
|
||||
|
||||
// Adds pitch to consoleplayer's viewpitch and clamps it
|
||||
|
|
|
@ -693,7 +693,7 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
|
|||
player->mo->special1 = 0;
|
||||
}
|
||||
// ]]
|
||||
G_DoReborn(i, false);
|
||||
level.DoReborn(i, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1360,7 +1360,7 @@ int G_FinishTravel ()
|
|||
pawndup = pawn->player->mo;
|
||||
assert (pawn != pawndup);
|
||||
|
||||
start = G_PickPlayerStart(pnum, 0);
|
||||
start = level.PickPlayerStart(pnum, 0);
|
||||
if (start == NULL)
|
||||
{
|
||||
if (pawndup != nullptr)
|
||||
|
|
|
@ -262,6 +262,17 @@ public:
|
|||
void SpawnExtraPlayers();
|
||||
void Serialize(FSerializer &arc, bool hubload);
|
||||
|
||||
// g_Game
|
||||
void PlayerReborn (int player);
|
||||
bool CheckSpot (int playernum, FPlayerStart *mthing);
|
||||
void DoReborn (int playernum, bool freshbot);
|
||||
void QueueBody (AActor *body);
|
||||
double PlayersRangeFromSpot (FPlayerStart *spot);
|
||||
FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections);
|
||||
FPlayerStart *SelectRandomDeathmatchSpot (int playernum, unsigned int selections);
|
||||
void DeathMatchSpawnPlayer (int playernum);
|
||||
FPlayerStart *PickPlayerStart(int playernum, int flags = 0);
|
||||
|
||||
|
||||
private:
|
||||
// Work data for CollectConnectedGroups.
|
||||
|
|
|
@ -109,8 +109,6 @@
|
|||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
void G_PlayerReborn (int player);
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void PlayerLandedOnThing (AActor *mo, AActor *onmobj);
|
||||
|
@ -4999,7 +4997,7 @@ AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flag
|
|||
state = p->playerstate;
|
||||
if (state == PST_REBORN || state == PST_ENTER)
|
||||
{
|
||||
G_PlayerReborn (playernum);
|
||||
PlayerReborn (playernum);
|
||||
}
|
||||
else if (oldactor != NULL && oldactor->player == p && !(flags & SPF_TEMPPLAYER))
|
||||
{
|
||||
|
|
|
@ -445,7 +445,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame)
|
|||
if (playeringame[i])
|
||||
{
|
||||
players[i].mo = nullptr;
|
||||
G_DeathMatchSpawnPlayer(i);
|
||||
Level->DeathMatchSpawnPlayer(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -457,7 +457,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame)
|
|||
if (playeringame[i])
|
||||
{
|
||||
players[i].mo = nullptr;
|
||||
FPlayerStart *mthing = G_PickPlayerStart(i);
|
||||
FPlayerStart *mthing = Level->PickPlayerStart(i);
|
||||
P_SpawnPlayer(mthing, i, (Level->flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
|
||||
}
|
||||
}
|
||||
|
@ -474,7 +474,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame)
|
|||
if (!(players[i].mo->flags & MF_FRIENDLY))
|
||||
{
|
||||
AActor * oldSpawn = players[i].mo;
|
||||
G_DeathMatchSpawnPlayer(i);
|
||||
Level->DeathMatchSpawnPlayer(i);
|
||||
oldSpawn->Destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -400,8 +400,14 @@ class Object native
|
|||
native static String G_SkillName();
|
||||
native static int G_SkillPropertyInt(int p);
|
||||
native static double G_SkillPropertyFloat(int p);
|
||||
native static vector3, int G_PickDeathmatchStart();
|
||||
native static vector3, int G_PickPlayerStart(int pnum, int flags = 0);
|
||||
deprecated("3.8") static vector3, int G_PickDeathmatchStart()
|
||||
{
|
||||
return level.PickDeathmatchStart();
|
||||
}
|
||||
deprecated("3.8") static vector3, int G_PickPlayerStart(int pnum, int flags = 0)
|
||||
{
|
||||
return level.PickPlayerStart(pnum, flags);
|
||||
}
|
||||
native static void S_Sound (Sound sound_id, int channel, float volume = 1, float attenuation = ATTN_NORM);
|
||||
native static void S_PauseSound (bool notmusic, bool notsfx);
|
||||
native static void S_ResumeSound (bool notsfx);
|
||||
|
@ -703,6 +709,8 @@ struct LevelLocals native
|
|||
native int FindUniqueTid(int start = 0, int limit = 0);
|
||||
native uint GetSkyboxPortal(Actor actor);
|
||||
native void ReplaceTextures(String from, String to, int flags);
|
||||
native vector3, int PickDeathmatchStart();
|
||||
native vector3, int PickPlayerStart(int pnum, int flags = 0);
|
||||
|
||||
native static clearscope bool IsPointInMap(vector3 p);
|
||||
|
||||
|
|
|
@ -157,12 +157,12 @@ class TelOtherFX1 : Actor
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
private static void P_TeleportToPlayerStarts (Actor victim)
|
||||
private void P_TeleportToPlayerStarts (Actor victim)
|
||||
{
|
||||
Vector3 dest;
|
||||
double destAngle;
|
||||
|
||||
[dest, destAngle] = G_PickPlayerStart(0, PPS_FORCERANDOM | PPS_NOBLOCKINGCHECK);
|
||||
[dest, destAngle] = level.PickPlayerStart(0, PPS_FORCERANDOM | PPS_NOBLOCKINGCHECK);
|
||||
dest.Z = ONFLOORZ;
|
||||
victim.Teleport ((dest.xy, ONFLOORZ), destangle, TELF_SOURCEFOG | TELF_DESTFOG);
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ class TelOtherFX1 : Actor
|
|||
Vector3 dest;
|
||||
double destAngle;
|
||||
|
||||
[dest, destAngle] = G_PickDeathmatchStart();
|
||||
[dest, destAngle] = level.PickDeathmatchStart();
|
||||
if (destAngle < 65536) victim.Teleport((dest.xy, ONFLOORZ), destangle, TELF_SOURCEFOG | TELF_DESTFOG);
|
||||
else P_TeleportToPlayerStarts(victim);
|
||||
}
|
||||
|
|
|
@ -30,11 +30,11 @@ class ArtiTeleport : Inventory
|
|||
|
||||
if (deathmatch)
|
||||
{
|
||||
[dest, destAngle] = G_PickDeathmatchStart();
|
||||
[dest, destAngle] = level.PickDeathmatchStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
[dest, destAngle] = G_PickPlayerStart(Owner.PlayerNumber());
|
||||
[dest, destAngle] = level.PickPlayerStart(Owner.PlayerNumber());
|
||||
}
|
||||
dest.Z = ONFLOORZ;
|
||||
Owner.Teleport (dest, destAngle, TELF_SOURCEFOG | TELF_DESTFOG);
|
||||
|
|
Loading…
Reference in a new issue