Merge branch 'EOL-10' into EOL

This commit is contained in:
Alam Ed Arias 2018-11-27 20:44:28 -05:00
commit 0646e96c77
26 changed files with 437 additions and 338 deletions

View file

@ -275,8 +275,7 @@ void B_RespawnBot(INT32 playernum)
player->accelstart = sonic->player->accelstart;
player->thrustfactor = sonic->player->thrustfactor;
player->normalspeed = sonic->player->normalspeed;
player->pflags |= PF_AUTOBRAKE;
player->pflags &= ~PF_DIRECTIONCHAR;
player->pflags |= PF_AUTOBRAKE|(sonic->player->pflags & PF_DIRECTIONCHAR);
P_TeleportMove(tails, x, y, z);
if (player->charability == CA_FLY)

View file

@ -2256,7 +2256,7 @@ static void Command_connect(void)
// Assume we connect directly.
boolean viams = false;
if (COM_Argc() < 2)
if (COM_Argc() < 2 || *COM_Argv(1) == 0)
{
CONS_Printf(M_GetText(
"Connect <serveraddress> (port): connect to a server\n"

View file

@ -734,11 +734,6 @@ void D_StartTitle(void)
CON_ToggleOff();
// Reset the palette
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_SetPaletteColor(0);
else
#endif
if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL");
}
@ -1049,7 +1044,7 @@ void D_SRB2Main(void)
// add any files specified on the command line with -file wadfile
// to the wad list
if (!(M_CheckParm("-connect")))
if (!(M_CheckParm("-connect") && !M_CheckParm("-server")))
{
if (M_CheckParm("-file"))
{
@ -1125,11 +1120,11 @@ void D_SRB2Main(void)
#ifndef DEVELOP // md5s last updated 12/14/14
// Check MD5s of autoloaded files
W_VerifyFileMD5(0, ASSET_HASH_SRB2_PK3); // srb2.pk3
W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
//W_VerifyFileMD5(0, ASSET_HASH_SRB2_PK3); // srb2.pk3
//W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
//W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
#ifdef USE_PATCH_DTA
W_VerifyFileMD5(3, ASSET_HASH_PATCH_PK3); // patch.pk3
//W_VerifyFileMD5(3, ASSET_HASH_PATCH_PK3); // patch.pk3
#endif
// don't check music.dta because people like to modify it, and it doesn't matter if they do
@ -1204,7 +1199,15 @@ void D_SRB2Main(void)
R_Init();
// setting up sound
CONS_Printf("S_Init(): Setting up sound.\n");
if (dedicated)
{
nosound = true;
nomidimusic = nodigimusic = true;
}
else
{
CONS_Printf("S_Init(): Setting up sound.\n");
}
if (M_CheckParm("-nosound"))
nosound = true;
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
@ -1316,7 +1319,7 @@ void D_SRB2Main(void)
}
}
if (autostart || netgame || M_CheckParm("+connect") || M_CheckParm("-connect"))
if (autostart || netgame)
{
gameaction = ga_nothing;
@ -1350,8 +1353,7 @@ void D_SRB2Main(void)
}
}
if (server && !M_CheckParm("+map") && !M_CheckParm("+connect")
&& !M_CheckParm("-connect"))
if (server && !M_CheckParm("+map"))
{
// Prevent warping to nonexistent levels
if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR)

View file

@ -3929,28 +3929,7 @@ static void Command_ExitLevel_f(void)
else if (gamestate != GS_LEVEL || demoplayback)
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
else
{
if ((netgame || multiplayer)
&& ((mapheaderinfo[gamemap-1]->nextlevel <= 0)
|| (mapheaderinfo[gamemap-1]->nextlevel > NUMMAPS)
|| !(mapvisited[mapheaderinfo[gamemap-1]->nextlevel-1])))
{
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && players[i].exiting)
break;
}
if (i == MAXPLAYERS)
{
CONS_Printf(M_GetText("Someone must finish the level for you to use this.\n"));
return;
}
}
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
}
}
static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)

View file

@ -950,15 +950,37 @@ filestatus_t checkfilemd5(char *filename, const UINT8 *wantedmd5sum)
return FS_FOUND; // will never happen, but makes the compiler shut up
}
// Rewritten by Monster Iestyn to be less stupid
// Note: if completepath is true, "filename" is modified, but only if FS_FOUND is going to be returned
// (Don't worry about WinCE's version of filesearch, nobody cares about that OS anymore)
filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean completepath)
{
filestatus_t homecheck = filesearch(filename, srb2home, wantedmd5sum, false, 10);
if (homecheck == FS_FOUND)
return filesearch(filename, srb2home, wantedmd5sum, completepath, 10);
filestatus_t homecheck; // store result of last file search
boolean badmd5 = false; // store whether md5 was bad from either of the first two searches (if nothing was found in the third)
homecheck = filesearch(filename, srb2path, wantedmd5sum, false, 10);
if (homecheck == FS_FOUND)
return filesearch(filename, srb2path, wantedmd5sum, completepath, 10);
// first, check SRB2's "home" directory
homecheck = filesearch(filename, srb2home, wantedmd5sum, completepath, 10);
return filesearch(filename, ".", wantedmd5sum, completepath, 10);
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
return FS_FOUND;
else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5
badmd5 = true;
// if not found at all, just move on without doing anything
// next, check SRB2's "path" directory
homecheck = filesearch(filename, srb2path, wantedmd5sum, completepath, 10);
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
return FS_FOUND;
else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5
badmd5 = true;
// if not found at all, just move on without doing anything
// finally check "." directory
homecheck = filesearch(filename, ".", wantedmd5sum, completepath, 10);
if (homecheck != FS_NOTFOUND) // if not found this time, fall back on the below return statement
return homecheck; // otherwise return the result we got
return (badmd5 ? FS_MD5SUMBAD : FS_NOTFOUND); // md5 sum bad or file not found
}

View file

@ -4391,12 +4391,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Gravity Wells for special stages
"S_GRAVWELLGREEN",
"S_GRAVWELLGREEN2",
"S_GRAVWELLGREEN3",
"S_GRAVWELLRED",
"S_GRAVWELLRED2",
"S_GRAVWELLRED3",
// Individual Team Rings
"S_TEAMRING",
@ -4701,6 +4696,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_THUNDERCOIN_ICON1",
"S_THUNDERCOIN_ICON2",
// ---
"S_ROCKET",
"S_LASER",
@ -6080,7 +6077,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_SHLEEPBOUNCE2",
"S_SHLEEPBOUNCE3",
// Secret badniks and hazards, shhhh
"S_PENGUINATOR_LOOK",
"S_PENGUINATOR_WADDLE1",

View file

@ -3025,7 +3025,7 @@ static void G_DoCompleted(void)
token--;
for (i = 0; i < 7; i++)
if (!(emeralds & i))
if (!(emeralds & (1<<i)))
{
nextmap = ((netgame || multiplayer) ? smpstage_start : sstage_start) + i - 1; // to special stage!
break;
@ -3204,7 +3204,7 @@ void G_LoadGameSettings(void)
// defaults
spstage_start = 1;
sstage_start = smpstage_start = 50;
sstage_end = smpstage_end = 57; // 7 special stages in vanilla SRB2
sstage_end = smpstage_end = 56; // 7 special stages in vanilla SRB2
sstage_end++; // plus one weirdo
// initialize free sfx slots for skin sounds
@ -3811,7 +3811,8 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
unlocktriggers = 0;
// clear itemfinder, just in case
CV_StealthSetValue(&cv_itemfinder, 0);
if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds
CV_StealthSetValue(&cv_itemfinder, 0);
}
// internal game map

View file

@ -68,7 +68,6 @@ typedef struct gr_vissprite_s
struct gr_vissprite_s *prev;
struct gr_vissprite_s *next;
float x1, x2;
float z1, z2;
float tz, ty;
lumpnum_t patchlumpnum;
boolean flip;
@ -79,6 +78,7 @@ typedef struct gr_vissprite_s
//Hurdler: 25/04/2000: now support colormap in hardware mode
UINT8 *colormap;
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
float z1, z2;
} gr_vissprite_t;
// --------

View file

@ -3032,8 +3032,8 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
return gld_clipper_SafeCheckRange(angle2, angle1);
#else
// check clip list for an open space
angle1 = R_PointToAngle(px1, py1) - dup_viewangle;
angle2 = R_PointToAngle(px2, py2) - dup_viewangle;
angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle;
angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle;
span = angle1 - angle2;
@ -4359,6 +4359,9 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
i = 0;
temp = FLOAT_TO_FIXED(realtop);
if (spr->mobj->frame & FF_FULLBRIGHT)
lightlevel = 255;
#ifdef ESLOPE
for (i = 1; i < sector->numlights; i++)
{
@ -4366,14 +4369,16 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
: sector->lightlist[i].height;
if (h <= temp)
{
lightlevel = *list[i-1].lightlevel;
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *list[i-1].lightlevel;
colormap = list[i-1].extra_colormap;
break;
}
}
#else
i = R_GetPlaneLight(sector, temp, false);
lightlevel = *list[i].lightlevel;
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *list[i].lightlevel;
colormap = list[i].extra_colormap;
#endif
@ -4388,7 +4393,8 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
// even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite
if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES))
{
lightlevel = *list[i].lightlevel;
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *list[i].lightlevel;
colormap = list[i].extra_colormap;
}
@ -5305,7 +5311,6 @@ static void HWR_ProjectSprite(mobj_t *thing)
float tr_x, tr_y;
float tz;
float x1, x2;
float z1, z2;
float rightsin, rightcos;
float this_scale;
float gz, gzt;
@ -5320,9 +5325,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
INT32 heightsec, phs;
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
angle_t mobjangle = (thing->player ? thing->player->drawangle : thing->angle);
// float offset;
// float ang_scale = 1.0f, ang_scalez = 0.0f;
// float z1, z2;
float z1, z2;
if (!thing)
return;
@ -5377,28 +5380,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
#endif
if (papersprite)
{
// Use the actual view angle, rather than the angle formed
// between the view point and the thing
// this makes sure paper sprites always appear at the right angle!
// Note: DO NOT do this in software mode version, it actually
// makes papersprites look WORSE there (I know, I've tried)
// Monster Iestyn - 13/05/17
ang = dup_viewangle - mobjangle;
/*
ang_scale = FIXED_TO_FLOAT(FINESINE(ang>>ANGLETOFINESHIFT));
ang_scalez = FIXED_TO_FLOAT(FINECOSINE(ang>>ANGLETOFINESHIFT));
if (ang_scale < 0)
{
ang_scale = -ang_scale;
ang_scalez = -ang_scalez;
}
*/
}
else if (sprframe->rotate != SRF_SINGLE)
ang = R_PointToAngle (thing->x, thing->y) - mobjangle;
ang = R_PointToAngle (thing->x, thing->y) - mobjangle;
if (sprframe->rotate == SRF_SINGLE)
{
@ -5406,6 +5388,14 @@ static void HWR_ProjectSprite(mobj_t *thing)
rot = 0; //Fab: for vis->patch below
lumpoff = sprframe->lumpid[0]; //Fab: see note above
flip = sprframe->flip; // Will only be 0x00 or 0xFF
if (papersprite && ang < ANGLE_180)
{
if (flip)
flip = 0;
else
flip = 255;
}
}
else
{
@ -5420,20 +5410,23 @@ static void HWR_ProjectSprite(mobj_t *thing)
//Fab: lumpid is the index for spritewidth,spriteoffset... tables
lumpoff = sprframe->lumpid[rot];
flip = sprframe->flip & (1<<rot);
if (papersprite && ang < ANGLE_180)
{
if (flip)
flip = 0;
else
flip = 1<<rot;
}
}
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale);
if (papersprite) // replaces the ang_scale and scalez thing above
if (papersprite)
{
rightsin = FIXED_TO_FLOAT(FINESINE(mobjangle>>ANGLETOFINESHIFT));
rightcos = FIXED_TO_FLOAT(FINECOSINE(mobjangle>>ANGLETOFINESHIFT));
if (flip) // flip the signs of the above values so you don't end up displaying the sprite backwards
{
rightsin *= -1.0;
rightcos *= -1.0;
}
rightsin = FIXED_TO_FLOAT(FINESINE((mobjangle)>>ANGLETOFINESHIFT));
rightcos = FIXED_TO_FLOAT(FINECOSINE((mobjangle)>>ANGLETOFINESHIFT));
}
else
{
@ -5505,13 +5498,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis = HWR_NewVisSprite();
vis->x1 = x1;
vis->x2 = x2;
vis->z1 = z1;
vis->z2 = z2;
vis->tz = tz; // Keep tz for the simple sprite sorting that happens
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
vis->patchlumpnum = sprframe->lumppat[rot];
vis->flip = flip;
vis->mobj = thing;
vis->z1 = z1;
vis->z2 = z2;
//Hurdler: 25/04/2000: now support colormap in hardware mode
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"

View file

@ -723,12 +723,12 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_MLEL, 35, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_MELEE_LANDING
// SF_SUPER
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS1
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_ANIMATE, 7, {NULL}, 0, 4, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS1
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 20, {A_FadeOverlay}, 0, 0, S_PLAY_FLOAT}, // S_PLAY_SUPER_TRANS6
{SPR_PLAY, SPR2_TRNS|FF_SPR2SUPER|FF_FULLBRIGHT, 19, {A_FadeOverlay}, 0, 0, S_PLAY_FALL}, // S_PLAY_SUPER_TRANS6
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY
@ -743,12 +743,12 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN
// NiGHTS Player, transforming
{SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS1
{SPR_PLAY, SPR2_TRNS|FF_ANIMATE, 7, {NULL}, 0, 4, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS1
{SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS3}, // S_PLAY_NIGHTS_TRANS2
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS4}, // S_PLAY_NIGHTS_TRANS3
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS5}, // S_PLAY_NIGHTS_TRANS4
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 25, {A_FadeOverlay}, 4, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS5
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 21, {A_FadeOverlay}, 2, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS5
// NiGHTS Player, stand, float, pain, pull and attack
{SPR_PLAY, SPR2_NSTD, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_STAND}, // S_PLAY_NIGHTS_STAND
@ -1736,14 +1736,14 @@ state_t states[NUMSTATES] =
{SPR_SIGN, 7, -1, {A_SignPlayer}, 0, 0, S_NULL}, // S_SIGN53 Blank
// Spike Ball
{SPR_SPIK, 0, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL2}, // S_SPIKEBALL1
{SPR_SPIK, 1, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL3}, // S_SPIKEBALL2
{SPR_SPIK, 2, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL4}, // S_SPIKEBALL3
{SPR_SPIK, 3, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL5}, // S_SPIKEBALL4
{SPR_SPIK, 4, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL6}, // S_SPIKEBALL5
{SPR_SPIK, 5, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL7}, // S_SPIKEBALL6
{SPR_SPIK, 6, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL8}, // S_SPIKEBALL7
{SPR_SPIK, 7, 1, {A_RotateSpikeBall}, 0, 0, S_SPIKEBALL1}, // S_SPIKEBALL8
{SPR_SPIK, 0, 1, {NULL}, 0, 0, S_SPIKEBALL2}, // S_SPIKEBALL1
{SPR_SPIK, 1, 1, {NULL}, 0, 0, S_SPIKEBALL3}, // S_SPIKEBALL2
{SPR_SPIK, 2, 1, {NULL}, 0, 0, S_SPIKEBALL4}, // S_SPIKEBALL3
{SPR_SPIK, 3, 1, {NULL}, 0, 0, S_SPIKEBALL5}, // S_SPIKEBALL4
{SPR_SPIK, 4, 1, {NULL}, 0, 0, S_SPIKEBALL6}, // S_SPIKEBALL5
{SPR_SPIK, 5, 1, {NULL}, 0, 0, S_SPIKEBALL7}, // S_SPIKEBALL6
{SPR_SPIK, 6, 1, {NULL}, 0, 0, S_SPIKEBALL8}, // S_SPIKEBALL7
{SPR_SPIK, 7, 1, {NULL}, 0, 0, S_SPIKEBALL1}, // S_SPIKEBALL8
// Elemental Shield's Spawn
{SPR_SFLM, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SPINFIRE2}, // S_SPINFIRE1
@ -2145,7 +2145,7 @@ state_t states[NUMSTATES] =
{SPR_FLMH, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FLAMEHOLDER
{SPR_CTRC, FF_FULLBRIGHT|FF_ANIMATE, 8*3, {A_FlameParticle}, 3, 3, S_NULL}, // S_FIRETORCH
{SPR_CTRC, FF_FULLBRIGHT|FF_ANIMATE, 8*3, {A_FlameParticle}, 3, 3, S_FIRETORCH}, // S_FIRETORCH
{SPR_CFLG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_WAVINGFLAG
{SPR_CFLG, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_WAVINGFLAGSEG
@ -10505,7 +10505,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
MT_FLAMEPARTICLE, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
@ -10513,7 +10513,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
24*FRACUNIT, // radius
16*FRACUNIT, // radius
80*FRACUNIT, // height
0, // display offset
100, // mass
@ -10546,7 +10546,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_PUSHABLE, // flags
MF_SOLID, // flags
S_NULL // raisestate
},
@ -10573,7 +10573,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
@ -11686,7 +11686,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_FHZICE2
4029, // doomednum
S_FHZICE1, // spawnstate
S_FHZICE2, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound

View file

@ -33,7 +33,9 @@
*/
fixed_t FixedMul(fixed_t a, fixed_t b)
{
return (fixed_t)((((INT64)a * b) ) / FRACUNIT);
// Need to cast to unsigned before shifting to avoid undefined behaviour
// for negative integers
return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS);
}
#endif //__USE_C_FIXEDMUL__

View file

@ -8452,6 +8452,13 @@ Update the maxplayers label...
static void M_ConnectIP(INT32 choice)
{
(void)choice;
if (*setupm_ip == 0)
{
M_StartMessage("You must specify an IP address.\n", NULL, MM_NOTHING);
return;
}
COM_BufAddText(va("connect \"%s\"\n", setupm_ip));
// A little "please wait" message.

View file

@ -5298,9 +5298,6 @@ void A_RotateSpikeBall(mobj_t *actor)
return;
#endif
if (actor->type == MT_SPIKEBALL) // don't remove this, these spikeballs share the same states as the rotating spikeballs
return;
if (!((!locvar1 && (actor->target)) || (locvar1 && (actor->tracer))))// This should NEVER happen.
{
CONS_Debug(DBG_GAMELOGIC, "A_RotateSpikeBall: Spikeball has no target\n");

View file

@ -2144,6 +2144,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
boolean floortouch = false;
fixed_t bottomheight, topheight;
msecnode_t *node;
ffloor_t *rover;
for (i = 0; i < MAXPLAYERS; i++)
{
@ -2191,6 +2192,19 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
{
targetsec = &sectors[targetsecnum];
// Find the FOF corresponding to the control linedef
for (rover = targetsec->ffloors; rover; rover = rover->next)
{
if (rover->master == sec->lines[i])
break;
}
if (!rover) // This should be impossible, but don't complain if it is the case somehow
continue;
if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there
continue;
for (j = 0; j < MAXPLAYERS; j++)
{
if (!playeringame[j])

View file

@ -105,10 +105,10 @@ void P_ClearStarPost(INT32 postnum)
mo2 = (mobj_t *)th;
if (mo2->type != MT_STARPOST)
return;
continue;
if (mo2->health > postnum)
return;
continue;
P_SetMobjState(mo2, mo2->info->seestate);
}

View file

@ -391,8 +391,8 @@ springstate:
P_SetMobjState(spring, spring->info->raisestate);
if (object->player && spring->reactiontime && !(spring->info->flags & MF_ENEMY))
{
mobj_t *scoremobj = P_SpawnMobj(spring->x, spring->y, spring->z + (spring->height/2), MT_SCORE);
P_SetMobjState(scoremobj, mobjinfo[MT_SCORE].spawnstate+11);
if (object->player->powers[pw_carry] != CR_NIGHTSMODE) // don't make graphic in NiGHTS
P_SetMobjState(P_SpawnMobj(spring->x, spring->y, spring->z + (spring->height/2), MT_SCORE), mobjinfo[MT_SCORE].spawnstate+11);
P_AddPlayerScore(object->player, 10);
spring->reactiontime--;
}

View file

@ -7540,6 +7540,8 @@ void P_MobjThinker(mobj_t *mobj)
{
if (!mobj->target || P_MobjWasRemoved(mobj->target))
{
if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer))
P_RemoveMobj(mobj->tracer);
P_RemoveMobj(mobj);
return;
}
@ -7547,6 +7549,12 @@ void P_MobjThinker(mobj_t *mobj)
if (!(mobj->eflags & MFE_VERTICALFLIP))
mobj->z += mobj->target->height;
}
if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer))
{
mobj->tracer->z = mobj->z + P_MobjFlip(mobj)*20*mobj->scale;
if (mobj->eflags & MFE_VERTICALFLIP)
mobj->tracer->z += mobj->height;
}
break;
case MT_WAVINGFLAG:
{
@ -8692,29 +8700,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
}
}
break;
case MT_CANDLE:
case MT_CANDLEPRICKET:
{
// Fake corona!!
mobj_t *corona = P_SpawnMobjFromMobj(mobj, 0, 0, ((mobj->type == MT_CANDLE) ? 40 : 176)<<FRACBITS, MT_PARTICLE);
//P_SetTarget(&corona->tracer, mobj);
//corona->flags2 |= MF2_LINKDRAW; -- crash??????? can't debug right now...
corona->sprite = SPR_FLAM;
corona->frame = (FF_FULLBRIGHT|FF_TRANS90|12);
corona->tics = -1;
if (mobj->type == MT_CANDLE)
P_SetScale(corona, (corona->destscale = mobj->scale*3));
}
break;
case MT_JACKO1:
case MT_JACKO2:
case MT_JACKO3:
{
mobj_t *overlay = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY);
P_SetTarget(&overlay->target, mobj);
P_SetMobjState(overlay, mobj->info->raisestate);
}
break;
case MT_EGGMOBILE2:
// Special condition for the 2nd boss.
mobj->watertop = mobj->info->speed;
@ -8753,6 +8738,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_NIGHTSDRONE:
if (G_IsSpecialStage(gamemap))
mobj->flags2 |= MF2_DONTDRAW;
nummaprings = -1; // no perfect bonus, rings are free
break;
case MT_EGGCAPSULE:
mobj->extravalue1 = -1; // timer for how long a player has been at the capsule
@ -8765,7 +8751,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break;
case MT_RING:
case MT_COIN:
nummaprings++;
case MT_NIGHTSSTAR:
if (nummaprings >= 0)
nummaprings++;
default:
break;
}
@ -8899,6 +8887,7 @@ void P_RemoveMobj(mobj_t *mobj)
if (mobj->spawnpoint &&
(mobj->type == MT_RING
|| mobj->type == MT_COIN
|| mobj->type == MT_NIGHTSSTAR
|| mobj->type == MT_REDTEAMRING
|| mobj->type == MT_BLUETEAMRING
|| P_WeaponOrPanel(mobj->type))
@ -9302,7 +9291,7 @@ void P_RespawnSpecials(void)
#endif
ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT;
if (mthing->options & MTF_AMBUSH
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i)))
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || i == MT_NIGHTSSTAR || P_WeaponOrPanel(i)))
z -= 24*FRACUNIT;
z -= mobjinfo[i].height; // Don't forget the height!
}
@ -9314,7 +9303,7 @@ void P_RespawnSpecials(void)
#endif
ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT;
if (mthing->options & MTF_AMBUSH
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i)))
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || i == MT_NIGHTSSTAR || P_WeaponOrPanel(i)))
z += 24*FRACUNIT;
}
@ -9713,19 +9702,21 @@ void P_SpawnMapThing(mapthing_t *mthing)
else if (mthing->type == 750) // Slope vertex point (formerly chaos spawn)
return;
else if (mthing->type == 300 // Ring
|| mthing->type == 308 || mthing->type == 309 // Team Rings
|| mthing->type == 1706 // Nights Wing
|| (mthing->type >= 600 && mthing->type <= 609) // Placement patterns
|| mthing->type == 1705 || mthing->type == 1713 // NiGHTS Hoops
|| mthing->type == 1800) // Mario Coin
else if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum
|| mthing->type == mobjinfo[MT_REDTEAMRING].doomednum || mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum
|| mthing->type == mobjinfo[MT_BLUESPHERE].doomednum || mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum
|| (mthing->type >= 600 && mthing->type <= 609) // circles and diagonals
|| mthing->type == 1705 || mthing->type == 1713 || mthing->type == 1800) // hoops
{
// Don't spawn hoops, wings, or rings yet!
return;
}
// check for players specially
if (mthing->type > 0 && mthing->type <= 32)
#if MAXPLAYERS > 32
You should think about modifying the deathmatch starts to take full advantage of this!
#endif
if (mthing->type > 0 && mthing->type <= MAXPLAYERS)
{
// save spots for respawning in network games
if (!metalrecording)
@ -9841,9 +9832,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
if (gametype != GT_CTF) // CTF specific things
{
if (i == MT_BLUETEAMRING || i == MT_REDTEAMRING)
i = MT_RING;
else if (i == MT_RING_BLUEBOX || i == MT_RING_REDBOX)
if (i == MT_RING_BLUEBOX || i == MT_RING_REDBOX)
i = MT_RING_BOX;
else if (i == MT_BLUEFLAG || i == MT_REDFLAG)
return; // No flags in non-CTF modes!
@ -9881,11 +9870,9 @@ void P_SpawnMapThing(mapthing_t *mthing)
{
if (i == MT_PITY_BOX || i == MT_ELEMENTAL_BOX || i == MT_ATTRACT_BOX
|| i == MT_FORCE_BOX || i == MT_ARMAGEDDON_BOX || i == MT_WHIRLWIND_BOX
|| i == MT_FLAMEAURA_BOX || i == MT_BUBBLEWRAP_BOX || i == MT_THUNDERCOIN_BOX)
return; // No shields in Ultimate mode
if (i == MT_RING_BOX && !G_IsSpecialStage(gamemap))
return; // No rings in Ultimate mode (except special stages)
|| i == MT_FLAMEAURA_BOX || i == MT_BUBBLEWRAP_BOX || i == MT_THUNDERCOIN_BOX
|| i == MT_RING_BOX)
return; // No rings or shields in Ultimate mode
// Don't include the gold repeating boxes here please.
// They're likely facets of the level's design and therefore required to progress.
@ -9910,7 +9897,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS);
else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE)
z = ONFLOORZ;
else if (i == MT_BOMBSPHERE || i == MT_SPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_TOKEN)
else if (i == MT_SPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_TOKEN)
{
if (mthing->options & MTF_OBJECTFLIP)
{
@ -10039,6 +10026,54 @@ void P_SpawnMapThing(mapthing_t *mthing)
if (mthing->angle > 0)
mobj->color = ((mthing->angle-1) % (MAXSKINCOLORS-1))+1;
break;
#define makesoftwarecorona(mo, h) \
corona = P_SpawnMobjFromMobj(mo, 0, 0, h<<FRACBITS, MT_PARTICLE);\
corona->sprite = SPR_FLAM;\
corona->frame = (FF_FULLBRIGHT|FF_TRANS90|12);\
corona->tics = -1
case MT_FLAME:
if (mthing->options & MTF_EXTRA)
{
mobj_t *corona;
makesoftwarecorona(mobj, 20);
P_SetScale(corona, (corona->destscale = mobj->scale*3));
P_SetTarget(&mobj->tracer, corona);
}
break;
case MT_FLAMEHOLDER:
if (!(mthing->options & MTF_OBJECTSPECIAL)) // Spawn the fire
{
mobj_t *flame = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_FLAME);
P_SetTarget(&flame->target, mobj);
flame->flags2 |= MF2_BOSSNOTRAP;
if (mthing->options & MTF_EXTRA)
{
mobj_t *corona;
makesoftwarecorona(flame, 20);
P_SetScale(corona, (corona->destscale = flame->scale*3));
P_SetTarget(&flame->tracer, corona);
}
}
break;
case MT_CANDLE:
case MT_CANDLEPRICKET:
if (mthing->options & MTF_EXTRA)
{
mobj_t *corona;
makesoftwarecorona(mobj, ((mobj->type == MT_CANDLE) ? 42 : 176));
}
break;
#undef makesoftwarecorona
case MT_JACKO1:
case MT_JACKO2:
case MT_JACKO3:
if (!(mthing->options & MTF_EXTRA)) // take the torch out of the crafting recipe
{
mobj_t *overlay = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY);
P_SetTarget(&overlay->target, mobj);
P_SetMobjState(overlay, mobj->info->raisestate);
}
break;
case MT_WATERDRIP:
if (mthing->angle)
mobj->tics = 3*TICRATE + mthing->angle;
@ -10524,14 +10559,6 @@ ML_EFFECT4 : Don't clip inside the ground
#undef doleaf
}
break;
case MT_FLAMEHOLDER:
if (!(mthing->options & MTF_OBJECTSPECIAL)) // Spawn the fire
{
mobj_t *flame = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_FLAME);
P_SetTarget(&flame->target, mobj);
flame->flags2 |= MF2_BOSSNOTRAP;
}
break;
case MT_SMASHINGSPIKEBALL:
if (mthing->angle > 0)
mobj->tics += mthing->angle;
@ -10664,7 +10691,7 @@ ML_EFFECT4 : Don't clip inside the ground
}
//count 10 ring boxes into the number of rings equation too.
if (i == MT_RING_BOX)
if (i == MT_RING_BOX && nummaprings >= 0)
nummaprings += 10;
if (i == MT_BIGTUMBLEWEED || i == MT_LITTLETUMBLEWEED)
@ -10807,6 +10834,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
sector_t *sec;
TVector v, *res;
angle_t closestangle, fa;
boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap));
x = mthing->x << FRACBITS;
y = mthing->y << FRACBITS;
@ -11079,79 +11107,6 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
return;
}
// All manners of rings and coins
else if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum ||
mthing->type == mobjinfo[MT_REDTEAMRING].doomednum || mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum ||
mthing->type == mobjinfo[MT_BLUESPHERE].doomednum)
{
// Which ringthing to use
if (mthing->type == mobjinfo[MT_COIN].doomednum)
ringthing = MT_COIN;
else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF
ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING;
else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto
ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING;
else if (mthing->type == mobjinfo[MT_BLUESPHERE].doomednum)
ringthing = MT_BLUESPHERE;
if (ringthing != MT_BLUESPHERE && ultimatemode)
return; // No rings in Ultimate!
if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
ringthing = ((ringthing == MT_BLUESPHERE) ? MT_NIGHTSCHIP : MT_NIGHTSSTAR);
// Set proper height
if (mthing->options & MTF_OBJECTFLIP)
{
z = (
#ifdef ESLOPE
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
#endif
sec->ceilingheight) - mobjinfo[ringthing].height;
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
}
else
{
z =
#ifdef ESLOPE
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
#endif
sec->floorheight;
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
}
if (mthing->options & MTF_AMBUSH) // Special flag for rings
{
if (mthing->options & MTF_OBJECTFLIP)
z -= 24*FRACUNIT;
else
z += 24*FRACUNIT;
}
mthing->z = (INT16)(z>>FRACBITS);
mobj = P_SpawnMobj(x, y, z, ringthing);
mobj->spawnpoint = mthing;
if (mthing->options & MTF_OBJECTFLIP)
{
mobj->eflags |= MFE_VERTICALFLIP;
mobj->flags2 |= MF2_OBJECTFLIP;
}
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
mthing->mobj = mobj;
if (mthing->options & MTF_AMBUSH)
mobj->flags2 |= MF2_AMBUSH;
if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP))
P_SetMobjState(mobj, mobj->info->raisestate);
else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
P_SetMobjState(mobj, mobj->info->seestate);
}
// ***
// Special placement patterns
// ***
@ -11166,7 +11121,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
if (ultimatemode)
return; // No rings in Ultimate!
if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
if (nightsreplace)
ringthing = MT_NIGHTSSTAR;
for (r = 1; r <= 5; r++)
@ -11218,7 +11173,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
if (ultimatemode)
return; // No rings in Ultimate!
if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
if (nightsreplace)
ringthing = MT_NIGHTSSTAR;
closestangle = FixedAngle(mthing->angle*FRACUNIT);
@ -11288,33 +11243,42 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
closestangle = FixedAngle(mthing->angle*FRACUNIT);
switch (mthing->type)
{
case 604:
case 605:
if (ultimatemode)
return; // No rings in Ultimate!
if (nightsreplace)
ringthing = MT_NIGHTSSTAR;
break;
case 608:
case 609:
/*ringthing = (i & 1) ? MT_RING : MT_BLUESPHERE; -- i == 0 is bluesphere
break;*/
case 606:
case 607:
ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE;
break;
default:
break;
}
// Create the hoop!
for (i = 0; i < numitems; i++)
{
switch (mthing->type)
if (mthing->type == 608 || mthing->type == 609)
{
case 604:
case 605:
ringthing = MT_BLUESPHERE;
break;
case 608:
case 609:
ringthing = (i & 1) ? MT_RING : MT_BLUESPHERE;
break;
case 606:
case 607:
ringthing = MT_RING;
break;
default:
break;
if (i & 1)
{
if (ultimatemode)
continue; // No rings in Ultimate!
ringthing = (nightsreplace) ? MT_NIGHTSSTAR : MT_RING;
}
else
ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE;
}
if (ringthing != MT_BLUESPHERE && ultimatemode)
continue; // No rings in Ultimate!
if ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap))
ringthing = ((ringthing == MT_BLUESPHERE) ? MT_NIGHTSCHIP : MT_NIGHTSSTAR);
fa = i*FINEANGLES/numitems;
v[0] = FixedMul(FINECOSINE(fa),size);
v[1] = 0;
@ -11346,7 +11310,81 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
P_SetMobjState(mobj, mobj->info->seestate);
}
return;
}
// All manners of rings and coins
else
{
// Which ringthing to use
if (mthing->type == mobjinfo[MT_BLUESPHERE].doomednum)
ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE;
else if (mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum)
ringthing = MT_BOMBSPHERE;
else
{
if (ultimatemode)
return; // No rings in Ultimate!
if (nightsreplace)
ringthing = MT_NIGHTSSTAR;
else if (mthing->type == mobjinfo[MT_COIN].doomednum)
ringthing = MT_COIN;
else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF
ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING;
else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto
ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING;
}
// Set proper height
if (mthing->options & MTF_OBJECTFLIP)
{
z = (
#ifdef ESLOPE
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
#endif
sec->ceilingheight) - mobjinfo[ringthing].height;
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
}
else
{
z =
#ifdef ESLOPE
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
#endif
sec->floorheight;
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
}
if (mthing->options & MTF_AMBUSH) // Special flag for rings
{
if (mthing->options & MTF_OBJECTFLIP)
z -= 24*FRACUNIT;
else
z += 24*FRACUNIT;
}
mthing->z = (INT16)(z>>FRACBITS);
mobj = P_SpawnMobj(x, y, z, ringthing);
mobj->spawnpoint = mthing;
if (mthing->options & MTF_OBJECTFLIP)
{
mobj->eflags |= MFE_VERTICALFLIP;
mobj->flags2 |= MF2_OBJECTFLIP;
}
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
mthing->mobj = mobj;
if (mthing->options & MTF_AMBUSH)
mobj->flags2 |= MF2_AMBUSH;
if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP))
P_SetMobjState(mobj, mobj->info->raisestate);
else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR))
P_SetMobjState(mobj, mobj->info->seestate);
}
}

View file

@ -842,9 +842,10 @@ void P_ReloadRings(void)
for (i = 0; i < nummapthings; i++, mt++)
{
// Notice an omission? We handle hoops differently.
if (mt->type == mobjinfo[MT_RING].doomednum || mt->type == mobjinfo[MT_REDTEAMRING].doomednum || mt->type == mobjinfo[MT_BLUETEAMRING].doomednum
|| mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_COIN].doomednum
|| (mt->type >= 600 && mt->type <= 609)) // circles
if (mt->type == mobjinfo[MT_RING].doomednum || mt->type == mobjinfo[MT_COIN].doomednum
|| mt->type == mobjinfo[MT_REDTEAMRING].doomednum || mt->type == mobjinfo[MT_BLUETEAMRING].doomednum
|| mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_BOMBSPHERE].doomednum
|| (mt->type >= 600 && mt->type <= 609)) // circles and diagonals
{
mt->mobj = NULL;
@ -852,7 +853,12 @@ void P_ReloadRings(void)
mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)
->sector->floorheight>>FRACBITS);
P_SpawnHoopsAndRings(mt, true);
P_SpawnHoopsAndRings(mt,
#ifdef MANIASPHERES
true);
#else
!G_IsSpecialStage(gamemap)); // prevent flashing spheres in special stages
#endif
}
}
for (i = 0; i < numHoops; i++)
@ -866,6 +872,11 @@ void P_SwitchSpheresBonusMode(boolean bonustime)
mobj_t *mo;
thinker_t *th;
#ifndef MANIASPHERES
if (G_IsSpecialStage(gamemap)) // prevent flashing spheres in special stages
return;
#endif
// scan the thinkers to find spheres to switch
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
@ -1075,9 +1086,11 @@ static void P_LoadThings(void)
mt = mapthings;
for (i = 0; i < nummapthings; i++, mt++)
{
if (mt->type == 300 || mt->type == 308 || mt->type == 309
|| mt->type == 1706 || (mt->type >= 600 && mt->type <= 609)
|| mt->type == 1705 || mt->type == 1713 || mt->type == 1800)
if (mt->type == mobjinfo[MT_RING].doomednum || mt->type == mobjinfo[MT_COIN].doomednum
|| mt->type == mobjinfo[MT_REDTEAMRING].doomednum || mt->type == mobjinfo[MT_BLUETEAMRING].doomednum
|| mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_BOMBSPHERE].doomednum
|| (mt->type >= 600 && mt->type <= 609) // circles and diagonals
|| mt->type == 1705 || mt->type == 1713 || mt->type == 1800) // hoops
{
mt->mobj = NULL;
@ -2347,6 +2360,8 @@ static void P_LevelInitStuff(void)
}
}
countdown = countdown2 = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (canresetlives && (netgame || multiplayer) && playeringame[i] && (gametype == GT_COMPETITION || players[i].lives <= 0))
@ -2355,42 +2370,36 @@ static void P_LevelInitStuff(void)
players[i].lives = cv_startinglives.value;
}
players[i].realtime = countdown = countdown2 = 0;
// obliteration station...
players[i].rings = players[i].spheres =\
players[i].xtralife = players[i].deadtimer =\
players[i].numboxes = players[i].totalring =\
players[i].laps = players[i].aiming =\
players[i].losstime = players[i].timeshit =\
players[i].marescore = players[i].lastmarescore =\
players[i].maxlink = players[i].startedtime =\
players[i].finishedtime = players[i].finishedspheres =\
players[i].lastmare = players[i].marebegunat =\
players[i].textvar = players[i].texttimer =\
players[i].linkcount = players[i].linktimer =\
players[i].flyangle = players[i].anotherflyangle =\
players[i].nightstime = players[i].mare =\
players[i].realtime = players[i].exiting = 0;
// i guess this could be part of the above but i feel mildly uncomfortable implicitly casting
players[i].gotcontinue = false;
players[i].xtralife = players[i].deadtimer = players[i].numboxes = players[i].totalring = players[i].laps = 0;
players[i].rings = 0;
players[i].spheres = 0;
players[i].aiming = 0;
players[i].pflags &= ~PF_GAMETYPEOVER;
players[i].losstime = 0;
players[i].timeshit = 0;
players[i].marescore = players[i].lastmarescore = players[i].maxlink = 0;
players[i].startedtime = players[i].finishedtime = players[i].finishedspheres = 0;
players[i].lastmare = players[i].marebegunat = 0;
// Don't show anything
players[i].textvar = players[i].texttimer = 0;
players[i].linkcount = players[i].linktimer = 0;
players[i].flyangle = players[i].anotherflyangle = 0;
players[i].nightstime = players[i].mare = 0;
P_SetTarget(&players[i].capsule, NULL);
// aha, the first evidence this shouldn't be a memset!
players[i].drillmeter = 40*20;
players[i].exiting = 0;
P_ResetPlayer(&players[i]);
// hit these too
players[i].pflags &= ~(PF_GAMETYPEOVER|PF_TRANSFERTOCLOSEST);
players[i].mo = NULL;
// we must unset axis details too
players[i].axis1 = players[i].axis2 = NULL;
// and this stupid flag as a result
players[i].pflags &= ~PF_TRANSFERTOCLOSEST;
// unset ALL the pointers. P_SetTarget isn't needed here because if this
// function is being called we're just going to clobber the data anyways
players[i].mo = players[i].followmobj = players[i].awayviewmobj =\
players[i].capsule = players[i].axis1 = players[i].axis2 = NULL;
}
}
@ -2703,11 +2712,6 @@ boolean P_SetupLevel(boolean skipprecip)
// Reset the palette
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_SetPaletteColor(0);
else
#endif
if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL");
@ -2765,6 +2769,7 @@ boolean P_SetupLevel(boolean skipprecip)
{
tic_t starttime = I_GetTime();
tic_t endtime = starttime + (3*TICRATE)/2;
tic_t nowtime;
S_StartSound(NULL, sfx_s3kaf);
@ -2774,9 +2779,17 @@ boolean P_SetupLevel(boolean skipprecip)
F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_speclevel_towhite], false);
nowtime = lastwipetic;
// Hold on white for extra effect.
while (I_GetTime() < endtime)
I_Sleep();
while (nowtime < endtime)
{
// wait loop
while (!((nowtime = I_GetTime()) - lastwipetic))
I_Sleep();
lastwipetic = nowtime;
if (moviemode) // make sure we save frames for the white hold too
M_SaveFrame();
}
ranspecialwipe = 1;
}
@ -3364,7 +3377,7 @@ boolean P_AddWadFile(const char *wadfilename)
if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX)
{
refreshdirmenu |= REFRESHDIR_NOTLOADED;
CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename);
CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename);
return false;
}
else

View file

@ -6699,6 +6699,7 @@ void T_Scroll(scroll_t *s)
line_t *line;
size_t i;
INT32 sect;
ffloor_t *rover;
case sc_side: // scroll wall texture
side = sides + s->affectee;
@ -6740,6 +6741,19 @@ void T_Scroll(scroll_t *s)
sector_t *psec;
psec = sectors + sect;
// Find the FOF corresponding to the control linedef
for (rover = psec->ffloors; rover; rover = rover->next)
{
if (rover->master == sec->lines[i])
break;
}
if (!rover) // This should be impossible, but don't complain if it is the case somehow
continue;
if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there
continue;
for (node = psec->touching_thinglist; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
@ -6803,6 +6817,19 @@ void T_Scroll(scroll_t *s)
sector_t *psec;
psec = sectors + sect;
// Find the FOF corresponding to the control linedef
for (rover = psec->ffloors; rover; rover = rover->next)
{
if (rover->master == sec->lines[i])
break;
}
if (!rover) // This should be impossible, but don't complain if it is the case somehow
continue;
if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there
continue;
for (node = psec->touching_thinglist; node; node = node->m_thinglist_next)
{
thing = node->m_thing;

View file

@ -483,6 +483,7 @@ static inline void P_DoSpecialStageStuff(void)
sstimer = 0;
P_GiveEmerald(true);
P_RestoreMusic(&players[consoleplayer]);
}
}
else
@ -597,7 +598,8 @@ void P_Ticker(boolean run)
}
// Keep track of how long they've been playing!
totalplaytime++;
if (!demoplayback) // Don't increment if a demo is playing.
totalplaytime++;
if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))
P_DoSpecialStageStuff();

View file

@ -1048,8 +1048,6 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
// Transformation animation
P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1);
player->pflags |= PF_NOJUMPDAMAGE; // just to avoid recurling but still allow thok
if (giverings)
player->rings = 50;
@ -1805,6 +1803,9 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue;
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
continue;
#ifdef ESLOPE
@ -2165,6 +2166,12 @@ static void P_CheckBouncySectors(player_t *player)
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue; // FOFs should not be bouncy if they don't even "exist"
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 15)
continue; // this sector type is required for FOFs to be bouncy
topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
@ -2178,7 +2185,6 @@ static void P_CheckBouncySectors(player_t *player)
&& oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL))
top = false;
if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15)
{
fixed_t linedist;

View file

@ -658,6 +658,14 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type)
SDL_memset(&event, 0, sizeof(event_t));
// Ignore the event if the mouse is not actually focused on the window.
// This can happen if you used the mouse to restore keyboard focus;
// this apparently makes a mouse button down event but not a mouse button up event,
// resulting in whatever key was pressed down getting "stuck" if we don't ignore it.
// -- Monster Iestyn (28/05/18)
if (SDL_GetMouseFocus() != window)
return;
/// \todo inputEvent.button.which
if (USE_MOUSEINPUT)
{

View file

@ -1180,12 +1180,6 @@ void I_StartupSound(void)
audio.callback = I_UpdateStream;
audio.userdata = &localdata;
if (dedicated)
{
nosound = nomidimusic = nodigimusic = true;
return;
}
// Configure sound device
CONS_Printf("I_StartupSound:\n");
@ -1481,9 +1475,6 @@ void I_InitMusic(void)
I_AddExitFunc(I_ShutdownGMEMusic);
#endif
if ((nomidimusic && nodigimusic) || dedicated)
return;
#ifdef HAVE_MIXER
MIX_VERSION(&MIXcompiled)
MIXlinked = Mix_Linked_Version();

View file

@ -299,7 +299,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3k3d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pop"},
{"s3k3e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flame Shield"},
{"s3k3f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bubble Shield"},
{"s3k40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Attraction shot"},
{"s3k40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Attraction blast"},
{"s3k41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning Shield"},
{"s3k42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Twinspin"},
{"s3k43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flame burst"},

View file

@ -204,17 +204,17 @@ void ST_doPaletteStuff(void)
else
palette = 0;
#ifdef HWRENDER
if (rendermode == render_opengl)
palette = 0; // No flashpals here in OpenGL
#endif
palette = min(max(palette, 0), 13);
if (palette != st_palette)
{
st_palette = palette;
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_SetPaletteColor(0);
else
#endif
if (rendermode != render_none)
{
V_SetPaletteLump(GetPalette()); // Reset the palette
@ -1577,11 +1577,13 @@ static void ST_drawNiGHTSHUD(void)
#endif
ST_DrawTopLeftOverlayPatch(16, 8, nbracket);
if (G_IsSpecialStage(gamemap))
ST_DrawTopLeftOverlayPatch(24, 16, ((stplyr->bonustime && (leveltime & 4)) ? nssbon : nsshud));
else if (stplyr->bonustime)
ST_DrawTopLeftOverlayPatch(24, 16, nbon[(leveltime/2)%12]);
ST_DrawTopLeftOverlayPatch(24, 16, (
#ifdef MANIASPHERES
(stplyr->bonustime && (leveltime & 4)) ? nssbon :
#endif
nsshud));
else
ST_DrawTopLeftOverlayPatch(24, 16, nhud[(leveltime/2)%12]);
ST_DrawTopLeftOverlayPatch(24, 16, *(((stplyr->bonustime) ? nbon : nhud)+((leveltime/2)%12)));
if (G_IsSpecialStage(gamemap))
{

View file

@ -1801,7 +1801,7 @@ static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct)
if (!playeringame[i]) continue;
sharedringtotal += players[i].rings;
}
if (!sharedringtotal || sharedringtotal < nummaprings)
if (!sharedringtotal || nummaprings == -1 || sharedringtotal < nummaprings)
data.coop.gotperfbonus = 0;
else
data.coop.gotperfbonus = 1;