mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-18 23:21:41 +00:00
- Sync scriptbranch with trunk.
SVN r2269 (scripting)
This commit is contained in:
commit
42ac75e894
127 changed files with 2567 additions and 994 deletions
|
@ -1,5 +1,7 @@
|
||||||
cmake_minimum_required( VERSION 2.4 )
|
cmake_minimum_required( VERSION 2.4 )
|
||||||
|
|
||||||
|
include( CheckFunctionExists )
|
||||||
|
|
||||||
# DUMB is much slower in a Debug build than a Release build, so we force a Release
|
# DUMB is much slower in a Debug build than a Release build, so we force a Release
|
||||||
# build here, since we're not maintaining DUMB, only using it.
|
# build here, since we're not maintaining DUMB, only using it.
|
||||||
# Comment out the below line to allow Debug builds.
|
# Comment out the below line to allow Debug builds.
|
||||||
|
@ -13,6 +15,11 @@ if( CMAKE_COMPILER_IS_GNUC )
|
||||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-pointer-sign -Wno-uninitialized" )
|
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-pointer-sign -Wno-uninitialized" )
|
||||||
endif( CMAKE_COMPILER_IS_GNUC )
|
endif( CMAKE_COMPILER_IS_GNUC )
|
||||||
|
|
||||||
|
CHECK_FUNCTION_EXISTS( itoa ITOA_EXISTS )
|
||||||
|
if( NOT ITOA_EXISTS )
|
||||||
|
add_definitions( -DNEED_ITOA=1 )
|
||||||
|
endif( NOT ITOA_EXISTS )
|
||||||
|
|
||||||
include_directories( include )
|
include_directories( include )
|
||||||
|
|
||||||
add_library( dumb
|
add_library( dumb
|
||||||
|
|
|
@ -58,7 +58,7 @@ int32 dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, int32 dst_size, VO
|
||||||
|
|
||||||
done = 0;
|
done = 0;
|
||||||
dt = (int)(delta * 65536.0 + 0.5);
|
dt = (int)(delta * 65536.0 + 0.5);
|
||||||
if (dt == 0) return 0;
|
if (dt == 0 || dt == 0x80000000) return 0;
|
||||||
SET_VOLUME_VARIABLES;
|
SET_VOLUME_VARIABLES;
|
||||||
|
|
||||||
if (VOLUMES_ARE_ZERO) dst = NULL;
|
if (VOLUMES_ARE_ZERO) dst = NULL;
|
||||||
|
|
|
@ -24,9 +24,6 @@
|
||||||
#include "internal/it.h"
|
#include "internal/it.h"
|
||||||
#include "internal/riff.h"
|
#include "internal/riff.h"
|
||||||
|
|
||||||
DUH *dumb_read_riff_amff( struct riff * stream );
|
|
||||||
DUH *dumb_read_riff_am( struct riff * stream );
|
|
||||||
|
|
||||||
static int it_riff_am_process_sample( IT_SAMPLE * sample, const unsigned char * data, int len, int ver )
|
static int it_riff_am_process_sample( IT_SAMPLE * sample, const unsigned char * data, int len, int ver )
|
||||||
{
|
{
|
||||||
int header_length;
|
int header_length;
|
||||||
|
|
|
@ -291,7 +291,7 @@ static int it_old_psm_read_patterns(IT_PATTERN * pattern, DUMBFILE * f, int num,
|
||||||
if (channel >= chans)
|
if (channel >= chans)
|
||||||
{
|
{
|
||||||
//channel = 0;
|
//channel = 0;
|
||||||
goto error_fb;
|
//goto error_fb;
|
||||||
}
|
}
|
||||||
if (flags & 0x80) {
|
if (flags & 0x80) {
|
||||||
if ((*ptr < 60) && (channel < pchans)) {
|
if ((*ptr < 60) && (channel < pchans)) {
|
||||||
|
|
|
@ -1271,7 +1271,11 @@ DUH *DUMBEXPORT dumb_read_psm_quick(DUMBFILE *f, int subsong)
|
||||||
if ( ver )
|
if ( ver )
|
||||||
{
|
{
|
||||||
tag[2][0] = "FORMATVERSION";
|
tag[2][0] = "FORMATVERSION";
|
||||||
|
#if NEED_ITOA
|
||||||
sprintf(version, "%d", ver);
|
sprintf(version, "%d", ver);
|
||||||
|
#else
|
||||||
|
itoa(ver, version, 10);
|
||||||
|
#endif
|
||||||
tag[2][1] = (const char *) &version;
|
tag[2][1] = (const char *) &version;
|
||||||
++n_tags;
|
++n_tags;
|
||||||
}
|
}
|
||||||
|
|
1
specs/fmod_version.txt
Normal file
1
specs/fmod_version.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
This version of ZDoom must be compiled with any version between 4.22 and 4.28 inclusive.
|
|
@ -12,7 +12,7 @@ DEFINE_SPECIAL(Door_Close, 10, 2, 3, 3)
|
||||||
DEFINE_SPECIAL(Door_Open, 11, 2, 3, 3)
|
DEFINE_SPECIAL(Door_Open, 11, 2, 3, 3)
|
||||||
DEFINE_SPECIAL(Door_Raise, 12, 3, 4, 4)
|
DEFINE_SPECIAL(Door_Raise, 12, 3, 4, 4)
|
||||||
DEFINE_SPECIAL(Door_LockedRaise, 13, 4, 5, 5)
|
DEFINE_SPECIAL(Door_LockedRaise, 13, 4, 5, 5)
|
||||||
DEFINE_SPECIAL(Door_Animated, 14, 3, 3, 3)
|
DEFINE_SPECIAL(Door_Animated, 14, 4, 4, 4)
|
||||||
DEFINE_SPECIAL(Autosave, 15, 0, 0, 0) // [RH] Save the game *now*
|
DEFINE_SPECIAL(Autosave, 15, 0, 0, 0) // [RH] Save the game *now*
|
||||||
DEFINE_SPECIAL(Transfer_WallLight, 16, -1, -1, 2)
|
DEFINE_SPECIAL(Transfer_WallLight, 16, -1, -1, 2)
|
||||||
DEFINE_SPECIAL(Thing_Raise, 17, 1, 1, 1)
|
DEFINE_SPECIAL(Thing_Raise, 17, 1, 1, 1)
|
||||||
|
|
29
src/actor.h
29
src/actor.h
|
@ -552,9 +552,6 @@ public:
|
||||||
|
|
||||||
virtual void Tick ();
|
virtual void Tick ();
|
||||||
|
|
||||||
// Smallest yaw interval for a mapthing to be spawned with
|
|
||||||
virtual angle_t AngleIncrements ();
|
|
||||||
|
|
||||||
// Called when actor dies
|
// Called when actor dies
|
||||||
virtual void Die (AActor *source, AActor *inflictor);
|
virtual void Die (AActor *source, AActor *inflictor);
|
||||||
|
|
||||||
|
@ -691,6 +688,31 @@ public:
|
||||||
return ( abs(x - other->x) < blockdist && abs(y - other->y) < blockdist);
|
return ( abs(x - other->x) < blockdist && abs(y - other->y) < blockdist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PalEntry GetBloodColor() const
|
||||||
|
{
|
||||||
|
return GetClass()->BloodColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
PClassActor *GetBloodType(int type = 0) const
|
||||||
|
{
|
||||||
|
if (type == 0)
|
||||||
|
{
|
||||||
|
return PClass::FindActor(GetClass()->BloodType);
|
||||||
|
}
|
||||||
|
else if (type == 1)
|
||||||
|
{
|
||||||
|
return PClass::FindActor(GetClass()->BloodType2);
|
||||||
|
}
|
||||||
|
else if (type == 2)
|
||||||
|
{
|
||||||
|
return PClass::FindActor(GetClass()->BloodType3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate amount of missile damage
|
// Calculate amount of missile damage
|
||||||
virtual int GetMissileDamage(int mask, int add);
|
virtual int GetMissileDamage(int mask, int add);
|
||||||
|
|
||||||
|
@ -821,6 +843,7 @@ public:
|
||||||
FSoundIDNoInit UseSound; // [RH] Sound to play when an actor is used.
|
FSoundIDNoInit UseSound; // [RH] Sound to play when an actor is used.
|
||||||
FSoundIDNoInit BounceSound;
|
FSoundIDNoInit BounceSound;
|
||||||
FSoundIDNoInit WallBounceSound;
|
FSoundIDNoInit WallBounceSound;
|
||||||
|
FSoundIDNoInit CrushPainSound;
|
||||||
|
|
||||||
fixed_t Speed;
|
fixed_t Speed;
|
||||||
fixed_t FloatSpeed;
|
fixed_t FloatSpeed;
|
||||||
|
|
|
@ -1850,7 +1850,7 @@ void AM_drawPlayers ()
|
||||||
{
|
{
|
||||||
float h, s, v, r, g, b;
|
float h, s, v, r, g, b;
|
||||||
|
|
||||||
D_GetPlayerColor (i, &h, &s, &v);
|
D_GetPlayerColor (i, &h, &s, &v, NULL);
|
||||||
HSVtoRGB (&r, &g, &b, h, s, v);
|
HSVtoRGB (&r, &g, &b, h, s, v);
|
||||||
|
|
||||||
color.FromRGB(clamp (int(r*255.f),0,255), clamp (int(g*255.f),0,255), clamp (int(b*255.f),0,255));
|
color.FromRGB(clamp (int(r*255.f),0,255), clamp (int(g*255.f),0,255), clamp (int(b*255.f),0,255));
|
||||||
|
|
|
@ -118,7 +118,7 @@ bool FCajunMaster::Reachable (AActor *looker, AActor *rtarget)
|
||||||
//in doom is 90 degrees infront.
|
//in doom is 90 degrees infront.
|
||||||
bool FCajunMaster::Check_LOS (AActor *from, AActor *to, angle_t vangle)
|
bool FCajunMaster::Check_LOS (AActor *from, AActor *to, angle_t vangle)
|
||||||
{
|
{
|
||||||
if (!P_CheckSight (from, to, 2))
|
if (!P_CheckSight (from, to, SF_SEEPASTBLOCKEVERYTHING))
|
||||||
return false; // out of sight
|
return false; // out of sight
|
||||||
if (vangle == ANGLE_MAX)
|
if (vangle == ANGLE_MAX)
|
||||||
return true;
|
return true;
|
||||||
|
@ -339,7 +339,7 @@ AActor *FCajunMaster::Choose_Mate (AActor *bot)
|
||||||
&& !p_leader[count]) //taken?
|
&& !p_leader[count]) //taken?
|
||||||
{
|
{
|
||||||
|
|
||||||
if (P_CheckSight (bot, client->mo, 1))
|
if (P_CheckSight (bot, client->mo, SF_IGNOREVISIBILITY))
|
||||||
{
|
{
|
||||||
test = P_AproxDistance (client->mo->x - bot->x,
|
test = P_AproxDistance (client->mo->x - bot->x,
|
||||||
client->mo->y - bot->y);
|
client->mo->y - bot->y);
|
||||||
|
@ -525,7 +525,7 @@ angle_t FCajunMaster::FireRox (AActor *bot, AActor *enemy, ticcmd_t *cmd)
|
||||||
enemy->y + FixedMul(enemy->vely, (m+2*FRACUNIT)), ONFLOORZ, 1);
|
enemy->y + FixedMul(enemy->vely, (m+2*FRACUNIT)), ONFLOORZ, 1);
|
||||||
dist = P_AproxDistance(actor->x-bglobal.body1->x, actor->y-bglobal.body1->y);
|
dist = P_AproxDistance(actor->x-bglobal.body1->x, actor->y-bglobal.body1->y);
|
||||||
//try the predicted location
|
//try the predicted location
|
||||||
if (P_CheckSight (actor, bglobal.body1, 1)) //See the predicted location, so give a test missile
|
if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile
|
||||||
{
|
{
|
||||||
FCheckPosition tm;
|
FCheckPosition tm;
|
||||||
if (SafeCheckPosition (bot, actor->x, actor->y, tm))
|
if (SafeCheckPosition (bot, actor->x, actor->y, tm))
|
||||||
|
|
|
@ -788,8 +788,8 @@ CCMD(info)
|
||||||
AActor *linetarget;
|
AActor *linetarget;
|
||||||
|
|
||||||
if (CheckCheatmode () || players[consoleplayer].mo == NULL) return;
|
if (CheckCheatmode () || players[consoleplayer].mo == NULL) return;
|
||||||
P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, &linetarget, 0,
|
P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE,
|
||||||
false, false, true);
|
&linetarget, 0, ALF_CHECKNONSHOOTABLE|ALF_FORCENOSMART);
|
||||||
if (linetarget)
|
if (linetarget)
|
||||||
{
|
{
|
||||||
Printf("Target=%s, Health=%d, Spawnhealth=%d\n",
|
Printf("Target=%s, Health=%d, Spawnhealth=%d\n",
|
||||||
|
@ -924,6 +924,19 @@ CCMD(nextsecret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CCMD(currentpos)
|
||||||
|
{
|
||||||
|
AActor *mo = players[consoleplayer].mo;
|
||||||
|
Printf("Current player position: (%1.3f,%1.3f,%1.3f), angle: %1.3f, floorheight: %1.3f, sector:%d, lightlevel: %d\n",
|
||||||
|
FIXED2FLOAT(mo->x), FIXED2FLOAT(mo->y), FIXED2FLOAT(mo->z), mo->angle/float(ANGLE_1), FIXED2FLOAT(mo->floorz), mo->Sector->sectornum, mo->Sector->lightlevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
|
@ -1035,6 +1035,32 @@ FString BuildString (int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FString BuildString (int argc, FString *argv)
|
||||||
|
{
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
return *argv;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FString buf;
|
||||||
|
int arg;
|
||||||
|
|
||||||
|
for (arg = 0; arg < argc; arg++)
|
||||||
|
{
|
||||||
|
if (strchr (argv[arg], ' '))
|
||||||
|
{
|
||||||
|
buf << '"' << argv[arg] << "\" ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf << argv[arg] << ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// SubstituteAliasParams
|
// SubstituteAliasParams
|
||||||
|
|
|
@ -59,6 +59,7 @@ void C_SetAlias (const char *name, const char *cmd);
|
||||||
|
|
||||||
// build a single string out of multiple strings
|
// build a single string out of multiple strings
|
||||||
FString BuildString (int argc, char **argv);
|
FString BuildString (int argc, char **argv);
|
||||||
|
FString BuildString (int argc, FString *argv);
|
||||||
|
|
||||||
// Class that can parse command lines
|
// Class that can parse command lines
|
||||||
class FCommandLine
|
class FCommandLine
|
||||||
|
|
|
@ -148,17 +148,13 @@ int Q_filelength (FILE *f)
|
||||||
|
|
||||||
bool FileExists (const char *filename)
|
bool FileExists (const char *filename)
|
||||||
{
|
{
|
||||||
FILE *f;
|
struct stat buff;
|
||||||
|
|
||||||
// [RH] Empty filenames are never there
|
// [RH] Empty filenames are never there
|
||||||
if (filename == NULL || *filename == 0)
|
if (filename == NULL || *filename == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
f = fopen (filename, "r");
|
return stat(filename, &buff) == 0 && !(buff.st_mode & S_IFDIR);
|
||||||
if (!f)
|
|
||||||
return false;
|
|
||||||
fclose (f);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -2135,20 +2135,7 @@ static int PatchText (int oldSize)
|
||||||
|
|
||||||
if (!good)
|
if (!good)
|
||||||
{
|
{
|
||||||
// search cluster text background flats (only if no user-defined MAPINFO is used!)
|
DPrintf (" (Unmatched)\n");
|
||||||
if (strlen(newStr) <= 8 && Wads.CheckNumForName("MAPINFO") >= 0)
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < wadclusterinfos.Size(); i++)
|
|
||||||
{
|
|
||||||
if (!strcmp(wadclusterinfos[i].finaleflat, oldStr))
|
|
||||||
{
|
|
||||||
strcpy(wadclusterinfos[i].finaleflat, newStr);
|
|
||||||
good = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!good) DPrintf (" (Unmatched)\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2904,6 +2891,12 @@ bool ADehackedPickup::TryPickup (AActor *&toucher)
|
||||||
RealPickup = static_cast<AInventory *>(Spawn (type, x, y, z, NO_REPLACE));
|
RealPickup = static_cast<AInventory *>(Spawn (type, x, y, z, NO_REPLACE));
|
||||||
if (RealPickup != NULL)
|
if (RealPickup != NULL)
|
||||||
{
|
{
|
||||||
|
// The internally spawned item should never count towards statistics.
|
||||||
|
if (RealPickup->flags & MF_COUNTITEM)
|
||||||
|
{
|
||||||
|
RealPickup->flags &= ~MF_COUNTITEM;
|
||||||
|
level.total_items--;
|
||||||
|
}
|
||||||
if (!(flags & MF_DROPPED))
|
if (!(flags & MF_DROPPED))
|
||||||
{
|
{
|
||||||
RealPickup->flags &= ~MF_DROPPED;
|
RealPickup->flags &= ~MF_DROPPED;
|
||||||
|
|
133
src/d_main.cpp
133
src/d_main.cpp
|
@ -129,7 +129,7 @@ void D_CheckNetGame ();
|
||||||
void D_ProcessEvents ();
|
void D_ProcessEvents ();
|
||||||
void G_BuildTiccmd (ticcmd_t* cmd);
|
void G_BuildTiccmd (ticcmd_t* cmd);
|
||||||
void D_DoAdvanceDemo ();
|
void D_DoAdvanceDemo ();
|
||||||
void D_AddWildFile (const char *pattern);
|
void D_AddWildFile (TArray<FString> &wadfiles, const char *pattern);
|
||||||
|
|
||||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||||
|
|
||||||
|
@ -657,6 +657,7 @@ void D_Display ()
|
||||||
switch (gamestate)
|
switch (gamestate)
|
||||||
{
|
{
|
||||||
case GS_FULLCONSOLE:
|
case GS_FULLCONSOLE:
|
||||||
|
R_UpdateAnimations(I_FPSTime());
|
||||||
screen->SetBlendingRect(0,0,0,0);
|
screen->SetBlendingRect(0,0,0,0);
|
||||||
hw2d = screen->Begin2D(false);
|
hw2d = screen->Begin2D(false);
|
||||||
C_DrawConsole (false);
|
C_DrawConsole (false);
|
||||||
|
@ -721,6 +722,7 @@ void D_Display ()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GS_INTERMISSION:
|
case GS_INTERMISSION:
|
||||||
|
R_UpdateAnimations(I_FPSTime());
|
||||||
screen->SetBlendingRect(0,0,0,0);
|
screen->SetBlendingRect(0,0,0,0);
|
||||||
hw2d = screen->Begin2D(false);
|
hw2d = screen->Begin2D(false);
|
||||||
WI_Drawer ();
|
WI_Drawer ();
|
||||||
|
@ -728,6 +730,7 @@ void D_Display ()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GS_FINALE:
|
case GS_FINALE:
|
||||||
|
R_UpdateAnimations(I_FPSTime());
|
||||||
screen->SetBlendingRect(0,0,0,0);
|
screen->SetBlendingRect(0,0,0,0);
|
||||||
hw2d = screen->Begin2D(false);
|
hw2d = screen->Begin2D(false);
|
||||||
F_Drawer ();
|
F_Drawer ();
|
||||||
|
@ -735,6 +738,7 @@ void D_Display ()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GS_DEMOSCREEN:
|
case GS_DEMOSCREEN:
|
||||||
|
R_UpdateAnimations(I_FPSTime());
|
||||||
screen->SetBlendingRect(0,0,0,0);
|
screen->SetBlendingRect(0,0,0,0);
|
||||||
hw2d = screen->Begin2D(false);
|
hw2d = screen->Begin2D(false);
|
||||||
D_PageDrawer ();
|
D_PageDrawer ();
|
||||||
|
@ -1478,27 +1482,22 @@ static const char *BaseFileSearch (const char *file, const char *ext, bool lookf
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool ConsiderPatches (const char *arg, const char *ext)
|
bool ConsiderPatches (const char *arg)
|
||||||
{
|
{
|
||||||
bool noDef = false;
|
int i, argc;
|
||||||
DArgs *files = Args->GatherFiles (arg, ext, false);
|
FString *args;
|
||||||
|
|
||||||
if (files->NumArgs() > 0)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
const char *f;
|
const char *f;
|
||||||
|
|
||||||
for (i = 0; i < files->NumArgs(); ++i)
|
argc = Args->CheckParmList(arg, &args);
|
||||||
|
for (i = 0; i < argc; ++i)
|
||||||
|
{
|
||||||
|
if ( (f = BaseFileSearch(args[i], ".deh")) ||
|
||||||
|
(f = BaseFileSearch(args[i], ".bex")) )
|
||||||
{
|
{
|
||||||
if ( (f = BaseFileSearch (files->GetArg (i), ".deh")) )
|
|
||||||
D_LoadDehFile(f);
|
|
||||||
else if ( (f = BaseFileSearch (files->GetArg (i), ".bex")) )
|
|
||||||
D_LoadDehFile(f);
|
D_LoadDehFile(f);
|
||||||
}
|
}
|
||||||
noDef = true;
|
|
||||||
}
|
}
|
||||||
files->Destroy();
|
return argc > 0;
|
||||||
return noDef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1591,40 +1590,18 @@ void D_MultiExec (DArgs *list, bool usePullin)
|
||||||
|
|
||||||
static void GetCmdLineFiles(TArray<FString> &wadfiles)
|
static void GetCmdLineFiles(TArray<FString> &wadfiles)
|
||||||
{
|
{
|
||||||
DArgs *files = Args->GatherFiles ("-file", ".wad", true);
|
FString *args;
|
||||||
DArgs *files1 = Args->GatherFiles (NULL, ".zip", false);
|
int i, argc;
|
||||||
DArgs *files2 = Args->GatherFiles (NULL, ".pk3", false);
|
|
||||||
DArgs *files3 = Args->GatherFiles (NULL, ".txt", false);
|
argc = Args->CheckParmList("-file", &args);
|
||||||
if (files->NumArgs() > 0 || files1->NumArgs() > 0 || files2->NumArgs() > 0 || files3->NumArgs() > 0)
|
if ((gameinfo.flags & GI_SHAREWARE) && argc > 0)
|
||||||
{
|
|
||||||
// Check for -file in shareware
|
|
||||||
if (gameinfo.flags & GI_SHAREWARE)
|
|
||||||
{
|
{
|
||||||
I_FatalError ("You cannot -file with the shareware version. Register!");
|
I_FatalError ("You cannot -file with the shareware version. Register!");
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < argc; ++i)
|
||||||
// the files gathered are wadfile/lump names
|
|
||||||
for (int i = 0; i < files->NumArgs(); i++)
|
|
||||||
{
|
{
|
||||||
D_AddWildFile (wadfiles, files->GetArg (i));
|
D_AddWildFile(wadfiles, args[i]);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < files1->NumArgs(); i++)
|
|
||||||
{
|
|
||||||
D_AddWildFile (wadfiles, files1->GetArg (i));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < files2->NumArgs(); i++)
|
|
||||||
{
|
|
||||||
D_AddWildFile (wadfiles, files2->GetArg (i));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < files3->NumArgs(); i++)
|
|
||||||
{
|
|
||||||
D_AddWildFile (wadfiles, files3->GetArg (i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
files->Destroy();
|
|
||||||
files1->Destroy();
|
|
||||||
files2->Destroy();
|
|
||||||
files3->Destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CopyFiles(TArray<FString> &to, TArray<FString> &from)
|
static void CopyFiles(TArray<FString> &to, TArray<FString> &from)
|
||||||
|
@ -1753,10 +1730,12 @@ static FString CheckGameInfo(TArray<FString> & pwads)
|
||||||
void D_DoomMain (void)
|
void D_DoomMain (void)
|
||||||
{
|
{
|
||||||
int p, flags;
|
int p, flags;
|
||||||
char *v;
|
const char *v;
|
||||||
const char *wad;
|
const char *wad;
|
||||||
DArgs *execFiles;
|
DArgs *execFiles;
|
||||||
TArray<FString> pwads;
|
TArray<FString> pwads;
|
||||||
|
FString *args;
|
||||||
|
int argcount;
|
||||||
|
|
||||||
// Set the FPU precision to 53 significant bits. This is the default
|
// Set the FPU precision to 53 significant bits. This is the default
|
||||||
// for Visual C++, but not for GCC, so some slight math variances
|
// for Visual C++, but not for GCC, so some slight math variances
|
||||||
|
@ -1775,6 +1754,13 @@ void D_DoomMain (void)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Combine different file parameters with their pre-switch bits.
|
||||||
|
Args->CollectFiles("-deh", ".deh");
|
||||||
|
Args->CollectFiles("-bex", ".bex");
|
||||||
|
Args->CollectFiles("-exec", ".cfg");
|
||||||
|
Args->CollectFiles("-playdemo", ".lmp");
|
||||||
|
Args->CollectFiles("-file", NULL); // anythnig left goes after -file
|
||||||
|
|
||||||
PClass::StaticInit ();
|
PClass::StaticInit ();
|
||||||
atterm (C_DeinitConsole);
|
atterm (C_DeinitConsole);
|
||||||
|
|
||||||
|
@ -1861,16 +1847,21 @@ void D_DoomMain (void)
|
||||||
D_MultiExec (execFiles, true);
|
D_MultiExec (execFiles, true);
|
||||||
|
|
||||||
// Run .cfg files at the start of the command line.
|
// Run .cfg files at the start of the command line.
|
||||||
execFiles = Args->GatherFiles (NULL, ".cfg", false);
|
execFiles = Args->GatherFiles ("-exec");
|
||||||
D_MultiExec (execFiles, true);
|
D_MultiExec (execFiles, true);
|
||||||
|
|
||||||
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
|
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
|
||||||
|
|
||||||
CopyFiles(allwads, pwads);
|
CopyFiles(allwads, pwads);
|
||||||
|
|
||||||
|
// Since this function will never leave we must delete this array here manually.
|
||||||
|
pwads.Clear();
|
||||||
|
pwads.ShrinkToFit();
|
||||||
|
|
||||||
Printf ("W_Init: Init WADfiles.\n");
|
Printf ("W_Init: Init WADfiles.\n");
|
||||||
Wads.InitMultipleFiles (allwads);
|
Wads.InitMultipleFiles (allwads);
|
||||||
allwads.Clear();
|
allwads.Clear();
|
||||||
|
allwads.ShrinkToFit();
|
||||||
|
|
||||||
// [RH] Initialize localizable strings.
|
// [RH] Initialize localizable strings.
|
||||||
GStrings.LoadStrings (false);
|
GStrings.LoadStrings (false);
|
||||||
|
@ -1963,21 +1954,23 @@ void D_DoomMain (void)
|
||||||
autostart = true;
|
autostart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [RH] Hack to handle +map
|
// [RH] Hack to handle +map. The standard console command line handler
|
||||||
p = Args->CheckParm ("+map");
|
// won't be able to handle it, so we take it out of the command line and set
|
||||||
if (p && p < Args->NumArgs()-1)
|
// it up like -warp.
|
||||||
|
FString mapvalue = Args->TakeValue("+map");
|
||||||
|
if (mapvalue.IsNotEmpty())
|
||||||
{
|
{
|
||||||
if (!P_CheckMapData(Args->GetArg (p+1)))
|
if (!P_CheckMapData(mapvalue))
|
||||||
{
|
{
|
||||||
Printf ("Can't find map %s\n", Args->GetArg (p+1));
|
Printf ("Can't find map %s\n", mapvalue.GetChars());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
startmap = Args->GetArg (p + 1);
|
startmap = mapvalue;
|
||||||
Args->GetArg (p)[0] = '-';
|
|
||||||
autostart = true;
|
autostart = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (devparm)
|
if (devparm)
|
||||||
{
|
{
|
||||||
Printf ("%s", GStrings("D_DEVSTR"));
|
Printf ("%s", GStrings("D_DEVSTR"));
|
||||||
|
@ -1995,17 +1988,12 @@ void D_DoomMain (void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// turbo option // [RH] (now a cvar)
|
// turbo option // [RH] (now a cvar)
|
||||||
|
v = Args->CheckValue("-turbo");
|
||||||
|
if (v != NULL)
|
||||||
{
|
{
|
||||||
UCVarValue value;
|
double amt = atof(v);
|
||||||
static char one_hundred[] = "100";
|
Printf ("turbo scale: %.0f%%\n", amt);
|
||||||
|
turbo = (float)amt;
|
||||||
value.String = Args->CheckValue ("-turbo");
|
|
||||||
if (value.String == NULL)
|
|
||||||
value.String = one_hundred;
|
|
||||||
else
|
|
||||||
Printf ("turbo scale: %s%%\n", value.String);
|
|
||||||
|
|
||||||
turbo.SetGenericRepDefault (value, CVAR_String);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v = Args->CheckValue ("-timer");
|
v = Args->CheckValue ("-timer");
|
||||||
|
@ -2039,6 +2027,9 @@ void D_DoomMain (void)
|
||||||
StartScreen->AppendStatusLine(temp);
|
StartScreen->AppendStatusLine(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [RH] Load sound environments
|
||||||
|
S_ParseReverbDef ();
|
||||||
|
|
||||||
// [RH] Parse through all loaded mapinfo lumps
|
// [RH] Parse through all loaded mapinfo lumps
|
||||||
Printf ("G_ParseMapInfo: Load map definitions.\n");
|
Printf ("G_ParseMapInfo: Load map definitions.\n");
|
||||||
G_ParseMapInfo (iwad_info->MapInfo);
|
G_ParseMapInfo (iwad_info->MapInfo);
|
||||||
|
@ -2047,7 +2038,6 @@ void D_DoomMain (void)
|
||||||
Printf ("S_InitData: Load sound definitions.\n");
|
Printf ("S_InitData: Load sound definitions.\n");
|
||||||
S_InitData ();
|
S_InitData ();
|
||||||
|
|
||||||
|
|
||||||
Printf ("Texman.Init: Init texture manager.\n");
|
Printf ("Texman.Init: Init texture manager.\n");
|
||||||
TexMan.Init();
|
TexMan.Init();
|
||||||
|
|
||||||
|
@ -2083,7 +2073,7 @@ void D_DoomMain (void)
|
||||||
// If there are none, try adding any in the config file.
|
// If there are none, try adding any in the config file.
|
||||||
// Note that the command line overrides defaults from the config.
|
// Note that the command line overrides defaults from the config.
|
||||||
|
|
||||||
if ((ConsiderPatches("-deh", ".deh") | ConsiderPatches("-bex", ".bex")) == 0 &&
|
if ((ConsiderPatches("-deh") | ConsiderPatches("-bex")) == 0 &&
|
||||||
gameinfo.gametype == GAME_Doom && GameConfig->SetSection ("Doom.DefaultDehacked"))
|
gameinfo.gametype == GAME_Doom && GameConfig->SetSection ("Doom.DefaultDehacked"))
|
||||||
{
|
{
|
||||||
const char *key;
|
const char *key;
|
||||||
|
@ -2121,10 +2111,10 @@ void D_DoomMain (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Added by MC:
|
//Added by MC:
|
||||||
DArgs *bots = Args->GatherFiles("-bots", "", false);
|
argcount = Args->CheckParmList("-bots", &args);
|
||||||
for (p = 0; p < bots->NumArgs(); ++p)
|
for (p = 0; p < argcount; ++p)
|
||||||
{
|
{
|
||||||
bglobal.getspawned.Push(bots->GetArg(p));
|
bglobal.getspawned.Push(args[p]);
|
||||||
}
|
}
|
||||||
bglobal.spawn_tries = 0;
|
bglobal.spawn_tries = 0;
|
||||||
bglobal.wanted_botnum = bglobal.getspawned.Size();
|
bglobal.wanted_botnum = bglobal.getspawned.Size();
|
||||||
|
@ -2174,14 +2164,13 @@ void D_DoomMain (void)
|
||||||
|
|
||||||
V_Init2();
|
V_Init2();
|
||||||
|
|
||||||
DArgs *files = Args->GatherFiles ("-playdemo", ".lmp", false);
|
v = Args->CheckValue("-playdemo");
|
||||||
if (files->NumArgs() > 0)
|
if (v != NULL)
|
||||||
{
|
{
|
||||||
singledemo = true; // quit after one demo
|
singledemo = true; // quit after one demo
|
||||||
G_DeferedPlayDemo (files->GetArg (0));
|
G_DeferedPlayDemo (v);
|
||||||
D_DoomLoop (); // never returns
|
D_DoomLoop (); // never returns
|
||||||
}
|
}
|
||||||
files->Destroy();
|
|
||||||
|
|
||||||
v = Args->CheckValue ("-timedemo");
|
v = Args->CheckValue ("-timedemo");
|
||||||
if (v)
|
if (v)
|
||||||
|
|
|
@ -54,7 +54,8 @@ void D_DoServerInfoChange (BYTE **stream, bool singlebit);
|
||||||
void D_WriteUserInfoStrings (int player, BYTE **stream, bool compact=false);
|
void D_WriteUserInfoStrings (int player, BYTE **stream, bool compact=false);
|
||||||
void D_ReadUserInfoStrings (int player, BYTE **stream, bool update);
|
void D_ReadUserInfoStrings (int player, BYTE **stream, bool update);
|
||||||
|
|
||||||
void D_GetPlayerColor (int player, float *h, float *s, float *v);
|
struct FPlayerColorSet;
|
||||||
|
void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet **colorset);
|
||||||
void D_PickRandomTeam (int player);
|
void D_PickRandomTeam (int player);
|
||||||
int D_PickRandomTeam ();
|
int D_PickRandomTeam ();
|
||||||
class player_t;
|
class player_t;
|
||||||
|
|
|
@ -65,6 +65,7 @@ EXTERN_CVAR (Bool, teamplay)
|
||||||
CVAR (Float, autoaim, 5000.f, CVAR_USERINFO | CVAR_ARCHIVE);
|
CVAR (Float, autoaim, 5000.f, CVAR_USERINFO | CVAR_ARCHIVE);
|
||||||
CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE);
|
CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||||
CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE);
|
CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE);
|
||||||
|
CVAR (Int, colorset, 0, CVAR_USERINFO | CVAR_ARCHIVE);
|
||||||
CVAR (String, skin, "base", CVAR_USERINFO | CVAR_ARCHIVE);
|
CVAR (String, skin, "base", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||||
CVAR (Int, team, TEAM_NONE, CVAR_USERINFO | CVAR_ARCHIVE);
|
CVAR (Int, team, TEAM_NONE, CVAR_USERINFO | CVAR_ARCHIVE);
|
||||||
CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE);
|
CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE);
|
||||||
|
@ -85,6 +86,7 @@ enum
|
||||||
INFO_MoveBob,
|
INFO_MoveBob,
|
||||||
INFO_StillBob,
|
INFO_StillBob,
|
||||||
INFO_PlayerClass,
|
INFO_PlayerClass,
|
||||||
|
INFO_ColorSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *GenderNames[3] = { "male", "female", "other" };
|
const char *GenderNames[3] = { "male", "female", "other" };
|
||||||
|
@ -101,6 +103,7 @@ static const char *UserInfoStrings[] =
|
||||||
"movebob",
|
"movebob",
|
||||||
"stillbob",
|
"stillbob",
|
||||||
"playerclass",
|
"playerclass",
|
||||||
|
"colorset",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -184,10 +187,24 @@ int D_PlayerClassToInt (const char *classname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void D_GetPlayerColor (int player, float *h, float *s, float *v)
|
void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet **set)
|
||||||
{
|
{
|
||||||
userinfo_t *info = &players[player].userinfo;
|
userinfo_t *info = &players[player].userinfo;
|
||||||
int color = info->color;
|
FPlayerColorSet *colorset = NULL;
|
||||||
|
int color;
|
||||||
|
|
||||||
|
if (players[player].mo != NULL)
|
||||||
|
{
|
||||||
|
colorset = P_GetPlayerColorSet(players[player].mo->GetClass()->TypeName, info->colorset);
|
||||||
|
}
|
||||||
|
if (colorset != NULL)
|
||||||
|
{
|
||||||
|
color = GPalette.BaseColors[GPalette.Remap[colorset->RepresentativeColor]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color = info->color;
|
||||||
|
}
|
||||||
|
|
||||||
RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f,
|
RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f,
|
||||||
h, s, v);
|
h, s, v);
|
||||||
|
@ -206,6 +223,10 @@ void D_GetPlayerColor (int player, float *h, float *s, float *v)
|
||||||
*s = clamp(ts + *s * 0.15f - 0.075f, 0.f, 1.f);
|
*s = clamp(ts + *s * 0.15f - 0.075f, 0.f, 1.f);
|
||||||
*v = clamp(tv + *v * 0.5f - 0.25f, 0.f, 1.f);
|
*v = clamp(tv + *v * 0.5f - 0.25f, 0.f, 1.f);
|
||||||
}
|
}
|
||||||
|
if (set != NULL)
|
||||||
|
{
|
||||||
|
*set = colorset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find out which teams are present. If there is only one,
|
// Find out which teams are present. If there is only one,
|
||||||
|
@ -379,6 +400,7 @@ void D_SetupUserInfo ()
|
||||||
coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1));
|
coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1));
|
||||||
}
|
}
|
||||||
coninfo->color = color;
|
coninfo->color = color;
|
||||||
|
coninfo->colorset = colorset;
|
||||||
coninfo->skin = R_FindSkin (skin, 0);
|
coninfo->skin = R_FindSkin (skin, 0);
|
||||||
coninfo->gender = D_GenderToInt (gender);
|
coninfo->gender = D_GenderToInt (gender);
|
||||||
coninfo->neverswitch = neverswitchonpickup;
|
coninfo->neverswitch = neverswitchonpickup;
|
||||||
|
@ -564,6 +586,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
|
||||||
"\\name\\%s"
|
"\\name\\%s"
|
||||||
"\\autoaim\\%g"
|
"\\autoaim\\%g"
|
||||||
"\\color\\%x %x %x"
|
"\\color\\%x %x %x"
|
||||||
|
"\\colorset\\%d"
|
||||||
"\\skin\\%s"
|
"\\skin\\%s"
|
||||||
"\\team\\%d"
|
"\\team\\%d"
|
||||||
"\\gender\\%s"
|
"\\gender\\%s"
|
||||||
|
@ -574,6 +597,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
|
||||||
,
|
,
|
||||||
D_EscapeUserInfo(info->netname).GetChars(),
|
D_EscapeUserInfo(info->netname).GetChars(),
|
||||||
(double)info->aimdist / (float)ANGLE_1,
|
(double)info->aimdist / (float)ANGLE_1,
|
||||||
|
info->colorset,
|
||||||
RPART(info->color), GPART(info->color), BPART(info->color),
|
RPART(info->color), GPART(info->color), BPART(info->color),
|
||||||
D_EscapeUserInfo(skins[info->skin].name).GetChars(),
|
D_EscapeUserInfo(skins[info->skin].name).GetChars(),
|
||||||
info->team,
|
info->team,
|
||||||
|
@ -599,6 +623,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
|
||||||
"\\%g" // movebob
|
"\\%g" // movebob
|
||||||
"\\%g" // stillbob
|
"\\%g" // stillbob
|
||||||
"\\%s" // playerclass
|
"\\%s" // playerclass
|
||||||
|
"\\%d" // colorset
|
||||||
,
|
,
|
||||||
D_EscapeUserInfo(info->netname).GetChars(),
|
D_EscapeUserInfo(info->netname).GetChars(),
|
||||||
(double)info->aimdist / (float)ANGLE_1,
|
(double)info->aimdist / (float)ANGLE_1,
|
||||||
|
@ -610,7 +635,8 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
|
||||||
info->neverswitch,
|
info->neverswitch,
|
||||||
(float)(info->MoveBob) / 65536.f,
|
(float)(info->MoveBob) / 65536.f,
|
||||||
(float)(info->StillBob) / 65536.f,
|
(float)(info->StillBob) / 65536.f,
|
||||||
info->PlayerClass == -1 ? "Random" : D_EscapeUserInfo(type->DisplayName).GetChars()
|
info->PlayerClass == -1 ? "Random" : D_EscapeUserInfo(type->DisplayName).GetChars(),
|
||||||
|
info->colorset
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -714,7 +740,15 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INFO_Color:
|
case INFO_Color:
|
||||||
|
case INFO_ColorSet:
|
||||||
|
if (infotype == INFO_Color)
|
||||||
|
{
|
||||||
info->color = V_GetColorFromString (NULL, value);
|
info->color = V_GetColorFromString (NULL, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info->colorset = atoi(value);
|
||||||
|
}
|
||||||
R_BuildPlayerTranslation (i);
|
R_BuildPlayerTranslation (i);
|
||||||
if (StatusBar != NULL && i == StatusBar->GetPlayer())
|
if (StatusBar != NULL && i == StatusBar->GetPlayer())
|
||||||
{
|
{
|
||||||
|
@ -804,6 +838,10 @@ FArchive &operator<< (FArchive &arc, userinfo_t &info)
|
||||||
arc.Read (&info.netname, sizeof(info.netname));
|
arc.Read (&info.netname, sizeof(info.netname));
|
||||||
}
|
}
|
||||||
arc << info.team << info.aimdist << info.color << info.skin << info.gender << info.neverswitch;
|
arc << info.team << info.aimdist << info.color << info.skin << info.gender << info.neverswitch;
|
||||||
|
if (SaveVersion >= 2193)
|
||||||
|
{
|
||||||
|
arc << info.colorset;
|
||||||
|
}
|
||||||
return arc;
|
return arc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,6 +867,7 @@ CCMD (playerinfo)
|
||||||
Printf ("Team: %s (%d)\n", ui->team == TEAM_NONE ? "None" : Teams[ui->team].GetName (), ui->team);
|
Printf ("Team: %s (%d)\n", ui->team == TEAM_NONE ? "None" : Teams[ui->team].GetName (), ui->team);
|
||||||
Printf ("Aimdist: %d\n", ui->aimdist);
|
Printf ("Aimdist: %d\n", ui->aimdist);
|
||||||
Printf ("Color: %06x\n", ui->color);
|
Printf ("Color: %06x\n", ui->color);
|
||||||
|
Printf ("ColorSet: %d\n", ui->colorset);
|
||||||
Printf ("Skin: %s (%d)\n", skins[ui->skin].name, ui->skin);
|
Printf ("Skin: %s (%d)\n", skins[ui->skin].name, ui->skin);
|
||||||
Printf ("Gender: %s (%d)\n", GenderNames[ui->gender], ui->gender);
|
Printf ("Gender: %s (%d)\n", GenderNames[ui->gender], ui->gender);
|
||||||
Printf ("NeverSwitch: %d\n", ui->neverswitch);
|
Printf ("NeverSwitch: %d\n", ui->neverswitch);
|
||||||
|
|
|
@ -65,6 +65,11 @@ public:
|
||||||
BYTE ColorRangeEnd;
|
BYTE ColorRangeEnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum);
|
||||||
|
void P_EnumPlayerColorSets(FName classname, TArray<int> *out);
|
||||||
|
|
||||||
|
class player_t;
|
||||||
|
|
||||||
class APlayerPawn : public AActor
|
class APlayerPawn : public AActor
|
||||||
{
|
{
|
||||||
DECLARE_CLASS_WITH_META(APlayerPawn, AActor, PClassPlayerPawn)
|
DECLARE_CLASS_WITH_META(APlayerPawn, AActor, PClassPlayerPawn)
|
||||||
|
@ -215,6 +220,7 @@ struct userinfo_t
|
||||||
BYTE team;
|
BYTE team;
|
||||||
int aimdist;
|
int aimdist;
|
||||||
int color;
|
int color;
|
||||||
|
int colorset;
|
||||||
int skin;
|
int skin;
|
||||||
int gender;
|
int gender;
|
||||||
bool neverswitch;
|
bool neverswitch;
|
||||||
|
|
|
@ -227,10 +227,10 @@ struct mapseg_t
|
||||||
{
|
{
|
||||||
WORD v1;
|
WORD v1;
|
||||||
WORD v2;
|
WORD v2;
|
||||||
short angle;
|
SWORD angle;
|
||||||
WORD linedef;
|
WORD linedef;
|
||||||
short side;
|
SWORD side;
|
||||||
short offset;
|
SWORD offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,11 +242,11 @@ struct mapseg_t
|
||||||
|
|
||||||
struct mapnode_t
|
struct mapnode_t
|
||||||
{
|
{
|
||||||
short x,y,dx,dy; // partition line
|
SWORD x,y,dx,dy; // partition line
|
||||||
short bbox[2][4]; // bounding box for each child
|
SWORD bbox[2][4]; // bounding box for each child
|
||||||
// If NF_SUBSECTOR is or'ed in, it's a subsector,
|
// If NF_SUBSECTOR is or'ed in, it's a subsector,
|
||||||
// else it's a node of another subtree.
|
// else it's a node of another subtree.
|
||||||
unsigned short children[2];
|
WORD children[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,23 +256,23 @@ struct mapnode_t
|
||||||
// plus skill/visibility flags and attributes.
|
// plus skill/visibility flags and attributes.
|
||||||
struct mapthing_t
|
struct mapthing_t
|
||||||
{
|
{
|
||||||
short x;
|
SWORD x;
|
||||||
short y;
|
SWORD y;
|
||||||
short angle;
|
SWORD angle;
|
||||||
short type;
|
SWORD type;
|
||||||
short options;
|
SWORD options;
|
||||||
};
|
};
|
||||||
|
|
||||||
// [RH] Hexen-compatible MapThing.
|
// [RH] Hexen-compatible MapThing.
|
||||||
struct mapthinghexen_t
|
struct mapthinghexen_t
|
||||||
{
|
{
|
||||||
unsigned short thingid;
|
SWORD thingid;
|
||||||
short x;
|
SWORD x;
|
||||||
short y;
|
SWORD y;
|
||||||
short z;
|
SWORD z;
|
||||||
short angle;
|
SWORD angle;
|
||||||
short type;
|
SWORD type;
|
||||||
short flags;
|
SWORD flags;
|
||||||
BYTE special;
|
BYTE special;
|
||||||
BYTE args[5];
|
BYTE args[5];
|
||||||
};
|
};
|
||||||
|
|
|
@ -117,6 +117,10 @@ void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int
|
||||||
}
|
}
|
||||||
|
|
||||||
FinaleFlat = (flat != NULL && *flat != 0) ? flat : gameinfo.finaleFlat;
|
FinaleFlat = (flat != NULL && *flat != 0) ? flat : gameinfo.finaleFlat;
|
||||||
|
if (FinaleFlat != NULL && FinaleFlat[0] == '$')
|
||||||
|
{
|
||||||
|
FinaleFlat = GStrings(FinaleFlat + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (textInLump)
|
if (textInLump)
|
||||||
{
|
{
|
||||||
|
@ -758,7 +762,7 @@ void F_CastDrawer (void)
|
||||||
FTexture* pic;
|
FTexture* pic;
|
||||||
|
|
||||||
// erase the entire screen to a background
|
// erase the entire screen to a background
|
||||||
screen->DrawTexture (TexMan["BOSSBACK"], 0, 0,
|
screen->DrawTexture (TexMan[GStrings("bgcastcall")], 0, 0,
|
||||||
DTA_DestWidth, screen->GetWidth(),
|
DTA_DestWidth, screen->GetWidth(),
|
||||||
DTA_DestHeight, screen->GetHeight(),
|
DTA_DestHeight, screen->GetHeight(),
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
|
|
|
@ -126,7 +126,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosRefire)
|
||||||
if (!self->target
|
if (!self->target
|
||||||
|| P_HitFriend (self)
|
|| P_HitFriend (self)
|
||||||
|| self->target->health <= 0
|
|| self->target->health <= 0
|
||||||
|| !P_CheckSight (self, self->target, 0) )
|
|| !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES))
|
||||||
{
|
{
|
||||||
self->SetState (self->SeeState);
|
self->SetState (self->SeeState);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpidRefire)
|
||||||
if (!self->target
|
if (!self->target
|
||||||
|| P_HitFriend (self)
|
|| P_HitFriend (self)
|
||||||
|| self->target->health <= 0
|
|| self->target->health <= 0
|
||||||
|| !P_CheckSight (self, self->target, 0) )
|
|| !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES))
|
||||||
{
|
{
|
||||||
self->SetState (self->SeeState);
|
self->SetState (self->SeeState);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2192,18 +2192,14 @@ void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf)
|
||||||
//
|
//
|
||||||
// G_RecordDemo
|
// G_RecordDemo
|
||||||
//
|
//
|
||||||
void G_RecordDemo (char* name)
|
void G_RecordDemo (const char* name)
|
||||||
{
|
{
|
||||||
char *v;
|
|
||||||
|
|
||||||
usergame = false;
|
usergame = false;
|
||||||
strcpy (demoname, name);
|
strcpy (demoname, name);
|
||||||
FixPathSeperator (demoname);
|
FixPathSeperator (demoname);
|
||||||
DefaultExtension (demoname, ".lmp");
|
DefaultExtension (demoname, ".lmp");
|
||||||
v = Args->CheckValue ("-maxdemo");
|
|
||||||
maxdemosize = 0x20000;
|
maxdemosize = 0x20000;
|
||||||
demobuffer = (BYTE *)M_Malloc (maxdemosize);
|
demobuffer = (BYTE *)M_Malloc (maxdemosize);
|
||||||
|
|
||||||
demorecording = true;
|
demorecording = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2288,7 +2284,7 @@ void G_BeginRecording (const char *startmap)
|
||||||
|
|
||||||
FString defdemoname;
|
FString defdemoname;
|
||||||
|
|
||||||
void G_DeferedPlayDemo (char *name)
|
void G_DeferedPlayDemo (const char *name)
|
||||||
{
|
{
|
||||||
defdemoname = name;
|
defdemoname = name;
|
||||||
gameaction = ga_playdemo;
|
gameaction = ga_playdemo;
|
||||||
|
@ -2516,7 +2512,7 @@ void G_DoPlayDemo (void)
|
||||||
//
|
//
|
||||||
// G_TimeDemo
|
// G_TimeDemo
|
||||||
//
|
//
|
||||||
void G_TimeDemo (char* name)
|
void G_TimeDemo (const char* name)
|
||||||
{
|
{
|
||||||
nodrawers = !!Args->CheckParm ("-nodraw");
|
nodrawers = !!Args->CheckParm ("-nodraw");
|
||||||
noblit = !!Args->CheckParm ("-noblit");
|
noblit = !!Args->CheckParm ("-noblit");
|
||||||
|
|
|
@ -32,7 +32,7 @@ struct PNGHandle;
|
||||||
//
|
//
|
||||||
void G_DeathMatchSpawnPlayer (int playernum);
|
void G_DeathMatchSpawnPlayer (int playernum);
|
||||||
|
|
||||||
void G_DeferedPlayDemo (char* demo);
|
void G_DeferedPlayDemo (const char* demo);
|
||||||
|
|
||||||
// Can be called by the startup code or M_Responder,
|
// Can be called by the startup code or M_Responder,
|
||||||
// calls P_SetupLevel or W_EnterWorld.
|
// calls P_SetupLevel or W_EnterWorld.
|
||||||
|
@ -44,12 +44,12 @@ void G_DoLoadGame (void);
|
||||||
void G_SaveGame (const char *filename, const char *description);
|
void G_SaveGame (const char *filename, const char *description);
|
||||||
|
|
||||||
// Only called by startup code.
|
// Only called by startup code.
|
||||||
void G_RecordDemo (char* name);
|
void G_RecordDemo (const char* name);
|
||||||
|
|
||||||
void G_BeginRecording (const char *startmap);
|
void G_BeginRecording (const char *startmap);
|
||||||
|
|
||||||
void G_PlayDemo (char* name);
|
void G_PlayDemo (char* name);
|
||||||
void G_TimeDemo (char* name);
|
void G_TimeDemo (const char* name);
|
||||||
bool G_CheckDemoStatus (void);
|
bool G_CheckDemoStatus (void);
|
||||||
|
|
||||||
void G_WorldDone (void);
|
void G_WorldDone (void);
|
||||||
|
|
|
@ -69,7 +69,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
angle = pmo->angle+i*(ANG45/16);
|
angle = pmo->angle+i*(ANG45/16);
|
||||||
slope = P_AimLineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, false, true);
|
slope = P_AimLineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D);
|
||||||
if (linetarget)
|
if (linetarget)
|
||||||
{
|
{
|
||||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindActor("CStaffPuff"));
|
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindActor("CStaffPuff"));
|
||||||
|
@ -93,7 +93,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
angle = pmo->angle-i*(ANG45/16);
|
angle = pmo->angle-i*(ANG45/16);
|
||||||
slope = P_AimLineAttack (player->mo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, false, true);
|
slope = P_AimLineAttack (player->mo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D);
|
||||||
if (linetarget)
|
if (linetarget)
|
||||||
{
|
{
|
||||||
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindActor("CStaffPuff"));
|
P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindActor("CStaffPuff"));
|
||||||
|
|
|
@ -50,7 +50,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
angle = pmo->angle + i*(ANG45/32);
|
angle = pmo->angle + i*(ANG45/32);
|
||||||
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, false, true);
|
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
|
||||||
if (linetarget)
|
if (linetarget)
|
||||||
{
|
{
|
||||||
P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true);
|
P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true);
|
||||||
|
@ -63,7 +63,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
|
||||||
goto hammerdone;
|
goto hammerdone;
|
||||||
}
|
}
|
||||||
angle = pmo->angle-i*(ANG45/32);
|
angle = pmo->angle-i*(ANG45/32);
|
||||||
slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &linetarget, 0, false, true);
|
slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
|
||||||
if(linetarget)
|
if(linetarget)
|
||||||
{
|
{
|
||||||
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true);
|
P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true);
|
||||||
|
@ -78,7 +78,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack)
|
||||||
}
|
}
|
||||||
// didn't find any targets in meleerange, so set to throw out a hammer
|
// didn't find any targets in meleerange, so set to throw out a hammer
|
||||||
angle = pmo->angle;
|
angle = pmo->angle;
|
||||||
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, false, true);
|
slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D);
|
||||||
if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true) != NULL)
|
if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true) != NULL)
|
||||||
{
|
{
|
||||||
pmo->special1 = false;
|
pmo->special1 = false;
|
||||||
|
|
|
@ -79,7 +79,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1)
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
angle = self->angle+i*(ANG45/16);
|
angle = self->angle+i*(ANG45/16);
|
||||||
slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget, 0, false, true);
|
slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget, 0, ALF_CHECK3D);
|
||||||
if (linetarget)
|
if (linetarget)
|
||||||
{
|
{
|
||||||
P_DamageMobj (linetarget, self, self, damage, NAME_Ice);
|
P_DamageMobj (linetarget, self, self, damage, NAME_Ice);
|
||||||
|
|
|
@ -572,7 +572,7 @@ void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nex
|
||||||
|
|
||||||
if (strncmp(levelname, "enDSeQ", 6) != 0)
|
if (strncmp(levelname, "enDSeQ", 6) != 0)
|
||||||
{
|
{
|
||||||
nextinfo = FindLevelInfo (nextlevel);
|
nextinfo = FindLevelInfo (levelname);
|
||||||
if (nextinfo != NULL)
|
if (nextinfo != NULL)
|
||||||
{
|
{
|
||||||
level_info_t *nextredir = nextinfo->CheckLevelRedirect();
|
level_info_t *nextredir = nextinfo->CheckLevelRedirect();
|
||||||
|
@ -1039,7 +1039,7 @@ void G_WorldDone (void)
|
||||||
{
|
{
|
||||||
F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder,
|
F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder,
|
||||||
thiscluster->cdtrack, thiscluster->cdid,
|
thiscluster->cdtrack, thiscluster->cdid,
|
||||||
thiscluster->finaleflat, thiscluster->ExitText,
|
thiscluster->FinaleFlat, thiscluster->ExitText,
|
||||||
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
|
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
|
||||||
thiscluster->flags & CLUSTER_FINALEPIC,
|
thiscluster->flags & CLUSTER_FINALEPIC,
|
||||||
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
|
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
|
||||||
|
@ -1057,7 +1057,7 @@ void G_WorldDone (void)
|
||||||
{
|
{
|
||||||
F_StartFinale (nextcluster->MessageMusic, nextcluster->musicorder,
|
F_StartFinale (nextcluster->MessageMusic, nextcluster->musicorder,
|
||||||
nextcluster->cdtrack, nextcluster->cdid,
|
nextcluster->cdtrack, nextcluster->cdid,
|
||||||
nextcluster->finaleflat, nextcluster->EnterText,
|
nextcluster->FinaleFlat, nextcluster->EnterText,
|
||||||
nextcluster->flags & CLUSTER_ENTERTEXTINLUMP,
|
nextcluster->flags & CLUSTER_ENTERTEXTINLUMP,
|
||||||
nextcluster->flags & CLUSTER_FINALEPIC,
|
nextcluster->flags & CLUSTER_FINALEPIC,
|
||||||
nextcluster->flags & CLUSTER_LOOKUPENTERTEXT,
|
nextcluster->flags & CLUSTER_LOOKUPENTERTEXT,
|
||||||
|
@ -1067,7 +1067,7 @@ void G_WorldDone (void)
|
||||||
{
|
{
|
||||||
F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder,
|
F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder,
|
||||||
thiscluster->cdtrack, nextcluster->cdid,
|
thiscluster->cdtrack, nextcluster->cdid,
|
||||||
thiscluster->finaleflat, thiscluster->ExitText,
|
thiscluster->FinaleFlat, thiscluster->ExitText,
|
||||||
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
|
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
|
||||||
thiscluster->flags & CLUSTER_FINALEPIC,
|
thiscluster->flags & CLUSTER_FINALEPIC,
|
||||||
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
|
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
|
||||||
|
@ -1319,6 +1319,8 @@ void G_InitLevelLocals ()
|
||||||
compatflags.Callback();
|
compatflags.Callback();
|
||||||
|
|
||||||
NormalLight.ChangeFade (level.fadeto);
|
NormalLight.ChangeFade (level.fadeto);
|
||||||
|
|
||||||
|
level.DefaultEnvironment = info->DefaultEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -66,15 +66,16 @@ struct FMapInfoParser
|
||||||
int format_type;
|
int format_type;
|
||||||
bool HexenHack;
|
bool HexenHack;
|
||||||
|
|
||||||
FMapInfoParser()
|
FMapInfoParser(int format = FMT_Unknown)
|
||||||
{
|
{
|
||||||
format_type = FMT_Unknown;
|
format_type = format;
|
||||||
HexenHack = false;
|
HexenHack = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParseLookupName(FString &dest);
|
bool ParseLookupName(FString &dest);
|
||||||
void ParseMusic(FString &name, int &order);
|
void ParseMusic(FString &name, int &order);
|
||||||
void ParseLumpOrTextureName(char *name);
|
void ParseLumpOrTextureName(char *name);
|
||||||
|
void ParseLumpOrTextureName(FString &name);
|
||||||
|
|
||||||
void ParseCluster();
|
void ParseCluster();
|
||||||
void ParseNextMap(char *mapname);
|
void ParseNextMap(char *mapname);
|
||||||
|
@ -276,6 +277,7 @@ struct level_info_t
|
||||||
DWORD compatflags;
|
DWORD compatflags;
|
||||||
DWORD compatmask;
|
DWORD compatmask;
|
||||||
FString Translator; // for converting Doom-format linedef and sector types.
|
FString Translator; // for converting Doom-format linedef and sector types.
|
||||||
|
int DefaultEnvironment; // Default sound environment for the map.
|
||||||
|
|
||||||
// Redirection: If any player is carrying the specified item, then
|
// Redirection: If any player is carrying the specified item, then
|
||||||
// you go to the RedirectMap instead of this one.
|
// you go to the RedirectMap instead of this one.
|
||||||
|
@ -388,6 +390,7 @@ struct FLevelLocals
|
||||||
fixed_t aircontrol;
|
fixed_t aircontrol;
|
||||||
fixed_t airfriction;
|
fixed_t airfriction;
|
||||||
int airsupply;
|
int airsupply;
|
||||||
|
int DefaultEnvironment; // Default sound environment.
|
||||||
|
|
||||||
FSectorScrollValues *Scrolls; // NULL if no DScrollers in this level
|
FSectorScrollValues *Scrolls; // NULL if no DScrollers in this level
|
||||||
|
|
||||||
|
@ -437,7 +440,7 @@ extern TArray<EndSequence> EndSequences;
|
||||||
struct cluster_info_t
|
struct cluster_info_t
|
||||||
{
|
{
|
||||||
int cluster;
|
int cluster;
|
||||||
char finaleflat[9];
|
FString FinaleFlat;
|
||||||
FString ExitText;
|
FString ExitText;
|
||||||
FString EnterText;
|
FString EnterText;
|
||||||
FString MessageMusic;
|
FString MessageMusic;
|
||||||
|
|
|
@ -265,6 +265,7 @@ void level_info_t::Reset()
|
||||||
bordertexture[0] = 0;
|
bordertexture[0] = 0;
|
||||||
teamdamage = 0.f;
|
teamdamage = 0.f;
|
||||||
specialactions.Clear();
|
specialactions.Clear();
|
||||||
|
DefaultEnvironment = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -389,7 +390,7 @@ bool level_info_t::isValid()
|
||||||
void cluster_info_t::Reset()
|
void cluster_info_t::Reset()
|
||||||
{
|
{
|
||||||
cluster = 0;
|
cluster = 0;
|
||||||
finaleflat[0] = 0;
|
FinaleFlat = "";
|
||||||
ExitText = "";
|
ExitText = "";
|
||||||
EnterText = "";
|
EnterText = "";
|
||||||
MessageMusic = "";
|
MessageMusic = "";
|
||||||
|
@ -615,6 +616,12 @@ void FMapInfoParser::ParseLumpOrTextureName(char *name)
|
||||||
name[8]=0;
|
name[8]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FMapInfoParser::ParseLumpOrTextureName(FString &name)
|
||||||
|
{
|
||||||
|
sc.MustGetString();
|
||||||
|
name = sc.String;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -691,12 +698,12 @@ void FMapInfoParser::ParseCluster()
|
||||||
else if (sc.Compare("flat"))
|
else if (sc.Compare("flat"))
|
||||||
{
|
{
|
||||||
ParseAssign();
|
ParseAssign();
|
||||||
ParseLumpOrTextureName(clusterinfo->finaleflat);
|
ParseLumpOrTextureName(clusterinfo->FinaleFlat);
|
||||||
}
|
}
|
||||||
else if (sc.Compare("pic"))
|
else if (sc.Compare("pic"))
|
||||||
{
|
{
|
||||||
ParseAssign();
|
ParseAssign();
|
||||||
ParseLumpOrTextureName(clusterinfo->finaleflat);
|
ParseLumpOrTextureName(clusterinfo->FinaleFlat);
|
||||||
clusterinfo->flags |= CLUSTER_FINALEPIC;
|
clusterinfo->flags |= CLUSTER_FINALEPIC;
|
||||||
}
|
}
|
||||||
else if (sc.Compare("hub"))
|
else if (sc.Compare("hub"))
|
||||||
|
@ -1244,6 +1251,36 @@ DEFINE_MAP_OPTION(mapbackground, true)
|
||||||
parse.ParseLumpOrTextureName(info->mapbg);
|
parse.ParseLumpOrTextureName(info->mapbg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_MAP_OPTION(defaultenvironment, false)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
|
||||||
|
parse.ParseAssign();
|
||||||
|
if (parse.sc.CheckNumber())
|
||||||
|
{ // Numeric ID XXX [, YYY]
|
||||||
|
id = parse.sc.Number << 8;
|
||||||
|
if (parse.CheckNumber())
|
||||||
|
{
|
||||||
|
id |= parse.sc.Number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Named environment
|
||||||
|
parse.sc.MustGetString();
|
||||||
|
ReverbContainer *reverb = S_FindEnvironment(parse.sc.String);
|
||||||
|
if (reverb == NULL)
|
||||||
|
{
|
||||||
|
parse.sc.ScriptMessage("Unknown sound environment '%s'\n", parse.sc.String);
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id = reverb->ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info->DefaultEnvironment = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -1923,10 +1960,23 @@ void G_ParseMapInfo (const char *basemapinfo)
|
||||||
parse.ParseMapInfo(Wads.GetNumForFullName(basemapinfo), gamedefaults, defaultinfo);
|
parse.ParseMapInfo(Wads.GetNumForFullName(basemapinfo), gamedefaults, defaultinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *mapinfonames[] = { "MAPINFO", "ZMAPINFO", NULL };
|
||||||
|
int nindex;
|
||||||
|
|
||||||
// Parse any extra MAPINFOs.
|
// Parse any extra MAPINFOs.
|
||||||
while ((lump = Wads.FindLump ("MAPINFO", &lastlump)) != -1)
|
while ((lump = Wads.FindLumpMulti (mapinfonames, &lastlump, false, &nindex)) != -1)
|
||||||
{
|
{
|
||||||
FMapInfoParser parse;
|
if (nindex == 0)
|
||||||
|
{
|
||||||
|
// If this lump is named MAPINFO we need to check if the same WAD contains a ZMAPINFO lump.
|
||||||
|
// If that exists we need to skip this one.
|
||||||
|
|
||||||
|
int wad = Wads.GetLumpFile(lump);
|
||||||
|
int altlump = Wads.CheckNumForName("ZMAPINFO", ns_global, wad, true);
|
||||||
|
|
||||||
|
if (altlump >= 0) continue;
|
||||||
|
}
|
||||||
|
FMapInfoParser parse(nindex == 1? FMapInfoParser::FMT_New : FMapInfoParser::FMT_Unknown);
|
||||||
level_info_t defaultinfo;
|
level_info_t defaultinfo;
|
||||||
parse.ParseMapInfo(lump, gamedefaults, defaultinfo);
|
parse.ParseMapInfo(lump, gamedefaults, defaultinfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,12 @@ void APowerup::DoEffect ()
|
||||||
|
|
||||||
void APowerup::EndEffect ()
|
void APowerup::EndEffect ()
|
||||||
{
|
{
|
||||||
|
int colormap = GetSpecialColormap(BlendColor);
|
||||||
|
|
||||||
|
if (colormap != NOFIXEDCOLORMAP && Owner && Owner->player && Owner->player->fixedcolormap == colormap)
|
||||||
|
{ // only unset if the fixed colormap comes from this item
|
||||||
|
Owner->player->fixedcolormap = NOFIXEDCOLORMAP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -347,6 +353,7 @@ IMPLEMENT_CLASS (APowerInvulnerable)
|
||||||
|
|
||||||
void APowerInvulnerable::InitEffect ()
|
void APowerInvulnerable::InitEffect ()
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
Owner->effects &= ~FX_RESPAWNINVUL;
|
Owner->effects &= ~FX_RESPAWNINVUL;
|
||||||
Owner->flags2 |= MF2_INVULNERABLE;
|
Owner->flags2 |= MF2_INVULNERABLE;
|
||||||
if (Mode == NAME_None && Owner->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
|
if (Mode == NAME_None && Owner->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
|
||||||
|
@ -421,6 +428,8 @@ void APowerInvulnerable::DoEffect ()
|
||||||
|
|
||||||
void APowerInvulnerable::EndEffect ()
|
void APowerInvulnerable::EndEffect ()
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
|
|
||||||
if (Owner == NULL)
|
if (Owner == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -498,6 +507,7 @@ bool APowerStrength::HandlePickup (AInventory *item)
|
||||||
|
|
||||||
void APowerStrength::InitEffect ()
|
void APowerStrength::InitEffect ()
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -537,7 +547,6 @@ PalEntry APowerStrength::GetBlend ()
|
||||||
// Invisibility Powerup ------------------------------------------------------
|
// Invisibility Powerup ------------------------------------------------------
|
||||||
|
|
||||||
IMPLEMENT_CLASS (APowerInvisibility)
|
IMPLEMENT_CLASS (APowerInvisibility)
|
||||||
IMPLEMENT_CLASS (APowerShadow)
|
|
||||||
|
|
||||||
// Invisibility flag combos
|
// Invisibility flag combos
|
||||||
#define INVISIBILITY_FLAGS1 (MF_SHADOW)
|
#define INVISIBILITY_FLAGS1 (MF_SHADOW)
|
||||||
|
@ -552,6 +561,7 @@ IMPLEMENT_CLASS (APowerShadow)
|
||||||
|
|
||||||
void APowerInvisibility::InitEffect ()
|
void APowerInvisibility::InitEffect ()
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
// This used to call CommonInit(), which used to contain all the code that's repeated every
|
// This used to call CommonInit(), which used to contain all the code that's repeated every
|
||||||
// tic, plus the following code that needs to happen once and only once.
|
// tic, plus the following code that needs to happen once and only once.
|
||||||
// The CommonInit() code has been moved to DoEffect(), so this now ends with a call to DoEffect(),
|
// The CommonInit() code has been moved to DoEffect(), so this now ends with a call to DoEffect(),
|
||||||
|
@ -615,6 +625,7 @@ void APowerInvisibility::DoEffect ()
|
||||||
|
|
||||||
void APowerInvisibility::EndEffect ()
|
void APowerInvisibility::EndEffect ()
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
if (Owner != NULL)
|
if (Owner != NULL)
|
||||||
{
|
{
|
||||||
Owner->flags &= ~(flags & INVISIBILITY_FLAGS1);
|
Owner->flags &= ~(flags & INVISIBILITY_FLAGS1);
|
||||||
|
@ -822,6 +833,7 @@ void APowerLightAmp::DoEffect ()
|
||||||
|
|
||||||
void APowerLightAmp::EndEffect ()
|
void APowerLightAmp::EndEffect ()
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
if (Owner != NULL && Owner->player != NULL && Owner->player->fixedcolormap < NUMCOLORMAPS)
|
if (Owner != NULL && Owner->player != NULL && Owner->player->fixedcolormap < NUMCOLORMAPS)
|
||||||
{
|
{
|
||||||
Owner->player->fixedlightlevel = -1;
|
Owner->player->fixedlightlevel = -1;
|
||||||
|
@ -914,6 +926,7 @@ void APowerFlight::Serialize (FArchive &arc)
|
||||||
|
|
||||||
void APowerFlight::InitEffect ()
|
void APowerFlight::InitEffect ()
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
Owner->flags2 |= MF2_FLY;
|
Owner->flags2 |= MF2_FLY;
|
||||||
Owner->flags |= MF_NOGRAVITY;
|
Owner->flags |= MF_NOGRAVITY;
|
||||||
if (Owner->z <= Owner->floorz)
|
if (Owner->z <= Owner->floorz)
|
||||||
|
@ -955,6 +968,7 @@ void APowerFlight::Tick ()
|
||||||
|
|
||||||
void APowerFlight::EndEffect ()
|
void APowerFlight::EndEffect ()
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
if (Owner == NULL || Owner->player == NULL)
|
if (Owner == NULL || Owner->player == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -1035,6 +1049,8 @@ void APowerWeaponLevel2::InitEffect ()
|
||||||
{
|
{
|
||||||
AWeapon *weapon, *sister;
|
AWeapon *weapon, *sister;
|
||||||
|
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if (Owner->player == NULL)
|
if (Owner->player == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1071,6 +1087,7 @@ void APowerWeaponLevel2::EndEffect ()
|
||||||
{
|
{
|
||||||
player_t *player = Owner != NULL ? Owner->player : NULL;
|
player_t *player = Owner != NULL ? Owner->player : NULL;
|
||||||
|
|
||||||
|
Super::EndEffect();
|
||||||
if (player != NULL)
|
if (player != NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1199,6 +1216,8 @@ void APowerTargeter::InitEffect ()
|
||||||
{
|
{
|
||||||
player_t *player;
|
player_t *player;
|
||||||
|
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if ((player = Owner->player) == NULL)
|
if ((player = Owner->player) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1250,6 +1269,7 @@ void APowerTargeter::DoEffect ()
|
||||||
|
|
||||||
void APowerTargeter::EndEffect ()
|
void APowerTargeter::EndEffect ()
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
if (Owner != NULL && Owner->player != NULL)
|
if (Owner != NULL && Owner->player != NULL)
|
||||||
{
|
{
|
||||||
P_SetPsprite (Owner->player, ps_targetcenter, NULL);
|
P_SetPsprite (Owner->player, ps_targetcenter, NULL);
|
||||||
|
@ -1281,6 +1301,8 @@ IMPLEMENT_CLASS (APowerFrightener)
|
||||||
|
|
||||||
void APowerFrightener::InitEffect ()
|
void APowerFrightener::InitEffect ()
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if (Owner== NULL || Owner->player == NULL)
|
if (Owner== NULL || Owner->player == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1295,6 +1317,8 @@ void APowerFrightener::InitEffect ()
|
||||||
|
|
||||||
void APowerFrightener::EndEffect ()
|
void APowerFrightener::EndEffect ()
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
|
|
||||||
if (Owner== NULL || Owner->player == NULL)
|
if (Owner== NULL || Owner->player == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1319,6 +1343,8 @@ void APowerTimeFreezer::InitEffect( )
|
||||||
{
|
{
|
||||||
int ulIdx;
|
int ulIdx;
|
||||||
|
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if (Owner== NULL || Owner->player == NULL)
|
if (Owner== NULL || Owner->player == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1394,6 +1420,8 @@ void APowerTimeFreezer::EndEffect( )
|
||||||
{
|
{
|
||||||
int ulIdx;
|
int ulIdx;
|
||||||
|
|
||||||
|
Super::EndEffect();
|
||||||
|
|
||||||
// Allow other actors to move about freely once again.
|
// Allow other actors to move about freely once again.
|
||||||
level.flags2 &= ~LEVEL2_FROZEN;
|
level.flags2 &= ~LEVEL2_FROZEN;
|
||||||
|
|
||||||
|
@ -1432,6 +1460,8 @@ IMPLEMENT_CLASS( APowerDamage)
|
||||||
|
|
||||||
void APowerDamage::InitEffect( )
|
void APowerDamage::InitEffect( )
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
// Use sound channel 5 to avoid interference with other actions.
|
// Use sound channel 5 to avoid interference with other actions.
|
||||||
if (Owner != NULL) S_Sound(Owner, 5, SeeSound, 1.0f, ATTN_NONE);
|
if (Owner != NULL) S_Sound(Owner, 5, SeeSound, 1.0f, ATTN_NONE);
|
||||||
}
|
}
|
||||||
|
@ -1444,6 +1474,7 @@ void APowerDamage::InitEffect( )
|
||||||
|
|
||||||
void APowerDamage::EndEffect( )
|
void APowerDamage::EndEffect( )
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
// Use sound channel 5 to avoid interference with other actions.
|
// Use sound channel 5 to avoid interference with other actions.
|
||||||
if (Owner != NULL) S_Sound(Owner, 5, DeathSound, 1.0f, ATTN_NONE);
|
if (Owner != NULL) S_Sound(Owner, 5, DeathSound, 1.0f, ATTN_NONE);
|
||||||
}
|
}
|
||||||
|
@ -1495,6 +1526,8 @@ IMPLEMENT_CLASS(APowerProtection)
|
||||||
|
|
||||||
void APowerProtection::InitEffect( )
|
void APowerProtection::InitEffect( )
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if (Owner != NULL)
|
if (Owner != NULL)
|
||||||
{
|
{
|
||||||
S_Sound(Owner, CHAN_AUTO, SeeSound, 1.0f, ATTN_NONE);
|
S_Sound(Owner, CHAN_AUTO, SeeSound, 1.0f, ATTN_NONE);
|
||||||
|
@ -1518,6 +1551,7 @@ void APowerProtection::InitEffect( )
|
||||||
|
|
||||||
void APowerProtection::EndEffect( )
|
void APowerProtection::EndEffect( )
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
if (Owner != NULL)
|
if (Owner != NULL)
|
||||||
{
|
{
|
||||||
S_Sound(Owner, CHAN_AUTO, DeathSound, 1.0f, ATTN_NONE);
|
S_Sound(Owner, CHAN_AUTO, DeathSound, 1.0f, ATTN_NONE);
|
||||||
|
@ -1570,6 +1604,8 @@ IMPLEMENT_CLASS(APowerDrain)
|
||||||
|
|
||||||
void APowerDrain::InitEffect( )
|
void APowerDrain::InitEffect( )
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if (Owner== NULL || Owner->player == NULL)
|
if (Owner== NULL || Owner->player == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1585,6 +1621,8 @@ void APowerDrain::InitEffect( )
|
||||||
|
|
||||||
void APowerDrain::EndEffect( )
|
void APowerDrain::EndEffect( )
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
|
|
||||||
// Nothing to do if there's no owner.
|
// Nothing to do if there's no owner.
|
||||||
if (Owner != NULL && Owner->player != NULL)
|
if (Owner != NULL && Owner->player != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1606,6 +1644,8 @@ IMPLEMENT_CLASS(APowerRegeneration)
|
||||||
|
|
||||||
void APowerRegeneration::InitEffect( )
|
void APowerRegeneration::InitEffect( )
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if (Owner== NULL || Owner->player == NULL)
|
if (Owner== NULL || Owner->player == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1621,6 +1661,7 @@ void APowerRegeneration::InitEffect( )
|
||||||
|
|
||||||
void APowerRegeneration::EndEffect( )
|
void APowerRegeneration::EndEffect( )
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
// Nothing to do if there's no owner.
|
// Nothing to do if there's no owner.
|
||||||
if (Owner != NULL && Owner->player != NULL)
|
if (Owner != NULL && Owner->player != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1641,6 +1682,8 @@ IMPLEMENT_CLASS(APowerHighJump)
|
||||||
|
|
||||||
void APowerHighJump::InitEffect( )
|
void APowerHighJump::InitEffect( )
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if (Owner== NULL || Owner->player == NULL)
|
if (Owner== NULL || Owner->player == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1656,6 +1699,7 @@ void APowerHighJump::InitEffect( )
|
||||||
|
|
||||||
void APowerHighJump::EndEffect( )
|
void APowerHighJump::EndEffect( )
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
// Nothing to do if there's no owner.
|
// Nothing to do if there's no owner.
|
||||||
if (Owner != NULL && Owner->player != NULL)
|
if (Owner != NULL && Owner->player != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1676,6 +1720,8 @@ IMPLEMENT_CLASS(APowerDoubleFiringSpeed)
|
||||||
|
|
||||||
void APowerDoubleFiringSpeed::InitEffect( )
|
void APowerDoubleFiringSpeed::InitEffect( )
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if (Owner== NULL || Owner->player == NULL)
|
if (Owner== NULL || Owner->player == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1691,6 +1737,7 @@ void APowerDoubleFiringSpeed::InitEffect( )
|
||||||
|
|
||||||
void APowerDoubleFiringSpeed::EndEffect( )
|
void APowerDoubleFiringSpeed::EndEffect( )
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
// Nothing to do if there's no owner.
|
// Nothing to do if there's no owner.
|
||||||
if (Owner != NULL && Owner->player != NULL)
|
if (Owner != NULL && Owner->player != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1724,6 +1771,8 @@ void APowerMorph::Serialize (FArchive &arc)
|
||||||
|
|
||||||
void APowerMorph::InitEffect( )
|
void APowerMorph::InitEffect( )
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if (Owner != NULL && Owner->player != NULL && PlayerClass != NAME_None)
|
if (Owner != NULL && Owner->player != NULL && PlayerClass != NAME_None)
|
||||||
{
|
{
|
||||||
player_t *realplayer = Owner->player; // Remember the identity of the player
|
player_t *realplayer = Owner->player; // Remember the identity of the player
|
||||||
|
@ -1751,6 +1800,8 @@ void APowerMorph::InitEffect( )
|
||||||
|
|
||||||
void APowerMorph::EndEffect( )
|
void APowerMorph::EndEffect( )
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
|
|
||||||
// Abort if owner already destroyed
|
// Abort if owner already destroyed
|
||||||
if (Owner == NULL)
|
if (Owner == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1806,6 +1857,8 @@ IMPLEMENT_CLASS(APowerInfiniteAmmo)
|
||||||
|
|
||||||
void APowerInfiniteAmmo::InitEffect( )
|
void APowerInfiniteAmmo::InitEffect( )
|
||||||
{
|
{
|
||||||
|
Super::InitEffect();
|
||||||
|
|
||||||
if (Owner== NULL || Owner->player == NULL)
|
if (Owner== NULL || Owner->player == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1821,6 +1874,8 @@ void APowerInfiniteAmmo::InitEffect( )
|
||||||
|
|
||||||
void APowerInfiniteAmmo::EndEffect( )
|
void APowerInfiniteAmmo::EndEffect( )
|
||||||
{
|
{
|
||||||
|
Super::EndEffect();
|
||||||
|
|
||||||
// Nothing to do if there's no owner.
|
// Nothing to do if there's no owner.
|
||||||
if (Owner != NULL && Owner->player != NULL)
|
if (Owner != NULL && Owner->player != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -81,12 +81,6 @@ protected:
|
||||||
// fixed_t OwnersNormalAlpha;
|
// fixed_t OwnersNormalAlpha;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Needed only for m_cheat.cpp now
|
|
||||||
class APowerShadow : public APowerInvisibility
|
|
||||||
{
|
|
||||||
DECLARE_CLASS (APowerShadow, APowerInvisibility)
|
|
||||||
};
|
|
||||||
|
|
||||||
class APowerIronFeet : public APowerup
|
class APowerIronFeet : public APowerup
|
||||||
{
|
{
|
||||||
DECLARE_CLASS (APowerIronFeet, APowerup)
|
DECLARE_CLASS (APowerIronFeet, APowerup)
|
||||||
|
|
|
@ -53,7 +53,6 @@ class ASecurityCamera : public AActor
|
||||||
public:
|
public:
|
||||||
void PostBeginPlay ();
|
void PostBeginPlay ();
|
||||||
void Tick ();
|
void Tick ();
|
||||||
angle_t AngleIncrements ();
|
|
||||||
|
|
||||||
void Serialize (FArchive &arc);
|
void Serialize (FArchive &arc);
|
||||||
protected:
|
protected:
|
||||||
|
@ -71,11 +70,6 @@ void ASecurityCamera::Serialize (FArchive &arc)
|
||||||
arc << Center << Acc << Delta << Range;
|
arc << Center << Acc << Delta << Range;
|
||||||
}
|
}
|
||||||
|
|
||||||
angle_t ASecurityCamera::AngleIncrements ()
|
|
||||||
{
|
|
||||||
return ANGLE_1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASecurityCamera::PostBeginPlay ()
|
void ASecurityCamera::PostBeginPlay ()
|
||||||
{
|
{
|
||||||
Super::PostBeginPlay ();
|
Super::PostBeginPlay ();
|
||||||
|
|
|
@ -43,7 +43,6 @@ class AHateTarget : public AActor
|
||||||
DECLARE_CLASS (AHateTarget, AActor)
|
DECLARE_CLASS (AHateTarget, AActor)
|
||||||
public:
|
public:
|
||||||
void BeginPlay ();
|
void BeginPlay ();
|
||||||
angle_t AngleIncrements (void);
|
|
||||||
int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype);
|
int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,7 +76,3 @@ int AHateTarget::TakeSpecialDamage (AActor *inflictor, AActor *source, int damag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
angle_t AHateTarget::AngleIncrements (void)
|
|
||||||
{
|
|
||||||
return ANGLE_1;
|
|
||||||
}
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ struct Lock
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else for(unsigned int i=0;i<keylist.Size();i++)
|
else for(unsigned int i=0;i<keylist.Size();i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,17 +42,11 @@ class ASpark : public AActor
|
||||||
{
|
{
|
||||||
DECLARE_CLASS (ASpark, AActor)
|
DECLARE_CLASS (ASpark, AActor)
|
||||||
public:
|
public:
|
||||||
angle_t AngleIncrements ();
|
|
||||||
void Activate (AActor *activator);
|
void Activate (AActor *activator);
|
||||||
};
|
};
|
||||||
|
|
||||||
IMPLEMENT_CLASS (ASpark)
|
IMPLEMENT_CLASS (ASpark)
|
||||||
|
|
||||||
angle_t ASpark::AngleIncrements ()
|
|
||||||
{
|
|
||||||
return ANGLE_1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASpark::Activate (AActor *activator)
|
void ASpark::Activate (AActor *activator)
|
||||||
{
|
{
|
||||||
Super::Activate (activator);
|
Super::Activate (activator);
|
||||||
|
|
|
@ -542,6 +542,10 @@ void SBarInfo::ParseSBarInfo(int lump)
|
||||||
sc.MustGetToken(TK_Identifier);
|
sc.MustGetToken(TK_Identifier);
|
||||||
barNum = sc.MustMatchString(StatusBars);
|
barNum = sc.MustMatchString(StatusBars);
|
||||||
}
|
}
|
||||||
|
if (this->huds[barNum] != NULL)
|
||||||
|
{
|
||||||
|
delete this->huds[barNum];
|
||||||
|
}
|
||||||
this->huds[barNum] = new SBarInfoMainBlock(this);
|
this->huds[barNum] = new SBarInfoMainBlock(this);
|
||||||
if(barNum == STBAR_AUTOMAP)
|
if(barNum == STBAR_AUTOMAP)
|
||||||
{
|
{
|
||||||
|
|
|
@ -166,12 +166,15 @@ static void DrawHudText(FFont *font, int color, char * text, int x, int y, int t
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
FTexture *texc = font->GetChar(text[i], &width);
|
FTexture *texc = font->GetChar(text[i], &width);
|
||||||
|
if (texc != NULL)
|
||||||
|
{
|
||||||
int offset = texc->TopOffset - tex_zero->TopOffset + tex_zero->GetHeight();
|
int offset = texc->TopOffset - tex_zero->TopOffset + tex_zero->GetHeight();
|
||||||
screen->DrawChar(font, color, x, y, text[i],
|
screen->DrawChar(font, color, x, y, text[i],
|
||||||
DTA_KeepRatio, true,
|
DTA_KeepRatio, true,
|
||||||
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, trans,
|
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, trans,
|
||||||
DTA_LeftOffset, width/2, DTA_TopOffset, offset,
|
DTA_LeftOffset, width/2, DTA_TopOffset, offset,
|
||||||
/*DTA_CenterBottomOffset, 1,*/ TAG_DONE);
|
/*DTA_CenterBottomOffset, 1,*/ TAG_DONE);
|
||||||
|
}
|
||||||
x += zerowidth;
|
x += zerowidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +182,7 @@ static void DrawHudText(FFont *font, int color, char * text, int x, int y, int t
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Draws a numberses a fixed widh for all characters
|
// Draws a number with a fixed width for all digits
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "thingdef/thingdef.h"
|
#include "thingdef/thingdef.h"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Sys_1ed64 (AActor *self)
|
static bool CrusaderCheckRange (AActor *self)
|
||||||
{
|
{
|
||||||
if (P_CheckSight (self, self->target) && self->reactiontime == 0)
|
if (P_CheckSight (self, self->target) && self->reactiontime == 0)
|
||||||
{
|
{
|
||||||
|
@ -25,7 +25,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderChoose)
|
||||||
if (self->target == NULL)
|
if (self->target == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (Sys_1ed64 (self))
|
if (CrusaderCheckRange (self))
|
||||||
{
|
{
|
||||||
A_FaceTarget (self);
|
A_FaceTarget (self);
|
||||||
self->angle -= ANGLE_180/16;
|
self->angle -= ANGLE_180/16;
|
||||||
|
|
|
@ -87,7 +87,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelRefire)
|
||||||
{
|
{
|
||||||
if (self->target == NULL ||
|
if (self->target == NULL ||
|
||||||
self->target->health <= 0 ||
|
self->target->health <= 0 ||
|
||||||
!P_CheckSight (self, self->target) ||
|
!P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES) ||
|
||||||
P_HitFriend(self) ||
|
P_HitFriend(self) ||
|
||||||
pr_sentinelrefire() < 40)
|
pr_sentinelrefire() < 40)
|
||||||
{
|
{
|
||||||
|
|
|
@ -536,13 +536,14 @@ void FGameConfigFile::ArchiveGlobalData ()
|
||||||
|
|
||||||
FString FGameConfigFile::GetConfigPath (bool tryProg)
|
FString FGameConfigFile::GetConfigPath (bool tryProg)
|
||||||
{
|
{
|
||||||
char *pathval;
|
const char *pathval;
|
||||||
FString path;
|
FString path;
|
||||||
|
|
||||||
pathval = Args->CheckValue ("-config");
|
pathval = Args->CheckValue ("-config");
|
||||||
if (pathval != NULL)
|
if (pathval != NULL)
|
||||||
|
{
|
||||||
return FString(pathval);
|
return FString(pathval);
|
||||||
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
path = NULL;
|
path = NULL;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
|
@ -418,7 +418,7 @@ void HU_DrawColorBar(int x, int y, int height, int playernum)
|
||||||
{
|
{
|
||||||
float h, s, v, r, g, b;
|
float h, s, v, r, g, b;
|
||||||
|
|
||||||
D_GetPlayerColor (playernum, &h, &s, &v);
|
D_GetPlayerColor (playernum, &h, &s, &v, NULL);
|
||||||
HSVtoRGB (&r, &g, &b, h, s, v);
|
HSVtoRGB (&r, &g, &b, h, s, v);
|
||||||
|
|
||||||
screen->Clear (x, y, x + 24*CleanXfac, y + height, -1,
|
screen->Clear (x, y, x + 24*CleanXfac, y + height, -1,
|
||||||
|
|
|
@ -338,20 +338,21 @@ void PreSend (const void *buffer, int bufferlen, const sockaddr_in *to)
|
||||||
sendto (mysocket, (const char *)buffer, bufferlen, 0, (const sockaddr *)to, sizeof(*to));
|
sendto (mysocket, (const char *)buffer, bufferlen, 0, (const sockaddr *)to, sizeof(*to));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildAddress (sockaddr_in *address, char *name)
|
void BuildAddress (sockaddr_in *address, const char *name)
|
||||||
{
|
{
|
||||||
hostent *hostentry; // host information entry
|
hostent *hostentry; // host information entry
|
||||||
u_short port;
|
u_short port;
|
||||||
char *portpart;
|
const char *portpart;
|
||||||
bool isnamed = false;
|
bool isnamed = false;
|
||||||
int curchar;
|
int curchar;
|
||||||
char c;
|
char c;
|
||||||
|
FString target;
|
||||||
|
|
||||||
address->sin_family = AF_INET;
|
address->sin_family = AF_INET;
|
||||||
|
|
||||||
if ( (portpart = strchr (name, ':')) )
|
if ( (portpart = strchr (name, ':')) )
|
||||||
{
|
{
|
||||||
*portpart = 0;
|
target = FString(name, portpart - name);
|
||||||
port = atoi (portpart + 1);
|
port = atoi (portpart + 1);
|
||||||
if (!port)
|
if (!port)
|
||||||
{
|
{
|
||||||
|
@ -361,11 +362,12 @@ void BuildAddress (sockaddr_in *address, char *name)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
target = name;
|
||||||
port = DOOMPORT;
|
port = DOOMPORT;
|
||||||
}
|
}
|
||||||
address->sin_port = htons(port);
|
address->sin_port = htons(port);
|
||||||
|
|
||||||
for (curchar = 0; (c = name[curchar]) ; curchar++)
|
for (curchar = 0; (c = target[curchar]) ; curchar++)
|
||||||
{
|
{
|
||||||
if ((c < '0' || c > '9') && c != '.')
|
if ((c < '0' || c > '9') && c != '.')
|
||||||
{
|
{
|
||||||
|
@ -376,21 +378,18 @@ void BuildAddress (sockaddr_in *address, char *name)
|
||||||
|
|
||||||
if (!isnamed)
|
if (!isnamed)
|
||||||
{
|
{
|
||||||
address->sin_addr.s_addr = inet_addr (name);
|
address->sin_addr.s_addr = inet_addr (target);
|
||||||
Printf ("Node number %d, address %s\n", doomcom.numnodes, name);
|
Printf ("Node number %d, address %s\n", doomcom.numnodes, target.GetChars());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hostentry = gethostbyname (name);
|
hostentry = gethostbyname (target);
|
||||||
if (!hostentry)
|
if (!hostentry)
|
||||||
I_FatalError ("gethostbyname: couldn't find %s\n%s", name, neterror());
|
I_FatalError ("gethostbyname: couldn't find %s\n%s", target.GetChars(), neterror());
|
||||||
address->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
|
address->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
|
||||||
Printf ("Node number %d, hostname %s\n",
|
Printf ("Node number %d, hostname %s\n",
|
||||||
doomcom.numnodes, hostentry->h_name);
|
doomcom.numnodes, hostentry->h_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (portpart)
|
|
||||||
*portpart = ':';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseNetwork (void)
|
void CloseNetwork (void)
|
||||||
|
@ -910,7 +909,7 @@ static bool NodesOnSameNetwork()
|
||||||
bool I_InitNetwork (void)
|
bool I_InitNetwork (void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *v;
|
const char *v;
|
||||||
|
|
||||||
memset (&doomcom, 0, sizeof(doomcom));
|
memset (&doomcom, 0, sizeof(doomcom));
|
||||||
|
|
||||||
|
|
28
src/info.cpp
28
src/info.cpp
|
@ -459,8 +459,6 @@ PClassActor *PClassActor::GetReplacee(bool lookskill)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void PClassActor::SetDamageFactor(FName type, fixed_t factor)
|
void PClassActor::SetDamageFactor(FName type, fixed_t factor)
|
||||||
{
|
|
||||||
if (factor != FRACUNIT)
|
|
||||||
{
|
{
|
||||||
if (DamageFactors == NULL)
|
if (DamageFactors == NULL)
|
||||||
{
|
{
|
||||||
|
@ -468,11 +466,6 @@ void PClassActor::SetDamageFactor(FName type, fixed_t factor)
|
||||||
}
|
}
|
||||||
DamageFactors->Insert(type, factor);
|
DamageFactors->Insert(type, factor);
|
||||||
}
|
}
|
||||||
else if (DamageFactors != NULL)
|
|
||||||
{
|
|
||||||
DamageFactors->Remove(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -488,7 +481,7 @@ void PClassActor::SetPainChance(FName type, int chance)
|
||||||
{
|
{
|
||||||
PainChances = new PainChanceList;
|
PainChances = new PainChanceList;
|
||||||
}
|
}
|
||||||
PainChances->Insert(type, MIN(chance, 255));
|
PainChances->Insert(type, MIN(chance, 256));
|
||||||
}
|
}
|
||||||
else if (PainChances != NULL)
|
else if (PainChances != NULL)
|
||||||
{
|
{
|
||||||
|
@ -501,6 +494,25 @@ void PClassActor::SetPainChance(FName type, int chance)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
void PClassActor::SetColorSet(int index, const FPlayerColorSet *set)
|
||||||
|
{
|
||||||
|
if (set != NULL)
|
||||||
|
{
|
||||||
|
if (ColorSets == NULL) ColorSets = new FPlayerColorSetMap;
|
||||||
|
ColorSets->Insert(index, *set);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ColorSets != NULL)
|
||||||
|
ColorSets->Remove(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
FDoomEdMap DoomEdMap;
|
FDoomEdMap DoomEdMap;
|
||||||
|
|
||||||
FDoomEdMap::FDoomEdEntry *FDoomEdMap::DoomEdHash[DOOMED_HASHSIZE];
|
FDoomEdMap::FDoomEdEntry *FDoomEdMap::DoomEdHash[DOOMED_HASHSIZE];
|
||||||
|
|
17
src/info.h
17
src/info.h
|
@ -123,8 +123,21 @@ FArchive &operator<< (FArchive &arc, FState *&state);
|
||||||
|
|
||||||
#include "gametype.h"
|
#include "gametype.h"
|
||||||
|
|
||||||
|
// Standard pre-defined skin colors
|
||||||
|
struct FPlayerColorSet
|
||||||
|
{
|
||||||
|
FName Name; // Name of this color
|
||||||
|
|
||||||
|
int Lump; // Lump to read the translation from, otherwise use next 2 fields
|
||||||
|
BYTE FirstColor, LastColor; // Describes the range of colors to use for the translation
|
||||||
|
|
||||||
|
BYTE RepresentativeColor; // A palette entry representative of this translation,
|
||||||
|
// for map arrows and status bar backgrounds and such
|
||||||
|
};
|
||||||
|
|
||||||
typedef TMap<FName, fixed_t> DmgFactors;
|
typedef TMap<FName, fixed_t> DmgFactors;
|
||||||
typedef TMap<FName, BYTE> PainChanceList;
|
typedef TMap<FName, int> PainChanceList;
|
||||||
|
typedef TMap<int, FPlayerColorSet> FPlayerColorSetMap;
|
||||||
class DDropItem;
|
class DDropItem;
|
||||||
|
|
||||||
class PClassActor : public PClass
|
class PClassActor : public PClass
|
||||||
|
@ -145,6 +158,7 @@ public:
|
||||||
void RegisterIDs();
|
void RegisterIDs();
|
||||||
void SetDamageFactor(FName type, fixed_t factor);
|
void SetDamageFactor(FName type, fixed_t factor);
|
||||||
void SetPainChance(FName type, int chance);
|
void SetPainChance(FName type, int chance);
|
||||||
|
void SetColorSet(int index, const FPlayerColorSet *set);
|
||||||
size_t PropagateMark();
|
size_t PropagateMark();
|
||||||
void InitializeNativeDefaults();
|
void InitializeNativeDefaults();
|
||||||
|
|
||||||
|
@ -168,6 +182,7 @@ public:
|
||||||
FStateLabels *StateList;
|
FStateLabels *StateList;
|
||||||
DmgFactors *DamageFactors;
|
DmgFactors *DamageFactors;
|
||||||
PainChanceList *PainChances;
|
PainChanceList *PainChances;
|
||||||
|
FPlayerColorSetMap *ColorSets;
|
||||||
FString Obituary; // Player was killed by this actor
|
FString Obituary; // Player was killed by this actor
|
||||||
FString HitObituary; // Player was killed by this actor in melee
|
FString HitObituary; // Player was killed by this actor in melee
|
||||||
fixed_t DeathHeight; // Height on normal death
|
fixed_t DeathHeight; // Height on normal death
|
||||||
|
|
401
src/m_argv.cpp
401
src/m_argv.cpp
|
@ -38,161 +38,348 @@
|
||||||
|
|
||||||
IMPLEMENT_CLASS (DArgs)
|
IMPLEMENT_CLASS (DArgs)
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs Default Constructor
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
DArgs::DArgs()
|
DArgs::DArgs()
|
||||||
{
|
{
|
||||||
m_ArgC = 0;
|
|
||||||
m_ArgV = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DArgs::DArgs (int argc, char **argv)
|
//===========================================================================
|
||||||
{
|
//
|
||||||
CopyArgs (argc, argv);
|
// DArgs Copy Constructor
|
||||||
}
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
DArgs::DArgs(const DArgs &other)
|
DArgs::DArgs(const DArgs &other)
|
||||||
{
|
{
|
||||||
CopyArgs (other.m_ArgC, other.m_ArgV);
|
Argv = other.Argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs Argv Constructor
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
DArgs::~DArgs ()
|
DArgs::DArgs(int argc, char **argv)
|
||||||
{
|
{
|
||||||
FlushArgs ();
|
SetArgs(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs String Argv Constructor
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
DArgs::DArgs(int argc, FString *argv)
|
||||||
|
{
|
||||||
|
AppendArgs(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs Copy Operator
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
DArgs &DArgs::operator=(const DArgs &other)
|
DArgs &DArgs::operator=(const DArgs &other)
|
||||||
{
|
{
|
||||||
FlushArgs ();
|
Argv = other.Argv;
|
||||||
CopyArgs (other.m_ArgC, other.m_ArgV);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: SetArgs
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
void DArgs::SetArgs(int argc, char **argv)
|
void DArgs::SetArgs(int argc, char **argv)
|
||||||
{
|
{
|
||||||
FlushArgs ();
|
Argv.Resize(argc);
|
||||||
CopyArgs (argc, argv);
|
for (int i = 0; i < argc; ++i)
|
||||||
}
|
|
||||||
|
|
||||||
void DArgs::CopyArgs (int argc, char **argv)
|
|
||||||
{
|
{
|
||||||
int i;
|
Argv[i] = argv[i];
|
||||||
|
|
||||||
m_ArgC = argc;
|
|
||||||
m_ArgV = new char *[argc];
|
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
m_ArgV[i] = copystring (argv[i]);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: FlushArgs
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
void DArgs::FlushArgs()
|
void DArgs::FlushArgs()
|
||||||
{
|
{
|
||||||
int i;
|
Argv.Clear();
|
||||||
|
|
||||||
for (i = 0; i < m_ArgC; i++)
|
|
||||||
delete[] m_ArgV[i];
|
|
||||||
delete[] m_ArgV;
|
|
||||||
m_ArgC = 0;
|
|
||||||
m_ArgV = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: CheckParm
|
||||||
//
|
//
|
||||||
// CheckParm
|
|
||||||
// Checks for the given parameter in the program's command line arguments.
|
// Checks for the given parameter in the program's command line arguments.
|
||||||
// Returns the argument number (1 to argc-1) or 0 if not present
|
// Returns the argument number (1 to argc-1) or 0 if not present
|
||||||
//
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
int DArgs::CheckParm(const char *check, int start) const
|
int DArgs::CheckParm(const char *check, int start) const
|
||||||
{
|
{
|
||||||
for (int i = start; i < m_ArgC; ++i)
|
for (unsigned i = start; i < Argv.Size(); ++i)
|
||||||
if (!stricmp (check, m_ArgV[i]))
|
{
|
||||||
|
if (0 == stricmp(check, Argv[i]))
|
||||||
|
{
|
||||||
return i;
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *DArgs::CheckValue (const char *check) const
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: CheckParmList
|
||||||
|
//
|
||||||
|
// Returns the number of arguments after the parameter (if found) and also
|
||||||
|
// returns a pointer to the first argument.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
int DArgs::CheckParmList(const char *check, FString **strings, int start) const
|
||||||
|
{
|
||||||
|
unsigned int i, parmat = CheckParm(check, start);
|
||||||
|
|
||||||
|
if (parmat == 0)
|
||||||
|
{
|
||||||
|
if (strings != NULL)
|
||||||
|
{
|
||||||
|
*strings = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (i = ++parmat; i < Argv.Size(); ++i)
|
||||||
|
{
|
||||||
|
if (Argv[i][0] == '-' || Argv[i][1] == '+')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strings != NULL)
|
||||||
|
{
|
||||||
|
*strings = &Argv[parmat];
|
||||||
|
}
|
||||||
|
return i - parmat;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: CheckValue
|
||||||
|
//
|
||||||
|
// Like CheckParm, but it also checks that the parameter has a value after
|
||||||
|
// it and returns that or NULL if not present.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
const char *DArgs::CheckValue(const char *check) const
|
||||||
{
|
{
|
||||||
int i = CheckParm(check);
|
int i = CheckParm(check);
|
||||||
|
|
||||||
if (i > 0 && i < m_ArgC - 1)
|
if (i > 0 && i < (int)Argv.Size() - 1)
|
||||||
return m_ArgV[i+1][0] != '+' && m_ArgV[i+1][0] != '-' ? m_ArgV[i+1] : NULL;
|
{
|
||||||
|
i++;
|
||||||
|
return Argv[i][0] != '+' && Argv[i][0] != '-' ? Argv[i].GetChars() : NULL;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char *DArgs::GetArg (int arg) const
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: TakeValue
|
||||||
|
//
|
||||||
|
// Like CheckValue, except it also removes the parameter and its argument
|
||||||
|
// (if present) from argv.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString DArgs::TakeValue(const char *check)
|
||||||
{
|
{
|
||||||
if (arg >= 0 && arg < m_ArgC)
|
int i = CheckParm(check);
|
||||||
return m_ArgV[arg];
|
FString out;
|
||||||
|
|
||||||
|
if (i > 0 && i < (int)Argv.Size())
|
||||||
|
{
|
||||||
|
if (i < (int)Argv.Size() - 1 && Argv[i+1][0] != '+' && Argv[i+1][0] != '-')
|
||||||
|
{
|
||||||
|
out = Argv[i+1];
|
||||||
|
Argv.Delete(i, 2); // Delete the parm and its value.
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char **DArgs::GetArgList (int arg) const
|
|
||||||
{
|
{
|
||||||
if (arg >= 0 && arg < m_ArgC)
|
Argv.Delete(i); // Just delete the parm, since it has no value.
|
||||||
return &m_ArgV[arg];
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DArgs::NumArgs () const
|
|
||||||
{
|
|
||||||
return m_ArgC;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DArgs::AppendArg (const char *arg)
|
|
||||||
{
|
|
||||||
char **temp = new char *[m_ArgC + 1];
|
|
||||||
if (m_ArgV)
|
|
||||||
{
|
|
||||||
memcpy (temp, m_ArgV, sizeof(*m_ArgV) * m_ArgC);
|
|
||||||
delete[] m_ArgV;
|
|
||||||
}
|
|
||||||
temp[m_ArgC] = copystring (arg);
|
|
||||||
m_ArgV = temp;
|
|
||||||
m_ArgC++;
|
|
||||||
}
|
|
||||||
|
|
||||||
DArgs *DArgs::GatherFiles (const char *param, const char *extension, bool acceptNoExt) const
|
|
||||||
{
|
|
||||||
DArgs *out = new DArgs;
|
|
||||||
int i;
|
|
||||||
size_t extlen = strlen (extension);
|
|
||||||
|
|
||||||
if (extlen > 0)
|
|
||||||
{
|
|
||||||
for (i = 1; i < m_ArgC && *m_ArgV[i] != '-' && *m_ArgV[i] != '+'; i++)
|
|
||||||
{
|
|
||||||
size_t len = strlen (m_ArgV[i]);
|
|
||||||
if (len >= extlen && stricmp (m_ArgV[i] + len - extlen, extension) == 0)
|
|
||||||
out->AppendArg (m_ArgV[i]);
|
|
||||||
else if (acceptNoExt)
|
|
||||||
{
|
|
||||||
const char *src = m_ArgV[i] + len - 1;
|
|
||||||
|
|
||||||
while (src != m_ArgV[i] && *src != '/'
|
|
||||||
#ifdef _WIN32
|
|
||||||
&& *src != '\\'
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (*src == '.')
|
|
||||||
goto morefor; // it has an extension
|
|
||||||
src--;
|
|
||||||
}
|
|
||||||
out->AppendArg (m_ArgV[i]);
|
|
||||||
morefor:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (param != NULL)
|
|
||||||
{
|
|
||||||
i = 1;
|
|
||||||
while (0 != (i = CheckParm (param, i)))
|
|
||||||
{
|
|
||||||
for (++i; i < m_ArgC && *m_ArgV[i] != '-' && *m_ArgV[i] != '+'; ++i)
|
|
||||||
out->AppendArg (m_ArgV[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: GetArg
|
||||||
|
//
|
||||||
|
// Gets the argument at a particular position.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
const char *DArgs::GetArg(int arg) const
|
||||||
|
{
|
||||||
|
return ((unsigned)arg < Argv.Size()) ? Argv[arg].GetChars() : NULL;
|
||||||
|
return Argv[arg];
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: GetArgList
|
||||||
|
//
|
||||||
|
// Returns a pointer to the FString at a particular position.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FString *DArgs::GetArgList(int arg) const
|
||||||
|
{
|
||||||
|
return ((unsigned)arg < Argv.Size()) ? &Argv[arg] : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: NumArgs
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
int DArgs::NumArgs() const
|
||||||
|
{
|
||||||
|
return (int)Argv.Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: AppendArg
|
||||||
|
//
|
||||||
|
// Adds another argument to argv. Invalidates any previous results from
|
||||||
|
// GetArgList().
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void DArgs::AppendArg(FString arg)
|
||||||
|
{
|
||||||
|
Argv.Push(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: AppendArgs
|
||||||
|
//
|
||||||
|
// Adds an array of FStrings to argv.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void DArgs::AppendArgs(int argc, const FString *argv)
|
||||||
|
{
|
||||||
|
if (argv != NULL && argc > 0)
|
||||||
|
{
|
||||||
|
Argv.Grow(argc);
|
||||||
|
for (int i = 0; i < argc; ++i)
|
||||||
|
{
|
||||||
|
Argv.Push(argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: CollectFiles
|
||||||
|
//
|
||||||
|
// Takes all arguments after any instance of -param and any arguments before
|
||||||
|
// all switches that end in .extension and combines them into a single
|
||||||
|
// -switch block at the end of the arguments. If extension is NULL, then
|
||||||
|
// every parameter before the first switch is added after this -param.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void DArgs::CollectFiles(const char *param, const char *extension)
|
||||||
|
{
|
||||||
|
TArray<FString> work;
|
||||||
|
DArgs *out = new DArgs;
|
||||||
|
unsigned int i;
|
||||||
|
size_t extlen = extension == NULL ? 0 : strlen(extension);
|
||||||
|
|
||||||
|
// Step 1: Find suitable arguments before the first switch.
|
||||||
|
i = 1;
|
||||||
|
while (i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+')
|
||||||
|
{
|
||||||
|
bool useit;
|
||||||
|
|
||||||
|
if (extlen > 0)
|
||||||
|
{ // Argument's extension must match.
|
||||||
|
size_t len = Argv[i].Len();
|
||||||
|
useit = (len >= extlen && stricmp(&Argv[i][len - extlen], extension) == 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Anything will do so long as it's before the first switch.
|
||||||
|
useit = true;
|
||||||
|
}
|
||||||
|
if (useit)
|
||||||
|
{
|
||||||
|
work.Push(Argv[i]);
|
||||||
|
Argv.Delete(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: Find each occurence of -param and add its arguments to work.
|
||||||
|
while ((i = CheckParm(param, i)) > 0)
|
||||||
|
{
|
||||||
|
Argv.Delete(i);
|
||||||
|
while (i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+')
|
||||||
|
{
|
||||||
|
work.Push(Argv[i]);
|
||||||
|
Argv.Delete(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Add work back to Argv, as long as it's non-empty.
|
||||||
|
if (work.Size() > 0)
|
||||||
|
{
|
||||||
|
Argv.Push(param);
|
||||||
|
AppendArgs(work.Size(), &work[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// DArgs :: GatherFiles
|
||||||
|
//
|
||||||
|
// Returns all the arguments after the first instance of -param. If you want
|
||||||
|
// to combine more than one or get switchless stuff included, you need to
|
||||||
|
// call CollectFiles first.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
DArgs *DArgs::GatherFiles(const char *param) const
|
||||||
|
{
|
||||||
|
FString *files;
|
||||||
|
int filecount;
|
||||||
|
|
||||||
|
filecount = CheckParmList(param, &files);
|
||||||
|
return new DArgs(filecount, files);
|
||||||
|
}
|
||||||
|
|
26
src/m_argv.h
26
src/m_argv.h
|
@ -35,6 +35,7 @@
|
||||||
#define __M_ARGV_H__
|
#define __M_ARGV_H__
|
||||||
|
|
||||||
#include "dobject.h"
|
#include "dobject.h"
|
||||||
|
#include "zstring.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// MISC
|
// MISC
|
||||||
|
@ -46,29 +47,28 @@ public:
|
||||||
DArgs();
|
DArgs();
|
||||||
DArgs(const DArgs &args);
|
DArgs(const DArgs &args);
|
||||||
DArgs(int argc, char **argv);
|
DArgs(int argc, char **argv);
|
||||||
~DArgs ();
|
DArgs(int argc, FString *argv);
|
||||||
|
|
||||||
DArgs &operator=(const DArgs &other);
|
DArgs &operator=(const DArgs &other);
|
||||||
|
|
||||||
void AppendArg (const char *arg);
|
void AppendArg(FString arg);
|
||||||
|
void AppendArgs(int argc, const FString *argv);
|
||||||
void SetArgs(int argc, char **argv);
|
void SetArgs(int argc, char **argv);
|
||||||
DArgs *GatherFiles (const char *param, const char *extension, bool acceptNoExt) const;
|
void CollectFiles(const char *param, const char *extension);
|
||||||
|
DArgs *GatherFiles(const char *param) const;
|
||||||
void SetArg(int argnum, const char *arg);
|
void SetArg(int argnum, const char *arg);
|
||||||
|
|
||||||
// Returns the position of the given parameter
|
int CheckParm(const char *check, int start=1) const; // Returns the position of the given parameter in the arg list (0 if not found).
|
||||||
// in the arg list (0 if not found).
|
int CheckParmList(const char *check, FString **strings, int start=1) const;
|
||||||
int CheckParm (const char *check, int start=1) const;
|
const char *CheckValue(const char *check) const;
|
||||||
char *CheckValue (const char *check) const;
|
const char *GetArg(int arg) const;
|
||||||
char *GetArg (int arg) const;
|
FString *GetArgList(int arg) const;
|
||||||
char **GetArgList (int arg) const;
|
FString TakeValue(const char *check);
|
||||||
int NumArgs() const;
|
int NumArgs() const;
|
||||||
void FlushArgs();
|
void FlushArgs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_ArgC;
|
TArray<FString> Argv;
|
||||||
char **m_ArgV;
|
|
||||||
|
|
||||||
void CopyArgs (int argc, char **argv);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern DArgs *Args;
|
extern DArgs *Args;
|
||||||
|
|
|
@ -52,17 +52,17 @@
|
||||||
|
|
||||||
void cht_DoCheat (player_t *player, int cheat)
|
void cht_DoCheat (player_t *player, int cheat)
|
||||||
{
|
{
|
||||||
static PClass *const *BeholdPowers[9] =
|
static const char * const BeholdPowers[9] =
|
||||||
{
|
{
|
||||||
&RUNTIME_CLASS_CASTLESS(APowerInvulnerable),
|
"PowerInvulnerable",
|
||||||
&RUNTIME_CLASS_CASTLESS(APowerStrength),
|
"PowerStrength",
|
||||||
&RUNTIME_CLASS_CASTLESS(APowerInvisibility),
|
"PowerInvisibility",
|
||||||
&RUNTIME_CLASS_CASTLESS(APowerIronFeet),
|
"PowerIronFeet",
|
||||||
NULL, // MapRevealer
|
"MapRevealer",
|
||||||
&RUNTIME_CLASS_CASTLESS(APowerLightAmp),
|
"PowerLightAmp",
|
||||||
&RUNTIME_CLASS_CASTLESS(APowerShadow),
|
"PowerShadow",
|
||||||
&RUNTIME_CLASS_CASTLESS(APowerMask),
|
"PowerMask",
|
||||||
&RUNTIME_CLASS_CASTLESS(APowerTargeter)
|
"PowerTargeter",
|
||||||
};
|
};
|
||||||
PClassActor *type;
|
PClassActor *type;
|
||||||
AInventory *item;
|
AInventory *item;
|
||||||
|
@ -245,12 +245,12 @@ void cht_DoCheat (player_t *player, int cheat)
|
||||||
}
|
}
|
||||||
else if (player->mo != NULL && player->health >= 0)
|
else if (player->mo != NULL && player->health >= 0)
|
||||||
{
|
{
|
||||||
item = player->mo->FindInventory(static_cast<PClassActor *>(*BeholdPowers[i]));
|
item = player->mo->FindInventory(PClass::FindActor(BeholdPowers[i]));
|
||||||
if (item == NULL)
|
if (item == NULL)
|
||||||
{
|
{
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
player->mo->GiveInventoryType(static_cast<PClassActor *>(*BeholdPowers[i]));
|
cht_Give(player, BeholdPowers[i]);
|
||||||
if (cheat == CHT_BEHOLDS)
|
if (cheat == CHT_BEHOLDS)
|
||||||
{
|
{
|
||||||
P_GiveBody (player->mo, -100);
|
P_GiveBody (player->mo, -100);
|
||||||
|
@ -259,7 +259,7 @@ void cht_DoCheat (player_t *player, int cheat)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Let's give the item here so that the power doesn't need colormap information.
|
// Let's give the item here so that the power doesn't need colormap information.
|
||||||
player->mo->GiveInventoryType(PClass::FindActor("InvulnerabilitySphere"));
|
cht_Give(player, "InvulnerabilitySphere");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -316,7 +316,10 @@ void cht_DoCheat (player_t *player, int cheat)
|
||||||
player->mo->special1 = 0; // required for the Hexen fighter's fist attack.
|
player->mo->special1 = 0; // required for the Hexen fighter's fist attack.
|
||||||
// This gets set by AActor::Die as flag for the wimpy death and must be reset here.
|
// This gets set by AActor::Die as flag for the wimpy death and must be reset here.
|
||||||
player->mo->SetState (player->mo->SpawnState);
|
player->mo->SetState (player->mo->SpawnState);
|
||||||
|
if (!(player->mo->flags2 & MF2_DONTTRANSLATE))
|
||||||
|
{
|
||||||
player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players));
|
player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players));
|
||||||
|
}
|
||||||
player->mo->DamageType = NAME_None;
|
player->mo->DamageType = NAME_None;
|
||||||
// player->mo->GiveDefaultInventory();
|
// player->mo->GiveDefaultInventory();
|
||||||
if (player->ReadyWeapon != NULL)
|
if (player->ReadyWeapon != NULL)
|
||||||
|
|
135
src/m_menu.cpp
135
src/m_menu.cpp
|
@ -118,7 +118,7 @@ protected:
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
|
||||||
void R_GetPlayerTranslation (int color, FPlayerSkin *skin, FRemapTable *table);
|
void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayerSkin *skin, FRemapTable *table);
|
||||||
|
|
||||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||||
|
|
||||||
|
@ -188,6 +188,7 @@ static void M_EditPlayerName (int choice);
|
||||||
static void M_ChangePlayerTeam (int choice);
|
static void M_ChangePlayerTeam (int choice);
|
||||||
static void M_PlayerNameChanged (FSaveGameNode *dummy);
|
static void M_PlayerNameChanged (FSaveGameNode *dummy);
|
||||||
static void M_PlayerNameNotChanged ();
|
static void M_PlayerNameNotChanged ();
|
||||||
|
static void M_ChangeColorSet (int choice);
|
||||||
static void M_SlidePlayerRed (int choice);
|
static void M_SlidePlayerRed (int choice);
|
||||||
static void M_SlidePlayerGreen (int choice);
|
static void M_SlidePlayerGreen (int choice);
|
||||||
static void M_SlidePlayerBlue (int choice);
|
static void M_SlidePlayerBlue (int choice);
|
||||||
|
@ -246,17 +247,10 @@ static char savegamestring[SAVESTRINGSIZE];
|
||||||
static FString EndString;
|
static FString EndString;
|
||||||
|
|
||||||
static short itemOn; // menu item skull is on
|
static short itemOn; // menu item skull is on
|
||||||
static short whichSkull; // which skull to draw
|
|
||||||
static int MenuTime;
|
static int MenuTime;
|
||||||
static int InfoType;
|
static int InfoType;
|
||||||
static int InfoTic;
|
static int InfoTic;
|
||||||
|
|
||||||
static const char skullName[2][9] = {"M_SKULL1", "M_SKULL2"}; // graphic name of skulls
|
|
||||||
static const char cursName[8][8] = // graphic names of Strife menu selector
|
|
||||||
{
|
|
||||||
"M_CURS1", "M_CURS2", "M_CURS3", "M_CURS4", "M_CURS5", "M_CURS6", "M_CURS7", "M_CURS8"
|
|
||||||
};
|
|
||||||
|
|
||||||
static oldmenu_t *currentMenu; // current menudef
|
static oldmenu_t *currentMenu; // current menudef
|
||||||
static oldmenu_t *TopLevelMenu; // The main menu everything hangs off of
|
static oldmenu_t *TopLevelMenu; // The main menu everything hangs off of
|
||||||
|
|
||||||
|
@ -269,6 +263,7 @@ static int PlayerSkin;
|
||||||
static FState *PlayerState;
|
static FState *PlayerState;
|
||||||
static int PlayerTics;
|
static int PlayerTics;
|
||||||
static int PlayerRotation;
|
static int PlayerRotation;
|
||||||
|
static TArray<int> PlayerColorSets;
|
||||||
|
|
||||||
static FTexture *SavePic;
|
static FTexture *SavePic;
|
||||||
static FBrokenLines *SaveComment;
|
static FBrokenLines *SaveComment;
|
||||||
|
@ -536,15 +531,24 @@ static oldmenuitem_t PlayerSetupMenu[] =
|
||||||
{
|
{
|
||||||
{ 1,0,'n',NULL,M_EditPlayerName, CR_UNTRANSLATED},
|
{ 1,0,'n',NULL,M_EditPlayerName, CR_UNTRANSLATED},
|
||||||
{ 2,0,'t',NULL,M_ChangePlayerTeam, CR_UNTRANSLATED},
|
{ 2,0,'t',NULL,M_ChangePlayerTeam, CR_UNTRANSLATED},
|
||||||
|
{ 2,0,'c',NULL,M_ChangeColorSet, CR_UNTRANSLATED},
|
||||||
{ 2,0,'r',NULL,M_SlidePlayerRed, CR_UNTRANSLATED},
|
{ 2,0,'r',NULL,M_SlidePlayerRed, CR_UNTRANSLATED},
|
||||||
{ 2,0,'g',NULL,M_SlidePlayerGreen, CR_UNTRANSLATED},
|
{ 2,0,'g',NULL,M_SlidePlayerGreen, CR_UNTRANSLATED},
|
||||||
{ 2,0,'b',NULL,M_SlidePlayerBlue, CR_UNTRANSLATED},
|
{ 2,0,'b',NULL,M_SlidePlayerBlue, CR_UNTRANSLATED},
|
||||||
{ 2,0,'c',NULL,M_ChangeClass, CR_UNTRANSLATED},
|
{ 2,0,'t',NULL,M_ChangeClass, CR_UNTRANSLATED},
|
||||||
{ 2,0,'s',NULL,M_ChangeSkin, CR_UNTRANSLATED},
|
{ 2,0,'s',NULL,M_ChangeSkin, CR_UNTRANSLATED},
|
||||||
{ 2,0,'e',NULL,M_ChangeGender, CR_UNTRANSLATED},
|
{ 2,0,'e',NULL,M_ChangeGender, CR_UNTRANSLATED},
|
||||||
{ 2,0,'a',NULL,M_ChangeAutoAim, CR_UNTRANSLATED}
|
{ 2,0,'a',NULL,M_ChangeAutoAim, CR_UNTRANSLATED}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
// These must be changed if the menu definition is altered
|
||||||
|
PSM_RED = 3,
|
||||||
|
PSM_GREEN = 4,
|
||||||
|
PSM_BLUE = 5,
|
||||||
|
};
|
||||||
|
|
||||||
static oldmenu_t PSetupDef =
|
static oldmenu_t PSetupDef =
|
||||||
{
|
{
|
||||||
countof(PlayerSetupMenu),
|
countof(PlayerSetupMenu),
|
||||||
|
@ -2088,13 +2092,16 @@ void M_PlayerSetup (void)
|
||||||
PlayerClass = &PlayerClasses[players[consoleplayer].CurrentPlayerClass];
|
PlayerClass = &PlayerClasses[players[consoleplayer].CurrentPlayerClass];
|
||||||
}
|
}
|
||||||
PlayerSkin = players[consoleplayer].userinfo.skin;
|
PlayerSkin = players[consoleplayer].userinfo.skin;
|
||||||
R_GetPlayerTranslation (players[consoleplayer].userinfo.color, &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
|
R_GetPlayerTranslation (players[consoleplayer].userinfo.color,
|
||||||
|
P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset),
|
||||||
|
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
|
||||||
PlayerState = GetDefaultByType (PlayerClass->Type)->SeeState;
|
PlayerState = GetDefaultByType (PlayerClass->Type)->SeeState;
|
||||||
PlayerTics = PlayerState->GetTics();
|
PlayerTics = PlayerState->GetTics();
|
||||||
if (FireTexture == NULL)
|
if (FireTexture == NULL)
|
||||||
{
|
{
|
||||||
FireTexture = new FBackdropTexture;
|
FireTexture = new FBackdropTexture;
|
||||||
}
|
}
|
||||||
|
P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_PlayerSetupTicker (void)
|
static void M_PlayerSetupTicker (void)
|
||||||
|
@ -2112,6 +2119,7 @@ static void M_PlayerSetupTicker (void)
|
||||||
item = (MenuTime>>2) % (ClassMenuDef.numitems-1);
|
item = (MenuTime>>2) % (ClassMenuDef.numitems-1);
|
||||||
|
|
||||||
PlayerClass = &PlayerClasses[D_PlayerClassToInt (ClassMenuItems[item].name)];
|
PlayerClass = &PlayerClasses[D_PlayerClassToInt (ClassMenuItems[item].name)];
|
||||||
|
P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2125,6 +2133,7 @@ static void M_PlayerSetupTicker (void)
|
||||||
|
|
||||||
PlayerSkin = R_FindSkin (skins[PlayerSkin].name, int(PlayerClass - &PlayerClasses[0]));
|
PlayerSkin = R_FindSkin (skins[PlayerSkin].name, int(PlayerClass - &PlayerClasses[0]));
|
||||||
R_GetPlayerTranslation (players[consoleplayer].userinfo.color,
|
R_GetPlayerTranslation (players[consoleplayer].userinfo.color,
|
||||||
|
P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset),
|
||||||
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
|
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2280,19 +2289,27 @@ static void M_PlayerSetupDrawer ()
|
||||||
DTA_Clean, true, TAG_DONE);
|
DTA_Clean, true, TAG_DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw player color sliders
|
// Draw player color selection and sliders
|
||||||
//V_DrawTextCleanMove (CR_GREY, PSetupDef.x, PSetupDef.y + LINEHEIGHT, "Color");
|
FPlayerColorSet *colorset = P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset);
|
||||||
|
x = SmallFont->StringWidth("Color") + 8 + PSetupDef.x;
|
||||||
|
screen->DrawText(SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*2+yo, "Color", DTA_Clean, true, TAG_DONE);
|
||||||
|
screen->DrawText(SmallFont, value, x, PSetupDef.y + LINEHEIGHT*2+yo,
|
||||||
|
colorset != NULL ? colorset->Name.GetChars() : "Custom", DTA_Clean, true, TAG_DONE);
|
||||||
|
|
||||||
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*2+yo, "Red", DTA_Clean, true, TAG_DONE);
|
// Only show the sliders for a custom color set.
|
||||||
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*3+yo, "Green", DTA_Clean, true, TAG_DONE);
|
if (colorset == NULL)
|
||||||
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*4+yo, "Blue", DTA_Clean, true, TAG_DONE);
|
{
|
||||||
|
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*2.875)+yo, "Red", DTA_Clean, true, TAG_DONE);
|
||||||
|
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*3.5)+yo, "Green", DTA_Clean, true, TAG_DONE);
|
||||||
|
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*4.125)+yo, "Blue", DTA_Clean, true, TAG_DONE);
|
||||||
|
|
||||||
x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x;
|
x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x;
|
||||||
color = players[consoleplayer].userinfo.color;
|
color = players[consoleplayer].userinfo.color;
|
||||||
|
|
||||||
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*2+yo, RPART(color));
|
M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*2.875)+yo, RPART(color));
|
||||||
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*3+yo, GPART(color));
|
M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*3.5)+yo, GPART(color));
|
||||||
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*4+yo, BPART(color));
|
M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*4.125)+yo, BPART(color));
|
||||||
|
}
|
||||||
|
|
||||||
// [GRB] Draw class setting
|
// [GRB] Draw class setting
|
||||||
int pclass = players[consoleplayer].userinfo.PlayerClass;
|
int pclass = players[consoleplayer].userinfo.PlayerClass;
|
||||||
|
@ -2586,7 +2603,9 @@ static void M_ChangeSkin (int choice)
|
||||||
PlayerSkin = (PlayerSkin < (int)numskins - 1) ? PlayerSkin + 1 : 0;
|
PlayerSkin = (PlayerSkin < (int)numskins - 1) ? PlayerSkin + 1 : 0;
|
||||||
} while (!PlayerClass->CheckSkin (PlayerSkin));
|
} while (!PlayerClass->CheckSkin (PlayerSkin));
|
||||||
|
|
||||||
R_GetPlayerTranslation (players[consoleplayer].userinfo.color, &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
|
R_GetPlayerTranslation (players[consoleplayer].userinfo.color,
|
||||||
|
P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset),
|
||||||
|
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
|
||||||
|
|
||||||
cvar_set ("skin", skins[PlayerSkin].name);
|
cvar_set ("skin", skins[PlayerSkin].name);
|
||||||
}
|
}
|
||||||
|
@ -2707,13 +2726,55 @@ static void M_ChangePlayerTeam (int choice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void M_ChangeColorSet (int choice)
|
||||||
|
{
|
||||||
|
int curpos = (int)PlayerColorSets.Size();
|
||||||
|
int mycolorset = players[consoleplayer].userinfo.colorset;
|
||||||
|
while (--curpos >= 0)
|
||||||
|
{
|
||||||
|
if (PlayerColorSets[curpos] == mycolorset)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (choice == 0)
|
||||||
|
{
|
||||||
|
curpos--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curpos++;
|
||||||
|
}
|
||||||
|
if (curpos < -1)
|
||||||
|
{
|
||||||
|
curpos = (int)PlayerColorSets.Size() - 1;
|
||||||
|
}
|
||||||
|
else if (curpos >= (int)PlayerColorSets.Size())
|
||||||
|
{
|
||||||
|
curpos = -1;
|
||||||
|
}
|
||||||
|
mycolorset = (curpos >= 0) ? PlayerColorSets[curpos] : -1;
|
||||||
|
|
||||||
|
// disable the sliders if a valid colorset is selected
|
||||||
|
PlayerSetupMenu[PSM_RED].status =
|
||||||
|
PlayerSetupMenu[PSM_GREEN].status =
|
||||||
|
PlayerSetupMenu[PSM_BLUE].status = (mycolorset == -1? 2:-1);
|
||||||
|
|
||||||
|
char command[24];
|
||||||
|
mysnprintf(command, countof(command), "colorset %d", mycolorset);
|
||||||
|
C_DoCommand(command);
|
||||||
|
R_GetPlayerTranslation(players[consoleplayer].userinfo.color,
|
||||||
|
P_GetPlayerColorSet(PlayerClass->Type->TypeName, mycolorset),
|
||||||
|
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
|
||||||
|
}
|
||||||
|
|
||||||
static void SendNewColor (int red, int green, int blue)
|
static void SendNewColor (int red, int green, int blue)
|
||||||
{
|
{
|
||||||
char command[24];
|
char command[24];
|
||||||
|
|
||||||
mysnprintf (command, countof(command), "color \"%02x %02x %02x\"", red, green, blue);
|
mysnprintf (command, countof(command), "color \"%02x %02x %02x\"", red, green, blue);
|
||||||
C_DoCommand (command);
|
C_DoCommand (command);
|
||||||
R_GetPlayerTranslation (MAKERGB (red, green, blue), &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
|
R_GetPlayerTranslation(MAKERGB (red, green, blue),
|
||||||
|
P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset),
|
||||||
|
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_SlidePlayerRed (int choice)
|
static void M_SlidePlayerRed (int choice)
|
||||||
|
@ -3645,27 +3706,50 @@ void M_Drawer ()
|
||||||
// [RH] Use options menu cursor for the player setup menu.
|
// [RH] Use options menu cursor for the player setup menu.
|
||||||
if (skullAnimCounter < 6)
|
if (skullAnimCounter < 6)
|
||||||
{
|
{
|
||||||
|
double item;
|
||||||
|
// The green slider is halfway between lines, and the red and
|
||||||
|
// blue ones are offset slightly to make room for it.
|
||||||
|
if (itemOn < 3)
|
||||||
|
{
|
||||||
|
item = itemOn;
|
||||||
|
}
|
||||||
|
else if (itemOn > 5)
|
||||||
|
{
|
||||||
|
item = itemOn - 1;
|
||||||
|
}
|
||||||
|
else if (itemOn == 3)
|
||||||
|
{
|
||||||
|
item = 2.875;
|
||||||
|
}
|
||||||
|
else if (itemOn == 4)
|
||||||
|
{
|
||||||
|
item = 3.5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item = 4.125;
|
||||||
|
}
|
||||||
screen->DrawText (ConFont, CR_RED, x - 16,
|
screen->DrawText (ConFont, CR_RED, x - 16,
|
||||||
currentMenu->y + itemOn*PLAYERSETUP_LINEHEIGHT +
|
currentMenu->y + int(item*PLAYERSETUP_LINEHEIGHT) +
|
||||||
(!(gameinfo.gametype & (GAME_DoomStrifeChex)) ? 6 : -1), "\xd",
|
(!(gameinfo.gametype & (GAME_DoomStrifeChex)) ? 6 : -1), "\xd",
|
||||||
DTA_Clean, true, TAG_DONE);
|
DTA_Clean, true, TAG_DONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (gameinfo.gametype & GAME_DoomChex)
|
else if (gameinfo.gametype & GAME_DoomChex)
|
||||||
{
|
{
|
||||||
screen->DrawTexture (TexMan[skullName[whichSkull]],
|
screen->DrawTexture (TexMan("M_SKULL1"),
|
||||||
x + SKULLXOFF, currentMenu->y - 5 + itemOn*LINEHEIGHT,
|
x + SKULLXOFF, currentMenu->y - 5 + itemOn*LINEHEIGHT,
|
||||||
DTA_Clean, true, TAG_DONE);
|
DTA_Clean, true, TAG_DONE);
|
||||||
}
|
}
|
||||||
else if (gameinfo.gametype == GAME_Strife)
|
else if (gameinfo.gametype == GAME_Strife)
|
||||||
{
|
{
|
||||||
screen->DrawTexture (TexMan[cursName[(MenuTime >> 2) & 7]],
|
screen->DrawTexture (TexMan("M_CURS1"),
|
||||||
x - 28, currentMenu->y - 5 + itemOn*LINEHEIGHT,
|
x - 28, currentMenu->y - 5 + itemOn*LINEHEIGHT,
|
||||||
DTA_Clean, true, TAG_DONE);
|
DTA_Clean, true, TAG_DONE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
screen->DrawTexture (TexMan[MenuTime & 16 ? "M_SLCTR1" : "M_SLCTR2"],
|
screen->DrawTexture (TexMan("M_SLCTR1"),
|
||||||
x + SELECTOR_XOFFSET,
|
x + SELECTOR_XOFFSET,
|
||||||
currentMenu->y + itemOn*LINEHEIGHT + SELECTOR_YOFFSET,
|
currentMenu->y + itemOn*LINEHEIGHT + SELECTOR_YOFFSET,
|
||||||
DTA_Clean, true, TAG_DONE);
|
DTA_Clean, true, TAG_DONE);
|
||||||
|
@ -3859,7 +3943,6 @@ void M_Ticker (void)
|
||||||
MenuTime++;
|
MenuTime++;
|
||||||
if (--skullAnimCounter <= 0)
|
if (--skullAnimCounter <= 0)
|
||||||
{
|
{
|
||||||
whichSkull ^= 1;
|
|
||||||
skullAnimCounter = 8;
|
skullAnimCounter = 8;
|
||||||
}
|
}
|
||||||
if (currentMenu == &PSetupDef || currentMenu == &ClassMenuDef)
|
if (currentMenu == &PSetupDef || currentMenu == &ClassMenuDef)
|
||||||
|
@ -3913,7 +3996,6 @@ void M_Init (void)
|
||||||
menuactive = MENU_Off;
|
menuactive = MENU_Off;
|
||||||
InfoType = 0;
|
InfoType = 0;
|
||||||
itemOn = currentMenu->lastOn;
|
itemOn = currentMenu->lastOn;
|
||||||
whichSkull = 0;
|
|
||||||
skullAnimCounter = 10;
|
skullAnimCounter = 10;
|
||||||
drawSkull = true;
|
drawSkull = true;
|
||||||
messageToPrint = 0;
|
messageToPrint = 0;
|
||||||
|
@ -4034,4 +4116,5 @@ static void PickPlayerClass ()
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerClass = &PlayerClasses[pclass];
|
PlayerClass = &PlayerClasses[pclass];
|
||||||
|
P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets);
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,6 @@ void M_FindResponseFile (void)
|
||||||
char **argv;
|
char **argv;
|
||||||
char *file;
|
char *file;
|
||||||
int argc;
|
int argc;
|
||||||
int argcinresp;
|
|
||||||
FILE *handle;
|
FILE *handle;
|
||||||
int size;
|
int size;
|
||||||
long argsize;
|
long argsize;
|
||||||
|
@ -183,23 +182,32 @@ void M_FindResponseFile (void)
|
||||||
file[size] = 0;
|
file[size] = 0;
|
||||||
fclose (handle);
|
fclose (handle);
|
||||||
|
|
||||||
argsize = ParseCommandLine (file, &argcinresp, NULL);
|
argsize = ParseCommandLine (file, &argc, NULL);
|
||||||
argc = argcinresp + Args->NumArgs() - 1;
|
argc = Args->NumArgs() - 1;
|
||||||
|
|
||||||
if (argc != 0)
|
if (argc != 0)
|
||||||
{
|
{
|
||||||
argv = (char **)M_Malloc (argc*sizeof(char *) + argsize);
|
argv = (char **)M_Malloc (argc*sizeof(char *) + argsize);
|
||||||
argv[i] = (char *)argv + argc*sizeof(char *);
|
argv[0] = (char *)argv + argc*sizeof(char *);
|
||||||
ParseCommandLine (file, NULL, argv+i);
|
ParseCommandLine (file, NULL, argv);
|
||||||
|
|
||||||
|
// Create a new argument vector
|
||||||
|
DArgs *newargs = new DArgs;
|
||||||
|
|
||||||
|
// Copy parameters before response file.
|
||||||
for (index = 0; index < i; ++index)
|
for (index = 0; index < i; ++index)
|
||||||
argv[index] = Args->GetArg (index);
|
newargs->AppendArg(Args->GetArg(index));
|
||||||
|
|
||||||
for (index = i + 1, i += argcinresp; index < Args->NumArgs (); ++index)
|
// Copy parameters from response file.
|
||||||
argv[i++] = Args->GetArg (index);
|
for (index = 0; index < argc; ++i)
|
||||||
|
newargs->AppendArg(argv[index]);
|
||||||
|
|
||||||
Args->Destroy();
|
// Copy parameters after response file.
|
||||||
Args = new DArgs(i, argv);
|
for (index = i + 1, i = newargs->NumArgs(); index < Args->NumArgs(); ++index)
|
||||||
|
newargs->AppendArg(Args->GetArg(index));
|
||||||
|
|
||||||
|
// Use the new argument vector as the global Args object.
|
||||||
|
Args = newargs;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] file;
|
delete[] file;
|
||||||
|
|
|
@ -789,7 +789,7 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou
|
||||||
newvert.y += fixed_t(frac * double(Vertices[seg->v2].y - newvert.y));
|
newvert.y += fixed_t(frac * double(Vertices[seg->v2].y - newvert.y));
|
||||||
vertnum = VertexMap->SelectVertexClose (newvert);
|
vertnum = VertexMap->SelectVertexClose (newvert);
|
||||||
|
|
||||||
if (vertnum == seg->v1 || vertnum == seg->v2)
|
if (vertnum == (unsigned int)seg->v1 || vertnum == (unsigned int)seg->v2)
|
||||||
{
|
{
|
||||||
Printf("SelectVertexClose selected endpoint of seg %u\n", set);
|
Printf("SelectVertexClose selected endpoint of seg %u\n", set);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3280,7 +3280,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
||||||
case ACSF_CheckActorClass:
|
case ACSF_CheckActorClass:
|
||||||
{
|
{
|
||||||
AActor *a = args[0] == 0 ? (AActor *)activator : SingleActorFromTID(args[0], NULL);
|
AActor *a = args[0] == 0 ? (AActor *)activator : SingleActorFromTID(args[0], NULL);
|
||||||
return a->GetClass()->TypeName == FName(FBehavior::StaticLookupString(args[1]));
|
return a == NULL ? false : a->GetClass()->TypeName == FName(FBehavior::StaticLookupString(args[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
case ACSF_SoundSequenceOnActor:
|
case ACSF_SoundSequenceOnActor:
|
||||||
|
@ -5360,13 +5360,13 @@ int DLevelScript::RunScript ()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCD_CLEARACTORINVENTORY:
|
case PCD_CLEARACTORINVENTORY:
|
||||||
if (STACK(3) == 0)
|
if (STACK(1) == 0)
|
||||||
{
|
{
|
||||||
ClearInventory(NULL);
|
ClearInventory(NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FActorIterator it(STACK(3));
|
FActorIterator it(STACK(1));
|
||||||
AActor *actor;
|
AActor *actor;
|
||||||
for (actor = it.Next(); actor != NULL; actor = it.Next())
|
for (actor = it.Next(); actor != NULL; actor = it.Next())
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,6 +109,21 @@ struct spritetype
|
||||||
SWORD lotag, hitag, extra;
|
SWORD lotag, hitag, extra;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// I used to have all the Xobjects mapped out. Not anymore.
|
||||||
|
// (Thanks for the great firmware, Seagate!)
|
||||||
|
struct Xsprite
|
||||||
|
{
|
||||||
|
BYTE NotReallyPadding[16];
|
||||||
|
WORD Data1;
|
||||||
|
WORD Data2;
|
||||||
|
WORD Data3;
|
||||||
|
WORD ThisIsntPaddingEither;
|
||||||
|
DWORD NorThis:2;
|
||||||
|
DWORD Data4:16;
|
||||||
|
DWORD WhatIsThisIDontEven:14;
|
||||||
|
BYTE ThisNeedsToBe56Bytes[28];
|
||||||
|
};
|
||||||
|
|
||||||
struct SlopeWork
|
struct SlopeWork
|
||||||
{
|
{
|
||||||
walltype *wal;
|
walltype *wal;
|
||||||
|
@ -128,7 +143,7 @@ void P_AdjustLine (line_t *line);
|
||||||
static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **sprites, int *numsprites);
|
static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **sprites, int *numsprites);
|
||||||
static void LoadSectors (sectortype *bsectors);
|
static void LoadSectors (sectortype *bsectors);
|
||||||
static void LoadWalls (walltype *walls, int numwalls, sectortype *bsectors);
|
static void LoadWalls (walltype *walls, int numwalls, sectortype *bsectors);
|
||||||
static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsectors, FMapThing *mapthings);
|
static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, sectortype *bsectors, FMapThing *mapthings);
|
||||||
static vertex_t *FindVertex (fixed_t x, fixed_t y);
|
static vertex_t *FindVertex (fixed_t x, fixed_t y);
|
||||||
static void CreateStartSpot (fixed_t *pos, FMapThing *start);
|
static void CreateStartSpot (fixed_t *pos, FMapThing *start);
|
||||||
static void CalcPlane (SlopeWork &slope, secplane_t &plane);
|
static void CalcPlane (SlopeWork &slope, secplane_t &plane);
|
||||||
|
@ -145,8 +160,10 @@ static void Decrypt (void *to, const void *from, int len, int key);
|
||||||
bool P_IsBuildMap(MapData *map)
|
bool P_IsBuildMap(MapData *map)
|
||||||
{
|
{
|
||||||
DWORD len = map->Size(ML_LABEL);
|
DWORD len = map->Size(ML_LABEL);
|
||||||
if (len < 4) return false;
|
if (len < 4)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
BYTE *data = new BYTE[len];
|
BYTE *data = new BYTE[len];
|
||||||
|
|
||||||
map->Seek(ML_LABEL);
|
map->Seek(ML_LABEL);
|
||||||
|
@ -215,7 +232,7 @@ bool P_LoadBuildMap (BYTE *data, size_t len, FMapThing **sprites, int *numspr)
|
||||||
*sprites = new FMapThing[numsprites + 1];
|
*sprites = new FMapThing[numsprites + 1];
|
||||||
CreateStartSpot ((fixed_t *)(data + 4), *sprites);
|
CreateStartSpot ((fixed_t *)(data + 4), *sprites);
|
||||||
*numspr = 1 + LoadSprites ((spritetype *)(data + 26 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype)),
|
*numspr = 1 + LoadSprites ((spritetype *)(data + 26 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype)),
|
||||||
numsprites, (sectortype *)(data + 22), *sprites + 1);
|
NULL, numsprites, (sectortype *)(data + 22), *sprites + 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -251,11 +268,11 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int *
|
||||||
{
|
{
|
||||||
memcpy (infoBlock, data + 6, 37);
|
memcpy (infoBlock, data + 6, 37);
|
||||||
}
|
}
|
||||||
numRevisions = *(DWORD *)(infoBlock + 27);
|
numRevisions = LittleLong(*(DWORD *)(infoBlock + 27));
|
||||||
numsectors = *(WORD *)(infoBlock + 31);
|
numsectors = LittleShort(*(WORD *)(infoBlock + 31));
|
||||||
numWalls = *(WORD *)(infoBlock + 33);
|
numWalls = LittleShort(*(WORD *)(infoBlock + 33));
|
||||||
numsprites = *(WORD *)(infoBlock + 35);
|
numsprites = LittleShort(*(WORD *)(infoBlock + 35));
|
||||||
skyLen = 2 << *(WORD *)(infoBlock + 16);
|
skyLen = 2 << LittleShort(*(WORD *)(infoBlock + 16));
|
||||||
|
|
||||||
if (mapver == 7)
|
if (mapver == 7)
|
||||||
{
|
{
|
||||||
|
@ -275,6 +292,7 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int *
|
||||||
sectortype *bsec = new sectortype[numsectors];
|
sectortype *bsec = new sectortype[numsectors];
|
||||||
walltype *bwal = new walltype[numWalls];
|
walltype *bwal = new walltype[numWalls];
|
||||||
spritetype *bspr = new spritetype[numsprites];
|
spritetype *bspr = new spritetype[numsprites];
|
||||||
|
Xsprite *xspr = new Xsprite[numsprites];
|
||||||
|
|
||||||
// Read sectors
|
// Read sectors
|
||||||
k = numRevisions * sizeof(sectortype);
|
k = numRevisions * sizeof(sectortype);
|
||||||
|
@ -327,9 +345,15 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int *
|
||||||
memcpy (&bspr[i], data, sizeof(spritetype));
|
memcpy (&bspr[i], data, sizeof(spritetype));
|
||||||
}
|
}
|
||||||
data += sizeof(spritetype);
|
data += sizeof(spritetype);
|
||||||
if (bspr[i].extra > 0) // skip Xsprite
|
if (bspr[i].extra > 0) // copy Xsprite
|
||||||
{
|
{
|
||||||
data += 56;
|
assert(sizeof(Xsprite) == 56);
|
||||||
|
memcpy(&xspr[i], data, sizeof(Xsprite));
|
||||||
|
data += sizeof(Xsprite);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(&xspr[i], 0, sizeof(Xsprite));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,11 +363,12 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int *
|
||||||
LoadWalls (bwal, numWalls, bsec);
|
LoadWalls (bwal, numWalls, bsec);
|
||||||
*mapthings = new FMapThing[numsprites + 1];
|
*mapthings = new FMapThing[numsprites + 1];
|
||||||
CreateStartSpot ((fixed_t *)infoBlock, *mapthings);
|
CreateStartSpot ((fixed_t *)infoBlock, *mapthings);
|
||||||
*numspr = 1 + LoadSprites (bspr, numsprites, bsec, *mapthings + 1);
|
*numspr = 1 + LoadSprites (bspr, xspr, numsprites, bsec, *mapthings + 1);
|
||||||
|
|
||||||
delete[] bsec;
|
delete[] bsec;
|
||||||
delete[] bwal;
|
delete[] bwal;
|
||||||
delete[] bspr;
|
delete[] bspr;
|
||||||
|
delete[] xspr;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -363,6 +388,8 @@ static void LoadSectors (sectortype *bsec)
|
||||||
sec = sectors = new sector_t[numsectors];
|
sec = sectors = new sector_t[numsectors];
|
||||||
memset (sectors, 0, sizeof(sector_t)*numsectors);
|
memset (sectors, 0, sizeof(sector_t)*numsectors);
|
||||||
|
|
||||||
|
sectors[0].e = new extsector_t[numsectors];
|
||||||
|
|
||||||
for (int i = 0; i < numsectors; ++i, ++bsec, ++sec)
|
for (int i = 0; i < numsectors; ++i, ++bsec, ++sec)
|
||||||
{
|
{
|
||||||
bsec->wallptr = WORD(bsec->wallptr);
|
bsec->wallptr = WORD(bsec->wallptr);
|
||||||
|
@ -370,6 +397,7 @@ static void LoadSectors (sectortype *bsec)
|
||||||
bsec->ceilingstat = WORD(bsec->ceilingstat);
|
bsec->ceilingstat = WORD(bsec->ceilingstat);
|
||||||
bsec->floorstat = WORD(bsec->floorstat);
|
bsec->floorstat = WORD(bsec->floorstat);
|
||||||
|
|
||||||
|
sec->e = §ors[0].e[i];
|
||||||
sec->SetPlaneTexZ(sector_t::floor, -(LittleLong(bsec->floorz) << 8));
|
sec->SetPlaneTexZ(sector_t::floor, -(LittleLong(bsec->floorz) << 8));
|
||||||
sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor);
|
sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor);
|
||||||
sec->floorplane.c = FRACUNIT;
|
sec->floorplane.c = FRACUNIT;
|
||||||
|
@ -512,6 +540,8 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec)
|
||||||
}
|
}
|
||||||
|
|
||||||
sides[i].TexelLength = walls[i].xrepeat * 8;
|
sides[i].TexelLength = walls[i].xrepeat * 8;
|
||||||
|
sides[i].SetTextureYScale(walls[i].yrepeat << (FRACBITS - 3));
|
||||||
|
sides[i].SetTextureXScale(FRACUNIT);
|
||||||
sides[i].SetLight(SHADE2LIGHT(walls[i].shade));
|
sides[i].SetLight(SHADE2LIGHT(walls[i].shade));
|
||||||
sides[i].Flags = WALLF_ABSLIGHTING;
|
sides[i].Flags = WALLF_ABSLIGHTING;
|
||||||
sides[i].RightSide = walls[i].point2;
|
sides[i].RightSide = walls[i].point2;
|
||||||
|
@ -631,14 +661,17 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec)
|
||||||
R_AlignFlat (linenum, sidenum == bsec->wallptr, 0);
|
R_AlignFlat (linenum, sidenum == bsec->wallptr, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i = 0; i < numsides; i++)
|
|
||||||
{
|
|
||||||
sides[i].linedef = &lines[intptr_t(sides[i].linedef)];
|
|
||||||
}
|
|
||||||
for (i = 0; i < numlines; i++)
|
for (i = 0; i < numlines; i++)
|
||||||
{
|
{
|
||||||
lines[i].sidedef[0] = &sides[intptr_t(lines[i].sidedef[0])];
|
intptr_t front = intptr_t(lines[i].sidedef[0]);
|
||||||
lines[i].sidedef[1] = &sides[intptr_t(lines[i].sidedef[1])];
|
intptr_t back = intptr_t(lines[i].sidedef[1]);
|
||||||
|
lines[i].sidedef[0] = front >= 0 ? &sides[front] : NULL;
|
||||||
|
lines[i].sidedef[1] = back >= 0 ? &sides[back] : NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < numsides; i++)
|
||||||
|
{
|
||||||
|
assert(sides[i].sector != NULL);
|
||||||
|
sides[i].linedef = &lines[intptr_t(sides[i].linedef)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,32 +681,46 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsectors,
|
static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites,
|
||||||
FMapThing *mapthings)
|
sectortype *bsectors, FMapThing *mapthings)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for (int i = 0; i < numsprites; ++i)
|
for (int i = 0; i < numsprites; ++i)
|
||||||
{
|
{
|
||||||
if (sprites[i].cstat & (16|32|32768)) continue;
|
|
||||||
if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue;
|
|
||||||
|
|
||||||
mapthings[count].thingid = 0;
|
mapthings[count].thingid = 0;
|
||||||
mapthings[count].x = (sprites[i].x << 12);
|
mapthings[count].x = (sprites[i].x << 12);
|
||||||
mapthings[count].y = -(sprites[i].y << 12);
|
mapthings[count].y = -(sprites[i].y << 12);
|
||||||
mapthings[count].z = (bsectors[sprites[i].sectnum].floorz - sprites[i].z) << 8;
|
mapthings[count].z = (bsectors[sprites[i].sectnum].floorz - sprites[i].z) << 8;
|
||||||
mapthings[count].angle = (((2048-sprites[i].ang) & 2047) * 360) >> 11;
|
mapthings[count].angle = (((2048-sprites[i].ang) & 2047) * 360) >> 11;
|
||||||
mapthings[count].type = 9988;
|
|
||||||
mapthings[count].ClassFilter = 0xffff;
|
mapthings[count].ClassFilter = 0xffff;
|
||||||
mapthings[count].SkillFilter = 0xffff;
|
mapthings[count].SkillFilter = 0xffff;
|
||||||
mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH;
|
mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH;
|
||||||
mapthings[count].special = 0;
|
mapthings[count].special = 0;
|
||||||
|
|
||||||
|
if (xsprites != NULL && sprites[i].lotag == 710)
|
||||||
|
{ // Blood ambient sound
|
||||||
|
mapthings[count].args[0] = xsprites[i].Data3;
|
||||||
|
// I am totally guessing abount the volume level. 50 seems to be a pretty
|
||||||
|
// typical value for Blood's standard maps, so I assume it's 100-based.
|
||||||
|
mapthings[count].args[1] = xsprites[i].Data4;
|
||||||
|
mapthings[count].args[2] = xsprites[i].Data1;
|
||||||
|
mapthings[count].args[3] = xsprites[i].Data2;
|
||||||
|
mapthings[count].args[4] = 0;
|
||||||
|
mapthings[count].type = 14065;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sprites[i].cstat & (16|32|32768)) continue;
|
||||||
|
if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue;
|
||||||
|
|
||||||
|
mapthings[count].type = 9988;
|
||||||
mapthings[count].args[0] = sprites[i].picnum & 255;
|
mapthings[count].args[0] = sprites[i].picnum & 255;
|
||||||
mapthings[count].args[1] = sprites[i].picnum >> 8;
|
mapthings[count].args[1] = sprites[i].picnum >> 8;
|
||||||
mapthings[count].args[2] = sprites[i].xrepeat;
|
mapthings[count].args[2] = sprites[i].xrepeat;
|
||||||
mapthings[count].args[3] = sprites[i].yrepeat;
|
mapthings[count].args[3] = sprites[i].yrepeat;
|
||||||
mapthings[count].args[4] = (sprites[i].cstat & 14) | ((sprites[i].cstat >> 9) & 1);
|
mapthings[count].args[4] = (sprites[i].cstat & 14) | ((sprites[i].cstat >> 9) & 1);
|
||||||
|
}
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
|
|
@ -198,16 +198,16 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void P_NoiseAlert (AActor *target, AActor *emmiter, bool splash)
|
void P_NoiseAlert (AActor *target, AActor *emitter, bool splash)
|
||||||
{
|
{
|
||||||
if (emmiter == NULL)
|
if (emitter == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (target != NULL && target->player && (target->player->cheats & CF_NOTARGET))
|
if (target != NULL && target->player && (target->player->cheats & CF_NOTARGET))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
validcount++;
|
validcount++;
|
||||||
P_RecursiveSound (emmiter->Sector, target, splash, 0);
|
P_RecursiveSound (emitter->Sector, target, splash, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ bool P_CheckMissileRange (AActor *actor)
|
||||||
{
|
{
|
||||||
fixed_t dist;
|
fixed_t dist;
|
||||||
|
|
||||||
if (!P_CheckSight (actor, actor->target, 4))
|
if (!P_CheckSight (actor, actor->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (actor->flags & MF_JUSTHIT)
|
if (actor->flags & MF_JUSTHIT)
|
||||||
|
@ -1136,7 +1136,7 @@ bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams
|
||||||
}
|
}
|
||||||
|
|
||||||
// P_CheckSight is by far the most expensive operation in here so let's do it last.
|
// P_CheckSight is by far the most expensive operation in here so let's do it last.
|
||||||
return P_CheckSight(lookee, other, 2);
|
return P_CheckSight(lookee, other, SF_SEEPASTBLOCKEVERYTHING);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -1154,7 +1154,7 @@ bool P_LookForMonsters (AActor *actor)
|
||||||
AActor *mo;
|
AActor *mo;
|
||||||
TThinkerIterator<AActor> iterator;
|
TThinkerIterator<AActor> iterator;
|
||||||
|
|
||||||
if (!P_CheckSight (players[0].mo, actor, 2))
|
if (!P_CheckSight (players[0].mo, actor, SF_SEEPASTBLOCKEVERYTHING))
|
||||||
{ // Player can't see monster
|
{ // Player can't see monster
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1178,11 +1178,11 @@ bool P_LookForMonsters (AActor *actor)
|
||||||
{ // Stop searching
|
{ // Stop searching
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mo->IsKindOf (actor->GetClass()) || actor->IsKindOf (mo->GetClass()))
|
if (mo->GetSpecies() == actor->GetSpecies())
|
||||||
{ // [RH] Don't go after same species
|
{ // [RH] Don't go after same species
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!P_CheckSight (actor, mo, 2))
|
if (!P_CheckSight (actor, mo, SF_SEEPASTBLOCKEVERYTHING))
|
||||||
{ // Out of sight
|
{ // Out of sight
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1765,7 +1765,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look)
|
||||||
|
|
||||||
if (self->flags & MF_AMBUSH)
|
if (self->flags & MF_AMBUSH)
|
||||||
{
|
{
|
||||||
if (P_CheckSight (self, self->target, 2))
|
if (P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING))
|
||||||
goto seeyou;
|
goto seeyou;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1933,7 +1933,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx)
|
||||||
if (self->flags & MF_AMBUSH)
|
if (self->flags & MF_AMBUSH)
|
||||||
{
|
{
|
||||||
dist = P_AproxDistance (self->target->x - self->x, self->target->y - self->y);
|
dist = P_AproxDistance (self->target->x - self->x, self->target->y - self->y);
|
||||||
if (P_CheckSight (self, self->target, 2) &&
|
if (P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING) &&
|
||||||
(!minseedist || dist > minseedist) &&
|
(!minseedist || dist > minseedist) &&
|
||||||
(!maxseedist || dist < maxseedist))
|
(!maxseedist || dist < maxseedist))
|
||||||
{
|
{
|
||||||
|
@ -2070,7 +2070,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look2)
|
||||||
{
|
{
|
||||||
if (self->flags & MF_AMBUSH)
|
if (self->flags & MF_AMBUSH)
|
||||||
{
|
{
|
||||||
if (!P_CheckSight (self, targ, 2))
|
if (!P_CheckSight (self, targ, SF_SEEPASTBLOCKEVERYTHING))
|
||||||
goto nosee;
|
goto nosee;
|
||||||
}
|
}
|
||||||
self->target = targ;
|
self->target = targ;
|
||||||
|
@ -2745,7 +2745,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail)
|
||||||
self->target->x,
|
self->target->x,
|
||||||
self->target->y);
|
self->target->y);
|
||||||
|
|
||||||
self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &linetarget, ANGLE_1*60, false, false, false, self->target);
|
self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &linetarget, ANGLE_1*60, 0, self->target);
|
||||||
if (linetarget == NULL)
|
if (linetarget == NULL)
|
||||||
{
|
{
|
||||||
// We probably won't hit the target, but aim at it anyway so we don't look stupid.
|
// We probably won't hit the target, but aim at it anyway so we don't look stupid.
|
||||||
|
|
|
@ -1274,7 +1274,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
|
||||||
painchance = target->PainChance;
|
painchance = target->PainChance;
|
||||||
if (pc != NULL)
|
if (pc != NULL)
|
||||||
{
|
{
|
||||||
BYTE * ppc = pc->CheckKey(mod);
|
int *ppc = pc->CheckKey(mod);
|
||||||
if (ppc != NULL)
|
if (ppc != NULL)
|
||||||
{
|
{
|
||||||
painchance = *ppc;
|
painchance = *ppc;
|
||||||
|
|
|
@ -189,8 +189,11 @@ FUNC(LS_Door_CloseWaitOpen)
|
||||||
}
|
}
|
||||||
|
|
||||||
FUNC(LS_Door_Animated)
|
FUNC(LS_Door_Animated)
|
||||||
// Door_Animated (tag, speed, delay)
|
// Door_Animated (tag, speed, delay, lock)
|
||||||
{
|
{
|
||||||
|
if (arg3 != 0 && !P_CheckKeys (it, arg3, arg0 != 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
return EV_SlidingDoor (ln, it, arg0, arg1, arg2);
|
return EV_SlidingDoor (ln, it, arg0, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -394,6 +394,15 @@ void P_SlideMove (AActor* mo, fixed_t tryx, fixed_t tryy, int numsteps);
|
||||||
bool P_BounceWall (AActor *mo);
|
bool P_BounceWall (AActor *mo);
|
||||||
bool P_BounceActor (AActor *mo, AActor * BlockingMobj);
|
bool P_BounceActor (AActor *mo, AActor * BlockingMobj);
|
||||||
bool P_CheckSight (const AActor* t1, const AActor* t2, int flags=0);
|
bool P_CheckSight (const AActor* t1, const AActor* t2, int flags=0);
|
||||||
|
|
||||||
|
enum ESightFlags
|
||||||
|
{
|
||||||
|
SF_IGNOREVISIBILITY=1,
|
||||||
|
SF_SEEPASTSHOOTABLELINES=2,
|
||||||
|
SF_SEEPASTBLOCKEVERYTHING=4,
|
||||||
|
SF_IGNOREWATERBOUNDARY=8
|
||||||
|
};
|
||||||
|
|
||||||
void P_ResetSightCounters (bool full);
|
void P_ResetSightCounters (bool full);
|
||||||
bool P_TalkFacing (AActor *player);
|
bool P_TalkFacing (AActor *player);
|
||||||
void P_UseLines (player_t* player);
|
void P_UseLines (player_t* player);
|
||||||
|
@ -402,7 +411,16 @@ void P_FindFloorCeiling (AActor *actor, bool onlymidtex = false);
|
||||||
|
|
||||||
bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset);
|
bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset);
|
||||||
|
|
||||||
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget = NULL, fixed_t vrange=0, bool forcenosmart=false, bool check3d = false, bool checknonshootable = false, AActor *target=NULL);
|
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget = NULL, fixed_t vrange=0, int flags = 0, AActor *target=NULL);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ALF_FORCENOSMART = 1,
|
||||||
|
ALF_CHECK3D = 2,
|
||||||
|
ALF_CHECKNONSHOOTABLE = 4,
|
||||||
|
ALF_CHECKCONVERSATION = 8,
|
||||||
|
};
|
||||||
|
|
||||||
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, PClassActor *pufftype, bool ismelee = false);
|
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, PClassActor *pufftype, bool ismelee = false);
|
||||||
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, bool ismelee = false);
|
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, bool ismelee = false);
|
||||||
void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch);
|
void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch);
|
||||||
|
|
|
@ -2807,8 +2807,7 @@ struct aim_t
|
||||||
AActor * linetarget;
|
AActor * linetarget;
|
||||||
AActor * thing_friend, * thing_other;
|
AActor * thing_friend, * thing_other;
|
||||||
angle_t pitch_friend, pitch_other;
|
angle_t pitch_friend, pitch_other;
|
||||||
bool notsmart;
|
int flags;
|
||||||
bool check3d;
|
|
||||||
#ifdef _3DFLOORS
|
#ifdef _3DFLOORS
|
||||||
sector_t * lastsector;
|
sector_t * lastsector;
|
||||||
secplane_t * lastfloorplane;
|
secplane_t * lastfloorplane;
|
||||||
|
@ -2819,7 +2818,7 @@ struct aim_t
|
||||||
bool AimTraverse3DFloors(const divline_t &trace, intercept_t * in);
|
bool AimTraverse3DFloors(const divline_t &trace, intercept_t * in);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, bool checknonshootable = false, AActor *target=NULL);
|
void AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, AActor *target=NULL);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2936,7 +2935,7 @@ bool aim_t::AimTraverse3DFloors(const divline_t &trace, intercept_t * in)
|
||||||
//
|
//
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, bool checknonshootable, AActor *target)
|
void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, AActor *target)
|
||||||
{
|
{
|
||||||
FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES|PT_ADDTHINGS);
|
FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES|PT_ADDTHINGS);
|
||||||
intercept_t *in;
|
intercept_t *in;
|
||||||
|
@ -2994,7 +2993,11 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
||||||
if (target != NULL && th != target)
|
if (target != NULL && th != target)
|
||||||
continue; // only care about target, and you're not it
|
continue; // only care about target, and you're not it
|
||||||
|
|
||||||
if (!checknonshootable) // For info CCMD, ignore stuff about GHOST and SHOOTABLE flags
|
// If we want to start a conversation anything that has one should be
|
||||||
|
// found, regardless of other settings.
|
||||||
|
if (!(flags & ALF_CHECKCONVERSATION) || th->Conversation == NULL)
|
||||||
|
{
|
||||||
|
if (!(flags & ALF_CHECKNONSHOOTABLE)) // For info CCMD, ignore stuff about GHOST and SHOOTABLE flags
|
||||||
{
|
{
|
||||||
if (!(th->flags&MF_SHOOTABLE))
|
if (!(th->flags&MF_SHOOTABLE))
|
||||||
continue; // corpse or something
|
continue; // corpse or something
|
||||||
|
@ -3008,6 +3011,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
dist = FixedMul (attackrange, in->frac);
|
dist = FixedMul (attackrange, in->frac);
|
||||||
|
|
||||||
#ifdef _3DFLOORS
|
#ifdef _3DFLOORS
|
||||||
|
@ -3053,7 +3057,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
||||||
if (crossedffloors)
|
if (crossedffloors)
|
||||||
{
|
{
|
||||||
// if 3D floors were in the way do an extra visibility check for safety
|
// if 3D floors were in the way do an extra visibility check for safety
|
||||||
if (!P_CheckSight(shootthing, th, 1))
|
if (!P_CheckSight(shootthing, th, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY))
|
||||||
{
|
{
|
||||||
// the thing can't be seen so we can safely exclude its range from our aiming field
|
// the thing can't be seen so we can safely exclude its range from our aiming field
|
||||||
if (thingtoppitch<toppitch)
|
if (thingtoppitch<toppitch)
|
||||||
|
@ -3079,7 +3083,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
||||||
|
|
||||||
thingpitch = thingtoppitch/2 + thingbottompitch/2;
|
thingpitch = thingtoppitch/2 + thingbottompitch/2;
|
||||||
|
|
||||||
if (check3d)
|
if (flags & ALF_CHECK3D)
|
||||||
{
|
{
|
||||||
// We need to do a 3D distance check here because this is nearly always used in
|
// We need to do a 3D distance check here because this is nearly always used in
|
||||||
// combination with P_LineAttack. P_LineAttack uses 3D distance but FPathTraverse
|
// combination with P_LineAttack. P_LineAttack uses 3D distance but FPathTraverse
|
||||||
|
@ -3096,7 +3100,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sv_smartaim && !notsmart)
|
if (sv_smartaim != 0 && !(flags & ALF_FORCENOSMART))
|
||||||
{
|
{
|
||||||
// try to be a little smarter about what to aim at!
|
// try to be a little smarter about what to aim at!
|
||||||
// In particular avoid autoaiming at friends amd barrels.
|
// In particular avoid autoaiming at friends amd barrels.
|
||||||
|
@ -3131,11 +3135,6 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
||||||
aimpitch = thingpitch;
|
aimpitch = thingpitch;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (checknonshootable)
|
|
||||||
{
|
|
||||||
linetarget = th;
|
|
||||||
aimpitch = thingpitch;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3145,15 +3144,16 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
||||||
//
|
//
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange, bool forcenosmart, bool check3d, bool checknonshootable, AActor *target)
|
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange,
|
||||||
|
int flags, AActor *target)
|
||||||
{
|
{
|
||||||
fixed_t x2;
|
fixed_t x2;
|
||||||
fixed_t y2;
|
fixed_t y2;
|
||||||
aim_t aim;
|
aim_t aim;
|
||||||
|
|
||||||
angle >>= ANGLETOFINESHIFT;
|
angle >>= ANGLETOFINESHIFT;
|
||||||
|
aim.flags = flags;
|
||||||
aim.shootthing = t1;
|
aim.shootthing = t1;
|
||||||
aim.check3d = check3d;
|
|
||||||
|
|
||||||
x2 = t1->x + (distance>>FRACBITS)*finecosine[angle];
|
x2 = t1->x + (distance>>FRACBITS)*finecosine[angle];
|
||||||
y2 = t1->y + (distance>>FRACBITS)*finesine[angle];
|
y2 = t1->y + (distance>>FRACBITS)*finesine[angle];
|
||||||
|
@ -3194,7 +3194,6 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p
|
||||||
}
|
}
|
||||||
aim.toppitch = t1->pitch - vrange;
|
aim.toppitch = t1->pitch - vrange;
|
||||||
aim.bottompitch = t1->pitch + vrange;
|
aim.bottompitch = t1->pitch + vrange;
|
||||||
aim.notsmart = forcenosmart;
|
|
||||||
|
|
||||||
aim.attackrange = distance;
|
aim.attackrange = distance;
|
||||||
aim.linetarget = NULL;
|
aim.linetarget = NULL;
|
||||||
|
@ -3223,7 +3222,7 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
aim.AimTraverse (t1->x, t1->y, x2, y2, checknonshootable, target);
|
aim.AimTraverse (t1->x, t1->y, x2, y2, target);
|
||||||
|
|
||||||
if (!aim.linetarget)
|
if (!aim.linetarget)
|
||||||
{
|
{
|
||||||
|
@ -3239,7 +3238,9 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pLineTarget)
|
if (pLineTarget)
|
||||||
|
{
|
||||||
*pLineTarget = aim.linetarget;
|
*pLineTarget = aim.linetarget;
|
||||||
|
}
|
||||||
return aim.linetarget ? aim.aimpitch : t1->pitch;
|
return aim.linetarget ? aim.aimpitch : t1->pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3588,7 +3589,7 @@ void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, a
|
||||||
{
|
{
|
||||||
if (bleedtrace.HitType == TRACE_HitWall)
|
if (bleedtrace.HitType == TRACE_HitWall)
|
||||||
{
|
{
|
||||||
PalEntry bloodcolor = actor->GetClass()->BloodColor;
|
PalEntry bloodcolor = actor->GetBloodColor();
|
||||||
if (bloodcolor != 0)
|
if (bloodcolor != 0)
|
||||||
{
|
{
|
||||||
bloodcolor.r>>=1; // the full color is too bright for blood decals
|
bloodcolor.r>>=1; // the full color is too bright for blood decals
|
||||||
|
@ -3921,13 +3922,13 @@ bool P_TalkFacing(AActor *player)
|
||||||
{
|
{
|
||||||
AActor *linetarget;
|
AActor *linetarget;
|
||||||
|
|
||||||
P_AimLineAttack(player, player->angle, TALKRANGE, &linetarget, ANGLE_1*35, true);
|
P_AimLineAttack(player, player->angle, TALKRANGE, &linetarget, ANGLE_1*35, ALF_FORCENOSMART|ALF_CHECKCONVERSATION);
|
||||||
if (linetarget == NULL)
|
if (linetarget == NULL)
|
||||||
{
|
{
|
||||||
P_AimLineAttack(player, player->angle + (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1*35, true);
|
P_AimLineAttack(player, player->angle + (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1*35, ALF_FORCENOSMART|ALF_CHECKCONVERSATION);
|
||||||
if (linetarget == NULL)
|
if (linetarget == NULL)
|
||||||
{
|
{
|
||||||
P_AimLineAttack(player, player->angle - (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1*35, true);
|
P_AimLineAttack(player, player->angle - (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1*35, ALF_FORCENOSMART|ALF_CHECKCONVERSATION);
|
||||||
if (linetarget == NULL)
|
if (linetarget == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -4327,7 +4328,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
|
||||||
}
|
}
|
||||||
points *= thing->GetClass()->RDFactor/(float)FRACUNIT;
|
points *= thing->GetClass()->RDFactor/(float)FRACUNIT;
|
||||||
|
|
||||||
if (points > 0.f && P_CheckSight (thing, bombspot, 1))
|
if (points > 0.f && P_CheckSight (thing, bombspot, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY))
|
||||||
{ // OK to damage; target is in direct path
|
{ // OK to damage; target is in direct path
|
||||||
float velz;
|
float velz;
|
||||||
float thrust;
|
float thrust;
|
||||||
|
@ -4385,7 +4386,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
|
||||||
if (dist >= bombdistance)
|
if (dist >= bombdistance)
|
||||||
continue; // out of range
|
continue; // out of range
|
||||||
|
|
||||||
if (P_CheckSight (thing, bombspot, 1))
|
if (P_CheckSight (thing, bombspot, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY))
|
||||||
{ // OK to damage; target is in direct path
|
{ // OK to damage; target is in direct path
|
||||||
dist = clamp<int>(dist - fulldamagedistance, 0, dist);
|
dist = clamp<int>(dist - fulldamagedistance, 0, dist);
|
||||||
int damage = Scale (bombdamage, bombdistance-dist, bombdistance);
|
int damage = Scale (bombdamage, bombdistance-dist, bombdistance);
|
||||||
|
@ -4595,11 +4596,12 @@ void P_DoCrunch (AActor *thing, FChangePosition *cpos)
|
||||||
P_DamageMobj (thing, NULL, NULL, cpos->crushchange, NAME_Crush);
|
P_DamageMobj (thing, NULL, NULL, cpos->crushchange, NAME_Crush);
|
||||||
|
|
||||||
// spray blood in a random direction
|
// spray blood in a random direction
|
||||||
if ((!(thing->flags&MF_NOBLOOD)) &&
|
if (!(thing->flags2&(MF2_INVULNERABLE|MF2_DORMANT)))
|
||||||
(!(thing->flags2&(MF2_INVULNERABLE|MF2_DORMANT))))
|
|
||||||
{
|
{
|
||||||
PalEntry bloodcolor = thing->GetClass()->BloodColor;
|
if (!(thing->flags&MF_NOBLOOD))
|
||||||
PClassActor *bloodcls = PClass::FindActor(thing->GetClass()->BloodType);
|
{
|
||||||
|
PalEntry bloodcolor = thing->GetBloodColor();
|
||||||
|
PClassActor *bloodcls = thing->GetBloodType();
|
||||||
|
|
||||||
P_TraceBleed (cpos->crushchange, thing);
|
P_TraceBleed (cpos->crushchange, thing);
|
||||||
if (cl_bloodtype <= 1 && bloodcls != NULL)
|
if (cl_bloodtype <= 1 && bloodcls != NULL)
|
||||||
|
@ -4625,6 +4627,11 @@ void P_DoCrunch (AActor *thing, FChangePosition *cpos)
|
||||||
thing->z + thing->height/2, an, 2, bloodcolor);
|
thing->z + thing->height/2, an, 2, bloodcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound))
|
||||||
|
{
|
||||||
|
S_Sound(thing, CHAN_VOICE, thing->CrushPainSound, 1.f, ATTN_NORM);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep checking (crush other things)
|
// keep checking (crush other things)
|
||||||
|
|
|
@ -270,8 +270,12 @@ void AActor::Serialize (FArchive &arc)
|
||||||
<< ActiveSound
|
<< ActiveSound
|
||||||
<< UseSound
|
<< UseSound
|
||||||
<< BounceSound
|
<< BounceSound
|
||||||
<< WallBounceSound
|
<< WallBounceSound;
|
||||||
<< Speed
|
if (SaveVersion >= 2234)
|
||||||
|
{
|
||||||
|
arc << CrushPainSound;
|
||||||
|
}
|
||||||
|
arc << Speed
|
||||||
<< FloatSpeed
|
<< FloatSpeed
|
||||||
<< Mass
|
<< Mass
|
||||||
<< PainChance
|
<< PainChance
|
||||||
|
@ -1069,7 +1073,7 @@ bool AActor::Grind(bool items)
|
||||||
if (isgeneric) // Not a custom crush state, so colorize it appropriately.
|
if (isgeneric) // Not a custom crush state, so colorize it appropriately.
|
||||||
{
|
{
|
||||||
S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE);
|
S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE);
|
||||||
PalEntry bloodcolor = GetClass()->BloodColor;
|
PalEntry bloodcolor = GetBloodColor();
|
||||||
if (bloodcolor!=0) Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
|
if (bloodcolor!=0) Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1113,7 +1117,7 @@ bool AActor::Grind(bool items)
|
||||||
}
|
}
|
||||||
S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE);
|
S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE);
|
||||||
|
|
||||||
PalEntry bloodcolor = GetClass()->BloodColor;
|
PalEntry bloodcolor = GetBloodColor();
|
||||||
if (bloodcolor!=0) gib->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
|
if (bloodcolor!=0) gib->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
|
||||||
}
|
}
|
||||||
if (flags & MF_ICECORPSE)
|
if (flags & MF_ICECORPSE)
|
||||||
|
@ -2130,6 +2134,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
|
||||||
fixed_t dist;
|
fixed_t dist;
|
||||||
fixed_t delta;
|
fixed_t delta;
|
||||||
fixed_t oldz = mo->z;
|
fixed_t oldz = mo->z;
|
||||||
|
fixed_t grav = mo->GetGravity();
|
||||||
|
|
||||||
//
|
//
|
||||||
// check for smooth step up
|
// check for smooth step up
|
||||||
|
@ -2155,8 +2160,6 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
|
||||||
if (!mo->waterlevel || mo->flags & MF_CORPSE || (mo->player &&
|
if (!mo->waterlevel || mo->flags & MF_CORPSE || (mo->player &&
|
||||||
!(mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove)))
|
!(mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove)))
|
||||||
{
|
{
|
||||||
fixed_t grav = mo->GetGravity();
|
|
||||||
|
|
||||||
// [RH] Double gravity only if running off a ledge. Coming down from
|
// [RH] Double gravity only if running off a ledge. Coming down from
|
||||||
// an upward thrust (e.g. a jump) should not double it.
|
// an upward thrust (e.g. a jump) should not double it.
|
||||||
if (mo->velz == 0 && oldfloorz > mo->floorz && mo->z == oldfloorz)
|
if (mo->velz == 0 && oldfloorz > mo->floorz && mo->z == oldfloorz)
|
||||||
|
@ -2230,12 +2233,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
|
||||||
// teleported the actor so it is no longer below the floor.
|
// teleported the actor so it is no longer below the floor.
|
||||||
if (mo->z <= mo->floorz)
|
if (mo->z <= mo->floorz)
|
||||||
{
|
{
|
||||||
// old code for boss cube disabled
|
if ((mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP))
|
||||||
//if ((mo->flags & MF_MISSILE) && (!(gameinfo.gametype & GAME_DoomChex) || !(mo->flags & MF_NOCLIP)))
|
|
||||||
|
|
||||||
// We can't remove this completely because it was abused by some DECORATE definitions
|
|
||||||
// (e.g. the monster pack's Afrit)
|
|
||||||
if ((mo->flags & MF_MISSILE) && ((mo->flags & MF_NOGRAVITY) || !(mo->flags & MF_NOCLIP)))
|
|
||||||
{
|
{
|
||||||
mo->z = mo->floorz;
|
mo->z = mo->floorz;
|
||||||
if (mo->BounceFlags & BOUNCE_Floors)
|
if (mo->BounceFlags & BOUNCE_Floors)
|
||||||
|
@ -2297,7 +2295,10 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
|
||||||
mo->HitFloor ();
|
mo->HitFloor ();
|
||||||
if (mo->player)
|
if (mo->player)
|
||||||
{
|
{
|
||||||
mo->player->jumpTics = 7; // delay any jumping for a short while
|
if (mo->player->jumpTics != 0 && mo->velz < -grav*4)
|
||||||
|
{ // delay any jumping for a short while
|
||||||
|
mo->player->jumpTics = 7;
|
||||||
|
}
|
||||||
if (mo->velz < minvel && !(mo->flags & MF_NOGRAVITY))
|
if (mo->velz < minvel && !(mo->flags & MF_NOGRAVITY))
|
||||||
{
|
{
|
||||||
// Squat down.
|
// Squat down.
|
||||||
|
@ -2346,8 +2347,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
|
||||||
}
|
}
|
||||||
if (mo->velz > 0)
|
if (mo->velz > 0)
|
||||||
mo->velz = 0;
|
mo->velz = 0;
|
||||||
if (mo->flags & MF_MISSILE)
|
if ((mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP))
|
||||||
//&& (!(gameinfo.gametype & GAME_DoomChex) || !(mo->flags & MF_NOCLIP)))
|
|
||||||
{
|
{
|
||||||
if (mo->flags3 & MF3_CEILINGHUGGER)
|
if (mo->flags3 & MF3_CEILINGHUGGER)
|
||||||
{
|
{
|
||||||
|
@ -2615,11 +2615,6 @@ void AActor::RemoveFromHash ()
|
||||||
tid = 0;
|
tid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
angle_t AActor::AngleIncrements ()
|
|
||||||
{
|
|
||||||
return ANGLE_45;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// AActor :: GetMissileDamage
|
// AActor :: GetMissileDamage
|
||||||
|
@ -3022,7 +3017,7 @@ void AActor::Tick ()
|
||||||
&& !players[i].enemy
|
&& !players[i].enemy
|
||||||
&& player ? !IsTeammate (players[i].mo) : true
|
&& player ? !IsTeammate (players[i].mo) : true
|
||||||
&& P_AproxDistance (players[i].mo->x-x, players[i].mo->y-y) < MAX_MONSTER_TARGET_DIST
|
&& P_AproxDistance (players[i].mo->x-x, players[i].mo->y-y) < MAX_MONSTER_TARGET_DIST
|
||||||
&& P_CheckSight (players[i].mo, this, 2))
|
&& P_CheckSight (players[i].mo, this, SF_SEEPASTBLOCKEVERYTHING))
|
||||||
{ //Probably a monster, so go kill it.
|
{ //Probably a monster, so go kill it.
|
||||||
players[i].enemy = this;
|
players[i].enemy = this;
|
||||||
}
|
}
|
||||||
|
@ -3700,8 +3695,6 @@ void AActor::LevelSpawned ()
|
||||||
{
|
{
|
||||||
if (tics > 0 && !(flags4 & MF4_SYNCHRONIZED))
|
if (tics > 0 && !(flags4 & MF4_SYNCHRONIZED))
|
||||||
tics = 1 + (pr_spawnmapthing() % tics);
|
tics = 1 + (pr_spawnmapthing() % tics);
|
||||||
angle_t incs = AngleIncrements ();
|
|
||||||
angle -= angle % incs;
|
|
||||||
flags &= ~MF_DROPPED; // [RH] clear MF_DROPPED flag
|
flags &= ~MF_DROPPED; // [RH] clear MF_DROPPED flag
|
||||||
HandleSpawnFlags ();
|
HandleSpawnFlags ();
|
||||||
}
|
}
|
||||||
|
@ -3960,8 +3953,16 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer)
|
||||||
{
|
{
|
||||||
spawn_x = mthing->x;
|
spawn_x = mthing->x;
|
||||||
spawn_y = mthing->y;
|
spawn_y = mthing->y;
|
||||||
|
// Allow full angular precision but avoid roundoff errors for multiples of 45 degrees.
|
||||||
|
if (mthing->angle % 45 != 0)
|
||||||
|
{
|
||||||
|
spawn_angle = mthing->angle * (ANG45 / 45);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
spawn_angle = ANG45 * (mthing->angle / 45);
|
spawn_angle = ANG45 * (mthing->angle / 45);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mobj = static_cast<APlayerPawn *>
|
mobj = static_cast<APlayerPawn *>
|
||||||
(Spawn (p->cls, spawn_x, spawn_y, ONFLOORZ, NO_REPLACE));
|
(Spawn (p->cls, spawn_x, spawn_y, ONFLOORZ, NO_REPLACE));
|
||||||
|
@ -3986,11 +3987,15 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer)
|
||||||
p->userinfo.skin = R_FindSkin (skins[p->userinfo.skin].name, p->CurrentPlayerClass);
|
p->userinfo.skin = R_FindSkin (skins[p->userinfo.skin].name, p->CurrentPlayerClass);
|
||||||
StatusBar->SetFace (&skins[p->userinfo.skin]);
|
StatusBar->SetFace (&skins[p->userinfo.skin]);
|
||||||
|
|
||||||
|
|
||||||
|
if (!(mobj->flags2 & MF2_DONTTRANSLATE))
|
||||||
|
{
|
||||||
// [RH] Be sure the player has the right translation
|
// [RH] Be sure the player has the right translation
|
||||||
R_BuildPlayerTranslation (playernum);
|
R_BuildPlayerTranslation (playernum);
|
||||||
|
|
||||||
// [RH] set color translations for player sprites
|
// [RH] set color translations for player sprites
|
||||||
mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum);
|
mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum);
|
||||||
|
}
|
||||||
|
|
||||||
mobj->angle = spawn_angle;
|
mobj->angle = spawn_angle;
|
||||||
mobj->pitch = mobj->roll = 0;
|
mobj->pitch = mobj->roll = 0;
|
||||||
|
@ -4506,8 +4511,8 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y
|
||||||
void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator)
|
void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator)
|
||||||
{
|
{
|
||||||
AActor *th;
|
AActor *th;
|
||||||
PalEntry bloodcolor = originator->GetClass()->BloodColor;
|
PalEntry bloodcolor = originator->GetBloodColor();
|
||||||
PClassActor *bloodcls = PClass::FindActor(originator->GetClass()->BloodType);
|
PClassActor *bloodcls = originator->GetBloodType();
|
||||||
|
|
||||||
int bloodtype = cl_bloodtype;
|
int bloodtype = cl_bloodtype;
|
||||||
|
|
||||||
|
@ -4568,8 +4573,8 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc
|
||||||
|
|
||||||
void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
|
void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
|
||||||
{
|
{
|
||||||
PalEntry bloodcolor = originator->GetClass()->BloodColor;
|
PalEntry bloodcolor = originator->GetBloodColor();
|
||||||
PClassActor *bloodcls = PClass::FindActor(originator->GetClass()->BloodType2);
|
PClassActor *bloodcls = originator->GetBloodType(1);
|
||||||
|
|
||||||
int bloodtype = cl_bloodtype;
|
int bloodtype = cl_bloodtype;
|
||||||
|
|
||||||
|
@ -4606,8 +4611,8 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
|
||||||
|
|
||||||
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
|
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
|
||||||
{
|
{
|
||||||
PalEntry bloodcolor = originator->GetClass()->BloodColor;
|
PalEntry bloodcolor = originator->GetBloodColor();
|
||||||
PClassActor *bloodcls = PClass::FindActor(originator->GetClass()->BloodType3);
|
PClassActor *bloodcls = originator->GetBloodType(2);
|
||||||
|
|
||||||
int bloodtype = cl_bloodtype;
|
int bloodtype = cl_bloodtype;
|
||||||
|
|
||||||
|
@ -4645,8 +4650,8 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
|
||||||
void P_RipperBlood (AActor *mo, AActor *bleeder)
|
void P_RipperBlood (AActor *mo, AActor *bleeder)
|
||||||
{
|
{
|
||||||
fixed_t x, y, z;
|
fixed_t x, y, z;
|
||||||
PalEntry bloodcolor = bleeder->GetClass()->BloodColor;
|
PalEntry bloodcolor = bleeder->GetBloodColor();
|
||||||
PClassActor *bloodcls = PClass::FindActor(bleeder->GetClass()->BloodType);
|
PClassActor *bloodcls = bleeder->GetBloodType();
|
||||||
|
|
||||||
x = mo->x + (pr_ripperblood.Random2 () << 12);
|
x = mo->x + (pr_ripperblood.Random2 () << 12);
|
||||||
y = mo->y + (pr_ripperblood.Random2 () << 12);
|
y = mo->y + (pr_ripperblood.Random2 () << 12);
|
||||||
|
|
|
@ -294,8 +294,10 @@ MapData *P_OpenMapData(const char * mapname)
|
||||||
{
|
{
|
||||||
// The following lump is from a different file so whatever this is,
|
// The following lump is from a different file so whatever this is,
|
||||||
// it is not a multi-lump Doom level so let's assume it is a Build map.
|
// it is not a multi-lump Doom level so let's assume it is a Build map.
|
||||||
map->MapLumps[0].FilePos = Wads.GetLumpOffset(lump_name);
|
map->MapLumps[0].FilePos = 0;
|
||||||
map->MapLumps[0].Size = Wads.LumpLength(lump_name);
|
map->MapLumps[0].Size = Wads.LumpLength(lump_name);
|
||||||
|
map->file = Wads.ReopenLumpNum(lump_name);
|
||||||
|
map->CloseOnDestruct = true;
|
||||||
if (!P_IsBuildMap(map))
|
if (!P_IsBuildMap(map))
|
||||||
{
|
{
|
||||||
delete map;
|
delete map;
|
||||||
|
@ -312,6 +314,9 @@ MapData *P_OpenMapData(const char * mapname)
|
||||||
|
|
||||||
if (map->Encrypted)
|
if (map->Encrypted)
|
||||||
{ // If it's encrypted, then it's a Blood file, presumably a map.
|
{ // If it's encrypted, then it's a Blood file, presumably a map.
|
||||||
|
map->file = Wads.ReopenLumpNum(lump_name);
|
||||||
|
map->CloseOnDestruct = true;
|
||||||
|
map->MapLumps[0].FilePos = 0;
|
||||||
if (!P_IsBuildMap(map))
|
if (!P_IsBuildMap(map))
|
||||||
{
|
{
|
||||||
delete map;
|
delete map;
|
||||||
|
@ -322,7 +327,7 @@ MapData *P_OpenMapData(const char * mapname)
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
if (stricmp(Wads.GetLumpFullName(lump_name + 1), "TEXTMAP"))
|
if (stricmp(Wads.GetLumpFullName(lump_name + 1), "TEXTMAP") != 0)
|
||||||
{
|
{
|
||||||
for(int i = 1;; i++)
|
for(int i = 1;; i++)
|
||||||
{
|
{
|
||||||
|
@ -404,7 +409,8 @@ MapData *P_OpenMapData(const char * mapname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DWORD id;
|
DWORD id;
|
||||||
(*map->file) >> id;
|
|
||||||
|
map->file->Read(&id, sizeof(id));
|
||||||
|
|
||||||
if (id == IWAD_ID || id == PWAD_ID)
|
if (id == IWAD_ID || id == PWAD_ID)
|
||||||
{
|
{
|
||||||
|
@ -705,9 +711,15 @@ void P_FloodZone (sector_t *sec, int zonenum)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (check->frontsector == sec)
|
if (check->frontsector == sec)
|
||||||
|
{
|
||||||
|
assert(check->backsector != NULL);
|
||||||
other = check->backsector;
|
other = check->backsector;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
assert(check->frontsector != NULL);
|
||||||
other = check->frontsector;
|
other = check->frontsector;
|
||||||
|
}
|
||||||
|
|
||||||
if (other->ZoneNumber != zonenum)
|
if (other->ZoneNumber != zonenum)
|
||||||
P_FloodZone (other, zonenum);
|
P_FloodZone (other, zonenum);
|
||||||
|
@ -717,6 +729,7 @@ void P_FloodZone (sector_t *sec, int zonenum)
|
||||||
void P_FloodZones ()
|
void P_FloodZones ()
|
||||||
{
|
{
|
||||||
int z = 0, i;
|
int z = 0, i;
|
||||||
|
ReverbContainer *reverb;
|
||||||
|
|
||||||
for (i = 0; i < numsectors; ++i)
|
for (i = 0; i < numsectors; ++i)
|
||||||
{
|
{
|
||||||
|
@ -727,9 +740,15 @@ void P_FloodZones ()
|
||||||
}
|
}
|
||||||
numzones = z;
|
numzones = z;
|
||||||
zones = new zone_t[z];
|
zones = new zone_t[z];
|
||||||
|
reverb = S_FindEnvironment(level.DefaultEnvironment);
|
||||||
|
if (reverb == NULL)
|
||||||
|
{
|
||||||
|
Printf("Sound environment %d, %d not found\n", level.DefaultEnvironment >> 8, level.DefaultEnvironment & 255);
|
||||||
|
reverb = DefaultEnvironments[0];
|
||||||
|
}
|
||||||
for (i = 0; i < z; ++i)
|
for (i = 0; i < z; ++i)
|
||||||
{
|
{
|
||||||
zones[i].Environment = DefaultEnvironments[0];
|
zones[i].Environment = reverb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3395,11 +3414,9 @@ void P_SetupLevel (char *lumpname, int position)
|
||||||
BYTE *mapdata = new BYTE[map->MapLumps[0].Size];
|
BYTE *mapdata = new BYTE[map->MapLumps[0].Size];
|
||||||
map->Seek(0);
|
map->Seek(0);
|
||||||
map->file->Read(mapdata, map->MapLumps[0].Size);
|
map->file->Read(mapdata, map->MapLumps[0].Size);
|
||||||
if (map->Encrypted)
|
times[0].Clock();
|
||||||
{
|
|
||||||
BloodCrypt (mapdata, 0, MIN<int> (map->MapLumps[0].Size, 256));
|
|
||||||
}
|
|
||||||
buildmap = P_LoadBuildMap (mapdata, map->MapLumps[0].Size, &buildthings, &numbuildthings);
|
buildmap = P_LoadBuildMap (mapdata, map->MapLumps[0].Size, &buildthings, &numbuildthings);
|
||||||
|
times[0].Unclock();
|
||||||
delete[] mapdata;
|
delete[] mapdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ class SightCheck
|
||||||
fixed_t lastzbottom; // z at last line
|
fixed_t lastzbottom; // z at last line
|
||||||
sector_t * lastsector; // last sector being entered by trace
|
sector_t * lastsector; // last sector being entered by trace
|
||||||
fixed_t topslope, bottomslope; // slopes to top and bottom of target
|
fixed_t topslope, bottomslope; // slopes to top and bottom of target
|
||||||
int SeePastBlockEverything, SeePastShootableLines;
|
int Flags;
|
||||||
divline_t trace;
|
divline_t trace;
|
||||||
int myseethrough;
|
int myseethrough;
|
||||||
|
|
||||||
|
@ -73,9 +73,8 @@ public:
|
||||||
seeingthing=t2;
|
seeingthing=t2;
|
||||||
bottomslope = t2->z - sightzstart;
|
bottomslope = t2->z - sightzstart;
|
||||||
topslope = bottomslope + t2->height;
|
topslope = bottomslope + t2->height;
|
||||||
|
Flags = flags;
|
||||||
|
|
||||||
SeePastBlockEverything = flags & 6;
|
|
||||||
SeePastShootableLines = flags & 4;
|
|
||||||
myseethrough = FF_SEETHROUGH;
|
myseethrough = FF_SEETHROUGH;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -144,6 +143,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
|
||||||
F3DFloor* rover=s->e->XFloor.ffloors[j];
|
F3DFloor* rover=s->e->XFloor.ffloors[j];
|
||||||
|
|
||||||
if((rover->flags & FF_SEETHROUGH) == myseethrough || !(rover->flags & FF_EXISTS)) continue;
|
if((rover->flags & FF_SEETHROUGH) == myseethrough || !(rover->flags & FF_EXISTS)) continue;
|
||||||
|
if ((Flags & SF_IGNOREWATERBOUNDARY) && (rover->flags & FF_SOLID) == 0) continue;
|
||||||
|
|
||||||
fixed_t ff_bottom=rover->bottom.plane->ZatPoint(trX, trY);
|
fixed_t ff_bottom=rover->bottom.plane->ZatPoint(trX, trY);
|
||||||
fixed_t ff_top=rover->top.plane->ZatPoint(trX, trY);
|
fixed_t ff_top=rover->top.plane->ZatPoint(trX, trY);
|
||||||
|
@ -176,6 +176,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
|
||||||
F3DFloor* rover2=sb->e->XFloor.ffloors[k];
|
F3DFloor* rover2=sb->e->XFloor.ffloors[k];
|
||||||
|
|
||||||
if((rover2->flags & FF_SEETHROUGH) == myseethrough || !(rover2->flags & FF_EXISTS)) continue;
|
if((rover2->flags & FF_SEETHROUGH) == myseethrough || !(rover2->flags & FF_EXISTS)) continue;
|
||||||
|
if ((Flags & SF_IGNOREWATERBOUNDARY) && (rover->flags & FF_SOLID) == 0) continue;
|
||||||
|
|
||||||
fixed_t ffb_bottom=rover2->bottom.plane->ZatPoint(trX, trY);
|
fixed_t ffb_bottom=rover2->bottom.plane->ZatPoint(trX, trY);
|
||||||
fixed_t ffb_top=rover2->top.plane->ZatPoint(trX, trY);
|
fixed_t ffb_top=rover2->top.plane->ZatPoint(trX, trY);
|
||||||
|
@ -255,7 +256,7 @@ bool SightCheck::P_SightCheckLine (line_t *ld)
|
||||||
// [RH] don't see past block everything lines
|
// [RH] don't see past block everything lines
|
||||||
if (ld->flags & ML_BLOCKEVERYTHING)
|
if (ld->flags & ML_BLOCKEVERYTHING)
|
||||||
{
|
{
|
||||||
if (!SeePastBlockEverything)
|
if (!(Flags & SF_SEEPASTBLOCKEVERYTHING))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +264,7 @@ bool SightCheck::P_SightCheckLine (line_t *ld)
|
||||||
// that runs a script on the current map. Used to prevent monsters
|
// that runs a script on the current map. Used to prevent monsters
|
||||||
// from trying to attack through a block everything line unless
|
// from trying to attack through a block everything line unless
|
||||||
// there's a chance their attack will make it nonblocking.
|
// there's a chance their attack will make it nonblocking.
|
||||||
if (!SeePastShootableLines)
|
if (!(Flags & SF_SEEPASTSHOOTABLELINES))
|
||||||
{
|
{
|
||||||
if (!(ld->activation & SPAC_Impact))
|
if (!(ld->activation & SPAC_Impact))
|
||||||
{
|
{
|
||||||
|
@ -407,6 +408,7 @@ bool SightCheck::P_SightTraverseIntercepts ()
|
||||||
F3DFloor* rover = lastsector->e->XFloor.ffloors[i];
|
F3DFloor* rover = lastsector->e->XFloor.ffloors[i];
|
||||||
|
|
||||||
if((rover->flags & FF_SOLID) == myseethrough || !(rover->flags & FF_EXISTS)) continue;
|
if((rover->flags & FF_SOLID) == myseethrough || !(rover->flags & FF_EXISTS)) continue;
|
||||||
|
if ((Flags & SF_IGNOREWATERBOUNDARY) && (rover->flags & FF_SOLID) == 0) continue;
|
||||||
|
|
||||||
fixed_t ff_bottom=rover->bottom.plane->ZatPoint(seeingthing->x, seeingthing->y);
|
fixed_t ff_bottom=rover->bottom.plane->ZatPoint(seeingthing->x, seeingthing->y);
|
||||||
fixed_t ff_top=rover->top.plane->ZatPoint(seeingthing->x, seeingthing->y);
|
fixed_t ff_top=rover->top.plane->ZatPoint(seeingthing->x, seeingthing->y);
|
||||||
|
@ -670,7 +672,7 @@ sightcounts[0]++;
|
||||||
//
|
//
|
||||||
// [RH] Andy Baker's stealth monsters:
|
// [RH] Andy Baker's stealth monsters:
|
||||||
// Cannot see an invisible object
|
// Cannot see an invisible object
|
||||||
if ((flags & 1) == 0 && ((t2->renderflags & RF_INVISIBLE) || !t2->RenderStyle.IsVisible(t2->alpha)))
|
if ((flags & SF_IGNOREVISIBILITY) == 0 && ((t2->renderflags & RF_INVISIBLE) || !t2->RenderStyle.IsVisible(t2->alpha)))
|
||||||
{ // small chance of an attack being made anyway
|
{ // small chance of an attack being made anyway
|
||||||
if ((bglobal.m_Thinking ? pr_botchecksight() : pr_checksight()) > 50)
|
if ((bglobal.m_Thinking ? pr_botchecksight() : pr_checksight()) > 50)
|
||||||
{
|
{
|
||||||
|
@ -681,6 +683,8 @@ sightcounts[0]++;
|
||||||
|
|
||||||
// killough 4/19/98: make fake floors and ceilings block monster view
|
// killough 4/19/98: make fake floors and ceilings block monster view
|
||||||
|
|
||||||
|
if (!(flags & SF_IGNOREWATERBOUNDARY))
|
||||||
|
{
|
||||||
if ((s1->GetHeightSec() &&
|
if ((s1->GetHeightSec() &&
|
||||||
((t1->z + t1->height <= s1->heightsec->floorplane.ZatPoint (t1->x, t1->y) &&
|
((t1->z + t1->height <= s1->heightsec->floorplane.ZatPoint (t1->x, t1->y) &&
|
||||||
t2->z >= s1->heightsec->floorplane.ZatPoint (t2->x, t2->y)) ||
|
t2->z >= s1->heightsec->floorplane.ZatPoint (t2->x, t2->y)) ||
|
||||||
|
@ -696,6 +700,7 @@ sightcounts[0]++;
|
||||||
res = false;
|
res = false;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// An unobstructed LOS is possible.
|
// An unobstructed LOS is possible.
|
||||||
// Now look from eyes of t1 to any part of t2.
|
// Now look from eyes of t1 to any part of t2.
|
||||||
|
|
|
@ -1939,7 +1939,7 @@ void DPusher::Tick ()
|
||||||
// If speed <= 0, you're outside the effective radius. You also have
|
// If speed <= 0, you're outside the effective radius. You also have
|
||||||
// to be able to see the push/pull source point.
|
// to be able to see the push/pull source point.
|
||||||
|
|
||||||
if ((speed > 0) && (P_CheckSight (thing, m_Source, 1)))
|
if ((speed > 0) && (P_CheckSight (thing, m_Source, SF_IGNOREVISIBILITY)))
|
||||||
{
|
{
|
||||||
angle_t pushangle = R_PointToAngle2 (thing->x, thing->y, sx, sy);
|
angle_t pushangle = R_PointToAngle2 (thing->x, thing->y, sx, sy);
|
||||||
if (m_Source->GetClass()->TypeName == NAME_PointPusher)
|
if (m_Source->GetClass()->TypeName == NAME_PointPusher)
|
||||||
|
|
|
@ -55,7 +55,6 @@
|
||||||
|
|
||||||
static FRandom pr_skullpop ("SkullPop");
|
static FRandom pr_skullpop ("SkullPop");
|
||||||
|
|
||||||
|
|
||||||
// [RH] # of ticks to complete a turn180
|
// [RH] # of ticks to complete a turn180
|
||||||
#define TURN180_TICKS ((TICRATE / 4) + 1)
|
#define TURN180_TICKS ((TICRATE / 4) + 1)
|
||||||
|
|
||||||
|
@ -2671,3 +2670,47 @@ void player_t::Serialize (FArchive &arc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FPlayerColorSetMap *GetPlayerColors(FName classname)
|
||||||
|
{
|
||||||
|
PClassPlayerPawn *cls = dyn_cast<PClassPlayerPawn>(PClass::FindClass(classname));
|
||||||
|
|
||||||
|
if (cls != NULL)
|
||||||
|
{
|
||||||
|
return cls->ColorSets;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum)
|
||||||
|
{
|
||||||
|
FPlayerColorSetMap *map = GetPlayerColors(classname);
|
||||||
|
if (map == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return map->CheckKey(setnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int STACK_ARGS intcmp(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
return *(const int *)a - *(const int *)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void P_EnumPlayerColorSets(FName classname, TArray<int> *out)
|
||||||
|
{
|
||||||
|
out->Clear();
|
||||||
|
FPlayerColorSetMap *map = GetPlayerColors(classname);
|
||||||
|
if (map != NULL)
|
||||||
|
{
|
||||||
|
FPlayerColorSetMap::Iterator it(*map);
|
||||||
|
FPlayerColorSetMap::Pair *pair;
|
||||||
|
|
||||||
|
while (it.NextPair(pair))
|
||||||
|
{
|
||||||
|
out->Push(pair->Key);
|
||||||
|
}
|
||||||
|
qsort(&(*out)[0], out->Size(), sizeof(int), intcmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -795,25 +795,25 @@ static void UpdateSegBBox (seg_t *seg)
|
||||||
|
|
||||||
line = seg->linedef;
|
line = seg->linedef;
|
||||||
|
|
||||||
if (seg->v1->x < seg->v2->x)
|
if (line->v1->x < line->v2->x)
|
||||||
{
|
{
|
||||||
line->bbox[BOXLEFT] = seg->v1->x;
|
line->bbox[BOXLEFT] = line->v1->x;
|
||||||
line->bbox[BOXRIGHT] = seg->v2->x;
|
line->bbox[BOXRIGHT] = line->v2->x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
line->bbox[BOXLEFT] = seg->v2->x;
|
line->bbox[BOXLEFT] = line->v2->x;
|
||||||
line->bbox[BOXRIGHT] = seg->v1->x;
|
line->bbox[BOXRIGHT] = line->v1->x;
|
||||||
}
|
}
|
||||||
if (seg->v1->y < seg->v2->y)
|
if (line->v1->y < line->v2->y)
|
||||||
{
|
{
|
||||||
line->bbox[BOXBOTTOM] = seg->v1->y;
|
line->bbox[BOXBOTTOM] = line->v1->y;
|
||||||
line->bbox[BOXTOP] = seg->v2->y;
|
line->bbox[BOXTOP] = line->v2->y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
line->bbox[BOXBOTTOM] = seg->v2->y;
|
line->bbox[BOXBOTTOM] = line->v2->y;
|
||||||
line->bbox[BOXTOP] = seg->v1->y;
|
line->bbox[BOXTOP] = line->v1->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the line's slopetype
|
// Update the line's slopetype
|
||||||
|
|
|
@ -2181,7 +2181,7 @@ ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation,
|
||||||
if (translation != 0)
|
if (translation != 0)
|
||||||
{
|
{
|
||||||
FRemapTable *table = TranslationToTable(translation);
|
FRemapTable *table = TranslationToTable(translation);
|
||||||
if (table != NULL)
|
if (table != NULL && !table->Inactive)
|
||||||
{
|
{
|
||||||
dc_translation = table->Remap;
|
dc_translation = table->Remap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1081,7 +1081,7 @@ void R_SetupFrame (AActor *actor)
|
||||||
iview->otic = nowtic;
|
iview->otic = nowtic;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UpdateAnimations (I_MSTime());
|
R_UpdateAnimations (I_FPSTime());
|
||||||
r_TicFrac = I_GetTimeFrac (&r_FrameTime);
|
r_TicFrac = I_GetTimeFrac (&r_FrameTime);
|
||||||
if (cl_capfps || r_NoInterpolate)
|
if (cl_capfps || r_NoInterpolate)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2346,7 +2346,7 @@ CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE )
|
||||||
|
|
||||||
void R_InitParticles ()
|
void R_InitParticles ()
|
||||||
{
|
{
|
||||||
char *i;
|
const char *i;
|
||||||
|
|
||||||
if ((i = Args->CheckValue ("-numparticles")))
|
if ((i = Args->CheckValue ("-numparticles")))
|
||||||
NumParticles = atoi (i);
|
NumParticles = atoi (i);
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "doomerrors.h"
|
#include "doomerrors.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
|
@ -78,7 +79,7 @@ const BYTE IcePalette[16][3] =
|
||||||
FRemapTable::FRemapTable(int count)
|
FRemapTable::FRemapTable(int count)
|
||||||
{
|
{
|
||||||
assert(count <= 256);
|
assert(count <= 256);
|
||||||
|
Inactive = false;
|
||||||
Alloc(count);
|
Alloc(count);
|
||||||
|
|
||||||
// Note that the tables are left uninitialized. It is assumed that
|
// Note that the tables are left uninitialized. It is assumed that
|
||||||
|
@ -163,6 +164,7 @@ FRemapTable &FRemapTable::operator=(const FRemapTable &o)
|
||||||
{
|
{
|
||||||
Alloc(o.NumEntries);
|
Alloc(o.NumEntries);
|
||||||
}
|
}
|
||||||
|
Inactive = o.Inactive;
|
||||||
memcpy(Remap, o.Remap, NumEntries*sizeof(*Remap) + NumEntries*sizeof(*Palette));
|
memcpy(Remap, o.Remap, NumEntries*sizeof(*Remap) + NumEntries*sizeof(*Palette));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -892,7 +894,8 @@ static void SetRemap(FRemapTable *table, int i, float r, float g, float b)
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable)
|
static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerColorSet *colorset,
|
||||||
|
FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
BYTE start = skin->range0start;
|
BYTE start = skin->range0start;
|
||||||
|
@ -915,7 +918,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s
|
||||||
{
|
{
|
||||||
for (i = 0; i < table->NumEntries; ++i)
|
for (i = 0; i < table->NumEntries; ++i)
|
||||||
{
|
{
|
||||||
table->Remap[i] = i;
|
table->Remap[i] = GPalette.Remap[i];
|
||||||
}
|
}
|
||||||
memcpy(table->Palette, GPalette.BaseColors, sizeof(*table->Palette) * table->NumEntries);
|
memcpy(table->Palette, GPalette.BaseColors, sizeof(*table->Palette) * table->NumEntries);
|
||||||
}
|
}
|
||||||
|
@ -927,16 +930,63 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s
|
||||||
// [GRB] Don't translate skins with color range 0-0 (APlayerPawn default)
|
// [GRB] Don't translate skins with color range 0-0 (APlayerPawn default)
|
||||||
if (start == 0 && end == 0)
|
if (start == 0 && end == 0)
|
||||||
{
|
{
|
||||||
|
table->Inactive = true;
|
||||||
table->UpdateNative();
|
table->UpdateNative();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table->Inactive = false;
|
||||||
range = (float)(end-start+1);
|
range = (float)(end-start+1);
|
||||||
|
|
||||||
bases = s;
|
bases = s;
|
||||||
basev = v;
|
basev = v;
|
||||||
|
|
||||||
if (gameinfo.gametype & GAME_DoomStrifeChex)
|
if (colorset != NULL && colorset->Lump >= 0 && Wads.LumpLength(colorset->Lump) < 256)
|
||||||
|
{ // Bad table length. Ignore it.
|
||||||
|
colorset = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorset != NULL)
|
||||||
|
{
|
||||||
|
bool identity = true;
|
||||||
|
// Use the pre-defined range instead of a custom one.
|
||||||
|
if (colorset->Lump < 0)
|
||||||
|
{
|
||||||
|
int first = colorset->FirstColor;
|
||||||
|
if (start == end)
|
||||||
|
{
|
||||||
|
table->Remap[i] = (first + colorset->LastColor) / 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int palrange = colorset->LastColor - first;
|
||||||
|
for (i = start; i <= end; ++i)
|
||||||
|
{
|
||||||
|
int pi = first + palrange * (i - start) / (end - start);
|
||||||
|
table->Remap[i] = GPalette.Remap[pi];
|
||||||
|
if (pi != i) identity = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FMemLump translump = Wads.ReadLump(colorset->Lump);
|
||||||
|
const BYTE *trans = (const BYTE *)translump.GetMem();
|
||||||
|
for (i = start; i <= end; ++i)
|
||||||
|
{
|
||||||
|
table->Remap[i] = GPalette.Remap[trans[i]];
|
||||||
|
if (trans[i] != i) identity = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = start; i <= end; ++i)
|
||||||
|
{
|
||||||
|
table->Palette[i] = GPalette.BaseColors[table->Remap[i]];
|
||||||
|
table->Palette[i].a = 255;
|
||||||
|
}
|
||||||
|
// If the colorset created an identity translation mark it as inactive
|
||||||
|
table->Inactive = identity;
|
||||||
|
}
|
||||||
|
else if (gameinfo.gametype & GAME_DoomStrifeChex)
|
||||||
{
|
{
|
||||||
// Build player sprite translation
|
// Build player sprite translation
|
||||||
s -= 0.23f;
|
s -= 0.23f;
|
||||||
|
@ -1014,9 +1064,19 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s
|
||||||
SetRemap(table, i, r, g, b);
|
SetRemap(table, i, r, g, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (gameinfo.gametype == GAME_Hexen && alttable != NULL)
|
||||||
|
{
|
||||||
|
// Build Hexen's lifegem translation.
|
||||||
|
|
||||||
// Build lifegem translation
|
// Is the player's translation range the same as the gem's and we are using a
|
||||||
if (alttable)
|
// predefined translation? If so, then use the same one for the gem. Otherwise,
|
||||||
|
// build one as per usual.
|
||||||
|
if (colorset != NULL && start == 164 && end == 185)
|
||||||
|
{
|
||||||
|
*alttable = *table;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
for (i = 164; i <= 185; ++i)
|
for (i = 164; i <= 185; ++i)
|
||||||
{
|
{
|
||||||
|
@ -1027,8 +1087,8 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s
|
||||||
HSVtoRGB (&r, &g, &b, h, s*bases, v*basev);
|
HSVtoRGB (&r, &g, &b, h, s*bases, v*basev);
|
||||||
SetRemap(alttable, i, r, g, b);
|
SetRemap(alttable, i, r, g, b);
|
||||||
}
|
}
|
||||||
alttable->UpdateNative();
|
|
||||||
}
|
}
|
||||||
|
alttable->UpdateNative();
|
||||||
}
|
}
|
||||||
table->UpdateNative();
|
table->UpdateNative();
|
||||||
}
|
}
|
||||||
|
@ -1042,10 +1102,11 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s
|
||||||
void R_BuildPlayerTranslation (int player)
|
void R_BuildPlayerTranslation (int player)
|
||||||
{
|
{
|
||||||
float h, s, v;
|
float h, s, v;
|
||||||
|
FPlayerColorSet *colorset;
|
||||||
|
|
||||||
D_GetPlayerColor (player, &h, &s, &v);
|
D_GetPlayerColor (player, &h, &s, &v, &colorset);
|
||||||
|
|
||||||
R_CreatePlayerTranslation (h, s, v,
|
R_CreatePlayerTranslation (h, s, v, colorset,
|
||||||
&skins[players[player].userinfo.skin],
|
&skins[players[player].userinfo.skin],
|
||||||
translationtables[TRANSLATION_Players][player],
|
translationtables[TRANSLATION_Players][player],
|
||||||
translationtables[TRANSLATION_PlayersExtra][player]);
|
translationtables[TRANSLATION_PlayersExtra][player]);
|
||||||
|
@ -1057,13 +1118,17 @@ void R_BuildPlayerTranslation (int player)
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void R_GetPlayerTranslation (int color, FPlayerSkin *skin, FRemapTable *table)
|
void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayerSkin *skin, FRemapTable *table)
|
||||||
{
|
{
|
||||||
float h, s, v;
|
float h, s, v;
|
||||||
|
|
||||||
|
if (colorset != NULL)
|
||||||
|
{
|
||||||
|
color = colorset->RepresentativeColor;
|
||||||
|
}
|
||||||
RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f,
|
RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f,
|
||||||
&h, &s, &v);
|
&h, &s, &v);
|
||||||
|
|
||||||
R_CreatePlayerTranslation (h, s, v, skin, table, NULL);
|
R_CreatePlayerTranslation (h, s, v, colorset, skin, table, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct FRemapTable
|
||||||
PalEntry *Palette; // The ideal palette this maps to
|
PalEntry *Palette; // The ideal palette this maps to
|
||||||
FNativePalette *Native; // The Palette stored in a HW texture
|
FNativePalette *Native; // The Palette stored in a HW texture
|
||||||
int NumEntries; // # of elements in this table (usually 256)
|
int NumEntries; // # of elements in this table (usually 256)
|
||||||
|
bool Inactive; // This table is inactive and should be treated as if it was passed as NULL
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Free();
|
void Free();
|
||||||
|
|
|
@ -56,13 +56,15 @@ struct RFFInfo
|
||||||
|
|
||||||
struct RFFLump
|
struct RFFLump
|
||||||
{
|
{
|
||||||
BYTE IDontKnow[16];
|
DWORD DontKnow1[4];
|
||||||
DWORD FilePos;
|
DWORD FilePos;
|
||||||
DWORD Size;
|
DWORD Size;
|
||||||
BYTE IStillDontKnow[8];
|
DWORD DontKnow2;
|
||||||
|
DWORD Time;
|
||||||
BYTE Flags;
|
BYTE Flags;
|
||||||
char Extension[3];
|
char Extension[3];
|
||||||
char Name[8+4]; // 4 bytes that I don't know what they are for
|
char Name[8];
|
||||||
|
DWORD IndexNum; // Used by .sfx, possibly others
|
||||||
};
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -75,6 +77,10 @@ struct FRFFLump : public FUncompressedLump
|
||||||
{
|
{
|
||||||
virtual FileReader *GetReader();
|
virtual FileReader *GetReader();
|
||||||
virtual int FillCache();
|
virtual int FillCache();
|
||||||
|
|
||||||
|
DWORD IndexNum;
|
||||||
|
|
||||||
|
int GetIndexNum() const { return IndexNum; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -149,33 +155,34 @@ bool FRFFFile::Open(bool quiet)
|
||||||
if (!quiet) Printf(", %d lumps\n", NumLumps);
|
if (!quiet) Printf(", %d lumps\n", NumLumps);
|
||||||
for (DWORD i = 0; i < NumLumps; ++i)
|
for (DWORD i = 0; i < NumLumps; ++i)
|
||||||
{
|
{
|
||||||
if (lumps[i].Extension[0] == 'S' && lumps[i].Extension[1] == 'F' &&
|
|
||||||
lumps[i].Extension[2] == 'X')
|
|
||||||
{
|
|
||||||
Lumps[i].Namespace = ns_bloodsfx;
|
|
||||||
}
|
|
||||||
else if (lumps[i].Extension[0] == 'R' && lumps[i].Extension[1] == 'A' &&
|
|
||||||
lumps[i].Extension[2] == 'W')
|
|
||||||
{
|
|
||||||
Lumps[i].Namespace = ns_bloodraw;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Lumps[i].Namespace = ns_global;
|
|
||||||
}
|
|
||||||
|
|
||||||
Lumps[i].Position = LittleLong(lumps[i].FilePos);
|
Lumps[i].Position = LittleLong(lumps[i].FilePos);
|
||||||
Lumps[i].LumpSize = LittleLong(lumps[i].Size);
|
Lumps[i].LumpSize = LittleLong(lumps[i].Size);
|
||||||
Lumps[i].Owner = this;
|
Lumps[i].Owner = this;
|
||||||
if (lumps[i].Flags & 0x10) Lumps[i].Flags |= LUMPF_BLOODCRYPT;
|
if (lumps[i].Flags & 0x10)
|
||||||
|
{
|
||||||
// Rearrange the name and extension in a part of the lump record
|
Lumps[i].Flags |= LUMPF_BLOODCRYPT;
|
||||||
// that I don't have any use for in order to cnstruct the fullname.
|
}
|
||||||
lumps[i].Name[8] = '\0';
|
Lumps[i].IndexNum = LittleLong(lumps[i].IndexNum);
|
||||||
strcpy ((char *)lumps[i].IDontKnow, lumps[i].Name);
|
// Rearrange the name and extension to construct the fullname.
|
||||||
strcat ((char *)lumps[i].IDontKnow, ".");
|
char name[13];
|
||||||
strcat ((char *)lumps[i].IDontKnow, lumps[i].Extension);
|
strncpy(name, lumps[i].Name, 8);
|
||||||
Lumps[i].LumpNameSetup((char *)lumps[i].IDontKnow);
|
name[8] = 0;
|
||||||
|
size_t len = strlen(name);
|
||||||
|
assert(len + 4 <= 12);
|
||||||
|
name[len+0] = '.';
|
||||||
|
name[len+1] = lumps[i].Extension[0];
|
||||||
|
name[len+2] = lumps[i].Extension[1];
|
||||||
|
name[len+3] = lumps[i].Extension[2];
|
||||||
|
name[len+4] = 0;
|
||||||
|
Lumps[i].LumpNameSetup(name);
|
||||||
|
if (name[len+1] == 'S' && name[len+2] == 'F' && name[len+3] == 'X')
|
||||||
|
{
|
||||||
|
Lumps[i].Namespace = ns_bloodsfx;
|
||||||
|
}
|
||||||
|
else if (name[len+1] == 'R' && name[len+2] == 'A' && name[len+3] == 'W')
|
||||||
|
{
|
||||||
|
Lumps[i].Namespace = ns_bloodraw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
delete[] lumps;
|
delete[] lumps;
|
||||||
return true;
|
return true;
|
||||||
|
@ -183,7 +190,10 @@ bool FRFFFile::Open(bool quiet)
|
||||||
|
|
||||||
FRFFFile::~FRFFFile()
|
FRFFFile::~FRFFFile()
|
||||||
{
|
{
|
||||||
if (Lumps != NULL) delete [] Lumps;
|
if (Lumps != NULL)
|
||||||
|
{
|
||||||
|
delete[] Lumps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,8 +207,14 @@ FileReader *FRFFLump::GetReader()
|
||||||
{
|
{
|
||||||
// Don't return the reader if this lump is encrypted
|
// Don't return the reader if this lump is encrypted
|
||||||
// In that case always force caching of the lump
|
// In that case always force caching of the lump
|
||||||
if (!(Flags & LUMPF_BLOODCRYPT)) return FUncompressedLump::GetReader();
|
if (!(Flags & LUMPF_BLOODCRYPT))
|
||||||
else return NULL;
|
{
|
||||||
|
return FUncompressedLump::GetReader();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct FResourceLump
|
||||||
virtual FileReader *GetReader();
|
virtual FileReader *GetReader();
|
||||||
virtual FileReader *NewReader();
|
virtual FileReader *NewReader();
|
||||||
virtual int GetFileOffset() { return -1; }
|
virtual int GetFileOffset() { return -1; }
|
||||||
|
virtual int GetIndexNum() const { return 0; }
|
||||||
void LumpNameSetup(const char *iname);
|
void LumpNameSetup(const char *iname);
|
||||||
void CheckEmbedded();
|
void CheckEmbedded();
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ protected:
|
||||||
void Free ();
|
void Free ();
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct AmbientSound
|
struct FAmbientSound
|
||||||
{
|
{
|
||||||
unsigned type; // type of ambient sound
|
unsigned type; // type of ambient sound
|
||||||
int periodmin; // # of tics between repeats
|
int periodmin; // # of tics between repeats
|
||||||
|
@ -122,7 +122,8 @@ static struct AmbientSound
|
||||||
float volume; // relative volume of sound
|
float volume; // relative volume of sound
|
||||||
float attenuation;
|
float attenuation;
|
||||||
FString sound; // Logical name of sound to play
|
FString sound; // Logical name of sound to play
|
||||||
} *Ambients[256];
|
};
|
||||||
|
TMap<int, FAmbientSound> Ambients;
|
||||||
|
|
||||||
enum SICommands
|
enum SICommands
|
||||||
{
|
{
|
||||||
|
@ -509,6 +510,7 @@ int S_AddSoundLump (const char *logicalname, int lump)
|
||||||
newsfx.Rolloff.RolloffType = ROLLOFF_Doom;
|
newsfx.Rolloff.RolloffType = ROLLOFF_Doom;
|
||||||
newsfx.Rolloff.MinDistance = 0;
|
newsfx.Rolloff.MinDistance = 0;
|
||||||
newsfx.Rolloff.MaxDistance = 0;
|
newsfx.Rolloff.MaxDistance = 0;
|
||||||
|
newsfx.LoopStart = -1;
|
||||||
|
|
||||||
return (int)S_sfx.Push (newsfx);
|
return (int)S_sfx.Push (newsfx);
|
||||||
}
|
}
|
||||||
|
@ -836,15 +838,7 @@ static void S_ClearSoundData()
|
||||||
S_UnloadSound(&S_sfx[i]);
|
S_UnloadSound(&S_sfx[i]);
|
||||||
}
|
}
|
||||||
S_sfx.Clear();
|
S_sfx.Clear();
|
||||||
|
Ambients.Clear();
|
||||||
for(i = 0; i < countof(Ambients); i++)
|
|
||||||
{
|
|
||||||
if (Ambients[i] != NULL)
|
|
||||||
{
|
|
||||||
delete Ambients[i];
|
|
||||||
Ambients[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (MusicVolumes != NULL)
|
while (MusicVolumes != NULL)
|
||||||
{
|
{
|
||||||
FMusicVolume *me = MusicVolumes;
|
FMusicVolume *me = MusicVolumes;
|
||||||
|
@ -967,23 +961,10 @@ static void S_AddSNDINFO (int lump)
|
||||||
// $ambient <num> <logical name> [point [atten] | surround | [world]]
|
// $ambient <num> <logical name> [point [atten] | surround | [world]]
|
||||||
// <continuous | random <minsecs> <maxsecs> | periodic <secs>>
|
// <continuous | random <minsecs> <maxsecs> | periodic <secs>>
|
||||||
// <volume>
|
// <volume>
|
||||||
AmbientSound *ambient, dummy;
|
FAmbientSound *ambient;
|
||||||
|
|
||||||
sc.MustGetNumber ();
|
sc.MustGetNumber ();
|
||||||
if (sc.Number < 0 || sc.Number > 255)
|
ambient = &Ambients[sc.Number];
|
||||||
{
|
|
||||||
Printf ("Bad ambient index (%d)\n", sc.Number);
|
|
||||||
ambient = &dummy;
|
|
||||||
}
|
|
||||||
else if (Ambients[sc.Number] == NULL)
|
|
||||||
{
|
|
||||||
ambient = new AmbientSound;
|
|
||||||
Ambients[sc.Number] = ambient;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ambient = Ambients[sc.Number];
|
|
||||||
}
|
|
||||||
ambient->type = 0;
|
ambient->type = 0;
|
||||||
ambient->periodmin = 0;
|
ambient->periodmin = 0;
|
||||||
ambient->periodmax = 0;
|
ambient->periodmax = 0;
|
||||||
|
@ -1366,7 +1347,6 @@ static void S_AddSNDINFO (int lump)
|
||||||
|
|
||||||
static void S_AddBloodSFX (int lumpnum)
|
static void S_AddBloodSFX (int lumpnum)
|
||||||
{
|
{
|
||||||
char name[13];
|
|
||||||
FMemLump sfxlump = Wads.ReadLump(lumpnum);
|
FMemLump sfxlump = Wads.ReadLump(lumpnum);
|
||||||
const FBloodSFX *sfx = (FBloodSFX *)sfxlump.GetMem();
|
const FBloodSFX *sfx = (FBloodSFX *)sfxlump.GetMem();
|
||||||
int rawlump = Wads.CheckNumForName(sfx->RawName, ns_bloodraw);
|
int rawlump = Wads.CheckNumForName(sfx->RawName, ns_bloodraw);
|
||||||
|
@ -1374,9 +1354,7 @@ static void S_AddBloodSFX (int lumpnum)
|
||||||
|
|
||||||
if (rawlump != -1)
|
if (rawlump != -1)
|
||||||
{
|
{
|
||||||
Wads.GetLumpName (name, lumpnum);
|
const char *name = Wads.GetLumpFullName(lumpnum);
|
||||||
name[8] = 0;
|
|
||||||
strcat (name, ".SFX");
|
|
||||||
sfxnum = S_AddSound(name, rawlump);
|
sfxnum = S_AddSound(name, rawlump);
|
||||||
if (sfx->Format == 5)
|
if (sfx->Format == 5)
|
||||||
{
|
{
|
||||||
|
@ -1387,6 +1365,17 @@ static void S_AddBloodSFX (int lumpnum)
|
||||||
S_sfx[sfxnum].bForce11025 = true;
|
S_sfx[sfxnum].bForce11025 = true;
|
||||||
}
|
}
|
||||||
S_sfx[sfxnum].bLoadRAW = true;
|
S_sfx[sfxnum].bLoadRAW = true;
|
||||||
|
S_sfx[sfxnum].LoopStart = LittleLong(sfx->LoopStart);
|
||||||
|
// Make an ambient sound out of it, whether it has a loop point
|
||||||
|
// defined or not. (Because none of the standard Blood ambient
|
||||||
|
// sounds are explicitly defined as looping.)
|
||||||
|
FAmbientSound *ambient = &Ambients[Wads.GetLumpIndexNum(lumpnum)];
|
||||||
|
ambient->type = CONTINUOUS;
|
||||||
|
ambient->periodmin = 0;
|
||||||
|
ambient->periodmax = 0;
|
||||||
|
ambient->volume = 1;
|
||||||
|
ambient->attenuation = 1;
|
||||||
|
ambient->sound = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1906,12 +1895,18 @@ public:
|
||||||
protected:
|
protected:
|
||||||
bool bActive;
|
bool bActive;
|
||||||
private:
|
private:
|
||||||
void SetTicker (struct AmbientSound *ambient);
|
void SetTicker (struct FAmbientSound *ambient);
|
||||||
int NextCheck;
|
int NextCheck;
|
||||||
};
|
};
|
||||||
|
|
||||||
IMPLEMENT_CLASS (AAmbientSound)
|
IMPLEMENT_CLASS (AAmbientSound)
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// AmbientSound :: Serialize
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void AAmbientSound::Serialize (FArchive &arc)
|
void AAmbientSound::Serialize (FArchive &arc)
|
||||||
{
|
{
|
||||||
Super::Serialize (arc);
|
Super::Serialize (arc);
|
||||||
|
@ -1948,6 +1943,11 @@ void AAmbientSound::Serialize (FArchive &arc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// AmbientSound :: Tick
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void AAmbientSound::Tick ()
|
void AAmbientSound::Tick ()
|
||||||
{
|
{
|
||||||
|
@ -1956,17 +1956,47 @@ void AAmbientSound::Tick ()
|
||||||
if (!bActive || gametic < NextCheck)
|
if (!bActive || gametic < NextCheck)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AmbientSound *ambient = Ambients[args[0]];
|
FAmbientSound *ambient;
|
||||||
int loop = 0;
|
int loop = 0;
|
||||||
|
|
||||||
|
ambient = Ambients.CheckKey(args[0]);
|
||||||
|
if (ambient == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ambient->type & CONTINUOUS) == CONTINUOUS)
|
if ((ambient->type & CONTINUOUS) == CONTINUOUS)
|
||||||
{
|
{
|
||||||
loop = CHAN_LOOP;
|
loop = CHAN_LOOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ambient->sound[0])
|
if (ambient->sound.IsNotEmpty())
|
||||||
{
|
{
|
||||||
S_Sound(this, CHAN_BODY | loop, ambient->sound, ambient->volume, ambient->attenuation);
|
// The second argument scales the ambient sound's volume.
|
||||||
|
// 0 and 100 are normal volume. The maximum volume level
|
||||||
|
// possible is always 1.
|
||||||
|
float volscale = args[1] == 0 ? 1 : args[1] / 100.f;
|
||||||
|
float usevol = clamp(ambient->volume * volscale, 0.f, 1.f);
|
||||||
|
|
||||||
|
// The third argument is the minimum distance for audible fading, and
|
||||||
|
// the fourth argument is the maximum distance for audibility. Setting
|
||||||
|
// either of these to 0 or setting min distance > max distance will
|
||||||
|
// use the standard rolloff.
|
||||||
|
if ((args[2] | args[3]) == 0 || args[2] > args[3])
|
||||||
|
{
|
||||||
|
S_Sound(this, CHAN_BODY | loop, ambient->sound, usevol, ambient->attenuation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float min = float(args[2]), max = float(args[3]);
|
||||||
|
// The fifth argument acts as a scalar for the preceding two, if it's non-zero.
|
||||||
|
if (args[4] > 0)
|
||||||
|
{
|
||||||
|
min *= args[4];
|
||||||
|
max *= args[4];
|
||||||
|
}
|
||||||
|
S_SoundMinMaxDist(this, CHAN_BODY | loop, ambient->sound, usevol, min, max);
|
||||||
|
}
|
||||||
if (!loop)
|
if (!loop)
|
||||||
{
|
{
|
||||||
SetTicker (ambient);
|
SetTicker (ambient);
|
||||||
|
@ -1982,8 +2012,13 @@ void AAmbientSound::Tick ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// AmbientSound :: SetTicker
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void AAmbientSound::SetTicker (struct AmbientSound *ambient)
|
void AAmbientSound::SetTicker (struct FAmbientSound *ambient)
|
||||||
{
|
{
|
||||||
if ((ambient->type & CONTINUOUS) == CONTINUOUS)
|
if ((ambient->type & CONTINUOUS) == CONTINUOUS)
|
||||||
{
|
{
|
||||||
|
@ -2001,17 +2036,31 @@ void AAmbientSound::SetTicker (struct AmbientSound *ambient)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// AmbientSound :: BeginPlay
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void AAmbientSound::BeginPlay ()
|
void AAmbientSound::BeginPlay ()
|
||||||
{
|
{
|
||||||
Super::BeginPlay ();
|
Super::BeginPlay ();
|
||||||
Activate (NULL);
|
Activate (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// AmbientSound :: Activate
|
||||||
|
//
|
||||||
|
// Starts playing a sound (or does nothing of the sound is already playing).
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void AAmbientSound::Activate (AActor *activator)
|
void AAmbientSound::Activate (AActor *activator)
|
||||||
{
|
{
|
||||||
Super::Activate (activator);
|
Super::Activate (activator);
|
||||||
|
|
||||||
AmbientSound *amb = Ambients[args[0]];
|
FAmbientSound *amb = Ambients.CheckKey(args[0]);
|
||||||
|
|
||||||
if (amb == NULL)
|
if (amb == NULL)
|
||||||
{
|
{
|
||||||
|
@ -2040,13 +2089,23 @@ void AAmbientSound::Activate (AActor *activator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// AmbientSound :: Deactivate
|
||||||
|
//
|
||||||
|
// Stops playing CONTINUOUS sounds immediately. Also prevents further
|
||||||
|
// occurrences of repeated sounds.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void AAmbientSound::Deactivate (AActor *activator)
|
void AAmbientSound::Deactivate (AActor *activator)
|
||||||
{
|
{
|
||||||
Super::Deactivate (activator);
|
Super::Deactivate (activator);
|
||||||
if (bActive)
|
if (bActive)
|
||||||
{
|
{
|
||||||
bActive = false;
|
bActive = false;
|
||||||
if ((Ambients[args[0]]->type & CONTINUOUS) == CONTINUOUS)
|
FAmbientSound *ambient = Ambients.CheckKey(args[0]);
|
||||||
|
if (ambient != NULL && (ambient->type & CONTINUOUS) == CONTINUOUS)
|
||||||
{
|
{
|
||||||
S_StopSound (this, CHAN_BODY);
|
S_StopSound (this, CHAN_BODY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,7 +198,7 @@ int FPlayList::Advance ()
|
||||||
|
|
||||||
int FPlayList::Backup ()
|
int FPlayList::Backup ()
|
||||||
{
|
{
|
||||||
if (--Position < 0)
|
if (Position-- == 0)
|
||||||
{
|
{
|
||||||
Position = Songs.Size() - 1;
|
Position = Songs.Size() - 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, co
|
||||||
static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z);
|
static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z);
|
||||||
static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z);
|
static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z);
|
||||||
static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly,
|
static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly,
|
||||||
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation);
|
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo *rolloff);
|
||||||
static void S_SetListener(SoundListener &listener, AActor *listenactor);
|
static void S_SetListener(SoundListener &listener, AActor *listenactor);
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
@ -165,6 +165,7 @@ void S_NoiseDebug (void)
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 340, y, "pri", TAG_DONE);
|
screen->DrawText (SmallFont, CR_GOLD, 340, y, "pri", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 380, y, "flags", TAG_DONE);
|
screen->DrawText (SmallFont, CR_GOLD, 380, y, "flags", TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GOLD, 460, y, "aud", TAG_DONE);
|
screen->DrawText (SmallFont, CR_GOLD, 460, y, "aud", TAG_DONE);
|
||||||
|
screen->DrawText (SmallFont, CR_GOLD, 520, y, "pos", TAG_DONE);
|
||||||
y += 8;
|
y += 8;
|
||||||
|
|
||||||
if (Channels == NULL)
|
if (Channels == NULL)
|
||||||
|
@ -253,6 +254,11 @@ void S_NoiseDebug (void)
|
||||||
mysnprintf(temp, countof(temp), "%.4f", GSnd->GetAudibility(chan));
|
mysnprintf(temp, countof(temp), "%.4f", GSnd->GetAudibility(chan));
|
||||||
screen->DrawText(SmallFont, color, 460, y, temp, TAG_DONE);
|
screen->DrawText(SmallFont, color, 460, y, temp, TAG_DONE);
|
||||||
|
|
||||||
|
// Position
|
||||||
|
mysnprintf(temp, countof(temp), "%u", GSnd->GetPosition(chan));
|
||||||
|
screen->DrawText(SmallFont, color, 520, y, temp, TAG_DONE);
|
||||||
|
|
||||||
|
|
||||||
y += 8;
|
y += 8;
|
||||||
if (chan->PrevChan == &Channels)
|
if (chan->PrevChan == &Channels)
|
||||||
{
|
{
|
||||||
|
@ -317,7 +323,6 @@ void S_InitData ()
|
||||||
LastLocalSndInfo = LastLocalSndSeq = "";
|
LastLocalSndInfo = LastLocalSndSeq = "";
|
||||||
S_ParseSndInfo ();
|
S_ParseSndInfo ();
|
||||||
S_ParseSndSeq (-1);
|
S_ParseSndSeq (-1);
|
||||||
S_ParseReverbDef ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -808,7 +813,8 @@ static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fi
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyObj *poly,
|
static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyObj *poly,
|
||||||
const FVector3 *pt, int channel, FSoundID sound_id, double volume, double attenuation)
|
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation,
|
||||||
|
FRolloffInfo *forcedrolloff=NULL)
|
||||||
{
|
{
|
||||||
sfxinfo_t *sfx;
|
sfxinfo_t *sfx;
|
||||||
int chanflags;
|
int chanflags;
|
||||||
|
@ -866,7 +872,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
sfx = &S_sfx[sound_id];
|
sfx = &S_sfx[sound_id];
|
||||||
|
|
||||||
// Scale volume according to SNDINFO data.
|
// Scale volume according to SNDINFO data.
|
||||||
volume = MIN(volume * sfx->Volume, 1.0);
|
volume = MIN(volume * sfx->Volume, 1.f);
|
||||||
if (volume <= 0)
|
if (volume <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -894,7 +900,10 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
near_limit = S_sfx[sound_id].NearLimit;
|
near_limit = S_sfx[sound_id].NearLimit;
|
||||||
limit_range = S_sfx[sound_id].LimitRange;
|
limit_range = S_sfx[sound_id].LimitRange;
|
||||||
}
|
}
|
||||||
if (rolloff->MinDistance == 0) rolloff = &S_sfx[sound_id].Rolloff;
|
if (rolloff->MinDistance == 0)
|
||||||
|
{
|
||||||
|
rolloff = &S_sfx[sound_id].Rolloff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -904,13 +913,25 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
near_limit = S_sfx[sound_id].NearLimit;
|
near_limit = S_sfx[sound_id].NearLimit;
|
||||||
limit_range = S_sfx[sound_id].LimitRange;
|
limit_range = S_sfx[sound_id].LimitRange;
|
||||||
}
|
}
|
||||||
if (rolloff->MinDistance == 0) rolloff = &S_sfx[sound_id].Rolloff;
|
if (rolloff->MinDistance == 0)
|
||||||
|
{
|
||||||
|
rolloff = &S_sfx[sound_id].Rolloff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sfx = &S_sfx[sound_id];
|
sfx = &S_sfx[sound_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no valid rolloff was set use the global default
|
// The passed rolloff overrides any sound-specific rolloff.
|
||||||
if (rolloff->MinDistance == 0) rolloff = &S_Rolloff;
|
if (forcedrolloff != NULL && forcedrolloff->MinDistance != 0)
|
||||||
|
{
|
||||||
|
rolloff = forcedrolloff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no valid rolloff was set, use the global default.
|
||||||
|
if (rolloff->MinDistance == 0)
|
||||||
|
{
|
||||||
|
rolloff = &S_Rolloff;
|
||||||
|
}
|
||||||
|
|
||||||
// If this is a singular sound, don't play it if it's already playing.
|
// If this is a singular sound, don't play it if it's already playing.
|
||||||
if (sfx->bSingular && S_CheckSingular(sound_id))
|
if (sfx->bSingular && S_CheckSingular(sound_id))
|
||||||
|
@ -1162,7 +1183,7 @@ void S_RestartSound(FSoundChan *chan)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void S_Sound (int channel, FSoundID sound_id, double volume, double attenuation)
|
void S_Sound (int channel, FSoundID sound_id, float volume, float attenuation)
|
||||||
{
|
{
|
||||||
S_StartSound (NULL, NULL, NULL, NULL, channel, sound_id, volume, attenuation);
|
S_StartSound (NULL, NULL, NULL, NULL, channel, sound_id, volume, attenuation);
|
||||||
}
|
}
|
||||||
|
@ -1173,20 +1194,41 @@ void S_Sound (int channel, FSoundID sound_id, double volume, double attenuation)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void S_Sound (AActor *ent, int channel, FSoundID sound_id, double volume, double attenuation)
|
void S_Sound (AActor *ent, int channel, FSoundID sound_id, float volume, float attenuation)
|
||||||
{
|
{
|
||||||
if (ent == NULL || ent->Sector->Flags & SECF_SILENT)
|
if (ent == NULL || ent->Sector->Flags & SECF_SILENT)
|
||||||
return;
|
return;
|
||||||
S_StartSound (ent, NULL, NULL, NULL, channel, sound_id, volume, attenuation);
|
S_StartSound (ent, NULL, NULL, NULL, channel, sound_id, volume, attenuation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// S_SoundMinMaxDist - An actor is source
|
||||||
|
//
|
||||||
|
// Attenuation is specified as min and max distances, rather than a scalar.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void S_SoundMinMaxDist(AActor *ent, int channel, FSoundID sound_id, float volume, float mindist, float maxdist)
|
||||||
|
{
|
||||||
|
if (ent == NULL || ent->Sector->Flags & SECF_SILENT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FRolloffInfo rolloff;
|
||||||
|
|
||||||
|
rolloff.RolloffType = ROLLOFF_Linear;
|
||||||
|
rolloff.MinDistance = mindist;
|
||||||
|
rolloff.MaxDistance = maxdist;
|
||||||
|
S_StartSound(ent, NULL, NULL, NULL, channel, sound_id, volume, 1, &rolloff);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// S_Sound - A polyobject is source
|
// S_Sound - A polyobject is source
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void S_Sound (const FPolyObj *poly, int channel, FSoundID sound_id, double volume, double attenuation)
|
void S_Sound (const FPolyObj *poly, int channel, FSoundID sound_id, float volume, float attenuation)
|
||||||
{
|
{
|
||||||
S_StartSound (NULL, NULL, poly, NULL, channel, sound_id, volume, attenuation);
|
S_StartSound (NULL, NULL, poly, NULL, channel, sound_id, volume, attenuation);
|
||||||
}
|
}
|
||||||
|
@ -1197,7 +1239,7 @@ void S_Sound (const FPolyObj *poly, int channel, FSoundID sound_id, double volum
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sound_id, double volume, double attenuation)
|
void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sound_id, float volume, float attenuation)
|
||||||
{
|
{
|
||||||
FVector3 pt(FIXED2FLOAT(x), FIXED2FLOAT(z), FIXED2FLOAT(y));
|
FVector3 pt(FIXED2FLOAT(x), FIXED2FLOAT(z), FIXED2FLOAT(y));
|
||||||
S_StartSound (NULL, NULL, NULL, &pt, channel, sound_id, volume, attenuation);
|
S_StartSound (NULL, NULL, NULL, &pt, channel, sound_id, volume, attenuation);
|
||||||
|
@ -1209,7 +1251,7 @@ void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sound_id, d
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, double volume, double attenuation)
|
void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation)
|
||||||
{
|
{
|
||||||
S_StartSound (NULL, sec, NULL, NULL, channel, sfxid, volume, attenuation);
|
S_StartSound (NULL, sec, NULL, NULL, channel, sfxid, volume, attenuation);
|
||||||
}
|
}
|
||||||
|
@ -1285,7 +1327,7 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx)
|
||||||
}
|
}
|
||||||
sfxstart = sfxdata + 8;
|
sfxstart = sfxdata + 8;
|
||||||
}
|
}
|
||||||
sfx->data = GSnd->LoadSoundRaw(sfxstart, len, frequency, 1, 8);
|
sfx->data = GSnd->LoadSoundRaw(sfxstart, len, frequency, 1, 8, sfx->LoopStart);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1879,8 +1921,8 @@ static void S_SetListener(SoundListener &listener, AActor *listenactor)
|
||||||
*/
|
*/
|
||||||
listener.velocity.Zero();
|
listener.velocity.Zero();
|
||||||
listener.position.X = FIXED2FLOAT(listenactor->x);
|
listener.position.X = FIXED2FLOAT(listenactor->x);
|
||||||
listener.position.Y = FIXED2FLOAT(listenactor->y);
|
listener.position.Y = FIXED2FLOAT(listenactor->z);
|
||||||
listener.position.Z = FIXED2FLOAT(listenactor->z);
|
listener.position.Z = FIXED2FLOAT(listenactor->y);
|
||||||
listener.underwater = listenactor->waterlevel == 3;
|
listener.underwater = listenactor->waterlevel == 3;
|
||||||
assert(zones != NULL);
|
assert(zones != NULL);
|
||||||
listener.Environment = zones[listenactor->Sector->ZoneNumber].Environment;
|
listener.Environment = zones[listenactor->Sector->ZoneNumber].Environment;
|
||||||
|
|
|
@ -59,6 +59,8 @@ struct sfxinfo_t
|
||||||
WORD bSingular:1;
|
WORD bSingular:1;
|
||||||
WORD bTentative:1;
|
WORD bTentative:1;
|
||||||
|
|
||||||
|
int LoopStart; // -1 means no specific loop defined
|
||||||
|
|
||||||
unsigned int link;
|
unsigned int link;
|
||||||
enum { NO_LINK = 0xffffffff };
|
enum { NO_LINK = 0xffffffff };
|
||||||
|
|
||||||
|
@ -216,11 +218,12 @@ void S_PrecacheLevel ();
|
||||||
void S_CacheSound (sfxinfo_t *sfx);
|
void S_CacheSound (sfxinfo_t *sfx);
|
||||||
|
|
||||||
// Start sound for thing at <ent>
|
// Start sound for thing at <ent>
|
||||||
void S_Sound (int channel, FSoundID sfxid, double volume, double attenuation);
|
void S_Sound (int channel, FSoundID sfxid, float volume, float attenuation);
|
||||||
void S_Sound (AActor *ent, int channel, FSoundID sfxid, double volume, double attenuation);
|
void S_Sound (AActor *ent, int channel, FSoundID sfxid, float volume, float attenuation);
|
||||||
void S_Sound (const FPolyObj *poly, int channel, FSoundID sfxid, double volume, double attenuation);
|
void S_SoundMinMaxDist (AActor *ent, int channel, FSoundID sfxid, float volume, float mindist, float maxdist);
|
||||||
void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, double volume, double attenuation);
|
void S_Sound (const FPolyObj *poly, int channel, FSoundID sfxid, float volume, float attenuation);
|
||||||
void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sfxid, double volume, double attenuation);
|
void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation);
|
||||||
|
void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sfxid, float volume, float attenuation);
|
||||||
|
|
||||||
// sound channels
|
// sound channels
|
||||||
// channel 0 never willingly overrides
|
// channel 0 never willingly overrides
|
||||||
|
|
|
@ -1737,7 +1737,7 @@ bool FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FISoundChannel *
|
||||||
if (FMOD_OK == chan->getCurrentSound(&sound))
|
if (FMOD_OK == chan->getCurrentSound(&sound))
|
||||||
{
|
{
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
if (FMOD_OK == sound->getLength(&len, FMOD_TIMEUNIT_MS))
|
if (FMOD_OK == sound->getLength(&len, FMOD_TIMEUNIT_MS) && len)
|
||||||
{
|
{
|
||||||
difftime %= len;
|
difftime %= len;
|
||||||
}
|
}
|
||||||
|
@ -1994,11 +1994,11 @@ void FMODSoundRenderer::UpdateListener(SoundListener *listener)
|
||||||
// Set velocity to 0 to prevent crazy doppler shifts just from running.
|
// Set velocity to 0 to prevent crazy doppler shifts just from running.
|
||||||
|
|
||||||
vel.x = listener->velocity.X;
|
vel.x = listener->velocity.X;
|
||||||
vel.z = listener->velocity.Y;
|
vel.y = listener->velocity.Y;
|
||||||
vel.y = listener->velocity.Z;
|
vel.z = listener->velocity.Z;
|
||||||
pos.x = listener->position.X;
|
pos.x = listener->position.X;
|
||||||
pos.z = listener->position.Y;
|
pos.y = listener->position.Y;
|
||||||
pos.y = listener->position.Z;
|
pos.z = listener->position.Z;
|
||||||
|
|
||||||
float angle = listener->angle;
|
float angle = listener->angle;
|
||||||
forward.x = cos(angle);
|
forward.x = cos(angle);
|
||||||
|
@ -2190,12 +2190,16 @@ void FMODSoundRenderer::UpdateSounds()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits)
|
SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart)
|
||||||
{
|
{
|
||||||
FMOD_CREATESOUNDEXINFO exinfo;
|
FMOD_CREATESOUNDEXINFO exinfo;
|
||||||
SoundHandle retval = { NULL };
|
SoundHandle retval = { NULL };
|
||||||
|
int numsamples;
|
||||||
|
|
||||||
if (length == 0) return retval;
|
if (length <= 0)
|
||||||
|
{
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
InitCreateSoundExInfo(&exinfo);
|
InitCreateSoundExInfo(&exinfo);
|
||||||
exinfo.length = length;
|
exinfo.length = length;
|
||||||
|
@ -2212,14 +2216,17 @@ SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequ
|
||||||
|
|
||||||
case -8:
|
case -8:
|
||||||
exinfo.format = FMOD_SOUND_FORMAT_PCM8;
|
exinfo.format = FMOD_SOUND_FORMAT_PCM8;
|
||||||
|
numsamples = length;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 16:
|
case 16:
|
||||||
exinfo.format = FMOD_SOUND_FORMAT_PCM16;
|
exinfo.format = FMOD_SOUND_FORMAT_PCM16;
|
||||||
|
numsamples = length >> 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 32:
|
case 32:
|
||||||
exinfo.format = FMOD_SOUND_FORMAT_PCM32;
|
exinfo.format = FMOD_SOUND_FORMAT_PCM32;
|
||||||
|
numsamples = length >> 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2236,6 +2243,12 @@ SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequ
|
||||||
DPrintf("Failed to allocate sample: Error %d\n", result);
|
DPrintf("Failed to allocate sample: Error %d\n", result);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loopstart >= 0)
|
||||||
|
{
|
||||||
|
sample->setLoopPoints(loopstart, FMOD_TIMEUNIT_PCM, numsamples - 1, FMOD_TIMEUNIT_PCM);
|
||||||
|
}
|
||||||
|
|
||||||
retval.data = sample;
|
retval.data = sample;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ public:
|
||||||
void SetSfxVolume (float volume);
|
void SetSfxVolume (float volume);
|
||||||
void SetMusicVolume (float volume);
|
void SetMusicVolume (float volume);
|
||||||
SoundHandle LoadSound(BYTE *sfxdata, int length);
|
SoundHandle LoadSound(BYTE *sfxdata, int length);
|
||||||
SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits);
|
SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart);
|
||||||
void UnloadSound (SoundHandle sfx);
|
void UnloadSound (SoundHandle sfx);
|
||||||
unsigned int GetMSLength(SoundHandle sfx);
|
unsigned int GetMSLength(SoundHandle sfx);
|
||||||
unsigned int GetSampleLength(SoundHandle sfx);
|
unsigned int GetSampleLength(SoundHandle sfx);
|
||||||
|
|
|
@ -112,7 +112,10 @@ CUSTOM_CVAR (Float, snd_musicvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Set general music volume.
|
// Set general music volume.
|
||||||
|
if (GSnd != NULL)
|
||||||
|
{
|
||||||
GSnd->SetMusicVolume(clamp<float>(self * relative_volume, 0, 1));
|
GSnd->SetMusicVolume(clamp<float>(self * relative_volume, 0, 1));
|
||||||
|
}
|
||||||
// For music not implemented through the digital sound system,
|
// For music not implemented through the digital sound system,
|
||||||
// let them know about the change.
|
// let them know about the change.
|
||||||
if (currSong != NULL)
|
if (currSong != NULL)
|
||||||
|
|
|
@ -123,7 +123,7 @@ public:
|
||||||
SoundHandle retval = { NULL };
|
SoundHandle retval = { NULL };
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits)
|
SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart)
|
||||||
{
|
{
|
||||||
SoundHandle retval = { NULL };
|
SoundHandle retval = { NULL };
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -92,7 +92,7 @@ public:
|
||||||
virtual void SetSfxVolume (float volume) = 0;
|
virtual void SetSfxVolume (float volume) = 0;
|
||||||
virtual void SetMusicVolume (float volume) = 0;
|
virtual void SetMusicVolume (float volume) = 0;
|
||||||
virtual SoundHandle LoadSound(BYTE *sfxdata, int length) = 0;
|
virtual SoundHandle LoadSound(BYTE *sfxdata, int length) = 0;
|
||||||
virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits) = 0;
|
virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart) = 0;
|
||||||
virtual void UnloadSound (SoundHandle sfx) = 0; // unloads a sound from memory
|
virtual void UnloadSound (SoundHandle sfx) = 0; // unloads a sound from memory
|
||||||
virtual unsigned int GetMSLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency
|
virtual unsigned int GetMSLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency
|
||||||
virtual unsigned int GetSampleLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency
|
virtual unsigned int GetSampleLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency
|
||||||
|
|
|
@ -171,7 +171,7 @@ static BYTE CheatDigitalCafe[] = { 'd','i','g','i','t','a','l','c','a','f','e',2
|
||||||
static BYTE CheatJoshuaStorms[] = { 'j','o','s','h','u','a','s','t','o','r','m','s',255 };
|
static BYTE CheatJoshuaStorms[] = { 'j','o','s','h','u','a','s','t','o','r','m','s',255 };
|
||||||
static BYTE CheatLeeSnyder[] = { 'l','e','e','s','n','y','d','e','r',0,0,255 };
|
static BYTE CheatLeeSnyder[] = { 'l','e','e','s','n','y','d','e','r',0,0,255 };
|
||||||
static BYTE CheatKimHyers[] = { 'k','i','m','h','y','e','r','s',255 };
|
static BYTE CheatKimHyers[] = { 'k','i','m','h','y','e','r','s',255 };
|
||||||
static BYTE CheatShrrill[] = { 's','h','r','r','i','l','l',255 };
|
static BYTE CheatShrrill[] = { 's','h','e','r','r','i','l','l',255 };
|
||||||
|
|
||||||
static BYTE CheatTNTem[] = { 't','n','t','e','m',255 };
|
static BYTE CheatTNTem[] = { 't','n','t','e','m',255 };
|
||||||
|
|
||||||
|
@ -274,8 +274,8 @@ static cheatseq_t ChexCheats[] =
|
||||||
{ CheatKimHyers, 0, 1, 0, {0,0}, Cht_MyPos },
|
{ CheatKimHyers, 0, 1, 0, {0,0}, Cht_MyPos },
|
||||||
{ CheatShrrill, 0, 0, 0, {0,0}, Cht_AutoMap },
|
{ CheatShrrill, 0, 0, 0, {0,0}, Cht_AutoMap },
|
||||||
{ CheatDavidBrus, 0, 0, 0, {CHT_IDDQD,0}, Cht_Generic },
|
{ CheatDavidBrus, 0, 0, 0, {CHT_IDDQD,0}, Cht_Generic },
|
||||||
{ CheatMikeKoenigs, 0, 0, 0, {CHT_IDKFA,0}, Cht_Generic },
|
{ CheatScottHolman, 0, 0, 0, {CHT_IDKFA,0}, Cht_Generic },
|
||||||
{ CheatScottHolman, 0, 0, 0, {CHT_IDFA,0}, Cht_Generic },
|
{ CheatMikeKoenigs, 0, 0, 0, {CHT_IDFA,0}, Cht_Generic },
|
||||||
{ CheatCharlesJacobi, 0, 0, 0, {CHT_NOCLIP,0}, Cht_Generic },
|
{ CheatCharlesJacobi, 0, 0, 0, {CHT_NOCLIP,0}, Cht_Generic },
|
||||||
{ CheatAndrewBenson, 0, 0, 0, {CHT_BEHOLDV,0}, Cht_Generic },
|
{ CheatAndrewBenson, 0, 0, 0, {CHT_BEHOLDV,0}, Cht_Generic },
|
||||||
{ CheatDeanHyers, 0, 0, 0, {CHT_BEHOLDS,0}, Cht_Generic },
|
{ CheatDeanHyers, 0, 0, 0, {CHT_BEHOLDS,0}, Cht_Generic },
|
||||||
|
|
|
@ -745,7 +745,11 @@ protected:
|
||||||
Node *mp = MainPosition(key), **mpp;
|
Node *mp = MainPosition(key), **mpp;
|
||||||
HashTraits Traits;
|
HashTraits Traits;
|
||||||
|
|
||||||
if (!mp->IsNil() && !Traits.Compare(mp->Pair.Key, key)) /* the key is in its main position */
|
if (mp->IsNil())
|
||||||
|
{
|
||||||
|
/* the key is definitely not present, because there is nothing at its main position */
|
||||||
|
}
|
||||||
|
else if (!Traits.Compare(mp->Pair.Key, key)) /* the key is in its main position */
|
||||||
{
|
{
|
||||||
if (mp->Next != NULL) /* move next node to its main position */
|
if (mp->Next != NULL) /* move next node to its main position */
|
||||||
{
|
{
|
||||||
|
|
|
@ -158,7 +158,7 @@ const BYTE *FBuildTexture::GetColumn (unsigned int column, const Span **spans_ou
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static void AddTiles (void *tiles)
|
void AddTiles (void *tiles)
|
||||||
{
|
{
|
||||||
// int numtiles = LittleLong(((DWORD *)tiles)[1]); // This value is not reliable
|
// int numtiles = LittleLong(((DWORD *)tiles)[1]); // This value is not reliable
|
||||||
int tilestart = LittleLong(((DWORD *)tiles)[2]);
|
int tilestart = LittleLong(((DWORD *)tiles)[2]);
|
||||||
|
@ -224,29 +224,29 @@ static void AddTiles (void *tiles)
|
||||||
if (rotType == 1)
|
if (rotType == 1)
|
||||||
{
|
{
|
||||||
spriteframe_t rot;
|
spriteframe_t rot;
|
||||||
rot.Texture[0] = texnum;
|
rot.Texture[0] =
|
||||||
rot.Texture[1] = texnum;
|
rot.Texture[1] = texnum;
|
||||||
for (int j = 1; j < 4; ++j)
|
for (int j = 1; j < 4; ++j)
|
||||||
{
|
{
|
||||||
rot.Texture[j*2] = texnum + j;
|
rot.Texture[j*2] =
|
||||||
rot.Texture[j*2+1] = texnum + j;
|
rot.Texture[j*2+1] =
|
||||||
rot.Texture[16-j*2] = texnum + j;
|
rot.Texture[16-j*2] =
|
||||||
rot.Texture[17-j*2] = texnum + j;
|
rot.Texture[17-j*2] = texnum.GetIndex() + j;
|
||||||
}
|
}
|
||||||
rot.Texture[8] = texnum + 4;
|
rot.Texture[8] =
|
||||||
rot.Texture[9] = texnum + 4;
|
rot.Texture[9] = texnum.GetIndex() + 4;
|
||||||
rot.Flip = 0x00FC;
|
rot.Flip = 0x00FC;
|
||||||
tex->Rotations = SpriteFrames.Push (rot);
|
tex->Rotations = SpriteFrames.Push (rot);
|
||||||
}
|
}
|
||||||
else if (rotType == 2)
|
else if (rotType == 2)
|
||||||
{
|
{
|
||||||
spriteframe_t rot;
|
spriteframe_t rot;
|
||||||
rot.Texture[0] = texnum;
|
rot.Texture[0] =
|
||||||
rot.Texture[1] = texnum;
|
rot.Texture[1] = texnum;
|
||||||
for (int j = 1; j < 8; ++j)
|
for (int j = 1; j < 8; ++j)
|
||||||
{
|
{
|
||||||
rot.Texture[16-j*2] = texnum + j;
|
rot.Texture[16-j*2] =
|
||||||
rot.Texture[17-j*2] = texnum + j;
|
rot.Texture[17-j*2] = texnum.GetIndex() + j;
|
||||||
}
|
}
|
||||||
rot.Flip = 0;
|
rot.Flip = 0;
|
||||||
tex->Rotations = SpriteFrames.Push (rot);
|
tex->Rotations = SpriteFrames.Push (rot);
|
||||||
|
|
|
@ -634,7 +634,7 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump, BYTE *tcbuf)
|
||||||
bMasked = true;
|
bMasked = true;
|
||||||
}
|
}
|
||||||
// Pick colors from the palette for each of the four colors.
|
// Pick colors from the palette for each of the four colors.
|
||||||
if (!tcbuf) for (i = 3; i >= 0; --i)
|
/*if (!tcbuf)*/ for (i = 3; i >= 0; --i)
|
||||||
{
|
{
|
||||||
palcol[i] = color[i].a ? RGB32k[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3] : 0;
|
palcol[i] = color[i].a ? RGB32k[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3] : 0;
|
||||||
}
|
}
|
||||||
|
@ -652,18 +652,18 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump, BYTE *tcbuf)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
int ci = (yslice >> (x + x)) & 3;
|
||||||
if (!tcbuf)
|
if (!tcbuf)
|
||||||
{
|
{
|
||||||
Pixels[oy + y + (ox + x) * Height] = palcol[(yslice >> (x + x)) & 3];
|
Pixels[oy + y + (ox + x) * Height] = palcol[ci];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BYTE * tcp = &tcbuf[ox + x + (oy + y) * Width*4];
|
BYTE * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4];
|
||||||
int c = (yslice >> (x + x)) & 3;
|
tcp[0] = color[ci].r;
|
||||||
tcp[0] = color[c].r;
|
tcp[1] = color[ci].g;
|
||||||
tcp[1] = color[c].g;
|
tcp[2] = color[ci].b;
|
||||||
tcp[2] = color[c].b;
|
tcp[3] = color[ci].a;
|
||||||
tcp[3] = color[c].a;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -740,7 +740,7 @@ void FDDSTexture::DecompressDXT3 (FWadLump &lump, bool premultiplied, BYTE *tcbu
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BYTE * tcp = &tcbuf[ox + x + (oy + y) * Width*4];
|
BYTE * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4];
|
||||||
int c = (yslice >> (x + x)) & 3;
|
int c = (yslice >> (x + x)) & 3;
|
||||||
tcp[0] = color[c].r;
|
tcp[0] = color[c].r;
|
||||||
tcp[1] = color[c].g;
|
tcp[1] = color[c].g;
|
||||||
|
@ -769,7 +769,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbu
|
||||||
BYTE *block;
|
BYTE *block;
|
||||||
PalEntry color[4];
|
PalEntry color[4];
|
||||||
BYTE palcol[4];
|
BYTE palcol[4];
|
||||||
DWORD yalphaslice;
|
DWORD yalphaslice = 0;
|
||||||
int ox, oy, x, y, i;
|
int ox, oy, x, y, i;
|
||||||
|
|
||||||
for (oy = 0; oy < Height; oy += 4)
|
for (oy = 0; oy < Height; oy += 4)
|
||||||
|
@ -831,7 +831,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbu
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Alpha values are stored in 3 bytes for 2 rows
|
// Alpha values are stored in 3 bytes for 2 rows
|
||||||
if ((y & 0) == 0)
|
if ((y & 1) == 0)
|
||||||
{
|
{
|
||||||
yalphaslice = block[y*3] | (block[y*3+1] << 8) | (block[y*3+2] << 16);
|
yalphaslice = block[y*3] | (block[y*3+1] << 8) | (block[y*3+2] << 16);
|
||||||
}
|
}
|
||||||
|
@ -853,7 +853,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbu
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BYTE * tcp = &tcbuf[ox + x + (oy + y) * Width*4];
|
BYTE * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4];
|
||||||
int c = (yslice >> (x + x)) & 3;
|
int c = (yslice >> (x + x)) & 3;
|
||||||
tcp[0] = color[c].r;
|
tcp[0] = color[c].r;
|
||||||
tcp[1] = color[c].g;
|
tcp[1] = color[c].g;
|
||||||
|
|
|
@ -140,7 +140,9 @@ FTextureID FTextureManager::CheckForTexture (const char *name, int usetype, BITF
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (firsttype == FTexture::TEX_Null ||
|
if (firsttype == FTexture::TEX_Null ||
|
||||||
(firsttype == FTexture::TEX_MiscPatch && tex->UseType != FTexture::TEX_Null)
|
(firsttype == FTexture::TEX_MiscPatch &&
|
||||||
|
tex->UseType != firsttype &&
|
||||||
|
tex->UseType != FTexture::TEX_Null)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
firstfound = i;
|
firstfound = i;
|
||||||
|
@ -1005,7 +1007,7 @@ FArchive &operator<< (FArchive &arc, FTextureID &tex)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FTextureID::operator+
|
// FTextureID::operator+
|
||||||
// Does not return incvalid texture IDs
|
// Does not return invalid texture IDs
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,8 @@ protected:
|
||||||
FTextureID(int num) { texnum = num; }
|
FTextureID(int num) { texnum = num; }
|
||||||
private:
|
private:
|
||||||
int texnum;
|
int texnum;
|
||||||
|
|
||||||
|
friend void AddTiles (void *tiles);
|
||||||
};
|
};
|
||||||
|
|
||||||
class FNullTextureID : public FTextureID
|
class FNullTextureID : public FTextureID
|
||||||
|
|
|
@ -153,6 +153,12 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
|
||||||
ti->PainChances = new PainChanceList;
|
ti->PainChances = new PainChanceList;
|
||||||
*ti->PainChances = *parent->PainChances;
|
*ti->PainChances = *parent->PainChances;
|
||||||
}
|
}
|
||||||
|
if (parent->ColorSets != NULL)
|
||||||
|
{
|
||||||
|
// copy color sets from parent
|
||||||
|
ti->ColorSets = new FPlayerColorSetMap;
|
||||||
|
*ti->ColorSets = *parent->ColorSets;
|
||||||
|
}
|
||||||
ti->Replacee = ti->Replacement = NULL;
|
ti->Replacee = ti->Replacement = NULL;
|
||||||
ti->DoomEdNum = -1;
|
ti->DoomEdNum = -1;
|
||||||
return ti;
|
return ti;
|
||||||
|
|
|
@ -1280,7 +1280,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
|
||||||
self->target->x,
|
self->target->x,
|
||||||
self->target->y);
|
self->target->y);
|
||||||
}
|
}
|
||||||
self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &linetarget, ANGLE_1*60, false, false, false, aim ? self->target : NULL);
|
self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &linetarget, ANGLE_1*60, 0, aim ? self->target : NULL);
|
||||||
if (linetarget == NULL && aim)
|
if (linetarget == NULL && aim)
|
||||||
{
|
{
|
||||||
// We probably won't hit the target, but aim at it anyway so we don't look stupid.
|
// We probably won't hit the target, but aim at it anyway so we don't look stupid.
|
||||||
|
@ -2016,7 +2016,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight)
|
||||||
|
|
||||||
for (int i = 0; i < MAXPLAYERS; i++)
|
for (int i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (playeringame[i] && P_CheckSight(players[i].camera, self, true))
|
if (playeringame[i] && P_CheckSight(players[i].camera, self, SF_IGNOREVISIBILITY))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2024,6 +2024,61 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// A_CheckSightOrRange
|
||||||
|
// Jumps if this actor is out of range of all players *and* out of sight.
|
||||||
|
// Useful for maps with many multi-actor special effects.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange)
|
||||||
|
{
|
||||||
|
PARAM_ACTION_PROLOGUE;
|
||||||
|
PARAM_FLOAT(range);
|
||||||
|
PARAM_STATE(jump);
|
||||||
|
|
||||||
|
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||||
|
|
||||||
|
range = range * range * (double(FRACUNIT) * FRACUNIT); // no need for square roots
|
||||||
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||||
|
{
|
||||||
|
if (playeringame[i])
|
||||||
|
{
|
||||||
|
AActor *camera = players[i].camera;
|
||||||
|
|
||||||
|
// Check distance first, since it's cheaper than checking sight.
|
||||||
|
double dx = self->x - camera->x;
|
||||||
|
double dy = self->y - camera->y;
|
||||||
|
double dz;
|
||||||
|
fixed_t eyez = (camera->z + camera->height - (camera->height>>2)); // same eye height as P_CheckSight
|
||||||
|
if (eyez > self->z + self->height)
|
||||||
|
{
|
||||||
|
dz = self->z + self->height - eyez;
|
||||||
|
}
|
||||||
|
else if (eyez < self->z)
|
||||||
|
{
|
||||||
|
dz = self->z - eyez;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dz = 0;
|
||||||
|
}
|
||||||
|
if ((dx*dx) + (dy*dy) + (dz*dz) <= range)
|
||||||
|
{ // Within range
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check LOS.
|
||||||
|
if (P_CheckSight(camera, self, SF_IGNOREVISIBILITY))
|
||||||
|
{ // Visible
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ACTION_JUMP(jump);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
@ -2493,7 +2548,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS)
|
||||||
if (target == NULL)
|
if (target == NULL)
|
||||||
return 0; // [KS] Let's not call P_CheckSight unnecessarily in this case.
|
return 0; // [KS] Let's not call P_CheckSight unnecessarily in this case.
|
||||||
|
|
||||||
if (!P_CheckSight (self, target, 1))
|
if (!P_CheckSight (self, target, SF_IGNOREVISIBILITY))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (fov && (fov < ANGLE_MAX))
|
if (fov && (fov < ANGLE_MAX))
|
||||||
|
@ -2555,7 +2610,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetLOS)
|
||||||
if (target == NULL)
|
if (target == NULL)
|
||||||
return 0; // [KS] Let's not call P_CheckSight unnecessarily in this case.
|
return 0; // [KS] Let's not call P_CheckSight unnecessarily in this case.
|
||||||
|
|
||||||
if (!P_CheckSight (target, self, 1))
|
if (!P_CheckSight (target, self, SF_IGNOREVISIBILITY))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (fov && (fov < ANGLE_MAX))
|
if (fov && (fov < ANGLE_MAX))
|
||||||
|
@ -2963,7 +3018,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MonsterRefire)
|
||||||
if (self->target == NULL
|
if (self->target == NULL
|
||||||
|| P_HitFriend (self)
|
|| P_HitFriend (self)
|
||||||
|| self->target->health <= 0
|
|| self->target->health <= 0
|
||||||
|| !P_CheckSight(self, self->target, 0) )
|
|| !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES) )
|
||||||
{
|
{
|
||||||
ACTION_JUMP(jump);
|
ACTION_JUMP(jump);
|
||||||
}
|
}
|
||||||
|
@ -3132,16 +3187,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserVar)
|
||||||
PARAM_NAME (varname);
|
PARAM_NAME (varname);
|
||||||
PARAM_INT (value);
|
PARAM_INT (value);
|
||||||
|
|
||||||
PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
|
PSymbolVariable *var = dyn_cast<PSymbolVariable>(stateowner->GetClass()->Symbols.FindSymbol(varname, true));
|
||||||
|
|
||||||
if (var == NULL || !var->bUserVar || var->ValueType.Type != VAL_Int)
|
if (var == NULL || !var->bUserVar || var->ValueType.Type != VAL_Int)
|
||||||
{
|
{
|
||||||
Printf("%s is not a user variable in class %s\n", varname.GetChars(),
|
Printf("%s is not a user variable in class %s\n", varname.GetChars(),
|
||||||
self->GetClass()->TypeName.GetChars());
|
stateowner->GetClass()->TypeName.GetChars());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Set the value of the specified user variable.
|
// Set the value of the specified user variable.
|
||||||
*(int *)(reinterpret_cast<BYTE *>(self) + var->offset) = value;
|
*(int *)(reinterpret_cast<BYTE *>(stateowner) + var->offset) = value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3158,22 +3213,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserArray)
|
||||||
PARAM_INT (pos);
|
PARAM_INT (pos);
|
||||||
PARAM_INT (value);
|
PARAM_INT (value);
|
||||||
|
|
||||||
PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
|
PSymbolVariable *var = dyn_cast<PSymbolVariable>(stateowner->GetClass()->Symbols.FindSymbol(varname, true));
|
||||||
|
|
||||||
if (var == NULL || !var->bUserVar || var->ValueType.Type != VAL_Array || var->ValueType.BaseType != VAL_Int)
|
if (var == NULL || !var->bUserVar || var->ValueType.Type != VAL_Array || var->ValueType.BaseType != VAL_Int)
|
||||||
{
|
{
|
||||||
Printf("%s is not a user array in class %s\n", varname.GetChars(),
|
Printf("%s is not a user array in class %s\n", varname.GetChars(),
|
||||||
self->GetClass()->TypeName.GetChars());
|
stateowner->GetClass()->TypeName.GetChars());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (pos < 0 || pos >= var->ValueType.size)
|
if (pos < 0 || pos >= var->ValueType.size)
|
||||||
{
|
{
|
||||||
Printf("%d is out of bounds in array %s in class %s\n", pos, varname.GetChars(),
|
Printf("%d is out of bounds in array %s in class %s\n", pos, varname.GetChars(),
|
||||||
self->GetClass()->TypeName.GetChars());
|
stateowner->GetClass()->TypeName.GetChars());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Set the value of the specified user array at index pos.
|
// Set the value of the specified user array at index pos.
|
||||||
((int *)(reinterpret_cast<BYTE *>(self) + var->offset))[pos] = value;
|
((int *)(reinterpret_cast<BYTE *>(stateowner) + var->offset))[pos] = value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -310,6 +310,7 @@ static FFlagDef WeaponFlags[] =
|
||||||
DEFINE_FLAG(WIF, NOAUTOAIM, AWeapon, WeaponFlags),
|
DEFINE_FLAG(WIF, NOAUTOAIM, AWeapon, WeaponFlags),
|
||||||
|
|
||||||
DEFINE_DUMMY_FLAG(NOLMS),
|
DEFINE_DUMMY_FLAG(NOLMS),
|
||||||
|
DEFINE_DUMMY_FLAG(ALLOW_WITH_RESPAWN_INVUL),
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFlagDef PlayerPawnFlags[] =
|
static FFlagDef PlayerPawnFlags[] =
|
||||||
|
@ -612,3 +613,4 @@ void InitThingdef()
|
||||||
qsort(&variables[0], variables.Size(), sizeof(variables[0]), varcmp);
|
qsort(&variables[0], variables.Size(), sizeof(variables[0]), varcmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -370,8 +370,7 @@ DEFINE_PROPERTY(painchance, ZI, Actor)
|
||||||
if (!stricmp(str, "Normal")) painType = NAME_None;
|
if (!stricmp(str, "Normal")) painType = NAME_None;
|
||||||
else painType=str;
|
else painType=str;
|
||||||
|
|
||||||
if (info->PainChances == NULL) info->PainChances=new PainChanceList;
|
info->SetPainChance(painType, id);
|
||||||
(*info->PainChances)[painType] = (BYTE)id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,6 +567,15 @@ DEFINE_PROPERTY(howlsound, S, Actor)
|
||||||
static_cast<PClassActor *>(info)->HowlSound = str;
|
static_cast<PClassActor *>(info)->HowlSound = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
DEFINE_PROPERTY(crushpainsound, S, Actor)
|
||||||
|
{
|
||||||
|
PROP_STRING_PARM(str, 0);
|
||||||
|
defaults->CrushPainSound = str;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -978,13 +986,11 @@ DEFINE_PROPERTY(damagefactor, ZF, Actor)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (info->DamageFactors == NULL) info->DamageFactors=new DmgFactors;
|
|
||||||
|
|
||||||
FName dmgType;
|
FName dmgType;
|
||||||
if (!stricmp(str, "Normal")) dmgType = NAME_None;
|
if (!stricmp(str, "Normal")) dmgType = NAME_None;
|
||||||
else dmgType=str;
|
else dmgType=str;
|
||||||
|
|
||||||
(*info->DamageFactors)[dmgType]=id;
|
info->SetDamageFactor(dmgType, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1606,6 +1612,15 @@ DEFINE_CLASS_PROPERTY(slotpriority, F, Weapon)
|
||||||
static_cast<PClassWeapon *>(info)->SlotPriority = i;
|
static_cast<PClassWeapon *>(info)->SlotPriority = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
DEFINE_CLASS_PROPERTY(preferredskin, S, Weapon)
|
||||||
|
{
|
||||||
|
PROP_STRING_PARM(str, 0);
|
||||||
|
// NoOp - only for Skulltag compatibility
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1892,6 +1907,75 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorrange, I_I, PlayerPawn)
|
||||||
static_cast<PClassPlayerPawn *>(info)->ColorRangeEnd = end;
|
static_cast<PClassPlayerPawn *>(info)->ColorRangeEnd = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
DEFINE_CLASS_PROPERTY_PREFIX(player, colorset, ISIII, PlayerPawn)
|
||||||
|
{
|
||||||
|
PROP_INT_PARM(setnum, 0);
|
||||||
|
PROP_STRING_PARM(setname, 1);
|
||||||
|
PROP_INT_PARM(rangestart, 2);
|
||||||
|
PROP_INT_PARM(rangeend, 3);
|
||||||
|
PROP_INT_PARM(representative_color, 4);
|
||||||
|
|
||||||
|
FPlayerColorSet color;
|
||||||
|
color.Name = setname;
|
||||||
|
color.Lump = -1;
|
||||||
|
color.FirstColor = rangestart;
|
||||||
|
color.LastColor = rangeend;
|
||||||
|
color.RepresentativeColor = representative_color;
|
||||||
|
|
||||||
|
if (setnum < 0)
|
||||||
|
{
|
||||||
|
bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info->SetColorSet(setnum, &color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
DEFINE_CLASS_PROPERTY_PREFIX(player, colorsetfile, ISSI, PlayerPawn)
|
||||||
|
{
|
||||||
|
PROP_INT_PARM(setnum, 0);
|
||||||
|
PROP_STRING_PARM(setname, 1);
|
||||||
|
PROP_STRING_PARM(rangefile, 2);
|
||||||
|
PROP_INT_PARM(representative_color, 3);
|
||||||
|
|
||||||
|
FPlayerColorSet color;
|
||||||
|
color.Name = setname;
|
||||||
|
color.Lump = Wads.CheckNumForName(rangefile);
|
||||||
|
color.RepresentativeColor = representative_color;
|
||||||
|
if (setnum < 0)
|
||||||
|
{
|
||||||
|
bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n");
|
||||||
|
}
|
||||||
|
else if (color.Lump >= 0)
|
||||||
|
{
|
||||||
|
info->SetColorSet(setnum, &color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
DEFINE_CLASS_PROPERTY_PREFIX(player, clearcolorset, I, PlayerPawn)
|
||||||
|
{
|
||||||
|
PROP_INT_PARM(setnum, 0);
|
||||||
|
|
||||||
|
if (setnum < 0)
|
||||||
|
{
|
||||||
|
bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info->SetColorSet(setnum, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -527,6 +527,10 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
|
|
||||||
case DTA_Translation:
|
case DTA_Translation:
|
||||||
parms->remap = va_arg(tags, FRemapTable *);
|
parms->remap = va_arg(tags, FRemapTable *);
|
||||||
|
if (parms->remap != NULL && parms->remap->Inactive)
|
||||||
|
{ // If it's inactive, pretend we were passed NULL instead.
|
||||||
|
parms->remap = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_ColorOverlay:
|
case DTA_ColorOverlay:
|
||||||
|
|
361
src/v_font.cpp
361
src/v_font.cpp
|
@ -130,7 +130,10 @@ protected:
|
||||||
bool rescale, PalEntry *out_palette);
|
bool rescale, PalEntry *out_palette);
|
||||||
void LoadFON1 (int lump, const BYTE *data);
|
void LoadFON1 (int lump, const BYTE *data);
|
||||||
void LoadFON2 (int lump, const BYTE *data);
|
void LoadFON2 (int lump, const BYTE *data);
|
||||||
|
void LoadBMF (int lump, const BYTE *data);
|
||||||
void CreateFontFromPic (FTextureID picnum);
|
void CreateFontFromPic (FTextureID picnum);
|
||||||
|
|
||||||
|
static int STACK_ARGS BMFCompare(const void *a, const void *b);
|
||||||
};
|
};
|
||||||
|
|
||||||
class FSinglePicFont : public FFont
|
class FSinglePicFont : public FFont
|
||||||
|
@ -175,7 +178,7 @@ protected:
|
||||||
class FFontChar2 : public FTexture
|
class FFontChar2 : public FTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height);
|
FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height, int leftofs=0, int topofs=0);
|
||||||
~FFontChar2 ();
|
~FFontChar2 ();
|
||||||
|
|
||||||
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
||||||
|
@ -261,12 +264,13 @@ FFont *V_GetFont(const char *name)
|
||||||
|
|
||||||
if (lump != -1)
|
if (lump != -1)
|
||||||
{
|
{
|
||||||
char head[3];
|
uint32 head;
|
||||||
{
|
{
|
||||||
FWadLump lumpy = Wads.OpenLumpNum (lump);
|
FWadLump lumpy = Wads.OpenLumpNum (lump);
|
||||||
lumpy.Read (head, 3);
|
lumpy.Read (&head, 4);
|
||||||
}
|
}
|
||||||
if (head[0] == 'F' && head[1] == 'O' && head[2] == 'N')
|
if ((head & MAKE_ID(255,255,255,0)) == MAKE_ID('F','O','N',0) ||
|
||||||
|
head == MAKE_ID(0xE1,0xE6,0xD5,0x1A))
|
||||||
{
|
{
|
||||||
font = new FSingleLumpFont (name, lump);
|
font = new FSingleLumpFont (name, lump);
|
||||||
}
|
}
|
||||||
|
@ -399,21 +403,26 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
||||||
if (charlumps[i] != NULL)
|
if (charlumps[i] != NULL)
|
||||||
{
|
{
|
||||||
Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap);
|
Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap);
|
||||||
|
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Chars[i].Pic = NULL;
|
Chars[i].Pic = NULL;
|
||||||
|
Chars[i].XMove = INT_MIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('N'-first>=0 && 'N'-first<count && Chars['N' - first].Pic)
|
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL)
|
||||||
{
|
{
|
||||||
SpaceWidth = (Chars['N' - first].Pic->GetScaledWidth() + 1) / 2;
|
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SpaceWidth = 4;
|
SpaceWidth = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FixXMoves();
|
||||||
|
|
||||||
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL);
|
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL);
|
||||||
|
|
||||||
delete[] luminosity;
|
delete[] luminosity;
|
||||||
|
@ -717,6 +726,33 @@ FRemapTable *FFont::GetColorTranslation (EColorRange range) const
|
||||||
return &Ranges[range];
|
return &Ranges[range];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FFont :: GetCharCode
|
||||||
|
//
|
||||||
|
// If the character code is in the font, returns it. If it is not, but it
|
||||||
|
// is lowercase and has an uppercase variant present, return that. Otherwise
|
||||||
|
// return -1.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int FFont::GetCharCode(int code, bool needpic) const
|
||||||
|
{
|
||||||
|
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL))
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
if (myislower[code])
|
||||||
|
{
|
||||||
|
code -= 32;
|
||||||
|
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL))
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FFont :: GetChar
|
// FFont :: GetChar
|
||||||
|
@ -725,31 +761,28 @@ FRemapTable *FFont::GetColorTranslation (EColorRange range) const
|
||||||
|
|
||||||
FTexture *FFont::GetChar (int code, int *const width) const
|
FTexture *FFont::GetChar (int code, int *const width) const
|
||||||
{
|
{
|
||||||
if (code < FirstChar ||
|
code = GetCharCode(code, false);
|
||||||
code > LastChar ||
|
int xmove = SpaceWidth;
|
||||||
Chars[code - FirstChar].Pic == NULL)
|
|
||||||
{
|
|
||||||
if (myislower[code])
|
|
||||||
{
|
|
||||||
code -= 32;
|
|
||||||
if (code < FirstChar ||
|
|
||||||
code > LastChar ||
|
|
||||||
Chars[code - FirstChar].Pic == NULL)
|
|
||||||
{
|
|
||||||
if (width != NULL) *width = SpaceWidth;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (width != NULL) *width = SpaceWidth;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (code >= 0)
|
||||||
|
{
|
||||||
code -= FirstChar;
|
code -= FirstChar;
|
||||||
if (width != NULL) *width = Chars[code].Pic->GetScaledWidth();
|
xmove = Chars[code].XMove;
|
||||||
return Chars[code].Pic;
|
if (Chars[code].Pic == NULL)
|
||||||
|
{
|
||||||
|
code = GetCharCode(code + FirstChar, true);
|
||||||
|
if (code >= 0)
|
||||||
|
{
|
||||||
|
code -= FirstChar;
|
||||||
|
xmove = Chars[code].XMove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (width != NULL)
|
||||||
|
{
|
||||||
|
*width = xmove;
|
||||||
|
}
|
||||||
|
return (code < 0) ? NULL : Chars[code].Pic;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -760,27 +793,8 @@ FTexture *FFont::GetChar (int code, int *const width) const
|
||||||
|
|
||||||
int FFont::GetCharWidth (int code) const
|
int FFont::GetCharWidth (int code) const
|
||||||
{
|
{
|
||||||
if (code < FirstChar ||
|
code = GetCharCode(code, false);
|
||||||
code > LastChar ||
|
return (code < 0) ? SpaceWidth : Chars[code - FirstChar].XMove;
|
||||||
Chars[code - FirstChar].Pic == NULL)
|
|
||||||
{
|
|
||||||
if (myislower[code])
|
|
||||||
{
|
|
||||||
code -= 32;
|
|
||||||
if (code < FirstChar ||
|
|
||||||
code > LastChar ||
|
|
||||||
Chars[code - FirstChar].Pic == NULL)
|
|
||||||
{
|
|
||||||
return SpaceWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return SpaceWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Chars[code - FirstChar].Pic->GetScaledWidth();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -858,7 +872,11 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump)
|
||||||
FMemLump data1 = Wads.ReadLump (lump);
|
FMemLump data1 = Wads.ReadLump (lump);
|
||||||
const BYTE *data = (const BYTE *)data1.GetMem();
|
const BYTE *data = (const BYTE *)data1.GetMem();
|
||||||
|
|
||||||
if (data[0] != 'F' || data[1] != 'O' || data[2] != 'N' ||
|
if (data[0] == 0xE1 && data[1] == 0xE6 && data[2] == 0xD5 && data[3] == 0x1A)
|
||||||
|
{
|
||||||
|
LoadBMF(lump, data);
|
||||||
|
}
|
||||||
|
else if (data[0] != 'F' || data[1] != 'O' || data[2] != 'N' ||
|
||||||
(data[3] != '1' && data[3] != '2'))
|
(data[3] != '1' && data[3] != '2'))
|
||||||
{
|
{
|
||||||
I_FatalError ("%s is not a recognizable font", name);
|
I_FatalError ("%s is not a recognizable font", name);
|
||||||
|
@ -1012,6 +1030,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
int destSize = widths2[i] * FontHeight;
|
int destSize = widths2[i] * FontHeight;
|
||||||
|
Chars[i].XMove = widths2[i];
|
||||||
if (destSize <= 0)
|
if (destSize <= 0)
|
||||||
{
|
{
|
||||||
Chars[i].Pic = NULL;
|
Chars[i].Pic = NULL;
|
||||||
|
@ -1045,6 +1064,157 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
|
||||||
delete[] widths2;
|
delete[] widths2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FSingleLumpFont :: LoadBMF
|
||||||
|
//
|
||||||
|
// Loads a BMF font. The file format is described at
|
||||||
|
// <http://bmf.wz.cz/bmf-format.htm>
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FSingleLumpFont::LoadBMF(int lump, const BYTE *data)
|
||||||
|
{
|
||||||
|
const BYTE *chardata;
|
||||||
|
int numchars, count, totalwidth, nwidth;
|
||||||
|
int infolen;
|
||||||
|
int i, chari;
|
||||||
|
BYTE raw_palette[256*3];
|
||||||
|
PalEntry sort_palette[256];
|
||||||
|
PalEntry local_palette[256];
|
||||||
|
double luminosity[256];
|
||||||
|
BYTE identity[256];
|
||||||
|
|
||||||
|
FontHeight = data[5];
|
||||||
|
GlobalKerning = (SBYTE)data[8];
|
||||||
|
ActiveColors = data[16];
|
||||||
|
SpaceWidth = -1;
|
||||||
|
nwidth = -1;
|
||||||
|
|
||||||
|
infolen = data[17 + ActiveColors*3];
|
||||||
|
chardata = data + 18 + ActiveColors*3 + infolen;
|
||||||
|
numchars = chardata[0] + 256*chardata[1];
|
||||||
|
chardata += 2;
|
||||||
|
|
||||||
|
// Scan for lowest and highest characters defined and total font width.
|
||||||
|
FirstChar = 256;
|
||||||
|
LastChar = 0;
|
||||||
|
totalwidth = 0;
|
||||||
|
for (i = chari = 0; i < numchars; ++i, chari += 6 + chardata[chari+1] * chardata[chari+2])
|
||||||
|
{
|
||||||
|
if ((chardata[chari+1] == 0 || chardata[chari+2] == 0) && chardata[chari+5] == 0)
|
||||||
|
{ // Don't count empty characters.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (chardata[chari] < FirstChar)
|
||||||
|
{
|
||||||
|
FirstChar = chardata[chari];
|
||||||
|
}
|
||||||
|
if (chardata[chari] > LastChar)
|
||||||
|
{
|
||||||
|
LastChar = chardata[chari];
|
||||||
|
}
|
||||||
|
totalwidth += chardata[chari+1];
|
||||||
|
}
|
||||||
|
if (LastChar < FirstChar)
|
||||||
|
{
|
||||||
|
I_FatalError("BMF font defines no characters");
|
||||||
|
}
|
||||||
|
count = LastChar - FirstChar + 1;
|
||||||
|
Chars = new CharData[count];
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
Chars[i].Pic = NULL;
|
||||||
|
Chars[i].XMove = INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BMF palettes are only six bits per component. Fix that.
|
||||||
|
for (i = 0; i < ActiveColors*3; ++i)
|
||||||
|
{
|
||||||
|
raw_palette[i] = (data[17 + i] << 2) | (data[17 + i] >> 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the palette by increasing brightness
|
||||||
|
for (i = 0; i < ActiveColors; ++i)
|
||||||
|
{
|
||||||
|
PalEntry *pal = &sort_palette[i];
|
||||||
|
pal->a = i; // Use alpha part to point back to original entry
|
||||||
|
pal->r = raw_palette[i*3 + 0];
|
||||||
|
pal->g = raw_palette[i*3 + 1];
|
||||||
|
pal->b = raw_palette[i*3 + 2];
|
||||||
|
}
|
||||||
|
qsort(sort_palette + 1, ActiveColors - 1, sizeof(PalEntry), BMFCompare);
|
||||||
|
|
||||||
|
// Create the PatchRemap table from the sorted "alpha" values.
|
||||||
|
PatchRemap = new BYTE[ActiveColors];
|
||||||
|
PatchRemap[0] = 0;
|
||||||
|
for (i = 1; i < ActiveColors; ++i)
|
||||||
|
{
|
||||||
|
PatchRemap[sort_palette[i].a] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
FixupPalette(identity, luminosity, raw_palette, true, local_palette);
|
||||||
|
|
||||||
|
// Now scan through the characters again, creating glyphs for each one.
|
||||||
|
for (i = chari = 0; i < numchars; ++i, chari += 6 + chardata[chari+1] * chardata[chari+2])
|
||||||
|
{
|
||||||
|
assert(chardata[chari] - FirstChar >= 0);
|
||||||
|
assert(chardata[chari] - FirstChar < count);
|
||||||
|
if (chardata[chari] == ' ')
|
||||||
|
{
|
||||||
|
SpaceWidth = chardata[chari+5];
|
||||||
|
}
|
||||||
|
else if (chardata[chari] == 'N')
|
||||||
|
{
|
||||||
|
nwidth = chardata[chari+5];
|
||||||
|
}
|
||||||
|
Chars[chardata[chari] - FirstChar].XMove = chardata[chari+5];
|
||||||
|
if (chardata[chari+1] == 0 || chardata[chari+2] == 0)
|
||||||
|
{ // Empty character: skip it.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Chars[chardata[chari] - FirstChar].Pic = new FFontChar2(lump, PatchRemap, int(chardata + chari + 6 - data),
|
||||||
|
chardata[chari+1], // width
|
||||||
|
chardata[chari+2], // height
|
||||||
|
-(SBYTE)chardata[chari+3], // x offset
|
||||||
|
-(SBYTE)chardata[chari+4] // y offset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the font did not define a space character, determine a suitable space width now.
|
||||||
|
if (SpaceWidth < 0)
|
||||||
|
{
|
||||||
|
if (nwidth >= 0)
|
||||||
|
{
|
||||||
|
SpaceWidth = nwidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SpaceWidth = totalwidth * 2 / (3 * count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FixXMoves();
|
||||||
|
BuildTranslations(luminosity, identity, &TranslationParms[0][0], ActiveColors, local_palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FSingleLumpFont :: BMFCompare STATIC
|
||||||
|
//
|
||||||
|
// Helper to sort BMF palettes.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int STACK_ARGS FSingleLumpFont::BMFCompare(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const PalEntry *pa = (const PalEntry *)a;
|
||||||
|
const PalEntry *pb = (const PalEntry *)b;
|
||||||
|
|
||||||
|
return (pa->r * 299 + pa->g * 587 + pa->b * 114) -
|
||||||
|
(pb->r * 299 + pb->g * 587 + pb->b * 114);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FSingleLumpFont :: CheckFON1Chars
|
// FSingleLumpFont :: CheckFON1Chars
|
||||||
|
@ -1069,6 +1239,7 @@ void FSingleLumpFont::CheckFON1Chars (int lump, const BYTE *data, double *lumino
|
||||||
int destSize = SpaceWidth * FontHeight;
|
int destSize = SpaceWidth * FontHeight;
|
||||||
|
|
||||||
Chars[i].Pic = new FFontChar2 (lump, PatchRemap, int(data_p - data), SpaceWidth, FontHeight);
|
Chars[i].Pic = new FFontChar2 (lump, PatchRemap, int(data_p - data), SpaceWidth, FontHeight);
|
||||||
|
Chars[i].XMove = SpaceWidth;
|
||||||
|
|
||||||
// Advance to next char's data and count the used colors.
|
// Advance to next char's data and count the used colors.
|
||||||
do
|
do
|
||||||
|
@ -1181,8 +1352,8 @@ FSinglePicFont::FSinglePicFont(const char *picname)
|
||||||
FTexture *pic = TexMan[picnum];
|
FTexture *pic = TexMan[picnum];
|
||||||
|
|
||||||
Name = copystring(picname);
|
Name = copystring(picname);
|
||||||
FontHeight = pic->GetHeight();
|
FontHeight = pic->GetScaledHeight();
|
||||||
SpaceWidth = pic->GetWidth();
|
SpaceWidth = pic->GetScaledWidth();
|
||||||
GlobalKerning = 0;
|
GlobalKerning = 0;
|
||||||
FirstChar = LastChar = 'A';
|
FirstChar = LastChar = 'A';
|
||||||
ActiveColors = 0;
|
ActiveColors = 0;
|
||||||
|
@ -1332,14 +1503,14 @@ FFontChar1::~FFontChar1 ()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FFontChar2::FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height)
|
FFontChar2::FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height, int leftofs, int topofs)
|
||||||
: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(sourceremap)
|
: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(sourceremap)
|
||||||
{
|
{
|
||||||
UseType = TEX_FontChar;
|
UseType = TEX_FontChar;
|
||||||
Width = width;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
TopOffset = 0;
|
LeftOffset = leftofs;
|
||||||
LeftOffset = 0;
|
TopOffset = topofs;
|
||||||
CalcBitSize ();
|
CalcBitSize ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1427,10 +1598,11 @@ void FFontChar2::MakeTexture ()
|
||||||
FWadLump lump = Wads.OpenLumpNum (SourceLump);
|
FWadLump lump = Wads.OpenLumpNum (SourceLump);
|
||||||
int destSize = Width * Height;
|
int destSize = Width * Height;
|
||||||
BYTE max = 255;
|
BYTE max = 255;
|
||||||
|
bool rle = true;
|
||||||
|
|
||||||
// This is to "fix" bad fonts
|
// This is to "fix" bad fonts
|
||||||
{
|
{
|
||||||
BYTE buff[8];
|
BYTE buff[16];
|
||||||
lump.Read (buff, 4);
|
lump.Read (buff, 4);
|
||||||
if (buff[3] == '2')
|
if (buff[3] == '2')
|
||||||
{
|
{
|
||||||
|
@ -1438,6 +1610,13 @@ void FFontChar2::MakeTexture ()
|
||||||
max = buff[6];
|
max = buff[6];
|
||||||
lump.Seek (SourcePos - 11, SEEK_CUR);
|
lump.Seek (SourcePos - 11, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
else if (buff[3] == 0x1A)
|
||||||
|
{
|
||||||
|
lump.Read(buff, 13);
|
||||||
|
max = buff[12] - 1;
|
||||||
|
lump.Seek (SourcePos - 17, SEEK_CUR);
|
||||||
|
rle = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lump.Seek (SourcePos - 4, SEEK_CUR);
|
lump.Seek (SourcePos - 4, SEEK_CUR);
|
||||||
|
@ -1452,6 +1631,8 @@ void FFontChar2::MakeTexture ()
|
||||||
int dest_adv = Height;
|
int dest_adv = Height;
|
||||||
int dest_rew = destSize - 1;
|
int dest_rew = destSize - 1;
|
||||||
|
|
||||||
|
if (rle)
|
||||||
|
{
|
||||||
for (int y = Height; y != 0; --y)
|
for (int y = Height; y != 0; --y)
|
||||||
{
|
{
|
||||||
for (int x = Width; x != 0; )
|
for (int x = Width; x != 0; )
|
||||||
|
@ -1461,11 +1642,12 @@ void FFontChar2::MakeTexture ()
|
||||||
BYTE color;
|
BYTE color;
|
||||||
|
|
||||||
lump >> color;
|
lump >> color;
|
||||||
*dest_p = MIN (color, max);
|
color = MIN (color, max);
|
||||||
if (SourceRemap != NULL)
|
if (SourceRemap != NULL)
|
||||||
{
|
{
|
||||||
*dest_p = SourceRemap[*dest_p];
|
color = SourceRemap[color];
|
||||||
}
|
}
|
||||||
|
*dest_p = color;
|
||||||
dest_p += dest_adv;
|
dest_p += dest_adv;
|
||||||
x--;
|
x--;
|
||||||
runlen--;
|
runlen--;
|
||||||
|
@ -1502,6 +1684,29 @@ void FFontChar2::MakeTexture ()
|
||||||
}
|
}
|
||||||
dest_p -= dest_rew;
|
dest_p -= dest_rew;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int y = Height; y != 0; --y)
|
||||||
|
{
|
||||||
|
for (int x = Width; x != 0; --x)
|
||||||
|
{
|
||||||
|
BYTE color;
|
||||||
|
lump >> color;
|
||||||
|
if (color > max)
|
||||||
|
{
|
||||||
|
color = max;
|
||||||
|
}
|
||||||
|
if (SourceRemap != NULL)
|
||||||
|
{
|
||||||
|
color = SourceRemap[color];
|
||||||
|
}
|
||||||
|
*dest_p = color;
|
||||||
|
dest_p += dest_adv;
|
||||||
|
}
|
||||||
|
dest_p -= dest_rew;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (destSize < 0)
|
if (destSize < 0)
|
||||||
{
|
{
|
||||||
|
@ -1593,23 +1798,27 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
||||||
if (charlumps[i] != NULL)
|
if (charlumps[i] != NULL)
|
||||||
{
|
{
|
||||||
Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap);
|
Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap);
|
||||||
|
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Chars[i].Pic = NULL;
|
Chars[i].Pic = NULL;
|
||||||
|
Chars[i].XMove = INT_MIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special fonts normally don't have all characters so be careful here!
|
// Special fonts normally don't have all characters so be careful here!
|
||||||
if ('N'-first>=0 && 'N'-first<count && Chars['N' - first].Pic)
|
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL)
|
||||||
{
|
{
|
||||||
SpaceWidth = (Chars['N' - first].Pic->GetScaledWidth() + 1) / 2;
|
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SpaceWidth = 4;
|
SpaceWidth = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FixXMoves();
|
||||||
|
|
||||||
BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors, NULL);
|
BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors, NULL);
|
||||||
|
|
||||||
// add the untranslated colors to the Ranges tables
|
// add the untranslated colors to the Ranges tables
|
||||||
|
@ -1632,6 +1841,36 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
||||||
delete[] charlumps;
|
delete[] charlumps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FFont :: FixXMoves
|
||||||
|
//
|
||||||
|
// If a font has gaps in its characters, set the missing characters'
|
||||||
|
// XMoves to either SpaceWidth or the uppercase variant's XMove. Missing
|
||||||
|
// XMoves must be initialized with INT_MIN beforehand.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FFont::FixXMoves()
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= LastChar - FirstChar; ++i)
|
||||||
|
{
|
||||||
|
if (Chars[i].XMove == INT_MIN)
|
||||||
|
{
|
||||||
|
if (myislower[i + FirstChar])
|
||||||
|
{
|
||||||
|
int upper = i - 32;
|
||||||
|
if (upper >= 0)
|
||||||
|
{
|
||||||
|
Chars[i].XMove = Chars[upper].XMove;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Chars[i].XMove = SpaceWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -94,11 +94,14 @@ public:
|
||||||
int StringWidth (const BYTE *str) const;
|
int StringWidth (const BYTE *str) const;
|
||||||
inline int StringWidth (const char *str) const { return StringWidth ((const BYTE *)str); }
|
inline int StringWidth (const char *str) const { return StringWidth ((const BYTE *)str); }
|
||||||
|
|
||||||
|
int GetCharCode(int code, bool needpic) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FFont ();
|
FFont ();
|
||||||
|
|
||||||
void BuildTranslations (const double *luminosity, const BYTE *identity,
|
void BuildTranslations (const double *luminosity, const BYTE *identity,
|
||||||
const void *ranges, int total_colors, const PalEntry *palette);
|
const void *ranges, int total_colors, const PalEntry *palette);
|
||||||
|
void FixXMoves();
|
||||||
|
|
||||||
static int SimpleTranslation (BYTE *colorsused, BYTE *translation,
|
static int SimpleTranslation (BYTE *colorsused, BYTE *translation,
|
||||||
BYTE *identity, double **luminosity);
|
BYTE *identity, double **luminosity);
|
||||||
|
@ -110,6 +113,7 @@ protected:
|
||||||
struct CharData
|
struct CharData
|
||||||
{
|
{
|
||||||
FTexture *Pic;
|
FTexture *Pic;
|
||||||
|
int XMove;
|
||||||
} *Chars;
|
} *Chars;
|
||||||
int ActiveColors;
|
int ActiveColors;
|
||||||
TArray<FRemapTable> Ranges;
|
TArray<FRemapTable> Ranges;
|
||||||
|
|
|
@ -276,7 +276,7 @@ int FFont::StringWidth (const BYTE *string) const
|
||||||
++string;
|
++string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (*string != '\0')
|
if (*string != '\0')
|
||||||
{
|
{
|
||||||
++string;
|
++string;
|
||||||
}
|
}
|
||||||
|
@ -317,14 +317,15 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string)
|
||||||
FBrokenLines lines[128]; // Support up to 128 lines (should be plenty)
|
FBrokenLines lines[128]; // Support up to 128 lines (should be plenty)
|
||||||
|
|
||||||
const BYTE *space = NULL, *start = string;
|
const BYTE *space = NULL, *start = string;
|
||||||
int i, c, w, nw;
|
size_t i, ii;
|
||||||
|
int c, w, nw;
|
||||||
FString lastcolor, linecolor;
|
FString lastcolor, linecolor;
|
||||||
bool lastWasSpace = false;
|
bool lastWasSpace = false;
|
||||||
int kerning = font->GetDefaultKerning ();
|
int kerning = font->GetDefaultKerning ();
|
||||||
|
|
||||||
i = w = 0;
|
i = w = 0;
|
||||||
|
|
||||||
while ( (c = *string++) && i < 128 )
|
while ( (c = *string++) && i < countof(lines) )
|
||||||
{
|
{
|
||||||
if (c == TEXTCOLOR_ESCAPE)
|
if (c == TEXTCOLOR_ESCAPE)
|
||||||
{
|
{
|
||||||
|
@ -400,7 +401,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// String here is pointing one character after the '\0'
|
// String here is pointing one character after the '\0'
|
||||||
if (i < 128 && --string - start >= 1)
|
if (i < countof(lines) && --string - start >= 1)
|
||||||
{
|
{
|
||||||
const BYTE *s = start;
|
const BYTE *s = start;
|
||||||
|
|
||||||
|
@ -418,11 +419,11 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string)
|
||||||
// Make a copy of the broken lines and return them
|
// Make a copy of the broken lines and return them
|
||||||
FBrokenLines *broken = new FBrokenLines[i+1];
|
FBrokenLines *broken = new FBrokenLines[i+1];
|
||||||
|
|
||||||
for (c = 0; c < i; ++c)
|
for (ii = 0; ii < i; ++ii)
|
||||||
{
|
{
|
||||||
broken[c] = lines[c];
|
broken[ii] = lines[ii];
|
||||||
}
|
}
|
||||||
broken[c].Width = -1;
|
broken[ii].Width = -1;
|
||||||
|
|
||||||
return broken;
|
return broken;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1523,7 +1523,7 @@ CCMD (vid_setmode)
|
||||||
|
|
||||||
void V_Init (void)
|
void V_Init (void)
|
||||||
{
|
{
|
||||||
char *i;
|
const char *i;
|
||||||
int width, height, bits;
|
int width, height, bits;
|
||||||
|
|
||||||
atterm (V_Shutdown);
|
atterm (V_Shutdown);
|
||||||
|
|
|
@ -848,6 +848,46 @@ int FWadCollection::FindLump (const char *name, int *lastlump, bool anyns)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// W_FindLumpMulti
|
||||||
|
//
|
||||||
|
// Find a named lump. Specifically allows duplicates for merging of e.g.
|
||||||
|
// SNDINFO lumps. Returns everything having one of the passed names.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int FWadCollection::FindLumpMulti (const char **names, int *lastlump, bool anyns, int *nameindex)
|
||||||
|
{
|
||||||
|
LumpRecord *lump_p;
|
||||||
|
|
||||||
|
assert(lastlump != NULL && *lastlump >= 0);
|
||||||
|
lump_p = &LumpInfo[*lastlump];
|
||||||
|
while (lump_p < &LumpInfo[NumLumps])
|
||||||
|
{
|
||||||
|
FResourceLump *lump = lump_p->lump;
|
||||||
|
|
||||||
|
if (anyns || lump->Namespace == ns_global)
|
||||||
|
{
|
||||||
|
|
||||||
|
for(const char **name = names; *name != NULL; name++)
|
||||||
|
{
|
||||||
|
if (!strnicmp(*name, lump->Name, 8))
|
||||||
|
{
|
||||||
|
int lump = int(lump_p - &LumpInfo[0]);
|
||||||
|
*lastlump = lump + 1;
|
||||||
|
if (nameindex != NULL) *nameindex = int(name - names);
|
||||||
|
return lump;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lump_p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lastlump = NumLumps;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// W_CheckLumpName
|
// W_CheckLumpName
|
||||||
|
@ -927,6 +967,24 @@ int FWadCollection::GetLumpNamespace (int lump) const
|
||||||
return LumpInfo[lump].lump->Namespace;
|
return LumpInfo[lump].lump->Namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FWadCollection :: GetLumpIndexNum
|
||||||
|
//
|
||||||
|
// Returns the index number for this lump. This is *not* the lump's position
|
||||||
|
// in the lump directory, but rather a special value that RFF can associate
|
||||||
|
// with files. Other archive types will return 0, since they don't have it.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int FWadCollection::GetLumpIndexNum(int lump) const
|
||||||
|
{
|
||||||
|
if ((size_t)lump >= NumLumps)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return LumpInfo[lump].lump->GetIndexNum();
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// W_GetLumpFile
|
// W_GetLumpFile
|
||||||
|
|
|
@ -182,6 +182,7 @@ public:
|
||||||
FileReader * GetFileReader(int wadnum); // Gets a FileReader object to the entire WAD
|
FileReader * GetFileReader(int wadnum); // Gets a FileReader object to the entire WAD
|
||||||
|
|
||||||
int FindLump (const char *name, int *lastlump, bool anyns=false); // [RH] Find lumps with duplication
|
int FindLump (const char *name, int *lastlump, bool anyns=false); // [RH] Find lumps with duplication
|
||||||
|
int FindLumpMulti (const char **names, int *lastlump, bool anyns = false, int *nameindex = NULL); // same with multiple possible names
|
||||||
bool CheckLumpName (int lump, const char *name); // [RH] True if lump's name == name
|
bool CheckLumpName (int lump, const char *name); // [RH] True if lump's name == name
|
||||||
|
|
||||||
static DWORD LumpNameHash (const char *name); // [RH] Create hash key from an 8-char name
|
static DWORD LumpNameHash (const char *name); // [RH] Create hash key from an 8-char name
|
||||||
|
@ -194,6 +195,7 @@ public:
|
||||||
FString GetLumpFullPath (int lump) const; // [RH] Returns wad's name + lump's full name
|
FString GetLumpFullPath (int lump) const; // [RH] Returns wad's name + lump's full name
|
||||||
int GetLumpFile (int lump) const; // [RH] Returns wadnum for a specified lump
|
int GetLumpFile (int lump) const; // [RH] Returns wadnum for a specified lump
|
||||||
int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to
|
int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to
|
||||||
|
int GetLumpIndexNum (int lump) const; // Returns the RFF index number for this lump
|
||||||
bool CheckLumpName (int lump, const char *name) const; // [RH] Returns true if the names match
|
bool CheckLumpName (int lump, const char *name) const; // [RH] Returns true if the names match
|
||||||
|
|
||||||
bool IsUncompressedFile(int lump) const;
|
bool IsUncompressedFile(int lump) const;
|
||||||
|
|
|
@ -1935,15 +1935,13 @@ void WI_loadData(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int dummywidth;
|
star = BigFont->GetChar('*', NULL);
|
||||||
star = BigFont->GetChar('*', &dummywidth); // just a dummy to avoid an error if it is being used
|
|
||||||
bstar = star;
|
bstar = star;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Strife needs some handling, too!
|
else // Strife needs some handling, too!
|
||||||
{
|
{
|
||||||
int dummywidth;
|
star = BigFont->GetChar('*', NULL);
|
||||||
star = BigFont->GetChar('*', &dummywidth); // just a dummy to avoid an error if it is being used
|
|
||||||
bstar = star;
|
bstar = star;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -503,6 +503,71 @@ void __cdecl Writef (HANDLE file, const char *format, ...)
|
||||||
WriteFile (file, buffer, len, &len, NULL);
|
WriteFile (file, buffer, len, &len, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// WriteLogFileStreamer
|
||||||
|
//
|
||||||
|
// The callback function to stream a Rich Edit's contents to a file.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static DWORD CALLBACK WriteLogFileStreamer(DWORD_PTR cookie, LPBYTE buffer, LONG cb, LONG *pcb)
|
||||||
|
{
|
||||||
|
DWORD didwrite;
|
||||||
|
LONG p, pp;
|
||||||
|
|
||||||
|
// Replace gray foreground color with black.
|
||||||
|
static const char *badfg = "\\red223\\green223\\blue223;";
|
||||||
|
// 4321098 765432109 876543210
|
||||||
|
// 2 1 0
|
||||||
|
for (p = pp = 0; p < cb; ++p)
|
||||||
|
{
|
||||||
|
if (buffer[p] == badfg[pp])
|
||||||
|
{
|
||||||
|
++pp;
|
||||||
|
if (pp == 25)
|
||||||
|
{
|
||||||
|
buffer[p - 1] = buffer[p - 2] = buffer[p - 3] =
|
||||||
|
buffer[p - 9] = buffer[p -10] = buffer[p -11] =
|
||||||
|
buffer[p -18] = buffer[p -19] = buffer[p -20] = '0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WriteFile((HANDLE)cookie, buffer, cb, &didwrite, NULL))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
*pcb = didwrite;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// WriteLogFile
|
||||||
|
//
|
||||||
|
// Writes the contents of a Rich Edit control to a file.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
HANDLE WriteLogFile(HWND edit)
|
||||||
|
{
|
||||||
|
HANDLE file;
|
||||||
|
|
||||||
|
file = CreateTempFile();
|
||||||
|
if (file != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
EDITSTREAM streamer = { (DWORD_PTR)file, 0, WriteLogFileStreamer };
|
||||||
|
SendMessage(edit, EM_STREAMOUT, SF_RTF, (LPARAM)&streamer);
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// CreateCrashLog
|
// CreateCrashLog
|
||||||
|
@ -511,7 +576,7 @@ void __cdecl Writef (HANDLE file, const char *format, ...)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void CreateCrashLog (char *custominfo, DWORD customsize)
|
void CreateCrashLog (char *custominfo, DWORD customsize, HWND richlog)
|
||||||
{
|
{
|
||||||
// Do not collect information more than once.
|
// Do not collect information more than once.
|
||||||
if (NumFiles != 0)
|
if (NumFiles != 0)
|
||||||
|
@ -561,6 +626,10 @@ void CreateCrashLog (char *custominfo, DWORD customsize)
|
||||||
AddFile (file, "local.txt");
|
AddFile (file, "local.txt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (richlog != NULL)
|
||||||
|
{
|
||||||
|
AddFile (WriteLogFile(richlog), "log.rtf");
|
||||||
|
}
|
||||||
CloseHandle (DbgProcess);
|
CloseHandle (DbgProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1984,7 +2053,6 @@ static INT_PTR CALLBACK CrashDlgProc (HWND hDlg, UINT message, WPARAM wParam, LP
|
||||||
|
|
||||||
static INT_PTR CALLBACK DetailsDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
static INT_PTR CALLBACK DetailsDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
HGDIOBJ font;
|
|
||||||
HWND ctrl;
|
HWND ctrl;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
@ -1996,15 +2064,9 @@ static INT_PTR CALLBACK DetailsDlgProc (HWND hDlg, UINT message, WPARAM wParam,
|
||||||
pEnableThemeDialogTexture (hDlg, ETDT_ENABLETAB);
|
pEnableThemeDialogTexture (hDlg, ETDT_ENABLETAB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the file contents display: Use a fixed width font,
|
// Set up the file contents display: No undos. The control's
|
||||||
// no undos. The control's userdata stores the index of the
|
// userdata stores the index of the file currently displayed.
|
||||||
// file currently displayed.
|
|
||||||
ctrl = GetDlgItem (hDlg, IDC_CRASHFILECONTENTS);
|
ctrl = GetDlgItem (hDlg, IDC_CRASHFILECONTENTS);
|
||||||
font = GetStockObject (ANSI_FIXED_FONT);
|
|
||||||
if (font != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
SendMessage (ctrl, WM_SETFONT, (WPARAM)font, FALSE);
|
|
||||||
}
|
|
||||||
SendMessage (ctrl, EM_SETUNDOLIMIT, 0, 0);
|
SendMessage (ctrl, EM_SETUNDOLIMIT, 0, 0);
|
||||||
SetWindowLongPtr (ctrl, GWLP_USERDATA, -1);
|
SetWindowLongPtr (ctrl, GWLP_USERDATA, -1);
|
||||||
SetEditControl (ctrl, GetDlgItem(hDlg, IDC_CRASHFILESIZE), 0);
|
SetEditControl (ctrl, GetDlgItem(hDlg, IDC_CRASHFILESIZE), 0);
|
||||||
|
@ -2178,6 +2240,8 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum)
|
||||||
EDITSTREAM stream;
|
EDITSTREAM stream;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
POINT pt = { 0, 0 };
|
POINT pt = { 0, 0 };
|
||||||
|
const char *rtf = NULL;
|
||||||
|
HGDIOBJ font;
|
||||||
|
|
||||||
// Don't refresh the control if it's already showing the file we want.
|
// Don't refresh the control if it's already showing the file we want.
|
||||||
if (GetWindowLongPtr (edit, GWLP_USERDATA) == filenum)
|
if (GetWindowLongPtr (edit, GWLP_USERDATA) == filenum)
|
||||||
|
@ -2201,10 +2265,19 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum)
|
||||||
SetFilePointer (TarFiles[filenum].File, 0, NULL, FILE_BEGIN);
|
SetFilePointer (TarFiles[filenum].File, 0, NULL, FILE_BEGIN);
|
||||||
SendMessage (edit, EM_SETSCROLLPOS, 0, (LPARAM)&pt);
|
SendMessage (edit, EM_SETSCROLLPOS, 0, (LPARAM)&pt);
|
||||||
|
|
||||||
|
// Set the font now, in case log.rtf was previously viewed, because
|
||||||
|
// that file changes it.
|
||||||
|
font = GetStockObject (ANSI_FIXED_FONT);
|
||||||
|
if (font != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
SendMessage (edit, WM_SETFONT, (WPARAM)font, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
// Text files are streamed in as-is.
|
// Text files are streamed in as-is.
|
||||||
// Binary files are streamed in as color-coded hex dumps.
|
// Binary files are streamed in as color-coded hex dumps.
|
||||||
stream.dwError = 0;
|
stream.dwError = 0;
|
||||||
if (strstr (TarFiles[filenum].Filename, ".txt") != NULL)
|
if (strstr (TarFiles[filenum].Filename, ".txt") != NULL ||
|
||||||
|
(rtf = strstr (TarFiles[filenum].Filename, ".rtf")) != NULL)
|
||||||
{
|
{
|
||||||
CHARFORMAT beBlack;
|
CHARFORMAT beBlack;
|
||||||
|
|
||||||
|
@ -2215,7 +2288,7 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum)
|
||||||
SendMessage (edit, EM_SETCHARFORMAT, 0, (LPARAM)&beBlack);
|
SendMessage (edit, EM_SETCHARFORMAT, 0, (LPARAM)&beBlack);
|
||||||
stream.dwCookie = (DWORD_PTR)TarFiles[filenum].File;
|
stream.dwCookie = (DWORD_PTR)TarFiles[filenum].File;
|
||||||
stream.pfnCallback = StreamEditText;
|
stream.pfnCallback = StreamEditText;
|
||||||
SendMessage (edit, EM_STREAMIN, SF_TEXT, (LPARAM)&stream);
|
SendMessage (edit, EM_STREAMIN, rtf ? SF_RTF : SF_TEXT | SF_USECODEPAGE | (1252 << 16), (LPARAM)&stream);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue