mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-20 18:01:16 +00:00
Merge remote-tracking branch 'origin/master' into musicplus-sdlmixerx
This commit is contained in:
commit
b99f06c0c9
57 changed files with 2365 additions and 572 deletions
|
@ -1608,7 +1608,7 @@ void CON_Drawer(void)
|
|||
if (con_curlines > 0)
|
||||
CON_DrawConsole();
|
||||
else if (gamestate == GS_LEVEL
|
||||
|| gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE
|
||||
|| gamestate == GS_INTERMISSION || gamestate == GS_ENDING || gamestate == GS_CUTSCENE
|
||||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
|
||||
CON_DrawHudlines();
|
||||
}
|
||||
|
|
|
@ -310,6 +310,12 @@ static void D_Display(void)
|
|||
wipe = true;
|
||||
break;
|
||||
|
||||
case GS_ENDING:
|
||||
F_EndingDrawer();
|
||||
HU_Erase();
|
||||
HU_Drawer();
|
||||
break;
|
||||
|
||||
case GS_CUTSCENE:
|
||||
F_CutsceneDrawer();
|
||||
HU_Erase();
|
||||
|
|
|
@ -517,7 +517,9 @@ static void readfreeslots(MYFILE *f)
|
|||
continue;
|
||||
// Copy in the spr2 name and increment free_spr2.
|
||||
if (free_spr2 < NUMPLAYERSPRITES) {
|
||||
CONS_Printf("Sprite SPR2_%s allocated.\n",word);
|
||||
strncpy(spr2names[free_spr2],word,4);
|
||||
spr2defaults[free_spr2] = 0;
|
||||
spr2names[free_spr2++][4] = 0;
|
||||
} else
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
|
||||
|
@ -1108,6 +1110,7 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
if (fastcmp(word2, "TITLE")) i = 1100;
|
||||
else if (fastcmp(word2, "EVALUATION")) i = 1101;
|
||||
else if (fastcmp(word2, "CREDITS")) i = 1102;
|
||||
else if (fastcmp(word2, "ENDING")) i = 1103;
|
||||
else
|
||||
// Support using the actual map name,
|
||||
// i.e., Nextlevel = AB, Nextlevel = FZ, etc.
|
||||
|
@ -5699,7 +5702,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
"S_CEZFLOWER",
|
||||
"S_CEZPOLE",
|
||||
"S_CEZBANNER",
|
||||
"S_CEZBANNER1",
|
||||
"S_CEZBANNER2",
|
||||
"S_PINETREE",
|
||||
"S_CEZBUSH1",
|
||||
"S_CEZBUSH2",
|
||||
|
@ -5708,7 +5712,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_FLAMEHOLDER",
|
||||
"S_FIRETORCH",
|
||||
"S_WAVINGFLAG",
|
||||
"S_WAVINGFLAGSEG",
|
||||
"S_WAVINGFLAGSEG1",
|
||||
"S_WAVINGFLAGSEG2",
|
||||
"S_CRAWLASTATUE",
|
||||
"S_FACESTABBERSTATUE",
|
||||
"S_SUSPICIOUSFACESTABBERSTATUE_WAIT",
|
||||
|
@ -7514,8 +7519,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_SMALLFIREBAR", // Small Firebar
|
||||
"MT_BIGFIREBAR", // Big Firebar
|
||||
"MT_CEZFLOWER", // Flower
|
||||
"MT_CEZPOLE", // Pole
|
||||
"MT_CEZBANNER", // Banner
|
||||
"MT_CEZPOLE1", // Pole (with red banner)
|
||||
"MT_CEZPOLE2", // Pole (with blue banner)
|
||||
"MT_CEZBANNER1", // Banner (red)
|
||||
"MT_CEZBANNER2", // Banner (blue)
|
||||
"MT_PINETREE", // Pine Tree
|
||||
"MT_CEZBUSH1", // Bush 1
|
||||
"MT_CEZBUSH2", // Bush 2
|
||||
|
@ -7523,8 +7530,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_CANDLEPRICKET", // Candle pricket
|
||||
"MT_FLAMEHOLDER", // Flame holder
|
||||
"MT_FIRETORCH", // Fire torch
|
||||
"MT_WAVINGFLAG", // Waving flag
|
||||
"MT_WAVINGFLAGSEG", // Waving flag segment
|
||||
"MT_WAVINGFLAG1", // Waving flag (red)
|
||||
"MT_WAVINGFLAG2", // Waving flag (blue)
|
||||
"MT_WAVINGFLAGSEG1", // Waving flag segment (red)
|
||||
"MT_WAVINGFLAGSEG2", // Waving flag segment (blue)
|
||||
"MT_CRAWLASTATUE", // Crawla statue
|
||||
"MT_FACESTABBERSTATUE", // Facestabber statue
|
||||
"MT_SUSPICIOUSFACESTABBERSTATUE", // :eggthinking:
|
||||
|
@ -9493,6 +9502,7 @@ static inline int lib_freeslot(lua_State *L)
|
|||
{
|
||||
CONS_Printf("Sprite SPR2_%s allocated.\n",word);
|
||||
strncpy(spr2names[free_spr2],word,4);
|
||||
spr2defaults[free_spr2] = 0;
|
||||
spr2names[free_spr2++][4] = 0;
|
||||
} else
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
|
||||
|
|
|
@ -234,7 +234,7 @@ extern textprompt_t *textprompts[MAX_PROMPTS];
|
|||
|
||||
// For the Custom Exit linedef.
|
||||
extern INT16 nextmapoverride;
|
||||
extern boolean skipstats;
|
||||
extern UINT8 skipstats;
|
||||
|
||||
extern UINT32 ssspheres; // Total # of spheres in a level
|
||||
|
||||
|
|
808
src/f_finale.c
808
src/f_finale.c
|
@ -14,6 +14,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "d_main.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "f_finale.h"
|
||||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include "p_setup.h"
|
||||
#include "st_stuff.h" // hud hiding
|
||||
#include "fastcmp.h"
|
||||
#include "console.h"
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "lua_hud.h"
|
||||
|
@ -53,7 +55,6 @@ static INT32 continuetime; // Short delay when continuing
|
|||
|
||||
static tic_t animtimer; // Used for some animation timings
|
||||
static INT16 skullAnimCounter; // Prompts: Chevron animation
|
||||
static INT32 roidtics; // Asteroid spinning
|
||||
|
||||
static INT32 deplete;
|
||||
static tic_t stoptimer;
|
||||
|
@ -95,10 +96,22 @@ static patch_t *ttspop5;
|
|||
static patch_t *ttspop6;
|
||||
static patch_t *ttspop7;
|
||||
|
||||
static boolean goodending;
|
||||
static patch_t *endbrdr[2]; // border - blue, white, pink - where have i seen those colours before?
|
||||
static patch_t *endbgsp[3]; // nebula, sun, planet
|
||||
static patch_t *endegrk[2]; // eggrock - replaced midway through good ending
|
||||
static patch_t *endfwrk[3]; // firework - replaced with skin when good ending
|
||||
static patch_t *endspkl[3]; // sparkle
|
||||
static patch_t *endglow[2]; // glow aura - replaced with black rock's midway through good ending
|
||||
static patch_t *endxpld[4]; // mini explosion
|
||||
static patch_t *endescp[5]; // escape pod + flame
|
||||
static INT32 sparkloffs[3][2]; // eggrock explosions/blackrock sparkles
|
||||
static INT32 sparklloop;
|
||||
|
||||
//
|
||||
// PROMPT STATE
|
||||
//
|
||||
static boolean promptactive = false;
|
||||
boolean promptactive = false;
|
||||
static mobj_t *promptmo;
|
||||
static INT16 promptpostexectag;
|
||||
static boolean promptblockcontrols;
|
||||
|
@ -230,6 +243,7 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
|||
void F_StartIntro(void)
|
||||
{
|
||||
S_StopMusic();
|
||||
S_StopSounds();
|
||||
|
||||
if (introtoplay)
|
||||
{
|
||||
|
@ -393,7 +407,6 @@ void F_StartIntro(void)
|
|||
|
||||
intro_scenenum = 0;
|
||||
finalecount = animtimer = skullAnimCounter = stoptimer = 0;
|
||||
roidtics = BASEVIDWIDTH - 64;
|
||||
timetonext = introscenetime[intro_scenenum];
|
||||
}
|
||||
|
||||
|
@ -676,11 +689,42 @@ static void F_IntroDrawScene(void)
|
|||
|
||||
if (intro_scenenum == 4) // The asteroid SPINS!
|
||||
{
|
||||
if (roidtics >= 0)
|
||||
if (intro_curtime > 1)
|
||||
{
|
||||
V_DrawScaledPatch(roidtics, 24, 0,
|
||||
(patch = W_CachePatchName(va("ROID00%.2d", intro_curtime%35), PU_CACHE)));
|
||||
W_UnlockCachedPatch(patch);
|
||||
INT32 worktics = intro_curtime - 1;
|
||||
INT32 scale = FRACUNIT;
|
||||
patch_t *rockpat;
|
||||
UINT8 *colormap = NULL;
|
||||
patch_t *glow;
|
||||
INT32 trans = 0;
|
||||
|
||||
INT32 x = ((BASEVIDWIDTH - 64)<<FRACBITS) - ((intro_curtime*FRACUNIT)/3);
|
||||
INT32 y = 24<<FRACBITS;
|
||||
|
||||
if (worktics < 5)
|
||||
{
|
||||
scale = (worktics<<(FRACBITS-2));
|
||||
x += (30*(FRACUNIT-scale));
|
||||
y += (30*(FRACUNIT-scale));
|
||||
}
|
||||
|
||||
rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (worktics % 35)), PU_LEVEL);
|
||||
glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(worktics & 1)), PU_LEVEL);
|
||||
|
||||
if (worktics >= 5)
|
||||
trans = (worktics-5)>>1;
|
||||
if (trans < 10)
|
||||
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, glow, NULL);
|
||||
|
||||
trans = (15-worktics);
|
||||
if (trans < 0)
|
||||
trans = -trans;
|
||||
|
||||
if (finalecount < 15)
|
||||
colormap = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
|
||||
V_DrawFixedPatch(x, y, scale, 0, rockpat, colormap);
|
||||
if (trans < 10)
|
||||
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, rockpat, R_GetTranslationColormap(TC_BLINK, SKINCOLOR_AQUA, GTC_CACHE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -702,7 +746,7 @@ static void F_IntroDrawScene(void)
|
|||
W_UnlockCachedPatch(sgrass);
|
||||
}
|
||||
|
||||
V_DrawString(cx, cy, 0, cutscene_disptext);
|
||||
V_DrawString(cx, cy, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -724,8 +768,6 @@ void F_IntroDrawer(void)
|
|||
|
||||
S_ChangeMusicInternal("_intro", false);
|
||||
}
|
||||
else if (intro_scenenum == 3)
|
||||
roidtics = BASEVIDWIDTH - 64;
|
||||
else if (intro_scenenum == 10)
|
||||
{
|
||||
// The only fade to white in the entire damn game.
|
||||
|
@ -849,9 +891,6 @@ void F_IntroTicker(void)
|
|||
// advance animation
|
||||
finalecount++;
|
||||
|
||||
if (finalecount % 3 == 0)
|
||||
roidtics--;
|
||||
|
||||
timetonext--;
|
||||
|
||||
F_WriteText();
|
||||
|
@ -947,6 +986,7 @@ static const char *credits[] = {
|
|||
"\1Assistance",
|
||||
"\"chi.miru\"", // helped port slope drawing code from ZDoom
|
||||
"Andrew \"orospakr\" Clunis",
|
||||
"Sally \"TehRealSalt\" Cochenour",
|
||||
"Gregor \"Oogaland\" Dick",
|
||||
"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
|
||||
"Victor \"Steel Titanium\" Fuentes",
|
||||
|
@ -966,8 +1006,9 @@ static const char *credits[] = {
|
|||
// Everyone else is acknowledged under "Special Thanks > SRB2 Community Contributors".
|
||||
"",
|
||||
"\1Sprite Artists",
|
||||
"Odi \"Iceman404\" Atunzu",
|
||||
"\"Iceman404\"",
|
||||
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
|
||||
"Sally \"TehRealSalt\" Cochenour",
|
||||
"Jim \"MotorRoach\" DeMello",
|
||||
"Desmond \"Blade\" DesJardins",
|
||||
"Sherman \"CoatRack\" DesJardins",
|
||||
|
@ -1049,7 +1090,10 @@ static const char *credits[] = {
|
|||
"Simon \"sirjuddington\" Judd", // SLADE developer
|
||||
// Acknowledged here are the following:
|
||||
// Minor merge request authors, see guideline above
|
||||
// Golden - Expanded thin font
|
||||
// - Golden - Expanded thin font
|
||||
// Creators of small quantities of sprite/texture assets
|
||||
// - Arietty - New Green Hill-styled textures
|
||||
// - Scizor300 - the only other contributor to the 2.0 SRB2 Asset Pack
|
||||
"SRB2 Community Contributors",
|
||||
"",
|
||||
"\1Produced By",
|
||||
|
@ -1103,6 +1147,7 @@ void F_StartCredits(void)
|
|||
paused = false;
|
||||
CON_ToggleOff();
|
||||
S_StopMusic();
|
||||
S_StopSounds();
|
||||
|
||||
S_ChangeMusicInternal("_creds", false);
|
||||
|
||||
|
@ -1221,7 +1266,7 @@ boolean F_CreditResponder(event_t *event)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!(timesBeaten) && !(netgame || multiplayer))
|
||||
if (!(timesBeaten) && !(netgame || multiplayer) && !cv_debug)
|
||||
return false;
|
||||
|
||||
if (event->type != ev_keydown)
|
||||
|
@ -1240,10 +1285,8 @@ boolean F_CreditResponder(event_t *event)
|
|||
// ============
|
||||
// EVALUATION
|
||||
// ============
|
||||
#define INTERVAL 50
|
||||
#define TRANSLEVEL V_80TRANS
|
||||
static INT32 eemeralds_start;
|
||||
static boolean drawemblem = false, drawchaosemblem = false;
|
||||
|
||||
#define SPARKLLOOPTIME 7 // must be odd
|
||||
|
||||
void F_StartGameEvaluation(void)
|
||||
{
|
||||
|
@ -1265,76 +1308,122 @@ void F_StartGameEvaluation(void)
|
|||
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
|
||||
G_SaveGame((UINT32)cursaveslot);
|
||||
|
||||
goodending = (ALL7EMERALDS(emeralds));
|
||||
|
||||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
|
||||
finalecount = 0;
|
||||
finalecount = -1;
|
||||
sparklloop = 0;
|
||||
}
|
||||
|
||||
void F_GameEvaluationDrawer(void)
|
||||
{
|
||||
INT32 x, y, i;
|
||||
const fixed_t radius = 48*FRACUNIT;
|
||||
angle_t fa;
|
||||
INT32 eemeralds_cur;
|
||||
char patchname[7] = "CEMGx0";
|
||||
const char* endingtext = (goodending ? "CONGRATULATIONS!" : "TRY AGAIN...");
|
||||
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
|
||||
// Draw all the good crap here.
|
||||
if (ALL7EMERALDS(emeralds))
|
||||
V_DrawString(114, 16, 0, "GOT THEM ALL!");
|
||||
else
|
||||
V_DrawString(124, 16, 0, "TRY AGAIN!");
|
||||
|
||||
eemeralds_start++;
|
||||
eemeralds_cur = eemeralds_start;
|
||||
|
||||
for (i = 0; i < 7; ++i)
|
||||
if (finalecount > 0)
|
||||
{
|
||||
fa = (FixedAngle(eemeralds_cur*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK;
|
||||
x = 160 + FixedInt(FixedMul(FINECOSINE(fa),radius));
|
||||
y = 100 + FixedInt(FixedMul(FINESINE(fa),radius));
|
||||
INT32 scale = FRACUNIT;
|
||||
patch_t *rockpat;
|
||||
UINT8 *colormap[2] = {NULL, NULL};
|
||||
patch_t *glow;
|
||||
INT32 trans = 0;
|
||||
|
||||
patchname[4] = 'A'+(char)i;
|
||||
if (emeralds & (1<<i))
|
||||
V_DrawScaledPatch(x, y, 0, W_CachePatchName(patchname, PU_CACHE));
|
||||
else
|
||||
V_DrawTranslucentPatch(x, y, TRANSLEVEL, W_CachePatchName(patchname, PU_CACHE));
|
||||
x = (((BASEVIDWIDTH-82)/2)+11)<<FRACBITS;
|
||||
y = (((BASEVIDHEIGHT-82)/2)+12)<<FRACBITS;
|
||||
|
||||
eemeralds_cur += INTERVAL;
|
||||
}
|
||||
if (eemeralds_start >= 360)
|
||||
eemeralds_start -= 360;
|
||||
|
||||
if (finalecount == 5*TICRATE)
|
||||
{
|
||||
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer))
|
||||
if (finalecount < 5)
|
||||
{
|
||||
++timesBeaten;
|
||||
scale = (finalecount<<(FRACBITS-2));
|
||||
x += (30*(FRACUNIT-scale));
|
||||
y += (30*(FRACUNIT-scale));
|
||||
}
|
||||
|
||||
if (ALL7EMERALDS(emeralds))
|
||||
++timesBeatenWithEmeralds;
|
||||
if (goodending)
|
||||
{
|
||||
rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (finalecount % 35)), PU_LEVEL);
|
||||
glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(finalecount & 1)), PU_LEVEL);
|
||||
x -= FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
rockpat = W_CachePatchName("ROID0000", PU_LEVEL);
|
||||
glow = W_CachePatchName(va("ENDGLOW%.1d", (finalecount & 1)), PU_LEVEL);
|
||||
}
|
||||
|
||||
if (ultimatemode)
|
||||
++timesBeatenUltimate;
|
||||
if (finalecount >= 5)
|
||||
trans = (finalecount-5)>>1;
|
||||
if (trans < 10)
|
||||
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, glow, NULL);
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
trans = (15-finalecount);
|
||||
if (trans < 0)
|
||||
trans = -trans;
|
||||
|
||||
G_SaveGameData();
|
||||
if (finalecount < 15)
|
||||
colormap[0] = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
|
||||
V_DrawFixedPatch(x, y, scale, 0, rockpat, colormap[0]);
|
||||
if (trans < 10)
|
||||
{
|
||||
colormap[1] = R_GetTranslationColormap(TC_BLINK, SKINCOLOR_AQUA, GTC_CACHE);
|
||||
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, rockpat, colormap[1]);
|
||||
}
|
||||
if (goodending)
|
||||
{
|
||||
INT32 j = (sparklloop & 1) ? 2 : 3;
|
||||
if (j > (finalecount/SPARKLLOOPTIME))
|
||||
j = (finalecount/SPARKLLOOPTIME);
|
||||
while (j)
|
||||
{
|
||||
if (j > 1 || sparklloop >= 2)
|
||||
{
|
||||
// if j == 0 - alternate between 0 and 1
|
||||
// 1 - 1 and 2
|
||||
// 2 - 2 and not rendered
|
||||
V_DrawFixedPatch(x+sparkloffs[j-1][0], y+sparkloffs[j-1][1], FRACUNIT, 0, W_CachePatchName(va("ENDSPKL%.1d", (j - ((sparklloop & 1) ? 0 : 1))), PU_LEVEL), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_AQUA, GTC_CACHE));
|
||||
}
|
||||
j--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
patch_t *eggrock = W_CachePatchName("ENDEGRK5", PU_LEVEL);
|
||||
V_DrawFixedPatch(x, y, scale, 0, eggrock, colormap[0]);
|
||||
if (trans < 10)
|
||||
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, eggrock, colormap[1]);
|
||||
else if (sparklloop)
|
||||
V_DrawFixedPatch(x, y, scale, (10-sparklloop)<<V_ALPHASHIFT,
|
||||
W_CachePatchName("ENDEGRK0", PU_LEVEL), colormap[1]);
|
||||
}
|
||||
}
|
||||
|
||||
eemeralds_cur = (finalecount % 360)<<FRACBITS;
|
||||
|
||||
for (i = 0; i < 7; ++i)
|
||||
{
|
||||
fa = (FixedAngle(eemeralds_cur)>>ANGLETOFINESHIFT) & FINEMASK;
|
||||
x = (BASEVIDWIDTH<<(FRACBITS-1)) + (60*FINECOSINE(fa));
|
||||
y = ((BASEVIDHEIGHT+16)<<(FRACBITS-1)) + (60*FINESINE(fa));
|
||||
eemeralds_cur += (360<<FRACBITS)/7;
|
||||
|
||||
patchname[4] = 'A'+(char)i;
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, ((emeralds & (1<<i)) ? 0 : V_80TRANS), W_CachePatchName(patchname, PU_LEVEL), NULL);
|
||||
}
|
||||
|
||||
V_DrawCreditString((BASEVIDWIDTH - V_CreditStringWidth(endingtext))<<(FRACBITS-1), (BASEVIDHEIGHT-100)<<(FRACBITS-1), 0, endingtext);
|
||||
|
||||
#if 0 // the following looks like hot garbage the more unlockables we add, and we now have a lot of unlockables
|
||||
if (finalecount >= 5*TICRATE)
|
||||
{
|
||||
if (drawemblem)
|
||||
V_DrawScaledPatch(120, 192, 0, W_CachePatchName("NWNGA0", PU_CACHE));
|
||||
|
||||
if (drawchaosemblem)
|
||||
V_DrawScaledPatch(200, 192, 0, W_CachePatchName("NWNGA0", PU_CACHE));
|
||||
|
||||
V_DrawString(8, 16, V_YELLOWMAP, "Unlocked:");
|
||||
|
||||
if (!(netgame) && (!modifiedgame || savemoddata))
|
||||
|
@ -1357,16 +1446,603 @@ void F_GameEvaluationDrawer(void)
|
|||
else
|
||||
V_DrawString(8, 96, V_YELLOWMAP, "Prizes not\nawarded in\nmodified games!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void F_GameEvaluationTicker(void)
|
||||
{
|
||||
finalecount++;
|
||||
|
||||
if (finalecount > 10*TICRATE)
|
||||
if (++finalecount > 10*TICRATE)
|
||||
{
|
||||
F_StartGameEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!goodending)
|
||||
{
|
||||
if (sparklloop)
|
||||
sparklloop--;
|
||||
|
||||
if (finalecount == (5*TICRATE)/2
|
||||
|| finalecount == (7*TICRATE)/2
|
||||
|| finalecount == ((7*TICRATE)/2)+5)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k5c);
|
||||
sparklloop = 10;
|
||||
}
|
||||
}
|
||||
else if (++sparklloop == SPARKLLOOPTIME) // time to roll the randomisation again
|
||||
{
|
||||
angle_t workingangle = FixedAngle((M_RandomKey(360))<<FRACBITS)>>ANGLETOFINESHIFT;
|
||||
fixed_t workingradius = M_RandomKey(26);
|
||||
|
||||
sparkloffs[2][0] = sparkloffs[1][0];
|
||||
sparkloffs[2][1] = sparkloffs[1][1];
|
||||
sparkloffs[1][0] = sparkloffs[0][0];
|
||||
sparkloffs[1][1] = sparkloffs[0][1];
|
||||
|
||||
sparkloffs[0][0] = (30<<FRACBITS) + workingradius*FINECOSINE(workingangle);
|
||||
sparkloffs[0][1] = (30<<FRACBITS) + workingradius*FINESINE(workingangle);
|
||||
sparklloop = 0;
|
||||
}
|
||||
|
||||
if (finalecount == 5*TICRATE)
|
||||
{
|
||||
if (netgame || multiplayer) // modify this when we finally allow unlocking stuff in 2P
|
||||
{
|
||||
HU_SetCEchoFlags(V_YELLOWMAP|V_RETURN8);
|
||||
HU_SetCEchoDuration(6);
|
||||
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Prizes only awarded in singleplayer!");
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
}
|
||||
else if (!modifiedgame || savemoddata)
|
||||
{
|
||||
++timesBeaten;
|
||||
|
||||
if (ALL7EMERALDS(emeralds))
|
||||
++timesBeatenWithEmeralds;
|
||||
|
||||
if (ultimatemode)
|
||||
++timesBeatenUltimate;
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
|
||||
G_SaveGameData();
|
||||
}
|
||||
else
|
||||
{
|
||||
HU_SetCEchoFlags(V_YELLOWMAP|V_RETURN8);
|
||||
HU_SetCEchoDuration(6);
|
||||
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Prizes not awarded in modified games!");
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef SPARKLLOOPTIME
|
||||
|
||||
// ==========
|
||||
// ENDING
|
||||
// ==========
|
||||
|
||||
#define INFLECTIONPOINT (6*TICRATE)
|
||||
#define SPARKLLOOPTIME 15 // must be odd
|
||||
|
||||
void F_StartEnding(void)
|
||||
{
|
||||
G_SetGamestate(GS_ENDING);
|
||||
wipetypepost = INT16_MAX;
|
||||
|
||||
// Just in case they're open ... somehow
|
||||
M_ClearMenus(true);
|
||||
|
||||
// Save before the credits sequence.
|
||||
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
|
||||
G_SaveGame((UINT32)cursaveslot);
|
||||
|
||||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
S_StopMusic(); // todo: placeholder
|
||||
S_StopSounds();
|
||||
|
||||
finalecount = -10; // what? this totally isn't a hack. why are you asking?
|
||||
|
||||
memset(sparkloffs, 0, sizeof(INT32)*3*2);
|
||||
sparklloop = 0;
|
||||
|
||||
endbrdr[1] = W_CachePatchName("ENDBRDR1", PU_LEVEL);
|
||||
|
||||
endegrk[0] = W_CachePatchName("ENDEGRK0", PU_LEVEL);
|
||||
endegrk[1] = W_CachePatchName("ENDEGRK1", PU_LEVEL);
|
||||
|
||||
endglow[0] = W_CachePatchName("ENDGLOW0", PU_LEVEL);
|
||||
endglow[1] = W_CachePatchName("ENDGLOW1", PU_LEVEL);
|
||||
|
||||
endbgsp[0] = W_CachePatchName("ENDBGSP0", PU_LEVEL);
|
||||
endbgsp[1] = W_CachePatchName("ENDBGSP1", PU_LEVEL);
|
||||
endbgsp[2] = W_CachePatchName("ENDBGSP2", PU_LEVEL);
|
||||
|
||||
endspkl[0] = W_CachePatchName("ENDSPKL0", PU_LEVEL);
|
||||
endspkl[1] = W_CachePatchName("ENDSPKL1", PU_LEVEL);
|
||||
endspkl[2] = W_CachePatchName("ENDSPKL2", PU_LEVEL);
|
||||
|
||||
endxpld[0] = W_CachePatchName("ENDXPLD0", PU_LEVEL);
|
||||
endxpld[1] = W_CachePatchName("ENDXPLD1", PU_LEVEL);
|
||||
endxpld[2] = W_CachePatchName("ENDXPLD2", PU_LEVEL);
|
||||
endxpld[3] = W_CachePatchName("ENDXPLD3", PU_LEVEL);
|
||||
|
||||
endescp[0] = W_CachePatchName("ENDESCP0", PU_LEVEL);
|
||||
endescp[1] = W_CachePatchName("ENDESCP1", PU_LEVEL);
|
||||
endescp[2] = W_CachePatchName("ENDESCP2", PU_LEVEL);
|
||||
endescp[3] = W_CachePatchName("ENDESCP3", PU_LEVEL);
|
||||
endescp[4] = W_CachePatchName("ENDESCP4", PU_LEVEL);
|
||||
|
||||
// so we only need to check once
|
||||
if ((goodending = ALL7EMERALDS(emeralds)))
|
||||
{
|
||||
UINT8 skinnum = players[consoleplayer].skin;
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 5)
|
||||
{
|
||||
sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
// character head, skin specific
|
||||
sprframe = &sprdef->spriteframes[2];
|
||||
endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||
sprframe = &sprdef->spriteframes[3];
|
||||
endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||
sprframe = &sprdef->spriteframes[4];
|
||||
endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||
}
|
||||
else // eh, yknow what? too lazy to put MISSINGs here. eggman wins if you don't give your character an ending firework display.
|
||||
{
|
||||
endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_LEVEL);
|
||||
endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_LEVEL);
|
||||
endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_LEVEL);
|
||||
}
|
||||
|
||||
endbrdr[0] = W_CachePatchName("ENDBRDR2", PU_LEVEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// eggman, skin nonspecific
|
||||
endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_LEVEL);
|
||||
endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_LEVEL);
|
||||
endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_LEVEL);
|
||||
|
||||
endbrdr[0] = W_CachePatchName("ENDBRDR0", PU_LEVEL);
|
||||
}
|
||||
}
|
||||
|
||||
void F_EndingTicker(void)
|
||||
{
|
||||
if (++finalecount > INFLECTIONPOINT*2)
|
||||
{
|
||||
F_StartCredits();
|
||||
wipetypepre = INT16_MAX;
|
||||
return;
|
||||
}
|
||||
|
||||
if (goodending && finalecount == INFLECTIONPOINT) // time to swap some assets
|
||||
{
|
||||
endegrk[0] = W_CachePatchName("ENDEGRK2", PU_LEVEL);
|
||||
endegrk[1] = W_CachePatchName("ENDEGRK3", PU_LEVEL);
|
||||
|
||||
endglow[0] = W_CachePatchName("ENDGLOW2", PU_LEVEL);
|
||||
endglow[1] = W_CachePatchName("ENDGLOW3", PU_LEVEL);
|
||||
|
||||
endxpld[0] = W_CachePatchName("ENDEGRK4", PU_LEVEL);
|
||||
}
|
||||
|
||||
if (++sparklloop == SPARKLLOOPTIME) // time to roll the randomisation again
|
||||
{
|
||||
angle_t workingangle = FixedAngle((M_RandomRange(-170, 80))<<FRACBITS)>>ANGLETOFINESHIFT;
|
||||
fixed_t workingradius = M_RandomKey(26);
|
||||
|
||||
sparkloffs[0][0] = (30<<FRACBITS) + workingradius*FINECOSINE(workingangle);
|
||||
sparkloffs[0][1] = (30<<FRACBITS) + workingradius*FINESINE(workingangle);
|
||||
|
||||
sparklloop = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void F_EndingDrawer(void)
|
||||
{
|
||||
INT32 x, y, i, j, parallaxticker;
|
||||
patch_t *rockpat;
|
||||
|
||||
if (!goodending || finalecount < INFLECTIONPOINT)
|
||||
rockpat = W_CachePatchName("ROID0000", PU_LEVEL);
|
||||
else
|
||||
rockpat = W_CachePatchName(va("ROID00%.2d", 34 - ((finalecount - INFLECTIONPOINT) % 35)), PU_LEVEL);
|
||||
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
|
||||
parallaxticker = finalecount - INFLECTIONPOINT;
|
||||
x = -((parallaxticker*20)<<FRACBITS)/INFLECTIONPOINT;
|
||||
y = ((parallaxticker*7)<<FRACBITS)/INFLECTIONPOINT;
|
||||
i = (((BASEVIDWIDTH-82)/2)+11)<<FRACBITS;
|
||||
j = (((BASEVIDHEIGHT-82)/2)+12)<<FRACBITS;
|
||||
|
||||
if (finalecount <= -10)
|
||||
;
|
||||
else if (finalecount < 0)
|
||||
V_DrawFadeFill(24, 24, BASEVIDWIDTH-48, BASEVIDHEIGHT-48, 0, 0, 10+finalecount);
|
||||
else if (finalecount <= 20)
|
||||
{
|
||||
V_DrawFill(24, 24, BASEVIDWIDTH-48, BASEVIDHEIGHT-48, 0);
|
||||
if (finalecount && finalecount < 20)
|
||||
{
|
||||
INT32 trans = (10-finalecount);
|
||||
if (trans < 0)
|
||||
{
|
||||
trans = -trans;
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, endbrdr[0]);
|
||||
}
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, trans<<V_ALPHASHIFT, endbrdr[1]);
|
||||
}
|
||||
else if (finalecount == 20)
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, endbrdr[0]);
|
||||
}
|
||||
else if (goodending && (parallaxticker == -2 || !parallaxticker))
|
||||
{
|
||||
V_DrawFill(24, 24, BASEVIDWIDTH-48, BASEVIDHEIGHT-48, 0);
|
||||
V_DrawFixedPatch(x+i, y+j, FRACUNIT, 0, endegrk[0],
|
||||
R_GetTranslationColormap(TC_BLINK, SKINCOLOR_BLACK, GTC_CACHE));
|
||||
//V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, endbrdr[1]);
|
||||
}
|
||||
else if (goodending && parallaxticker == -1)
|
||||
{
|
||||
V_DrawFixedPatch(x+i, y+j, FRACUNIT, 0, rockpat,
|
||||
R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE));
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, endbrdr[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean doexplosions = false;
|
||||
boolean borderstuff = false;
|
||||
INT32 tweakx = 0, tweaky = 0;
|
||||
|
||||
if (parallaxticker < 75) // f background's supposed to be visible
|
||||
{
|
||||
V_DrawFixedPatch(-(x/10), -(y/10), FRACUNIT, 0, endbgsp[0], NULL); // nebula
|
||||
V_DrawFixedPatch(-(x/5), -(y/5), FRACUNIT, 0, endbgsp[1], NULL); // sun
|
||||
V_DrawFixedPatch( 0, -(y/2), FRACUNIT, 0, endbgsp[2], NULL); // planet
|
||||
|
||||
// player's escape pod
|
||||
V_DrawFixedPatch((200<<FRACBITS)+(finalecount<<(FRACBITS-2)),
|
||||
(100<<FRACBITS)+(finalecount<<(FRACBITS-2)),
|
||||
FRACUNIT, 0, endescp[4], NULL);
|
||||
if (parallaxticker > -19)
|
||||
{
|
||||
INT32 trans = (-parallaxticker)>>1;
|
||||
if (trans < 0)
|
||||
trans = 0;
|
||||
V_DrawFixedPatch((200<<FRACBITS)+(finalecount<<(FRACBITS-2)),
|
||||
(100<<FRACBITS)+(finalecount<<(FRACBITS-2)),
|
||||
FRACUNIT, trans<<V_ALPHASHIFT, endescp[(finalecount/2)&3], NULL);
|
||||
}
|
||||
|
||||
if (goodending && parallaxticker > 0) // gunchedrock
|
||||
{
|
||||
INT32 scale = FRACUNIT + ((parallaxticker-10)<<7);
|
||||
INT32 trans = parallaxticker>>2;
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_JET, GTC_CACHE);
|
||||
|
||||
if (parallaxticker < 10)
|
||||
{
|
||||
tweakx = parallaxticker<<FRACBITS;
|
||||
tweaky = ((7*parallaxticker)<<(FRACBITS-2))/5;
|
||||
}
|
||||
else
|
||||
{
|
||||
tweakx = 10<<FRACBITS;
|
||||
tweaky = 7<<(FRACBITS-1);
|
||||
}
|
||||
i += tweakx;
|
||||
j -= tweaky;
|
||||
|
||||
x <<= 1;
|
||||
y <<= 1;
|
||||
|
||||
// center detritrus
|
||||
V_DrawFixedPatch(i-x, j-y, FRACUNIT, 0, endegrk[0], colormap);
|
||||
if (trans < 10)
|
||||
V_DrawFixedPatch(i-x, j-y, FRACUNIT, trans<<V_ALPHASHIFT, endegrk[0], NULL);
|
||||
|
||||
// ring detritrus
|
||||
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(2*x), (30*(FRACUNIT-scale))+j-(2*y) - ((7<<FRACBITS)/2), scale, 0, endegrk[1], colormap);
|
||||
if (trans < 10)
|
||||
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(2*x), (30*(FRACUNIT-scale))+j-(2*y), scale, trans<<V_ALPHASHIFT, endegrk[1], NULL);
|
||||
|
||||
scale += ((parallaxticker-10)<<7);
|
||||
|
||||
// shard detritrus
|
||||
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(x/2), (30*(FRACUNIT-scale))+j-(y/2) - ((7<<FRACBITS)/2), scale, 0, endxpld[0], colormap);
|
||||
if (trans < 10)
|
||||
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(x/2), (30*(FRACUNIT-scale))+j-(y/2), scale, trans<<V_ALPHASHIFT, endxpld[0], NULL);
|
||||
}
|
||||
}
|
||||
else if (goodending)
|
||||
{
|
||||
tweakx = 10<<FRACBITS;
|
||||
tweaky = 7<<(FRACBITS-1);
|
||||
i += tweakx;
|
||||
j += tweaky;
|
||||
x <<= 1;
|
||||
y <<= 1;
|
||||
}
|
||||
|
||||
if (goodending && parallaxticker > 0)
|
||||
{
|
||||
i -= (3+(tweakx<<1));
|
||||
j += tweaky<<2;
|
||||
}
|
||||
|
||||
if (parallaxticker <= 70) // eggrock/blackrock
|
||||
{
|
||||
INT32 trans;
|
||||
fixed_t scale = FRACUNIT;
|
||||
UINT8 *colormap[2] = {NULL, NULL};
|
||||
|
||||
x += i;
|
||||
y += j;
|
||||
|
||||
if (parallaxticker > 66)
|
||||
{
|
||||
scale = ((70 - parallaxticker)<<(FRACBITS-2));
|
||||
x += (30*(FRACUNIT-scale));
|
||||
y += (30*(FRACUNIT-scale));
|
||||
}
|
||||
else if ((parallaxticker > 60) || (goodending && parallaxticker > 0))
|
||||
;
|
||||
else
|
||||
{
|
||||
doexplosions = true;
|
||||
if (!sparklloop)
|
||||
{
|
||||
x += ((sparkloffs[0][0] < 30<<FRACBITS) ? FRACUNIT : -FRACUNIT);
|
||||
y += ((sparkloffs[0][1] < 30<<FRACBITS) ? FRACUNIT : -FRACUNIT);
|
||||
}
|
||||
}
|
||||
|
||||
if (goodending && finalecount > INFLECTIONPOINT)
|
||||
parallaxticker -= 40;
|
||||
|
||||
if ((-parallaxticker/4) < 5)
|
||||
{
|
||||
trans = (-parallaxticker/4) + 5;
|
||||
if (trans < 0)
|
||||
trans = 0;
|
||||
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, endglow[(finalecount & 1) ? 0 : 1], NULL);
|
||||
}
|
||||
|
||||
if (goodending && finalecount > INFLECTIONPOINT)
|
||||
{
|
||||
if (finalecount < INFLECTIONPOINT+10)
|
||||
V_DrawFadeFill(24, 24, BASEVIDWIDTH-48, BASEVIDHEIGHT-48, 0, 0, INFLECTIONPOINT+10-finalecount);
|
||||
parallaxticker -= 30;
|
||||
}
|
||||
|
||||
if ((parallaxticker/2) > -15)
|
||||
colormap[0] = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
|
||||
V_DrawFixedPatch(x, y, scale, 0, rockpat, colormap[0]);
|
||||
if ((parallaxticker/2) > -25)
|
||||
{
|
||||
trans = (parallaxticker/2) + 15;
|
||||
if (trans < 0)
|
||||
trans = -trans;
|
||||
if (trans < 10)
|
||||
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, rockpat,
|
||||
R_GetTranslationColormap(TC_BLINK, SKINCOLOR_AQUA, GTC_CACHE));
|
||||
}
|
||||
|
||||
if (goodending && finalecount > INFLECTIONPOINT)
|
||||
{
|
||||
if (finalecount < INFLECTIONPOINT+10)
|
||||
V_DrawFixedPatch(x, y, scale, (finalecount-INFLECTIONPOINT)<<V_ALPHASHIFT, rockpat,
|
||||
R_GetTranslationColormap(TC_BLINK, SKINCOLOR_BLACK, GTC_CACHE));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((-parallaxticker/2) < -5)
|
||||
colormap[1] = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
|
||||
|
||||
V_DrawFixedPatch(x, y, scale, 0, endegrk[0], colormap[1]);
|
||||
|
||||
if ((-parallaxticker/2) < 5)
|
||||
{
|
||||
trans = (-parallaxticker/2) + 5;
|
||||
if (trans < 0)
|
||||
trans = -trans;
|
||||
if (trans < 10)
|
||||
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, endegrk[1], NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // firework
|
||||
{
|
||||
fixed_t scale = FRACUNIT;
|
||||
INT32 frame;
|
||||
UINT8 *colormap = NULL;
|
||||
parallaxticker -= 70;
|
||||
x += ((BASEVIDWIDTH-3)<<(FRACBITS-1)) - tweakx;
|
||||
y += (BASEVIDHEIGHT<<(FRACBITS-1)) + tweaky;
|
||||
borderstuff = true;
|
||||
|
||||
if (parallaxticker < 5)
|
||||
{
|
||||
scale = (parallaxticker<<FRACBITS)/4;
|
||||
V_DrawFadeFill(24, 24, BASEVIDWIDTH-48, BASEVIDHEIGHT-48, 0, 31, parallaxticker*2);
|
||||
}
|
||||
else
|
||||
scale += (parallaxticker-4)<<5;
|
||||
|
||||
if (goodending)
|
||||
colormap = R_GetTranslationColormap(players[consoleplayer].skin, players[consoleplayer].skincolor, GTC_CACHE);
|
||||
|
||||
if ((frame = ((parallaxticker & 1) ? 1 : 0) + (parallaxticker/TICRATE)) < 3)
|
||||
V_DrawFixedPatch(x, y, scale, 0, endfwrk[frame], colormap);
|
||||
}
|
||||
|
||||
// explosions
|
||||
if (sparklloop >= 3 && doexplosions)
|
||||
{
|
||||
INT32 boomtime = parallaxticker - sparklloop;
|
||||
|
||||
x = ((((BASEVIDWIDTH-82)/2)+11)<<FRACBITS) - ((boomtime*20)<<FRACBITS)/INFLECTIONPOINT;
|
||||
y = ((((BASEVIDHEIGHT-82)/2)+12)<<FRACBITS) + ((boomtime*7)<<FRACBITS)/INFLECTIONPOINT;
|
||||
|
||||
V_DrawFixedPatch(x + sparkloffs[0][0], y + sparkloffs[0][1],
|
||||
FRACUNIT, 0, endxpld[sparklloop/4], NULL);
|
||||
}
|
||||
|
||||
// initial fade
|
||||
if (finalecount < 30)
|
||||
V_DrawFadeFill(24, 24, BASEVIDWIDTH-48, BASEVIDHEIGHT-48, 0, 0, 30-finalecount);
|
||||
|
||||
// border - only emeralds can exist outside it
|
||||
{
|
||||
INT32 trans = 0;
|
||||
if (borderstuff)
|
||||
trans = (10*parallaxticker)/(3*TICRATE);
|
||||
if (trans < 10)
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, trans<<V_ALPHASHIFT, endbrdr[0]);
|
||||
if (borderstuff && parallaxticker < 11)
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, (parallaxticker-1)<<V_ALPHASHIFT, endbrdr[1]);
|
||||
else if (goodending && finalecount > INFLECTIONPOINT && finalecount < INFLECTIONPOINT+10)
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, (finalecount-INFLECTIONPOINT)<<V_ALPHASHIFT, endbrdr[1]);
|
||||
}
|
||||
|
||||
// emeralds and emerald accessories
|
||||
if (goodending && finalecount >= TICRATE && finalecount < INFLECTIONPOINT)
|
||||
{
|
||||
INT32 workingtime = finalecount - TICRATE;
|
||||
fixed_t radius = ((vid.width/vid.dupx)*(INFLECTIONPOINT - TICRATE - workingtime))/(INFLECTIONPOINT - TICRATE);
|
||||
angle_t fa;
|
||||
INT32 eemeralds_cur[4];
|
||||
char patchname[7] = "CEMGx0";
|
||||
|
||||
radius <<= FRACBITS;
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
if (i == 1)
|
||||
workingtime -= sparklloop;
|
||||
else if (i)
|
||||
workingtime -= SPARKLLOOPTIME;
|
||||
eemeralds_cur[i] = (workingtime % 360)<<FRACBITS;
|
||||
}
|
||||
|
||||
// sparkles
|
||||
for (i = 0; i < 7; ++i)
|
||||
{
|
||||
UINT8* colormap;
|
||||
skincolors_t col = SKINCOLOR_GREEN;
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
col = SKINCOLOR_MAGENTA;
|
||||
break;
|
||||
case 2:
|
||||
col = SKINCOLOR_BLUE;
|
||||
break;
|
||||
case 3:
|
||||
col = SKINCOLOR_SKY;
|
||||
break;
|
||||
case 4:
|
||||
col = SKINCOLOR_ORANGE;
|
||||
break;
|
||||
case 5:
|
||||
col = SKINCOLOR_RED;
|
||||
break;
|
||||
case 6:
|
||||
col = SKINCOLOR_GREY;
|
||||
default:
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_CACHE);
|
||||
|
||||
j = (sparklloop & 1) ? 2 : 3;
|
||||
while (j)
|
||||
{
|
||||
fa = (FixedAngle(eemeralds_cur[j])>>ANGLETOFINESHIFT) & FINEMASK;
|
||||
x = (BASEVIDWIDTH<<(FRACBITS-1)) + FixedMul(FINECOSINE(fa),radius);
|
||||
y = (BASEVIDHEIGHT<<(FRACBITS-1)) + FixedMul(FINESINE(fa),radius);
|
||||
eemeralds_cur[j] += (360<<FRACBITS)/7;
|
||||
|
||||
// if j == 0 - alternate between 0 and 1
|
||||
// 1 - 1 and 2
|
||||
// 2 - 2 and not rendered
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, 0, endspkl[(j - ((sparklloop & 1) ? 0 : 1))], colormap);
|
||||
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
// ...then emeralds themselves
|
||||
for (i = 0; i < 7; ++i)
|
||||
{
|
||||
fa = (FixedAngle(eemeralds_cur[0])>>ANGLETOFINESHIFT) & FINEMASK;
|
||||
x = (BASEVIDWIDTH<<(FRACBITS-1)) + FixedMul(FINECOSINE(fa),radius);
|
||||
y = ((BASEVIDHEIGHT+16)<<(FRACBITS-1)) + FixedMul(FINESINE(fa),radius);
|
||||
eemeralds_cur[0] += (360<<FRACBITS)/7;
|
||||
|
||||
patchname[4] = 'A'+(char)i;
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, 0, W_CachePatchName(patchname, PU_LEVEL), NULL);
|
||||
}
|
||||
} // if (goodending...
|
||||
} // (finalecount > 20)
|
||||
|
||||
// look, i make an ending for you last-minute, the least you could do is let me have this
|
||||
if (cv_soundtest.value == 413)
|
||||
{
|
||||
INT32 trans = 0;
|
||||
boolean donttouch = false;
|
||||
const char *str;
|
||||
if (goodending)
|
||||
str = va("[S] %s: Engage.", skins[players[consoleplayer].skin].realname);
|
||||
else
|
||||
str = "[S] Eggman: Abscond.";
|
||||
|
||||
if (finalecount < 10)
|
||||
trans = (10-finalecount)/2;
|
||||
else if (finalecount > (2*INFLECTIONPOINT) - 20)
|
||||
{
|
||||
trans = 10 + (finalecount/2) - INFLECTIONPOINT;
|
||||
donttouch = true;
|
||||
}
|
||||
|
||||
if (trans != 10)
|
||||
{
|
||||
//colset(linkmap, 164, 165, 169); -- the ideal purple colour to represent a clicked in-game link, but not worth it just for a soundtest-controlled secret
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 8, V_ALLOWLOWERCASE|(trans<<V_ALPHASHIFT), str);
|
||||
V_DrawCharacter(32, BASEVIDHEIGHT-16, '>'|(trans<<V_ALPHASHIFT), false);
|
||||
V_DrawString(40, ((finalecount == (2*INFLECTIONPOINT)-(20+TICRATE)) ? 1 : 0)+BASEVIDHEIGHT-16, ((timesBeaten || finalecount >= (2*INFLECTIONPOINT)-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<<V_ALPHASHIFT), " [S] ===>");
|
||||
}
|
||||
|
||||
if (finalecount > (2*INFLECTIONPOINT)-(20+(2*TICRATE)))
|
||||
{
|
||||
INT32 trans2 = abs((5*FINECOSINE((FixedAngle((finalecount*5)<<FRACBITS)>>ANGLETOFINESHIFT & FINEMASK)))>>FRACBITS)+2;
|
||||
if (!donttouch)
|
||||
{
|
||||
trans = 10 + ((2*INFLECTIONPOINT)-(20+(2*TICRATE))) - finalecount;
|
||||
if (trans > trans2)
|
||||
trans2 = trans;
|
||||
}
|
||||
else
|
||||
trans2 += 2*trans;
|
||||
if (trans2 < 10)
|
||||
V_DrawCharacter(26, BASEVIDHEIGHT-33, '\x1C'|(trans2<<V_ALPHASHIFT), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef SPARKLLOOPTIME
|
||||
|
||||
// ==========
|
||||
// GAME END
|
||||
// ==========
|
||||
|
@ -1378,6 +2054,7 @@ void F_StartGameEnd(void)
|
|||
paused = false;
|
||||
CON_ToggleOff();
|
||||
S_StopMusic();
|
||||
S_StopSounds();
|
||||
|
||||
// In case menus are still up?!!
|
||||
M_ClearMenus(true);
|
||||
|
@ -1892,7 +2569,7 @@ boolean F_ContinueResponder(event_t *event)
|
|||
keypressed = true;
|
||||
imcontinuing = true;
|
||||
continuetime = TICRATE;
|
||||
S_StartSound(0, sfx_itemup);
|
||||
S_StartSound(NULL, sfx_itemup);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2004,6 +2681,7 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
|||
cutscenes[cutnum]->scene[scenenum].musswitchposition, 0, 0);
|
||||
else
|
||||
S_StopMusic();
|
||||
S_StopSounds();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2044,7 +2722,7 @@ void F_CutsceneDrawer(void)
|
|||
F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeoutid, true);
|
||||
}
|
||||
|
||||
V_DrawString(textxpos, textypos, 0, cutscene_disptext);
|
||||
V_DrawString(textxpos, textypos, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
}
|
||||
|
||||
void F_CutsceneTicker(void)
|
||||
|
|
|
@ -46,6 +46,9 @@ void F_GameEvaluationDrawer(void);
|
|||
void F_StartGameEvaluation(void);
|
||||
void F_GameEvaluationTicker(void);
|
||||
|
||||
void F_EndingTicker(void);
|
||||
void F_EndingDrawer(void);
|
||||
|
||||
void F_CreditTicker(void);
|
||||
void F_CreditDrawer(void);
|
||||
|
||||
|
@ -63,6 +66,7 @@ boolean F_GetPromptHideHud(fixed_t y);
|
|||
void F_StartGameEnd(void);
|
||||
void F_StartIntro(void);
|
||||
void F_StartTitleScreen(void);
|
||||
void F_StartEnding(void);
|
||||
void F_StartCredits(void);
|
||||
|
||||
boolean F_ContinueResponder(event_t *event);
|
||||
|
@ -82,7 +86,6 @@ typedef enum
|
|||
|
||||
// Current menu parameters
|
||||
|
||||
extern UINT8 titlemapinaction;
|
||||
extern mobj_t *titlemapcameraref;
|
||||
extern char curbgname[8];
|
||||
extern SINT8 curfadevalue;
|
||||
|
@ -126,6 +129,7 @@ enum
|
|||
wipe_evaluation_toblack,
|
||||
wipe_gameend_toblack,
|
||||
wipe_intro_toblack,
|
||||
wipe_ending_toblack,
|
||||
wipe_cutscene_toblack,
|
||||
|
||||
// custom intermissions
|
||||
|
@ -142,15 +146,16 @@ enum
|
|||
wipe_evaluation_final,
|
||||
wipe_gameend_final,
|
||||
wipe_intro_final,
|
||||
wipe_ending_final,
|
||||
wipe_cutscene_final,
|
||||
|
||||
// custom intermissions
|
||||
wipe_specinter_final,
|
||||
wipe_multinter_final,
|
||||
|
||||
NUMWIPEDEFS
|
||||
NUMWIPEDEFS,
|
||||
WIPEFINALSHIFT = (wipe_level_final-wipe_level_toblack)
|
||||
};
|
||||
#define WIPEFINALSHIFT 13
|
||||
extern UINT8 wipedefs[NUMWIPEDEFS];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,6 +54,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
|
|||
0, // wipe_evaluation_toblack
|
||||
0, // wipe_gameend_toblack
|
||||
99, // wipe_intro_toblack (hardcoded)
|
||||
0, // wipe_ending_toblack
|
||||
99, // wipe_cutscene_toblack (hardcoded)
|
||||
|
||||
0, // wipe_specinter_toblack
|
||||
|
@ -69,6 +70,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
|
|||
0, // wipe_evaluation_final
|
||||
0, // wipe_gameend_final
|
||||
99, // wipe_intro_final (hardcoded)
|
||||
0, // wipe_ending_final
|
||||
99, // wipe_cutscene_final (hardcoded)
|
||||
|
||||
0, // wipe_specinter_final
|
||||
|
|
35
src/g_game.c
35
src/g_game.c
|
@ -152,7 +152,7 @@ cutscene_t *cutscenes[128];
|
|||
textprompt_t *textprompts[MAX_PROMPTS];
|
||||
|
||||
INT16 nextmapoverride;
|
||||
boolean skipstats;
|
||||
UINT8 skipstats;
|
||||
|
||||
// Pointers to each CTF flag
|
||||
mobj_t *redflag;
|
||||
|
@ -1842,7 +1842,7 @@ boolean G_Responder(event_t *ev)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
else if (gamestate == GS_CREDITS)
|
||||
else if (gamestate == GS_CREDITS || gamestate == GS_ENDING) // todo: keep ending here?
|
||||
{
|
||||
if (HU_Responder(ev))
|
||||
return true; // chat ate the event
|
||||
|
@ -2032,6 +2032,12 @@ void G_Ticker(boolean run)
|
|||
F_IntroTicker();
|
||||
break;
|
||||
|
||||
case GS_ENDING:
|
||||
if (run)
|
||||
F_EndingTicker();
|
||||
HU_Ticker();
|
||||
break;
|
||||
|
||||
case GS_CUTSCENE:
|
||||
if (run)
|
||||
F_CutsceneTicker();
|
||||
|
@ -2645,7 +2651,7 @@ void G_DoReborn(INT32 playernum)
|
|||
//nextmapoverride = spstage_start;
|
||||
nextmapoverride = gamemap;
|
||||
countdown2 = TICRATE;
|
||||
skipstats = true;
|
||||
skipstats = 2;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
@ -2849,6 +2855,10 @@ void G_ExitLevel(void)
|
|||
// Remove CEcho text on round end.
|
||||
HU_ClearCEcho();
|
||||
}
|
||||
else if (gamestate == GS_ENDING)
|
||||
{
|
||||
F_StartCredits();
|
||||
}
|
||||
else if (gamestate == GS_CREDITS)
|
||||
{
|
||||
F_StartGameEvaluation();
|
||||
|
@ -3116,7 +3126,7 @@ static void G_DoCompleted(void)
|
|||
nextmap = cm;
|
||||
}
|
||||
|
||||
if (nextmap < 0 || (nextmap >= NUMMAPS && nextmap < 1100-1) || nextmap > 1102-1)
|
||||
if (nextmap < 0 || (nextmap >= NUMMAPS && nextmap < 1100-1) || nextmap > 1103-1)
|
||||
I_Error("Followed map %d to invalid map %d\n", prevmap + 1, nextmap + 1);
|
||||
|
||||
// wrap around in race
|
||||
|
@ -3170,7 +3180,7 @@ void G_AfterIntermission(void)
|
|||
{
|
||||
HU_ClearCEcho();
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking) // Start a custom cutscene.
|
||||
if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene.
|
||||
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
|
||||
else
|
||||
{
|
||||
|
@ -3282,6 +3292,11 @@ void G_EndGame(void)
|
|||
// Only do evaluation and credits in coop games.
|
||||
if (gametype == GT_COOP)
|
||||
{
|
||||
if (nextmap == 1103-1) // end game with ending
|
||||
{
|
||||
F_StartEnding();
|
||||
return;
|
||||
}
|
||||
if (nextmap == 1102-1) // end game with credits
|
||||
{
|
||||
F_StartCredits();
|
||||
|
@ -3700,7 +3715,7 @@ void G_SaveGame(UINT32 slot)
|
|||
backup = va("%s",savename);
|
||||
|
||||
// save during evaluation or credits? game's over, folks!
|
||||
if (gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
|
||||
if (gamestate == GS_ENDING || gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
|
||||
gamecomplete = true;
|
||||
|
||||
gameaction = ga_nothing;
|
||||
|
@ -4366,7 +4381,7 @@ void G_WriteGhostTic(mobj_t *ghost)
|
|||
ghostext.flags = 0;
|
||||
}
|
||||
|
||||
if (ghost->player && ghost->player->followmobj)
|
||||
if (ghost->player && ghost->player->followmobj) // bloats tails runs but what can ya do
|
||||
{
|
||||
INT16 temp;
|
||||
|
||||
|
@ -4592,6 +4607,9 @@ void G_GhostTicker(void)
|
|||
switch(g->color)
|
||||
{
|
||||
default:
|
||||
case GHC_RETURNSKIN:
|
||||
g->mo->skin = g->oldmo.skin;
|
||||
// fallthru
|
||||
case GHC_NORMAL: // Go back to skin color
|
||||
g->mo->color = g->oldmo.color;
|
||||
break;
|
||||
|
@ -4602,6 +4620,9 @@ void G_GhostTicker(void)
|
|||
case GHC_FIREFLOWER: // Fireflower
|
||||
g->mo->color = SKINCOLOR_WHITE;
|
||||
break;
|
||||
case GHC_NIGHTSSKIN: // not actually a colour
|
||||
g->mo->skin = &skins[DEFAULTNIGHTSSKIN];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (xziptic & EZT_FLIP)
|
||||
|
|
|
@ -56,6 +56,8 @@ extern INT16 rw_maximums[NUM_WEAPONS];
|
|||
extern INT32 pausedelay;
|
||||
extern boolean pausebreakkey;
|
||||
|
||||
extern boolean promptactive;
|
||||
|
||||
// used in game menu
|
||||
extern consvar_t cv_tutorialprompt;
|
||||
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard;
|
||||
|
@ -140,7 +142,9 @@ typedef enum
|
|||
GHC_NORMAL = 0,
|
||||
GHC_SUPER,
|
||||
GHC_FIREFLOWER,
|
||||
GHC_INVINCIBLE
|
||||
GHC_INVINCIBLE,
|
||||
GHC_NIGHTSSKIN, // not actually a colour
|
||||
GHC_RETURNSKIN // ditto
|
||||
} ghostcolor_t;
|
||||
|
||||
// Record/playback tics
|
||||
|
|
|
@ -27,12 +27,14 @@ typedef enum
|
|||
|
||||
GS_TITLESCREEN, // title screen
|
||||
GS_TIMEATTACK, // time attack menu
|
||||
|
||||
GS_CREDITS, // credit sequence
|
||||
GS_EVALUATION, // Evaluation at the end of a game.
|
||||
GS_GAMEEND, // game end sequence
|
||||
GS_GAMEEND, // game end sequence - "did you get all those chaos emeralds?"
|
||||
|
||||
// Hardcoded fades or other fading methods
|
||||
GS_INTRO, // introduction
|
||||
GS_ENDING, // currently shared between bad and good endings
|
||||
GS_CUTSCENE, // custom cutscene
|
||||
|
||||
// Not fadable
|
||||
|
@ -50,6 +52,7 @@ typedef enum
|
|||
} gameaction_t;
|
||||
|
||||
extern gamestate_t gamestate;
|
||||
extern UINT8 titlemapinaction;
|
||||
extern UINT8 ultimatemode; // was sk_insane
|
||||
extern gameaction_t gameaction;
|
||||
|
||||
|
|
|
@ -283,7 +283,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
|
||||
if (!(option & V_SCALEPATCHMASK))
|
||||
{
|
||||
// if it's meant to cover the whole screen, black out the rest
|
||||
// if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT)
|
||||
// cx and cy are possibly *slightly* off from float maths
|
||||
// This is done before here compared to software because we directly alter cx and cy to centre
|
||||
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
|
||||
|
@ -291,8 +291,11 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
// Need to temporarily cache the real patch to get the colour of the top left pixel
|
||||
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
|
||||
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
|
||||
const UINT8 *source = (const UINT8 *)(column) + 3;
|
||||
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
||||
if (!column->topdelta)
|
||||
{
|
||||
const UINT8 *source = (const UINT8 *)(column) + 3;
|
||||
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
||||
}
|
||||
Z_Free(realpatch);
|
||||
}
|
||||
// centre screen
|
||||
|
@ -439,7 +442,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
|
|||
|
||||
if (!(option & V_SCALEPATCHMASK))
|
||||
{
|
||||
// if it's meant to cover the whole screen, black out the rest
|
||||
// if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT)
|
||||
// cx and cy are possibly *slightly* off from float maths
|
||||
// This is done before here compared to software because we directly alter cx and cy to centre
|
||||
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
|
||||
|
@ -447,8 +450,11 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
|
|||
// Need to temporarily cache the real patch to get the colour of the top left pixel
|
||||
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
|
||||
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
|
||||
const UINT8 *source = (const UINT8 *)(column) + 3;
|
||||
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
||||
if (!column->topdelta)
|
||||
{
|
||||
const UINT8 *source = (const UINT8 *)(column) + 3;
|
||||
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
||||
}
|
||||
Z_Free(realpatch);
|
||||
}
|
||||
// centre screen
|
||||
|
@ -683,8 +689,183 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
|
|||
}
|
||||
else // Do TRANSMAP** fade.
|
||||
{
|
||||
Surf.FlatColor.rgba = pLocalPalette[color].rgba;
|
||||
Surf.FlatColor.s.alpha = (UINT8)(strength*25.5f);
|
||||
Surf.FlatColor.rgba = V_GetColor(color).rgba;
|
||||
Surf.FlatColor.s.alpha = softwaretranstogl[strength];
|
||||
}
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// HWR_DrawFadeFill : draw flat coloured rectangle, with transparency
|
||||
// -----------------+
|
||||
void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 actualcolor, UINT8 strength)
|
||||
{
|
||||
FOutVector v[4];
|
||||
FSurfaceInfo Surf;
|
||||
float fx, fy, fw, fh;
|
||||
|
||||
UINT8 perplayershuffle = 0;
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
|
||||
if (splitscreen && (color & V_PERPLAYER))
|
||||
{
|
||||
fixed_t adjusty = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
||||
h >>= 1;
|
||||
y >>= 1;
|
||||
#ifdef QUADS
|
||||
if (splitscreen > 1) // 3 or 4 players
|
||||
{
|
||||
fixed_t adjustx = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
||||
w >>= 1;
|
||||
x >>= 1;
|
||||
if (stplyr == &players[displayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 4;
|
||||
color &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT;
|
||||
}
|
||||
else if (stplyr == &players[secondarydisplayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 8;
|
||||
x += adjustx;
|
||||
color &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT;
|
||||
}
|
||||
else if (stplyr == &players[thirddisplayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 4;
|
||||
y += adjusty;
|
||||
color &= ~V_SNAPTOTOP|V_SNAPTORIGHT;
|
||||
}
|
||||
else //if (stplyr == &players[fourthdisplayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 8;
|
||||
x += adjustx;
|
||||
y += adjusty;
|
||||
color &= ~V_SNAPTOTOP|V_SNAPTOLEFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// 2 players
|
||||
{
|
||||
if (stplyr == &players[displayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
color &= ~V_SNAPTOBOTTOM;
|
||||
}
|
||||
else //if (stplyr == &players[secondarydisplayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
y += adjusty;
|
||||
color &= ~V_SNAPTOTOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fx = (float)x;
|
||||
fy = (float)y;
|
||||
fw = (float)w;
|
||||
fh = (float)h;
|
||||
|
||||
if (!(color & V_NOSCALESTART))
|
||||
{
|
||||
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
|
||||
|
||||
fx *= dupx;
|
||||
fy *= dupy;
|
||||
fw *= dupx;
|
||||
fh *= dupy;
|
||||
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
||||
{
|
||||
if (color & V_SNAPTORIGHT)
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
||||
else if (!(color & V_SNAPTOLEFT))
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
|
||||
if (perplayershuffle & 4)
|
||||
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
||||
else if (perplayershuffle & 8)
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
||||
}
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
||||
{
|
||||
// same thing here
|
||||
if (color & V_SNAPTOBOTTOM)
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
||||
else if (!(color & V_SNAPTOTOP))
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
|
||||
if (perplayershuffle & 1)
|
||||
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
||||
else if (perplayershuffle & 2)
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (fx >= vid.width || fy >= vid.height)
|
||||
return;
|
||||
if (fx < 0)
|
||||
{
|
||||
fw += fx;
|
||||
fx = 0;
|
||||
}
|
||||
if (fy < 0)
|
||||
{
|
||||
fh += fy;
|
||||
fy = 0;
|
||||
}
|
||||
|
||||
if (fw <= 0 || fh <= 0)
|
||||
return;
|
||||
if (fx + fw > vid.width)
|
||||
fw = (float)vid.width - fx;
|
||||
if (fy + fh > vid.height)
|
||||
fh = (float)vid.height - fy;
|
||||
|
||||
fx = -1 + fx / (vid.width / 2);
|
||||
fy = 1 - fy / (vid.height / 2);
|
||||
fw = fw / (vid.width / 2);
|
||||
fh = fh / (vid.height / 2);
|
||||
|
||||
v[0].x = v[3].x = fx;
|
||||
v[2].x = v[1].x = fx + fw;
|
||||
v[0].y = v[1].y = fy;
|
||||
v[2].y = v[3].y = fy - fh;
|
||||
|
||||
//Hurdler: do we still use this argb color? if not, we should remove it
|
||||
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
||||
|
||||
v[0].sow = v[3].sow = 0.0f;
|
||||
v[2].sow = v[1].sow = 1.0f;
|
||||
v[0].tow = v[1].tow = 0.0f;
|
||||
v[2].tow = v[3].tow = 1.0f;
|
||||
|
||||
if (actualcolor & 0xFF00) // Do COLORMAP fade.
|
||||
{
|
||||
Surf.FlatColor.rgba = UINT2RGBA(0x01010160);
|
||||
Surf.FlatColor.s.alpha = (strength*8);
|
||||
}
|
||||
else // Do TRANSMAP** fade.
|
||||
{
|
||||
Surf.FlatColor.rgba = V_GetColor(actualcolor).rgba;
|
||||
Surf.FlatColor.s.alpha = softwaretranstogl[strength];
|
||||
}
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
||||
}
|
||||
|
@ -905,54 +1086,117 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
|
|||
FSurfaceInfo Surf;
|
||||
float fx, fy, fw, fh;
|
||||
|
||||
if (w < 0 || h < 0)
|
||||
return; // consistency w/ software
|
||||
UINT8 perplayershuffle = 0;
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
|
||||
if (splitscreen && (color & V_PERPLAYER))
|
||||
{
|
||||
fixed_t adjusty = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
||||
h >>= 1;
|
||||
y >>= 1;
|
||||
#ifdef QUADS
|
||||
if (splitscreen > 1) // 3 or 4 players
|
||||
{
|
||||
fixed_t adjustx = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
||||
w >>= 1;
|
||||
x >>= 1;
|
||||
if (stplyr == &players[displayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 4;
|
||||
color &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT;
|
||||
}
|
||||
else if (stplyr == &players[secondarydisplayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 8;
|
||||
x += adjustx;
|
||||
color &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT;
|
||||
}
|
||||
else if (stplyr == &players[thirddisplayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 4;
|
||||
y += adjusty;
|
||||
color &= ~V_SNAPTOTOP|V_SNAPTORIGHT;
|
||||
}
|
||||
else //if (stplyr == &players[fourthdisplayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 8;
|
||||
x += adjustx;
|
||||
y += adjusty;
|
||||
color &= ~V_SNAPTOTOP|V_SNAPTOLEFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// 2 players
|
||||
{
|
||||
if (stplyr == &players[displayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
color &= ~V_SNAPTOBOTTOM;
|
||||
}
|
||||
else //if (stplyr == &players[secondarydisplayplayer])
|
||||
{
|
||||
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
y += adjusty;
|
||||
color &= ~V_SNAPTOTOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fx = (float)x;
|
||||
fy = (float)y;
|
||||
fw = (float)w;
|
||||
fh = (float)h;
|
||||
|
||||
if (!(options & V_NOSCALESTART))
|
||||
if (!(color & V_NOSCALESTART))
|
||||
{
|
||||
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
|
||||
|
||||
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
|
||||
{
|
||||
RGBA_t rgbaColour = V_GetColor(color);
|
||||
FRGBAFloat clearColour;
|
||||
clearColour.red = (float)rgbaColour.s.red / 255;
|
||||
clearColour.green = (float)rgbaColour.s.green / 255;
|
||||
clearColour.blue = (float)rgbaColour.s.blue / 255;
|
||||
clearColour.alpha = 1;
|
||||
HWD.pfnClearBuffer(true, false, &clearColour);
|
||||
return;
|
||||
}
|
||||
|
||||
fx *= dupx;
|
||||
fy *= dupy;
|
||||
fw *= dupx;
|
||||
fh *= dupy;
|
||||
|
||||
if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
|
||||
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
||||
{
|
||||
if (options & V_SNAPTORIGHT)
|
||||
if (color & V_SNAPTORIGHT)
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
||||
else if (!(options & V_SNAPTOLEFT))
|
||||
else if (!(color & V_SNAPTOLEFT))
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
|
||||
if (perplayershuffle & 4)
|
||||
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
||||
else if (perplayershuffle & 8)
|
||||
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
||||
}
|
||||
if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
|
||||
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
||||
{
|
||||
// same thing here
|
||||
if (options & V_SNAPTOBOTTOM)
|
||||
if (color & V_SNAPTOBOTTOM)
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
||||
else if (!(options & V_SNAPTOTOP))
|
||||
else if (!(color & V_SNAPTOTOP))
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
|
||||
if (perplayershuffle & 1)
|
||||
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
||||
else if (perplayershuffle & 2)
|
||||
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,9 +1256,6 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
|
|||
|
||||
UINT8 perplayershuffle = 0;
|
||||
|
||||
if (w < 0 || h < 0)
|
||||
return; // consistency w/ software
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
// |/ |
|
||||
|
|
|
@ -49,6 +49,7 @@ void HWR_CreatePlanePolygons(INT32 bspnum);
|
|||
void HWR_CreateStaticLightmaps(INT32 bspnum);
|
||||
void HWR_PrepLevelCache(size_t pnumtextures);
|
||||
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
|
||||
void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 actualcolor, UINT8 strength);
|
||||
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right.
|
||||
void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum);
|
||||
|
||||
|
|
|
@ -1198,6 +1198,9 @@ static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *p
|
|||
if (!md2 || !skin)
|
||||
return 0;
|
||||
|
||||
if ((spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
return 0;
|
||||
|
||||
while (!(md2->model->spr2frames[spr2*2 + 1])
|
||||
&& spr2 != SPR2_STND
|
||||
&& ++i != 32) // recursion limiter
|
||||
|
@ -1220,7 +1223,10 @@ static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *p
|
|||
& SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL;
|
||||
break;
|
||||
case SPR2_TIRE:
|
||||
spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||
spr2 = ((player
|
||||
? player->charability
|
||||
: skin->ability)
|
||||
== CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||
break;
|
||||
|
||||
// Use the handy list, that's what it's there for!
|
||||
|
@ -1232,6 +1238,9 @@ static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *p
|
|||
spr2 |= super;
|
||||
}
|
||||
|
||||
if (i >= 32) // probably an infinite loop...
|
||||
return 0;
|
||||
|
||||
return spr2;
|
||||
}
|
||||
|
||||
|
|
|
@ -2138,7 +2138,7 @@ void HU_Drawer(void)
|
|||
if (!Playing()
|
||||
|| gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE
|
||||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION
|
||||
|| gamestate == GS_GAMEEND)
|
||||
|| gamestate == GS_ENDING || gamestate == GS_GAMEEND)
|
||||
return;
|
||||
|
||||
// draw multiplayer rankings
|
||||
|
|
156
src/info.c
156
src/info.c
|
@ -578,7 +578,8 @@ char spr2names[NUMPLAYERSPRITES][5] =
|
|||
"TALB",
|
||||
|
||||
"SIGN",
|
||||
"LIFE"
|
||||
"LIFE",
|
||||
"XTRA",
|
||||
};
|
||||
playersprite_t free_spr2 = SPR2_FIRSTFREESLOT;
|
||||
|
||||
|
@ -595,7 +596,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
|
|||
SPR2_DEAD, // SPR2_DRWN,
|
||||
0, // SPR2_ROLL,
|
||||
SPR2_SPNG, // SPR2_GASP,
|
||||
0, // SPR2_JUMP, (conditional)
|
||||
0, // SPR2_JUMP, (conditional, will never be referenced)
|
||||
SPR2_FALL, // SPR2_SPNG,
|
||||
SPR2_WALK, // SPR2_FALL,
|
||||
0, // SPR2_EDGE,
|
||||
|
@ -605,7 +606,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
|
|||
|
||||
SPR2_SPNG, // SPR2_FLY ,
|
||||
SPR2_FLY , // SPR2_SWIM,
|
||||
0, // SPR2_TIRE, (conditional)
|
||||
0, // SPR2_TIRE, (conditional, will never be referenced)
|
||||
|
||||
SPR2_FLY , // SPR2_GLID,
|
||||
SPR2_CLMB, // SPR2_CLNG,
|
||||
|
@ -632,7 +633,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
|
|||
SPR2_NSTN, // SPR2_NPUL,
|
||||
FF_SPR2SUPER|SPR2_ROLL, // SPR2_NATK,
|
||||
|
||||
0, // SPR2_NGT0, (should never be referenced)
|
||||
0, // SPR2_NGT0, (will never be referenced unless skin 0 lacks this)
|
||||
SPR2_NGT0, // SPR2_NGT1,
|
||||
SPR2_NGT1, // SPR2_NGT2,
|
||||
SPR2_NGT2, // SPR2_NGT3,
|
||||
|
@ -660,7 +661,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
|
|||
SPR2_NGTB, // SPR2_DRLB,
|
||||
SPR2_NGTC, // SPR2_DRLC,
|
||||
|
||||
0, // SPR2_TAL0,
|
||||
0, // SPR2_TAL0, (this will look mighty stupid but oh well)
|
||||
SPR2_TAL0, // SPR2_TAL1,
|
||||
SPR2_TAL1, // SPR2_TAL2,
|
||||
SPR2_TAL2, // SPR2_TAL3,
|
||||
|
@ -675,6 +676,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
|
|||
|
||||
0, // SPR2_SIGN,
|
||||
0, // SPR2_LIFE,
|
||||
0, // SPR2_XTRA (should never be referenced)
|
||||
};
|
||||
|
||||
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)
|
||||
|
@ -1791,7 +1793,11 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// Blue Sphere for special stages
|
||||
{SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE
|
||||
{SPR_SPHR, FF_FULLBRIGHT|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS
|
||||
{SPR_SPHR, FF_FULLBRIGHT
|
||||
#ifdef MANIASPHERES
|
||||
|FF_ANIMATE|FF_RANDOMANIM
|
||||
#endif
|
||||
, -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS
|
||||
{SPR_SPHR, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK
|
||||
|
||||
// Bomb Sphere
|
||||
|
@ -2322,9 +2328,10 @@ state_t states[NUMSTATES] =
|
|||
{SPR_BFBR, FF_FULLBRIGHT|15, 1, {NULL}, 0, 0, S_BIGFIREBAR1}, // S_BIGFIREBAR16
|
||||
|
||||
{SPR_FWR4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZFLOWER
|
||||
{SPR_BANR, 1, -1, {NULL}, 0, 0, S_NULL}, // S_CEZPOLE
|
||||
{SPR_BANR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZPOLE
|
||||
|
||||
{SPR_BANR, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBANNER
|
||||
{SPR_BANR, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBANNER1
|
||||
{SPR_BANR, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBANNER2
|
||||
|
||||
{SPR_PINE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_PINETREE
|
||||
{SPR_CEZB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZBUSH1
|
||||
|
@ -2338,7 +2345,8 @@ state_t states[NUMSTATES] =
|
|||
{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
|
||||
{SPR_CFLG, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_WAVINGFLAGSEG1
|
||||
{SPR_CFLG, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_WAVINGFLAGSEG2
|
||||
|
||||
{SPR_CSTA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CRAWLASTATUE
|
||||
|
||||
|
@ -11018,7 +11026,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_CEZPOLE
|
||||
{ // MT_CEZPOLE1
|
||||
1117, // doomednum
|
||||
S_CEZPOLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
|
@ -11045,9 +11053,63 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_CEZBANNER
|
||||
{ // MT_CEZPOLE2
|
||||
1118, // doomednum
|
||||
S_CEZPOLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
40*FRACUNIT, // radius
|
||||
224*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_CEZBANNER1
|
||||
-1, // doomednum
|
||||
S_CEZBANNER, // spawnstate
|
||||
S_CEZBANNER1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
40*FRACUNIT, // radius
|
||||
224*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_CEZBANNER2
|
||||
-1, // doomednum
|
||||
S_CEZBANNER2, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
@ -11261,8 +11323,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_WAVINGFLAG
|
||||
1118, // doomednum
|
||||
{ // MT_WAVINGFLAG1
|
||||
1128, // doomednum
|
||||
S_WAVINGFLAG, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
|
@ -11278,8 +11340,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
4*FRACUNIT, // radius
|
||||
104*FRACUNIT, // height
|
||||
8*FRACUNIT, // radius
|
||||
208*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
|
@ -11288,9 +11350,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_WAVINGFLAGSEG
|
||||
-1, // doomednum
|
||||
S_WAVINGFLAGSEG, // spawnstate
|
||||
{ // MT_WAVINGFLAG2
|
||||
1129, // doomednum
|
||||
S_WAVINGFLAG, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
@ -11305,7 +11367,61 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
4*FRACUNIT, // radius
|
||||
8*FRACUNIT, // radius
|
||||
208*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_WAVINGFLAGSEG1
|
||||
-1, // doomednum
|
||||
S_WAVINGFLAGSEG1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8*FRACUNIT, // radius
|
||||
1, // height -- this is not a typo
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_WAVINGFLAGSEG2
|
||||
-1, // doomednum
|
||||
S_WAVINGFLAGSEG2, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8*FRACUNIT, // radius
|
||||
1, // height -- this is not a typo
|
||||
0, // display offset
|
||||
100, // mass
|
||||
|
|
19
src/info.h
19
src/info.h
|
@ -834,6 +834,7 @@ typedef enum playersprite
|
|||
|
||||
SPR2_SIGN, // end sign head
|
||||
SPR2_LIFE, // life monitor icon
|
||||
SPR2_XTRA, // stuff that isn't in-game - keep this last in the list
|
||||
|
||||
SPR2_FIRSTFREESLOT,
|
||||
SPR2_LASTFREESLOT = 0x7f,
|
||||
|
@ -2458,7 +2459,8 @@ typedef enum state
|
|||
|
||||
S_CEZFLOWER,
|
||||
S_CEZPOLE,
|
||||
S_CEZBANNER,
|
||||
S_CEZBANNER1,
|
||||
S_CEZBANNER2,
|
||||
S_PINETREE,
|
||||
S_CEZBUSH1,
|
||||
S_CEZBUSH2,
|
||||
|
@ -2467,7 +2469,8 @@ typedef enum state
|
|||
S_FLAMEHOLDER,
|
||||
S_FIRETORCH,
|
||||
S_WAVINGFLAG,
|
||||
S_WAVINGFLAGSEG,
|
||||
S_WAVINGFLAGSEG1,
|
||||
S_WAVINGFLAGSEG2,
|
||||
S_CRAWLASTATUE,
|
||||
S_FACESTABBERSTATUE,
|
||||
S_SUSPICIOUSFACESTABBERSTATUE_WAIT,
|
||||
|
@ -4295,8 +4298,10 @@ typedef enum mobj_type
|
|||
MT_SMALLFIREBAR, // Small Firebar
|
||||
MT_BIGFIREBAR, // Big Firebar
|
||||
MT_CEZFLOWER, // Flower
|
||||
MT_CEZPOLE, // Pole
|
||||
MT_CEZBANNER, // Banner
|
||||
MT_CEZPOLE1, // Pole (with red banner)
|
||||
MT_CEZPOLE2, // Pole (with blue banner)
|
||||
MT_CEZBANNER1, // Banner (red)
|
||||
MT_CEZBANNER2, // Banner (blue)
|
||||
MT_PINETREE, // Pine Tree
|
||||
MT_CEZBUSH1, // Bush 1
|
||||
MT_CEZBUSH2, // Bush 2
|
||||
|
@ -4304,8 +4309,10 @@ typedef enum mobj_type
|
|||
MT_CANDLEPRICKET, // Candle pricket
|
||||
MT_FLAMEHOLDER, // Flame holder
|
||||
MT_FIRETORCH, // Fire torch
|
||||
MT_WAVINGFLAG, // Waving flag
|
||||
MT_WAVINGFLAGSEG, // Waving flag segment
|
||||
MT_WAVINGFLAG1, // Waving flag (red)
|
||||
MT_WAVINGFLAG2, // Waving flag (blue)
|
||||
MT_WAVINGFLAGSEG1, // Waving flag segment (red)
|
||||
MT_WAVINGFLAGSEG2, // Waving flag segment (blue)
|
||||
MT_CRAWLASTATUE, // Crawla statue
|
||||
MT_FACESTABBERSTATUE, // Facestabber statue
|
||||
MT_SUSPICIOUSFACESTABBERSTATUE, // :eggthinking:
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
|
||||
#define NOHUD if (hud_running)\
|
||||
return luaL_error(L, "HUD rendering code should not call this function!");
|
||||
#define INLEVEL if (gamestate != GS_LEVEL)\
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
|
||||
boolean luaL_checkboolean(lua_State *L, int narg) {
|
||||
luaL_checktype(L, narg, LUA_TBOOLEAN);
|
||||
|
@ -2047,12 +2045,22 @@ static int lib_pStartQuake(lua_State *L)
|
|||
|
||||
static int lib_evCrumbleChain(lua_State *L)
|
||||
{
|
||||
sector_t *sec = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
|
||||
ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR));
|
||||
sector_t *sec = NULL;
|
||||
ffloor_t *rover = NULL;
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!sec)
|
||||
return LUA_ErrInvalid(L, "sector_t");
|
||||
if (!lua_isnone(L, 2))
|
||||
{
|
||||
if (!lua_isnil(L, 1))
|
||||
{
|
||||
sec = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
|
||||
if (!sec)
|
||||
return LUA_ErrInvalid(L, "sector_t");
|
||||
}
|
||||
rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR));
|
||||
}
|
||||
else
|
||||
rover = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
|
||||
if (!rover)
|
||||
return LUA_ErrInvalid(L, "ffloor_t");
|
||||
EV_CrumbleChain(sec, rover);
|
||||
|
@ -2601,12 +2609,12 @@ static int lib_gSetCustomExitVars(lua_State *L)
|
|||
nextmapoverride = (INT16)luaL_checknumber(L, 1);
|
||||
lua_remove(L, 1); // remove nextmapoverride; skipstats now 1 if available
|
||||
}
|
||||
skipstats = lua_optboolean(L, 1);
|
||||
skipstats = luaL_optinteger(L, 2, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextmapoverride = 0;
|
||||
skipstats = false;
|
||||
skipstats = 0;
|
||||
}
|
||||
// ---
|
||||
|
||||
|
|
|
@ -28,9 +28,6 @@ return luaL_error(L, "HUD rendering code should not call this function!");
|
|||
// for functions not allowed in hooks or coroutines (supercedes above)
|
||||
#define NOHOOK if (!lua_lumploading)\
|
||||
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
|
||||
// for functions only allowed within a level
|
||||
#define INLEVEL if (gamestate != GS_LEVEL)\
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
|
||||
static const char *cvname = NULL;
|
||||
|
||||
|
|
|
@ -157,6 +157,18 @@ static int lib_setSpr2default(lua_State *L)
|
|||
playersprite_t i;
|
||||
UINT8 j = 0;
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter spr2defaults[] in HUD rendering code!");
|
||||
|
||||
// todo: maybe allow setting below first freeslot..? step 1 is toggling this, step 2 is testing to see whether it's net-safe
|
||||
#ifdef SETALLSPR2DEFAULTS
|
||||
#define FIRSTMODIFY 0
|
||||
#else
|
||||
#define FIRSTMODIFY SPR2_FIRSTFREESLOT
|
||||
if (free_spr2 == SPR2_FIRSTFREESLOT)
|
||||
return luaL_error(L, "You can only modify the spr2defaults[] entries of sprite2 freeslots, and none are currently added.");
|
||||
#endif
|
||||
|
||||
lua_remove(L, 1); // don't care about spr2defaults[] dummy userdata.
|
||||
|
||||
if (lua_isnumber(L, 1))
|
||||
|
@ -175,8 +187,9 @@ static int lib_setSpr2default(lua_State *L)
|
|||
else
|
||||
return luaL_error(L, "spr2defaults[] invalid index");
|
||||
|
||||
if (i < SPR2_FIRSTFREESLOT || i >= free_spr2)
|
||||
return luaL_error(L, "spr2defaults[] index %d out of range (%d - %d)", i, SPR2_FIRSTFREESLOT, free_spr2-1);
|
||||
if (i < FIRSTMODIFY || i >= free_spr2)
|
||||
return luaL_error(L, "spr2defaults[] index %d out of range (%d - %d)", i, FIRSTMODIFY, free_spr2-1);
|
||||
#undef FIRSTMODIFY
|
||||
|
||||
if (lua_isnumber(L, 2))
|
||||
j = lua_tonumber(L, 2);
|
||||
|
@ -189,11 +202,13 @@ static int lib_setSpr2default(lua_State *L)
|
|||
break;
|
||||
}
|
||||
if (j == free_spr2)
|
||||
return luaL_error(L, "spr2defaults[] invalid index");
|
||||
return luaL_error(L, "spr2defaults[] invalid set");
|
||||
}
|
||||
else
|
||||
return luaL_error(L, "spr2defaults[] invalid set");
|
||||
|
||||
if (j >= free_spr2)
|
||||
j = 0; // return luaL_error(L, "spr2defaults[] set %d out of range (%d - %d)", j, 0, free_spr2-1);
|
||||
if (j < 0 || j >= free_spr2)
|
||||
return luaL_error(L, "spr2defaults[] set %d out of range (%d - %d)", j, 0, free_spr2-1);
|
||||
|
||||
spr2defaults[i] = j;
|
||||
return 0;
|
||||
|
|
|
@ -333,8 +333,7 @@ static int lib_iterateSectorThinglist(lua_State *L)
|
|||
mobj_t *state = NULL;
|
||||
mobj_t *thing = NULL;
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call sector.thinglist() directly, use it as 'for rover in sector.thinglist do <block> end'.");
|
||||
|
@ -369,8 +368,7 @@ static int lib_iterateSectorFFloors(lua_State *L)
|
|||
ffloor_t *state = NULL;
|
||||
ffloor_t *ffloor = NULL;
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call sector.ffloors() directly, use it as 'for rover in sector.ffloors do <block> end'.");
|
||||
|
@ -1251,8 +1249,7 @@ static int bbox_get(lua_State *L)
|
|||
static int lib_iterateSectors(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call sectors.iterate() directly, use it as 'for sector in sectors.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
|
@ -1270,8 +1267,7 @@ static int lib_iterateSectors(lua_State *L)
|
|||
static int lib_getSector(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "You cannot access this outside of a level!");
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
|
@ -1305,8 +1301,7 @@ static int lib_numsectors(lua_State *L)
|
|||
static int lib_iterateSubsectors(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call subsectors.iterate() directly, use it as 'for subsector in subsectors.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
|
@ -1324,8 +1319,7 @@ static int lib_iterateSubsectors(lua_State *L)
|
|||
static int lib_getSubsector(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "You cannot access this outside of a level!");
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
|
@ -1359,8 +1353,7 @@ static int lib_numsubsectors(lua_State *L)
|
|||
static int lib_iterateLines(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call lines.iterate() directly, use it as 'for line in lines.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
|
@ -1378,8 +1371,7 @@ static int lib_iterateLines(lua_State *L)
|
|||
static int lib_getLine(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "You cannot access this outside of a level!");
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
|
@ -1413,8 +1405,7 @@ static int lib_numlines(lua_State *L)
|
|||
static int lib_iterateSides(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call sides.iterate() directly, use it as 'for side in sides.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
|
@ -1432,8 +1423,7 @@ static int lib_iterateSides(lua_State *L)
|
|||
static int lib_getSide(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "You cannot access this outside of a level!");
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
|
@ -1467,8 +1457,7 @@ static int lib_numsides(lua_State *L)
|
|||
static int lib_iterateVertexes(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call vertexes.iterate() directly, use it as 'for vertex in vertexes.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
|
@ -1486,8 +1475,7 @@ static int lib_iterateVertexes(lua_State *L)
|
|||
static int lib_getVertex(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "You cannot access this outside of a level!");
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
|
@ -1523,8 +1511,7 @@ static int lib_numvertexes(lua_State *L)
|
|||
static int lib_iterateSegs(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call segs.iterate() directly, use it as 'for seg in segs.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
|
@ -1542,8 +1529,7 @@ static int lib_iterateSegs(lua_State *L)
|
|||
static int lib_getSeg(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "You cannot access this outside of a level!");
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
|
@ -1577,8 +1563,7 @@ static int lib_numsegs(lua_State *L)
|
|||
static int lib_iterateNodes(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call nodes.iterate() directly, use it as 'for node in nodes.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
|
@ -1596,8 +1581,7 @@ static int lib_iterateNodes(lua_State *L)
|
|||
static int lib_getNode(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "You cannot access this outside of a level!");
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
|
|
|
@ -804,7 +804,12 @@ static int mapthing_set(lua_State *L)
|
|||
else if(fastcmp(field,"z"))
|
||||
mt->z = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"extrainfo"))
|
||||
mt->extrainfo = (UINT8)luaL_checkinteger(L, 3);
|
||||
{
|
||||
INT32 extrainfo = luaL_checkinteger(L, 3);
|
||||
if (extrainfo & ~15)
|
||||
return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15);
|
||||
mt->extrainfo = (UINT8)extrainfo;
|
||||
}
|
||||
else if(fastcmp(field,"mobj"))
|
||||
mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
else
|
||||
|
@ -816,8 +821,7 @@ static int mapthing_set(lua_State *L)
|
|||
static int lib_iterateMapthings(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call mapthings.iterate() directly, use it as 'for mapthing in mapthings.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
|
@ -835,8 +839,7 @@ static int lib_iterateMapthings(lua_State *L)
|
|||
static int lib_getMapthing(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "You cannot access this outside of a level!");
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
static int lib_iteratePlayers(lua_State *L)
|
||||
{
|
||||
INT32 i = -1;
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
if (lua_gettop(L) < 2)
|
||||
{
|
||||
//return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do <block> end'.");
|
||||
|
@ -53,8 +52,7 @@ static int lib_getPlayer(lua_State *L)
|
|||
{
|
||||
const char *field;
|
||||
// i -> players[i]
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "You cannot access this outside of a level!");
|
||||
INLEVEL
|
||||
if (lua_type(L, 2) == LUA_TNUMBER)
|
||||
{
|
||||
lua_Integer i = luaL_checkinteger(L, 2);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "m_fixed.h"
|
||||
#include "doomtype.h"
|
||||
#include "d_player.h"
|
||||
#include "g_state.h"
|
||||
|
||||
#include "blua/lua.h"
|
||||
#include "blua/lualib.h"
|
||||
|
@ -97,4 +98,7 @@ void COM_Lua_f(void);
|
|||
// uncomment if you want seg_t/node_t in Lua
|
||||
// #define HAVE_LUA_SEGS
|
||||
|
||||
#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\
|
||||
return luaL_error(L, "This can only be used in a level!");
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,9 +27,6 @@ enum skin {
|
|||
skin_flags,
|
||||
skin_realname,
|
||||
skin_hudname,
|
||||
skin_charsel,
|
||||
skin_face,
|
||||
skin_superface,
|
||||
skin_ability,
|
||||
skin_ability2,
|
||||
skin_thokitem,
|
||||
|
@ -66,9 +63,6 @@ static const char *const skin_opt[] = {
|
|||
"flags",
|
||||
"realname",
|
||||
"hudname",
|
||||
"charsel",
|
||||
"face",
|
||||
"superface",
|
||||
"ability",
|
||||
"ability2",
|
||||
"thokitem",
|
||||
|
@ -104,7 +98,6 @@ static int skin_get(lua_State *L)
|
|||
{
|
||||
skin_t *skin = *((skin_t **)luaL_checkudata(L, 1, META_SKIN));
|
||||
enum skin field = luaL_checkoption(L, 2, NULL, skin_opt);
|
||||
INT32 i;
|
||||
|
||||
// skins are always valid, only added, never removed
|
||||
I_Assert(skin != NULL);
|
||||
|
@ -131,24 +124,6 @@ static int skin_get(lua_State *L)
|
|||
case skin_hudname:
|
||||
lua_pushstring(L, skin->hudname);
|
||||
break;
|
||||
case skin_charsel:
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!skin->charsel[i])
|
||||
break;
|
||||
lua_pushlstring(L, skin->charsel, i);
|
||||
break;
|
||||
case skin_face:
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!skin->face[i])
|
||||
break;
|
||||
lua_pushlstring(L, skin->face, i);
|
||||
break;
|
||||
case skin_superface:
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!skin->superface[i])
|
||||
break;
|
||||
lua_pushlstring(L, skin->superface, i);
|
||||
break;
|
||||
case skin_ability:
|
||||
lua_pushinteger(L, skin->ability);
|
||||
break;
|
||||
|
|
|
@ -56,8 +56,7 @@ static int lib_iterateThinkers(lua_State *L)
|
|||
thinker_t *th = NULL, *next = NULL;
|
||||
struct iterationState *it;
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
|
||||
it = luaL_checkudata(L, 1, META_ITERATIONSTATE);
|
||||
|
||||
|
@ -112,8 +111,7 @@ static int lib_startIterate(lua_State *L)
|
|||
{
|
||||
struct iterationState *it;
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
return luaL_error(L, "This function can only be used in a level!");
|
||||
INLEVEL
|
||||
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
it = lua_newuserdata(L, sizeof(struct iterationState));
|
||||
|
|
|
@ -240,7 +240,7 @@ UINT8 M_UpdateUnlockablesAndExtraEmblems(void)
|
|||
if (cechoLines)
|
||||
{
|
||||
char slashed[1024] = "";
|
||||
for (i = 0; (i < 21) && (i < 24 - cechoLines); ++i)
|
||||
for (i = 0; (i < 19) && (i < 24 - cechoLines); ++i)
|
||||
slashed[i] = '\\';
|
||||
slashed[i] = 0;
|
||||
|
||||
|
|
37
src/m_menu.c
37
src/m_menu.c
|
@ -2830,8 +2830,8 @@ boolean M_Responder(event_t *ev)
|
|||
void (*routine)(INT32 choice); // for some casting problem
|
||||
|
||||
if (dedicated || (demoplayback && titledemo)
|
||||
|| gamestate == GS_INTRO || gamestate == GS_CUTSCENE || gamestate == GS_GAMEEND
|
||||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
|
||||
|| gamestate == GS_INTRO || gamestate == GS_ENDING || gamestate == GS_CUTSCENE
|
||||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_GAMEEND)
|
||||
return false;
|
||||
|
||||
if (noFurtherInput)
|
||||
|
@ -3531,6 +3531,7 @@ void M_InitCharacterTables(void)
|
|||
strcpy(description[i].picname, "");
|
||||
strcpy(description[i].skinname, "");
|
||||
description[i].prev = description[i].next = 0;
|
||||
description[i].pic = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7577,8 +7578,19 @@ static void M_SetupChoosePlayer(INT32 choice)
|
|||
if (i == char_on)
|
||||
allowed = true;
|
||||
|
||||
if (description[i].picname[0] == '\0')
|
||||
strncpy(description[i].picname, skins[skinnum].charsel, 8);
|
||||
if (!(description[i].picname[0]))
|
||||
{
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 2)
|
||||
{
|
||||
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[1];
|
||||
description[i].pic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
||||
}
|
||||
else
|
||||
description[i].pic = W_CachePatchName("MISSING", PU_CACHE);
|
||||
}
|
||||
else
|
||||
description[i].pic = W_CachePatchName(description[i].picname, PU_CACHE);
|
||||
}
|
||||
// else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them.
|
||||
Z_Free(name);
|
||||
|
@ -7732,7 +7744,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
|
|||
// Draw prev character if it's visible and its number isn't greater than the current one or there's more than two
|
||||
if (o < 32)
|
||||
{
|
||||
patch = W_CachePatchName(description[prev].picname, PU_CACHE);
|
||||
patch = description[prev].pic;
|
||||
if (SHORT(patch->width) >= 256)
|
||||
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, SHORT(patch->height) + 2*(o-32), SHORT(patch->width), 64 - 2*o);
|
||||
else
|
||||
|
@ -7743,7 +7755,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
|
|||
// Draw next character if it's visible and its number isn't less than the current one or there's more than two
|
||||
if (o < 128) // (next != i) was previously a part of this, but it's implicitly true if (prev != i) is true.
|
||||
{
|
||||
patch = W_CachePatchName(description[next].picname, PU_CACHE);
|
||||
patch = description[next].pic;
|
||||
if (SHORT(patch->width) >= 256)
|
||||
V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT/2, 0, patch, 0, 0, SHORT(patch->width), 2*o);
|
||||
else
|
||||
|
@ -7752,7 +7764,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
|
|||
}
|
||||
}
|
||||
|
||||
patch = W_CachePatchName(description[i].picname, PU_CACHE);
|
||||
patch = description[i].pic;
|
||||
if (o >= 0 && o <= 32)
|
||||
{
|
||||
if (SHORT(patch->width) >= 256)
|
||||
|
@ -8144,9 +8156,16 @@ void M_DrawTimeAttackMenu(void)
|
|||
V_DrawString(currentMenu->x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text);
|
||||
|
||||
// Character face!
|
||||
if (W_CheckNumForName(skins[cv_chooseskin.value-1].charsel) != LUMPERROR)
|
||||
{
|
||||
PictureOfUrFace = W_CachePatchName(skins[cv_chooseskin.value-1].charsel, PU_CACHE);
|
||||
if (skins[cv_chooseskin.value-1].sprites[SPR2_XTRA].numframes >= 2)
|
||||
{
|
||||
spritedef_t *sprdef = &skins[cv_chooseskin.value-1].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[1];
|
||||
PictureOfUrFace = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
||||
}
|
||||
else
|
||||
PictureOfUrFace = W_CachePatchName("MISSING", PU_CACHE);
|
||||
|
||||
if (PictureOfUrFace->width >= 256)
|
||||
V_DrawTinyScaledPatch(224, 120, 0, PictureOfUrFace);
|
||||
else
|
||||
|
|
|
@ -316,6 +316,7 @@ typedef struct
|
|||
char notes[441];
|
||||
char picname[8];
|
||||
char skinname[SKINNAMESIZE*2+2]; // skin&skin\0
|
||||
patch_t *pic;
|
||||
UINT8 prev;
|
||||
UINT8 next;
|
||||
} description_t;
|
||||
|
|
|
@ -3878,6 +3878,8 @@ bossjustdie:
|
|||
}
|
||||
default: //eggmobiles
|
||||
{
|
||||
UINT8 extrainfo = (mo->spawnpoint ? mo->spawnpoint->extrainfo : 0);
|
||||
|
||||
// Stop exploding and prepare to run.
|
||||
P_SetMobjState(mo, mo->info->xdeathstate);
|
||||
if (P_MobjWasRemoved(mo))
|
||||
|
@ -3897,6 +3899,9 @@ bossjustdie:
|
|||
if (mo2->type != MT_BOSSFLYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->spawnpoint && mo2->spawnpoint->extrainfo != extrainfo)
|
||||
continue;
|
||||
|
||||
// If this one's further then the last one, don't go for it.
|
||||
if (mo->target &&
|
||||
P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) >
|
||||
|
@ -12303,6 +12308,7 @@ void A_Boss5FindWaypoint(mobj_t *actor)
|
|||
//INT32 locvar2 = var2;
|
||||
boolean avoidcenter;
|
||||
UINT32 i;
|
||||
UINT8 extrainfo = (actor->spawnpoint ? actor->spawnpoint->extrainfo : 0);
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_Boss5FindWaypoint", actor))
|
||||
return;
|
||||
|
@ -12312,16 +12318,34 @@ void A_Boss5FindWaypoint(mobj_t *actor)
|
|||
|
||||
if (locvar1 == 2) // look for the boss waypoint
|
||||
{
|
||||
for (i = 0; i < nummapthings; i++)
|
||||
thinker_t *th;
|
||||
mobj_t *mo2;
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
// Flee! Flee! Find a point to escape to! If none, just shoot upward!
|
||||
// scan the thinkers to find the runaway point
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
{
|
||||
if (!mapthings[i].mobj)
|
||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
continue;
|
||||
if (mapthings[i].mobj->type != MT_BOSSFLYPOINT)
|
||||
|
||||
mo2 = (mobj_t *)th;
|
||||
|
||||
if (mo2->type != MT_BOSSFLYPOINT)
|
||||
continue;
|
||||
P_SetTarget(&actor->tracer, mapthings[i].mobj);
|
||||
break;
|
||||
|
||||
if (mo2->spawnpoint && mo2->spawnpoint->extrainfo != extrainfo)
|
||||
continue;
|
||||
|
||||
// If this one's further then the last one, don't go for it.
|
||||
if (actor->tracer &&
|
||||
P_AproxDistance(P_AproxDistance(actor->x - mo2->x, actor->y - mo2->y), actor->z - mo2->z) >
|
||||
P_AproxDistance(P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y), actor->z - actor->tracer->z))
|
||||
continue;
|
||||
|
||||
// Otherwise... Do!
|
||||
P_SetTarget(&actor->tracer, mo2);
|
||||
}
|
||||
if (i == nummapthings)
|
||||
if (!actor->tracer)
|
||||
return; // no boss flypoints found
|
||||
}
|
||||
else if (locvar1 == 1) // always go to ambush-marked waypoint
|
||||
|
@ -12335,11 +12359,13 @@ void A_Boss5FindWaypoint(mobj_t *actor)
|
|||
continue;
|
||||
if (mapthings[i].mobj->type != MT_FANGWAYPOINT)
|
||||
continue;
|
||||
if (mapthings[i].options & MTF_AMBUSH)
|
||||
{
|
||||
P_SetTarget(&actor->tracer, mapthings[i].mobj);
|
||||
break;
|
||||
}
|
||||
if (mapthings[i].extrainfo != extrainfo)
|
||||
continue;
|
||||
if (!(mapthings[i].options & MTF_AMBUSH))
|
||||
continue;
|
||||
|
||||
P_SetTarget(&actor->tracer, mapthings[i].mobj);
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == nummapthings)
|
||||
|
@ -12363,6 +12389,8 @@ void A_Boss5FindWaypoint(mobj_t *actor)
|
|||
continue;
|
||||
if (actor->tracer == mapthings[i].mobj) // this was your tracer last time
|
||||
continue;
|
||||
if (mapthings[i].extrainfo != extrainfo)
|
||||
continue;
|
||||
if (mapthings[i].options & MTF_AMBUSH)
|
||||
{
|
||||
if (avoidcenter)
|
||||
|
@ -12418,6 +12446,8 @@ void A_Boss5FindWaypoint(mobj_t *actor)
|
|||
continue;
|
||||
if (actor->tracer == mapthings[i].mobj) // this was your tracer last time
|
||||
continue;
|
||||
if (mapthings[i].extrainfo != extrainfo)
|
||||
continue;
|
||||
if (mapthings[i].options & MTF_AMBUSH)
|
||||
{
|
||||
if (avoidcenter)
|
||||
|
|
|
@ -719,6 +719,8 @@ void T_ContinuousFalling(levelspecthink_t *faller)
|
|||
}
|
||||
}
|
||||
|
||||
P_CheckSector(faller->sector, false); // you might think this is irrelevant. you would be wrong
|
||||
|
||||
faller->sector->floorspeed = faller->speed*faller->direction;
|
||||
faller->sector->ceilspeed = 42;
|
||||
faller->sector->moved = true;
|
||||
|
@ -3029,20 +3031,40 @@ INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed)
|
|||
|
||||
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
|
||||
{
|
||||
size_t i;
|
||||
size_t leftmostvertex = 0, rightmostvertex = 0;
|
||||
size_t topmostvertex = 0, bottommostvertex = 0;
|
||||
fixed_t leftx, rightx;
|
||||
fixed_t topy, bottomy;
|
||||
fixed_t topz, bottomz;
|
||||
fixed_t widthfactor = FRACUNIT, heightfactor = FRACUNIT;
|
||||
fixed_t a, b, c;
|
||||
mobjtype_t type = MT_ROCKCRUMBLE1;
|
||||
fixed_t spacing = (32<<FRACBITS);
|
||||
tic_t lifetime = 3*TICRATE;
|
||||
INT16 flags = 0;
|
||||
size_t i, leftmostvertex, rightmostvertex, topmostvertex, bottommostvertex;
|
||||
fixed_t leftx, rightx, topy, bottomy, topz, bottomz, widthfactor, heightfactor, a, b, c, spacing;
|
||||
mobjtype_t type;
|
||||
tic_t lifetime;
|
||||
INT16 flags;
|
||||
|
||||
#define controlsec rover->master->frontsector
|
||||
sector_t *controlsec = rover->master->frontsector;
|
||||
|
||||
if (sec == NULL)
|
||||
{
|
||||
if (controlsec->numattached)
|
||||
{
|
||||
for (i = 0; i < controlsec->numattached; i++)
|
||||
{
|
||||
sec = §ors[controlsec->attached[i]];
|
||||
if (!sec->ffloors)
|
||||
continue;
|
||||
|
||||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector == controlsec)
|
||||
EV_CrumbleChain(sec, rover);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
leftmostvertex = rightmostvertex = topmostvertex = bottommostvertex = 0;
|
||||
widthfactor = heightfactor = FRACUNIT;
|
||||
spacing = (32<<FRACBITS);
|
||||
type = MT_ROCKCRUMBLE1;
|
||||
lifetime = 3*TICRATE;
|
||||
flags = 0;
|
||||
|
||||
if (controlsec->tag != 0)
|
||||
{
|
||||
|
|
|
@ -670,7 +670,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
P_DoMatchSuper(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
emeralds |= special->info->speed;
|
||||
stagefailed = false;
|
||||
}
|
||||
|
||||
if (special->target && special->target->type == MT_EMERALDSPAWN)
|
||||
{
|
||||
|
@ -3652,7 +3655,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
{
|
||||
INT32 i;
|
||||
mobj_t *mo;
|
||||
angle_t fa;
|
||||
angle_t fa, va;
|
||||
fixed_t ns;
|
||||
fixed_t z;
|
||||
boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap));
|
||||
|
@ -3674,6 +3677,11 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
// Spill weapons first
|
||||
P_PlayerWeaponPanelOrAmmoBurst(player);
|
||||
|
||||
if (abs(player->mo->momx) > player->mo->scale || abs(player->mo->momy) > player->mo->scale)
|
||||
va = R_PointToAngle2(player->mo->momx, player->mo->momy, 0, 0)>>ANGLETOFINESHIFT;
|
||||
else
|
||||
va = player->mo->angle>>ANGLETOFINESHIFT;
|
||||
|
||||
for (i = 0; i < num_rings; i++)
|
||||
{
|
||||
INT32 objType = mobjinfo[MT_RING].reactiontime;
|
||||
|
@ -3695,7 +3703,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
P_SetScale(mo, player->mo->scale);
|
||||
|
||||
// Angle offset by player angle, then slightly offset by amount of rings
|
||||
fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT) - ((num_rings-1)*FINEANGLES/32)) & FINEMASK;
|
||||
fa = ((i*FINEANGLES/16) + va - ((num_rings-1)*FINEANGLES/32)) & FINEMASK;
|
||||
|
||||
// Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2.
|
||||
// Technically a non-SA way of spilling rings. They just so happen to be a little similar.
|
||||
|
|
|
@ -142,7 +142,7 @@ boolean P_IsObjectOnGround(mobj_t *mo);
|
|||
boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
|
||||
boolean P_InSpaceSector(mobj_t *mo);
|
||||
boolean P_InQuicksand(mobj_t *mo);
|
||||
boolean P_PlayerHitFloor(player_t *player);
|
||||
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff);
|
||||
|
||||
void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
|
||||
void P_RestoreMusic(player_t *player);
|
||||
|
|
113
src/p_map.c
113
src/p_map.c
|
@ -342,7 +342,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
if (horizspeed)
|
||||
{
|
||||
object->player->drawangle = spring->angle;
|
||||
if (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0)
|
||||
if (vertispeed || (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0))
|
||||
{
|
||||
object->angle = spring->angle;
|
||||
|
||||
|
@ -1808,7 +1808,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
{
|
||||
tmceilingz = opentop;
|
||||
ceilingline = ld;
|
||||
tmceilingrover = NULL;
|
||||
tmceilingrover = openceilingrover;
|
||||
#ifdef ESLOPE
|
||||
tmceilingslope = opentopslope;
|
||||
#endif
|
||||
|
@ -1817,7 +1817,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
if (openbottom > tmfloorz)
|
||||
{
|
||||
tmfloorz = openbottom;
|
||||
tmfloorrover = NULL;
|
||||
tmfloorrover = openfloorrover;
|
||||
#ifdef ESLOPE
|
||||
tmfloorslope = openbottomslope;
|
||||
#endif
|
||||
|
@ -2089,6 +2089,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
#ifdef ESLOPE
|
||||
tmfloorslope = NULL;
|
||||
#endif
|
||||
tmfloorrover = NULL;
|
||||
}
|
||||
|
||||
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) {
|
||||
|
@ -2096,6 +2097,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
#ifdef ESLOPE
|
||||
tmceilingslope = NULL;
|
||||
#endif
|
||||
tmceilingrover = NULL;
|
||||
}
|
||||
}
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
|
@ -2820,7 +2822,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
static boolean P_ThingHeightClip(mobj_t *thing)
|
||||
{
|
||||
boolean floormoved;
|
||||
fixed_t oldfloorz = thing->floorz;
|
||||
fixed_t oldfloorz = thing->floorz, oldz = thing->z;
|
||||
ffloor_t *oldfloorrover = thing->floorrover;
|
||||
ffloor_t *oldceilingrover = thing->ceilingrover;
|
||||
boolean onfloor = P_IsObjectOnGround(thing);//(thing->z <= thing->floorz);
|
||||
|
@ -2879,6 +2881,12 @@ static boolean P_ThingHeightClip(mobj_t *thing)
|
|||
thing->z = thing->ceilingz - thing->height;
|
||||
}
|
||||
|
||||
if (thing->z != oldz)
|
||||
{
|
||||
if (thing->player)
|
||||
P_PlayerHitFloor(thing->player, false);
|
||||
}
|
||||
|
||||
// debug: be sure it falls to the floor
|
||||
thing->eflags &= ~MFE_ONGROUND;
|
||||
|
||||
|
@ -4079,6 +4087,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|
|||
boolean P_CheckSector(sector_t *sector, boolean crunch)
|
||||
{
|
||||
msecnode_t *n;
|
||||
size_t i;
|
||||
|
||||
nofit = false;
|
||||
crushchange = crunch;
|
||||
|
@ -4093,9 +4102,57 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
|
|||
|
||||
|
||||
// First, let's see if anything will keep it from crushing.
|
||||
|
||||
// Sal: This stupid function chain is required to fix polyobjects not being able to crush.
|
||||
// Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead
|
||||
validcount++;
|
||||
|
||||
for (i = 0; i < sector->linecount; i++)
|
||||
{
|
||||
if (sector->lines[i]->polyobj)
|
||||
{
|
||||
polyobj_t *po = sector->lines[i]->polyobj;
|
||||
if (po->validcount == validcount)
|
||||
continue; // skip if already checked
|
||||
if (!(po->flags & POF_SOLID))
|
||||
continue;
|
||||
if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector
|
||||
{
|
||||
INT32 x, y;
|
||||
po->validcount = validcount;
|
||||
|
||||
for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y)
|
||||
{
|
||||
for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x)
|
||||
{
|
||||
mobj_t *mo;
|
||||
|
||||
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
|
||||
continue;
|
||||
|
||||
mo = blocklinks[y * bmapwidth + x];
|
||||
|
||||
for (; mo; mo = mo->bnext)
|
||||
{
|
||||
// Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect
|
||||
|
||||
if (!P_MobjTouchingPolyobj(po, mo))
|
||||
continue;
|
||||
|
||||
if (!PIT_ChangeSector(mo, false))
|
||||
{
|
||||
nofit = true;
|
||||
return nofit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sector->numattached)
|
||||
{
|
||||
size_t i;
|
||||
sector_t *sec;
|
||||
for (i = 0; i < sector->numattached; i++)
|
||||
{
|
||||
|
@ -4155,9 +4212,53 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
|
|||
} while (n); // repeat from scratch until all things left are marked valid
|
||||
|
||||
// Nothing blocked us, so lets crush for real!
|
||||
|
||||
// Sal: This stupid function chain is required to fix polyobjects not being able to crush.
|
||||
// Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead
|
||||
validcount++;
|
||||
|
||||
for (i = 0; i < sector->linecount; i++)
|
||||
{
|
||||
if (sector->lines[i]->polyobj)
|
||||
{
|
||||
polyobj_t *po = sector->lines[i]->polyobj;
|
||||
if (po->validcount == validcount)
|
||||
continue; // skip if already checked
|
||||
if (!(po->flags & POF_SOLID))
|
||||
continue;
|
||||
if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector
|
||||
{
|
||||
INT32 x, y;
|
||||
po->validcount = validcount;
|
||||
|
||||
for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y)
|
||||
{
|
||||
for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x)
|
||||
{
|
||||
mobj_t *mo;
|
||||
|
||||
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
|
||||
continue;
|
||||
|
||||
mo = blocklinks[y * bmapwidth + x];
|
||||
|
||||
for (; mo; mo = mo->bnext)
|
||||
{
|
||||
// Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect
|
||||
|
||||
if (!P_MobjTouchingPolyobj(po, mo))
|
||||
continue;
|
||||
|
||||
PIT_ChangeSector(mo, true);
|
||||
return nofit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sector->numattached)
|
||||
{
|
||||
size_t i;
|
||||
sector_t *sec;
|
||||
for (i = 0; i < sector->numattached; i++)
|
||||
{
|
||||
|
|
|
@ -311,6 +311,7 @@ fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
|
|||
#ifdef ESLOPE
|
||||
pslope_t *opentopslope, *openbottomslope;
|
||||
#endif
|
||||
ffloor_t *openfloorrover, *openceilingrover;
|
||||
|
||||
// P_CameraLineOpening
|
||||
// P_LineOpening, but for camera
|
||||
|
@ -517,6 +518,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
I_Assert(front != NULL);
|
||||
I_Assert(back != NULL);
|
||||
|
||||
openfloorrover = openceilingrover = NULL;
|
||||
|
||||
{ // Set open and high/low values here
|
||||
fixed_t frontheight, backheight;
|
||||
|
||||
|
@ -641,6 +644,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
pslope_t *ceilingslope = opentopslope;
|
||||
pslope_t *floorslope = openbottomslope;
|
||||
#endif
|
||||
ffloor_t *floorrover = NULL;
|
||||
ffloor_t *ceilingrover = NULL;
|
||||
|
||||
// Check for frontsector's fake floors
|
||||
for (rover = front->ffloors; rover; rover = rover->next)
|
||||
|
@ -668,6 +673,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
#ifdef ESLOPE
|
||||
ceilingslope = *rover->b_slope;
|
||||
#endif
|
||||
ceilingrover = rover;
|
||||
}
|
||||
else if (bottomheight < highestceiling)
|
||||
highestceiling = bottomheight;
|
||||
|
@ -680,6 +686,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
#ifdef ESLOPE
|
||||
floorslope = *rover->t_slope;
|
||||
#endif
|
||||
floorrover = rover;
|
||||
}
|
||||
else if (topheight > lowestfloor)
|
||||
lowestfloor = topheight;
|
||||
|
@ -712,6 +719,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
#ifdef ESLOPE
|
||||
ceilingslope = *rover->b_slope;
|
||||
#endif
|
||||
ceilingrover = rover;
|
||||
}
|
||||
else if (bottomheight < highestceiling)
|
||||
highestceiling = bottomheight;
|
||||
|
@ -724,6 +732,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
#ifdef ESLOPE
|
||||
floorslope = *rover->t_slope;
|
||||
#endif
|
||||
floorrover = rover;
|
||||
}
|
||||
else if (topheight > lowestfloor)
|
||||
lowestfloor = topheight;
|
||||
|
@ -743,6 +752,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
#ifdef ESLOPE
|
||||
ceilingslope = NULL;
|
||||
#endif
|
||||
ceilingrover = NULL;
|
||||
}
|
||||
else if (polysec->floorheight < highestceiling && delta1 >= delta2)
|
||||
highestceiling = polysec->floorheight;
|
||||
|
@ -752,6 +762,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
#ifdef ESLOPE
|
||||
floorslope = NULL;
|
||||
#endif
|
||||
floorrover = NULL;
|
||||
}
|
||||
else if (polysec->ceilingheight > lowestfloor && delta1 < delta2)
|
||||
lowestfloor = polysec->ceilingheight;
|
||||
|
@ -765,6 +776,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
#ifdef ESLOPE
|
||||
openbottomslope = floorslope;
|
||||
#endif
|
||||
openfloorrover = floorrover;
|
||||
}
|
||||
|
||||
if (lowestceiling < opentop) {
|
||||
|
@ -772,6 +784,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
#ifdef ESLOPE
|
||||
opentopslope = ceilingslope;
|
||||
#endif
|
||||
openceilingrover = ceilingrover;
|
||||
}
|
||||
|
||||
if (lowestfloor > lowfloor)
|
||||
|
|
|
@ -58,6 +58,7 @@ extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
|
|||
#ifdef ESLOPE
|
||||
extern pslope_t *opentopslope, *openbottomslope;
|
||||
#endif
|
||||
extern ffloor_t *openfloorrover, *openceilingrover;
|
||||
|
||||
void P_LineOpening(line_t *plinedef, mobj_t *mobj);
|
||||
|
||||
|
|
193
src/p_mobj.c
193
src/p_mobj.c
|
@ -1784,7 +1784,7 @@ static void P_PushableCheckBustables(mobj_t *mo)
|
|||
continue;
|
||||
}
|
||||
|
||||
EV_CrumbleChain(node->m_sector, rover);
|
||||
EV_CrumbleChain(NULL, rover); // node->m_sector
|
||||
|
||||
// Run a linedef executor??
|
||||
if (rover->master->flags & ML_EFFECT5)
|
||||
|
@ -3047,7 +3047,7 @@ static void P_PlayerZMovement(mobj_t *mo)
|
|||
}
|
||||
}
|
||||
|
||||
clipmomz = P_PlayerHitFloor(mo->player);
|
||||
clipmomz = P_PlayerHitFloor(mo->player, true);
|
||||
|
||||
if (!(mo->player->pflags & PF_SPINNING) && mo->player->powers[pw_carry] != CR_NIGHTSMODE)
|
||||
mo->player->pflags &= ~PF_STARTDASH;
|
||||
|
@ -3129,7 +3129,7 @@ nightsdone:
|
|||
{
|
||||
// DO THE MARIO!
|
||||
if (rover->flags & FF_SHATTERBOTTOM) // Brick block!
|
||||
EV_CrumbleChain(node->m_sector, rover);
|
||||
EV_CrumbleChain(NULL, rover); // node->m_sector
|
||||
else // Question block!
|
||||
EV_MarioBlock(rover, node->m_sector, mo);
|
||||
}
|
||||
|
@ -4674,7 +4674,7 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz)
|
|||
}
|
||||
|
||||
dz /= 9;
|
||||
|
||||
|
||||
while ((base = base->tracer)) // there are 10 per spoke, remember that
|
||||
{
|
||||
dx = (originx + P_ReturnThrustX(mobj, angle, (9*132)<<FRACBITS) - mobj->x)/9;
|
||||
|
@ -5236,6 +5236,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
|||
INT32 i;
|
||||
boolean foundgoop = false;
|
||||
INT32 closestNum;
|
||||
UINT8 extrainfo = (mobj->spawnpoint ? mobj->spawnpoint->extrainfo : 0);
|
||||
|
||||
// Looks for players in goop. If you find one, try to jump on him.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -5261,17 +5262,23 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
|||
continue;
|
||||
|
||||
mo2 = (mobj_t *)th;
|
||||
if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint)
|
||||
{
|
||||
dist = P_AproxDistance(players[i].mo->x - mo2->x, players[i].mo->y - mo2->y);
|
||||
if (mo2->type != MT_BOSS3WAYPOINT)
|
||||
continue;
|
||||
if (!mo2->spawnpoint)
|
||||
continue;
|
||||
if (mo2->spawnpoint->extrainfo != extrainfo)
|
||||
continue;
|
||||
if (mobj->health <= mobj->info->damage && !(mo2->spawnpoint->options & 7))
|
||||
continue; // don't jump to center
|
||||
|
||||
if (closestNum == -1 || dist < closestdist)
|
||||
{
|
||||
closestNum = (mo2->spawnpoint->options & 7);
|
||||
closestdist = dist;
|
||||
foundgoop = true;
|
||||
}
|
||||
}
|
||||
dist = P_AproxDistance(players[i].mo->x - mo2->x, players[i].mo->y - mo2->y);
|
||||
|
||||
if (!(closestNum == -1 || dist < closestdist))
|
||||
continue;
|
||||
|
||||
closestNum = (mo2->spawnpoint->options & 7);
|
||||
closestdist = dist;
|
||||
foundgoop = true;
|
||||
}
|
||||
waypointNum = closestNum;
|
||||
break;
|
||||
|
@ -5280,17 +5287,14 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
|||
|
||||
if (!foundgoop)
|
||||
{
|
||||
if (mobj->z > 1056*FRACUNIT)
|
||||
waypointNum = 0;
|
||||
else
|
||||
// Don't jump to the center when health is low.
|
||||
// Force the player to beat you with missiles.
|
||||
if (mobj->z <= 1056*FRACUNIT || mobj->health <= mobj->info->damage)
|
||||
waypointNum = 1 + P_RandomKey(4);
|
||||
else
|
||||
waypointNum = 0;
|
||||
}
|
||||
|
||||
// Don't jump to the center when health is low.
|
||||
// Force the player to beat you with missiles.
|
||||
if (mobj->health <= mobj->info->damage && waypointNum == 0)
|
||||
waypointNum = 1 + P_RandomKey(4);
|
||||
|
||||
if (mobj->tracer && mobj->tracer->type == MT_BOSS3WAYPOINT
|
||||
&& mobj->tracer->spawnpoint && (mobj->tracer->spawnpoint->options & 7) == waypointNum)
|
||||
{
|
||||
|
@ -5299,15 +5303,12 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
|||
else
|
||||
waypointNum--;
|
||||
|
||||
waypointNum %= 5;
|
||||
|
||||
if (waypointNum < 0)
|
||||
waypointNum = 0;
|
||||
if (mobj->health <= mobj->info->damage)
|
||||
waypointNum = ((waypointNum + 3) % 4) + 1; // plus four to avoid modulo being negative, minus one to avoid waypoint #0
|
||||
else
|
||||
waypointNum = ((waypointNum + 5) % 5);
|
||||
}
|
||||
|
||||
if (waypointNum == 0 && mobj->health <= mobj->info->damage)
|
||||
waypointNum = 1 + (P_RandomFixed() & 1);
|
||||
|
||||
// scan the thinkers to find
|
||||
// the waypoint to use
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
|
@ -5316,11 +5317,17 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
|||
continue;
|
||||
|
||||
mo2 = (mobj_t *)th;
|
||||
if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint && (mo2->spawnpoint->options & 7) == waypointNum)
|
||||
{
|
||||
hitspot = mo2;
|
||||
break;
|
||||
}
|
||||
if (mo2->type != MT_BOSS3WAYPOINT)
|
||||
continue;
|
||||
if (!mo2->spawnpoint)
|
||||
continue;
|
||||
if ((mo2->spawnpoint->options & 7) != waypointNum)
|
||||
continue;
|
||||
if (mo2->spawnpoint->extrainfo != extrainfo)
|
||||
continue;
|
||||
|
||||
hitspot = mo2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hitspot == NULL)
|
||||
|
@ -7004,6 +7011,9 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (mobj->flags & MF_NOTHINK)
|
||||
return;
|
||||
|
||||
if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<<mobj->spawnpoint->extrainfo)))
|
||||
return;
|
||||
|
||||
// Remove dead target/tracer.
|
||||
if (mobj->target && P_MobjWasRemoved(mobj->target))
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
|
@ -8072,7 +8082,8 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->tracer->z += mobj->height;
|
||||
}
|
||||
break;
|
||||
case MT_WAVINGFLAG:
|
||||
case MT_WAVINGFLAG1:
|
||||
case MT_WAVINGFLAG2:
|
||||
{
|
||||
fixed_t base = (leveltime<<(FRACBITS+1));
|
||||
mobj_t *seg = mobj->tracer, *prev = mobj;
|
||||
|
@ -9675,15 +9686,14 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
case MT_BIGMINE:
|
||||
mobj->extravalue1 = FixedHypot(mobj->x, mobj->y)>>FRACBITS;
|
||||
break;
|
||||
case MT_WAVINGFLAG:
|
||||
case MT_WAVINGFLAG1:
|
||||
case MT_WAVINGFLAG2:
|
||||
{
|
||||
mobj_t *prev = mobj, *cur;
|
||||
UINT8 i;
|
||||
mobj->destscale <<= 2;
|
||||
P_SetScale(mobj, mobj->destscale);
|
||||
for (i = 0; i <= 16; i++) // probably should be < but staying authentic to the Lua version
|
||||
{
|
||||
cur = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_WAVINGFLAGSEG);
|
||||
cur = P_SpawnMobjFromMobj(mobj, 0, 0, 0, ((mobj->type == MT_WAVINGFLAG1) ? MT_WAVINGFLAGSEG1 : MT_WAVINGFLAGSEG2));;
|
||||
P_SetTarget(&prev->tracer, cur);
|
||||
cur->extravalue1 = i;
|
||||
prev = cur;
|
||||
|
@ -11100,6 +11110,12 @@ You should think about modifying the deathmatch starts to take full advantage of
|
|||
else
|
||||
skyboxviewpnts[mthing->extrainfo] = mobj;
|
||||
break;
|
||||
case MT_EGGSTATUE:
|
||||
if (tutorialmode != (mthing->options & MTF_OBJECTSPECIAL))
|
||||
{
|
||||
mobj->color = SKINCOLOR_GOLD;
|
||||
mobj->colorized = true;
|
||||
}
|
||||
case MT_EGGMOBILE3:
|
||||
mobj->cusval = mthing->extrainfo;
|
||||
break;
|
||||
|
@ -11754,13 +11770,14 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
P_SpawnMobjFromMobj(mobj, -1*FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270;
|
||||
}
|
||||
break;
|
||||
case MT_CEZPOLE:
|
||||
case MT_CEZPOLE1:
|
||||
case MT_CEZPOLE2:
|
||||
{ // Spawn the banner
|
||||
angle_t mobjangle = FixedAngle(mthing->angle<<FRACBITS);
|
||||
P_SpawnMobjFromMobj(mobj,
|
||||
P_ReturnThrustX(mobj, mobjangle, 4<<FRACBITS),
|
||||
P_ReturnThrustY(mobj, mobjangle, 4<<FRACBITS),
|
||||
0, MT_CEZBANNER)->angle = mobjangle + ANGLE_90;
|
||||
0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2))->angle = mobjangle + ANGLE_90;
|
||||
}
|
||||
break;
|
||||
case MT_HHZTREE_TOP:
|
||||
|
@ -11984,6 +12001,15 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
if (i == MT_YELLOWDIAG || i == MT_REDDIAG)
|
||||
mobj->angle += ANGLE_22h;
|
||||
|
||||
if (i == MT_YELLOWHORIZ || i == MT_REDHORIZ || i == MT_BLUEHORIZ)
|
||||
{
|
||||
if (mthing->options & MTF_OBJECTFLIP)
|
||||
mobj->z -= 16*FRACUNIT;
|
||||
else
|
||||
mobj->z += 16*FRACUNIT;
|
||||
}
|
||||
|
||||
|
||||
if (mobj->flags & MF_NIGHTSITEM)
|
||||
{
|
||||
// Spawn already displayed
|
||||
|
@ -12011,6 +12037,9 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
{
|
||||
if (i == MT_YELLOWDIAG || i == MT_REDDIAG)
|
||||
mobj->flags |= MF_NOGRAVITY;
|
||||
|
||||
if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0)
|
||||
{
|
||||
// flag for strong/weak random boxes
|
||||
|
@ -12354,28 +12383,33 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
|
|||
if (nightsreplace)
|
||||
ringthing = MT_NIGHTSSTAR;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (r = 1; r <= 5; r++)
|
||||
{
|
||||
if (mthing->options & MTF_OBJECTFLIP)
|
||||
{
|
||||
z = (
|
||||
#ifdef ESLOPE
|
||||
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
|
||||
#endif
|
||||
sec->ceilingheight) - mobjinfo[ringthing].height - dist*r;
|
||||
if (mthing->options >> ZSHIFT)
|
||||
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
|
||||
}
|
||||
z -= dist;
|
||||
else
|
||||
{
|
||||
z = (
|
||||
#ifdef ESLOPE
|
||||
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
||||
#endif
|
||||
sec->floorheight) + dist*r;
|
||||
if (mthing->options >> ZSHIFT)
|
||||
z += ((mthing->options >> ZSHIFT) << FRACBITS);
|
||||
}
|
||||
z += dist;
|
||||
|
||||
mobj = P_SpawnMobj(x, y, z, ringthing);
|
||||
|
||||
|
@ -12409,31 +12443,36 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
|
|||
closestangle = FixedAngle(mthing->angle*FRACUNIT);
|
||||
fa = (closestangle >> ANGLETOFINESHIFT);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (r = 1; r <= iterations; r++)
|
||||
{
|
||||
x += FixedMul(64*FRACUNIT, FINECOSINE(fa));
|
||||
y += FixedMul(64*FRACUNIT, FINESINE(fa));
|
||||
|
||||
if (mthing->options & MTF_OBJECTFLIP)
|
||||
{
|
||||
z = (
|
||||
#ifdef ESLOPE
|
||||
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
|
||||
#endif
|
||||
sec->ceilingheight) - mobjinfo[ringthing].height - 64*FRACUNIT*r;
|
||||
if (mthing->options >> ZSHIFT)
|
||||
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
|
||||
}
|
||||
z -= 64*FRACUNIT;
|
||||
else
|
||||
{
|
||||
z = (
|
||||
#ifdef ESLOPE
|
||||
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
|
||||
#endif
|
||||
sec->floorheight) + 64*FRACUNIT*r;
|
||||
if (mthing->options >> ZSHIFT)
|
||||
z += ((mthing->options >> ZSHIFT) << FRACBITS);
|
||||
}
|
||||
z += 64*FRACUNIT;
|
||||
|
||||
mobj = P_SpawnMobj(x, y, z, ringthing);
|
||||
|
||||
|
|
|
@ -470,4 +470,5 @@ extern INT32 numhuntemeralds;
|
|||
extern boolean runemeraldmanager;
|
||||
extern UINT16 emeraldspawndelay;
|
||||
extern INT32 numstarposts;
|
||||
extern UINT16 bossdisabled;
|
||||
#endif
|
||||
|
|
|
@ -1873,7 +1873,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
|||
po->lines[0]->backsector->floorheight = target->z - amtz;
|
||||
po->lines[0]->backsector->ceilingheight = target->z + amtz;
|
||||
// Sal: Remember to check your sectors!
|
||||
P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
|
||||
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
||||
// updating objects in the front one too just added teleporting to ground bugs
|
||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
||||
// Apply action to mirroring polyobjects as well
|
||||
start = 0;
|
||||
|
@ -1887,7 +1888,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
|||
po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did
|
||||
po->lines[0]->backsector->ceilingheight += diffz;
|
||||
// Sal: Remember to check your sectors!
|
||||
P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
|
||||
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
||||
// updating objects in the front one too just added teleporting to ground bugs
|
||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
||||
}
|
||||
|
||||
|
@ -2050,8 +2052,9 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
|||
po->lines[0]->backsector->floorheight += momz;
|
||||
po->lines[0]->backsector->ceilingheight += momz;
|
||||
// Sal: Remember to check your sectors!
|
||||
P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); // frontsector is NEEDED for crushing
|
||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); // backsector may not be necessary, but just in case
|
||||
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
||||
// updating objects in the front one too just added teleporting to ground bugs
|
||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
||||
|
||||
// Apply action to mirroring polyobjects as well
|
||||
start = 0;
|
||||
|
@ -2065,7 +2068,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
|||
po->lines[0]->backsector->floorheight += momz;
|
||||
po->lines[0]->backsector->ceilingheight += momz;
|
||||
// Sal: Remember to check your sectors!
|
||||
P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
|
||||
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
||||
// updating objects in the front one too just added teleporting to ground bugs
|
||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3408,7 +3408,7 @@ static void P_NetUnArchiveThinkers(void)
|
|||
{
|
||||
for (;;)
|
||||
{
|
||||
thinker_t* th;
|
||||
thinker_t* th = NULL;
|
||||
tclass = READUINT8(save_p);
|
||||
|
||||
if (tclass == tc_end)
|
||||
|
@ -3990,6 +3990,7 @@ static void P_NetArchiveMisc(void)
|
|||
WRITEUINT32(save_p, leveltime);
|
||||
WRITEUINT32(save_p, ssspheres);
|
||||
WRITEINT16(save_p, lastmap);
|
||||
WRITEUINT16(save_p, bossdisabled);
|
||||
|
||||
WRITEUINT16(save_p, emeralds);
|
||||
WRITEUINT8(save_p, stagefailed);
|
||||
|
@ -4067,6 +4068,7 @@ static inline boolean P_NetUnArchiveMisc(void)
|
|||
leveltime = READUINT32(save_p);
|
||||
ssspheres = READUINT32(save_p);
|
||||
lastmap = READINT16(save_p);
|
||||
bossdisabled = READUINT16(save_p);
|
||||
|
||||
emeralds = READUINT16(save_p);
|
||||
stagefailed = READUINT8(save_p);
|
||||
|
|
|
@ -102,6 +102,7 @@ line_t *lines;
|
|||
side_t *sides;
|
||||
mapthing_t *mapthings;
|
||||
INT32 numstarposts;
|
||||
UINT16 bossdisabled;
|
||||
boolean levelloading;
|
||||
UINT8 levelfadecol;
|
||||
|
||||
|
@ -859,12 +860,7 @@ void P_ReloadRings(void)
|
|||
mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)
|
||||
->sector->floorheight>>FRACBITS);
|
||||
|
||||
P_SpawnHoopsAndRings(mt,
|
||||
#ifdef MANIASPHERES
|
||||
true);
|
||||
#else
|
||||
!G_IsSpecialStage(gamemap)); // prevent flashing spheres in special stages
|
||||
#endif
|
||||
P_SpawnHoopsAndRings(mt, true);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < numHoops; i++)
|
||||
|
@ -878,11 +874,6 @@ 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 = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
{
|
||||
|
@ -2215,7 +2206,7 @@ static void P_LevelInitStuff(void)
|
|||
ssspheres = timeinmap = 0;
|
||||
|
||||
// special stage
|
||||
stagefailed = false;
|
||||
stagefailed = true; // assume failed unless proven otherwise - P_GiveEmerald or emerald touchspecial
|
||||
// Reset temporary record data
|
||||
memset(&ntemprecords, 0, sizeof(nightsdata_t));
|
||||
|
||||
|
@ -3126,7 +3117,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
R_PrecacheLevel();
|
||||
|
||||
nextmapoverride = 0;
|
||||
skipstats = false;
|
||||
skipstats = 0;
|
||||
|
||||
if (!(netgame || multiplayer) && (!modifiedgame || savemoddata))
|
||||
mapvisited[gamemap-1] |= MV_VISITED;
|
||||
|
@ -3437,13 +3428,13 @@ boolean P_AddWadFile(const char *wadfilename)
|
|||
ST_UnloadGraphics();
|
||||
HU_LoadGraphics();
|
||||
ST_LoadGraphics();
|
||||
ST_ReloadSkinFaceGraphics();
|
||||
|
||||
//
|
||||
// look for skins
|
||||
//
|
||||
R_AddSkins(wadnum); // faB: wadfile index in wadfiles[]
|
||||
R_PatchSkins(wadnum); // toast: PATCH PATCH
|
||||
ST_ReloadSkinFaceGraphics();
|
||||
|
||||
//
|
||||
// search for maps
|
||||
|
|
61
src/p_spec.c
61
src/p_spec.c
|
@ -3554,6 +3554,29 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
}
|
||||
break;
|
||||
|
||||
case 449: // Enable bosses with parameter
|
||||
{
|
||||
INT32 bossid = sides[line->sidenum[0]].textureoffset>>FRACBITS;
|
||||
if (bossid & ~15) // if any bits other than first 16 are set
|
||||
{
|
||||
CONS_Alert(CONS_WARNING,
|
||||
M_GetText("Boss enable linedef (tag %d) has an invalid texture x offset.\nConsider changing it or removing it entirely.\n"),
|
||||
line->tag);
|
||||
break;
|
||||
}
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
{
|
||||
bossdisabled |= (1<<bossid);
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 449 Executor: bossid disabled = %d", bossid);
|
||||
}
|
||||
else
|
||||
{
|
||||
bossdisabled &= ~(1<<bossid);
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 449 Executor: bossid enabled = %d", bossid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 450: // Execute Linedef Executor - for recursion
|
||||
P_LinedefExecute(line->tag, mo, NULL);
|
||||
break;
|
||||
|
@ -3918,6 +3941,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
}
|
||||
break;
|
||||
|
||||
case 460: // Award rings
|
||||
{
|
||||
INT16 rings = (sides[line->sidenum[0]].textureoffset>>FRACBITS);
|
||||
INT32 delay = (sides[line->sidenum[0]].rowoffset>>FRACBITS);
|
||||
if (mo && mo->player)
|
||||
{
|
||||
if (delay <= 0 || !(leveltime % delay))
|
||||
P_GivePlayerRings(mo->player, rings);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef POLYOBJECTS
|
||||
case 480: // Polyobj_DoorSlide
|
||||
case 481: // Polyobj_DoorSwing
|
||||
|
@ -4601,7 +4636,10 @@ DoneSection2:
|
|||
if (player->bot)
|
||||
break;
|
||||
if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && player->nightstime > 6)
|
||||
{
|
||||
player->nightstime = 6; // Just let P_Ticker take care of the rest.
|
||||
return;
|
||||
}
|
||||
|
||||
// Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c)
|
||||
{
|
||||
|
@ -4624,7 +4662,7 @@ DoneSection2:
|
|||
nextmapoverride = (INT16)(lines[lineindex].frontsector->floorheight>>FRACBITS);
|
||||
|
||||
if (lines[lineindex].flags & ML_NOCLIMB)
|
||||
skipstats = true;
|
||||
skipstats = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -6401,6 +6439,9 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
// but currently isn't.
|
||||
(void)fromnetsave;
|
||||
|
||||
// yep, we do this here - "bossdisabled" is considered an apparatus of specials.
|
||||
bossdisabled = 0;
|
||||
|
||||
// Init special SECTORs.
|
||||
sector = sectors;
|
||||
for (i = 0; i < numsectors; i++, sector++)
|
||||
|
@ -7289,6 +7330,24 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
case 431:
|
||||
break;
|
||||
|
||||
case 449: // Enable bosses with parameter
|
||||
{
|
||||
INT32 bossid = sides[*lines[i].sidenum].textureoffset>>FRACBITS;
|
||||
if (bossid & ~15) // if any bits other than first 16 are set
|
||||
{
|
||||
CONS_Alert(CONS_WARNING,
|
||||
M_GetText("Boss enable linedef (tag %d) has an invalid texture x offset.\nConsider changing it or removing it entirely.\n"),
|
||||
lines[i].tag);
|
||||
break;
|
||||
}
|
||||
if (!(lines[i].flags & ML_NOCLIMB))
|
||||
{
|
||||
bossdisabled |= (1<<bossid); // gotta disable in the first place to enable
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 449 spawn effect: bossid disabled = %d", bossid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 500 is used for a scroller
|
||||
// 501 is used for a scroller
|
||||
// 502 is used for a scroller
|
||||
|
|
|
@ -518,10 +518,7 @@ static inline void P_DoSpecialStageStuff(void)
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sstimer = 0;
|
||||
stagefailed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
141
src/p_user.c
141
src/p_user.c
|
@ -302,15 +302,39 @@ void P_GiveEmerald(boolean spawnObj)
|
|||
|
||||
S_StartSound(NULL, sfx_cgot); // Got the emerald!
|
||||
emeralds |= (1 << em);
|
||||
stagefailed = false;
|
||||
|
||||
if (spawnObj && playeringame[consoleplayer])
|
||||
if (spawnObj)
|
||||
{
|
||||
// The Chaos Emerald begins to orbit us!
|
||||
// Only give it to ONE person!
|
||||
mobj_t *emmo = P_SpawnMobjFromMobj(players[consoleplayer].mo, 0, 0, players[consoleplayer].mo->height, MT_GOTEMERALD);
|
||||
P_SetTarget(&emmo->target, players[consoleplayer].mo);
|
||||
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
|
||||
P_SetTarget(&players[consoleplayer].mo->tracer, emmo);
|
||||
// Only visibly give it to ONE person!
|
||||
UINT8 i, pnum = ((playeringame[consoleplayer]) && (!players[consoleplayer].spectator) && (players[consoleplayer].mo)) ? consoleplayer : 255;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
mobj_t *emmo;
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
if (players[i].spectator)
|
||||
continue;
|
||||
if (!players[i].mo)
|
||||
continue;
|
||||
|
||||
emmo = P_SpawnMobjFromMobj(players[i].mo, 0, 0, players[i].mo->height, MT_GOTEMERALD);
|
||||
P_SetTarget(&emmo->target, players[i].mo);
|
||||
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
|
||||
P_SetTarget(&players[i].mo->tracer, emmo);
|
||||
|
||||
if (pnum == 255)
|
||||
{
|
||||
i = pnum;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == pnum)
|
||||
continue;
|
||||
|
||||
emmo->flags2 |= MF2_DONTDRAW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -597,7 +621,7 @@ static void P_DeNightserizePlayer(player_t *player)
|
|||
player->mo->skin = &skins[player->skin];
|
||||
player->followitem = skins[player->skin].followitem;
|
||||
player->mo->color = player->skincolor;
|
||||
G_GhostAddColor(GHC_NORMAL);
|
||||
G_GhostAddColor(GHC_RETURNSKIN);
|
||||
|
||||
// Restore aiming angle
|
||||
if (player == &players[consoleplayer])
|
||||
|
@ -615,7 +639,6 @@ static void P_DeNightserizePlayer(player_t *player)
|
|||
if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
|
||||
players[i].nightstime = 1; // force everyone else to fall too.
|
||||
player->exiting = 3*TICRATE;
|
||||
stagefailed = true; // NIGHT OVER
|
||||
|
||||
// If you screwed up, kiss your score and ring bonus goodbye.
|
||||
// But only do this in special stage (and instakill!) In regular stages, wait til we hit the ground.
|
||||
|
@ -716,6 +739,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
|
||||
player->mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor;
|
||||
player->followitem = skins[DEFAULTNIGHTSSKIN].followitem;
|
||||
G_GhostAddColor(GHC_NIGHTSSKIN);
|
||||
}
|
||||
|
||||
player->nightstime = player->startedtime = player->lapstartedtime = nighttime*TICRATE;
|
||||
|
@ -2007,7 +2031,7 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
|
|||
//
|
||||
// Handles player hitting floor surface.
|
||||
// Returns whether to clip momz.
|
||||
boolean P_PlayerHitFloor(player_t *player)
|
||||
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
||||
{
|
||||
boolean clipmomz;
|
||||
|
||||
|
@ -2015,22 +2039,31 @@ boolean P_PlayerHitFloor(player_t *player)
|
|||
|
||||
if ((clipmomz = !(P_CheckDeathPitCollide(player->mo))) && player->mo->health && !player->spectator)
|
||||
{
|
||||
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale)))
|
||||
if (dorollstuff)
|
||||
{
|
||||
player->pflags |= PF_SPINNING;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
|
||||
S_StartSound(player->mo, sfx_spin);
|
||||
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale)))
|
||||
{
|
||||
player->pflags |= PF_SPINNING;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
|
||||
S_StartSound(player->mo, sfx_spin);
|
||||
}
|
||||
else
|
||||
player->pflags &= ~PF_SPINNING;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->pflags &= ~PF_SPINNING;
|
||||
|
||||
if (player->pflags & PF_GLIDING) // ground gliding
|
||||
if (player->pflags & PF_GLIDING) // ground gliding
|
||||
{
|
||||
if (dorollstuff)
|
||||
{
|
||||
player->skidtime = TICRATE;
|
||||
player->mo->tics = -1;
|
||||
}
|
||||
else if (player->charability2 == CA2_MELEE && (player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING))
|
||||
else
|
||||
player->pflags &= ~PF_GLIDING;
|
||||
}
|
||||
else if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
|
||||
{
|
||||
if (player->mo->state-states != S_PLAY_MELEE_LANDING)
|
||||
{
|
||||
mobjtype_t type = player->revitem;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING);
|
||||
|
@ -2049,7 +2082,7 @@ boolean P_PlayerHitFloor(player_t *player)
|
|||
fixed_t mu = FixedMul(player->maxdash, player->mo->scale);
|
||||
fixed_t mu2 = FixedHypot(player->mo->momx, player->mo->momy);
|
||||
fixed_t ev;
|
||||
mobj_t *missile;
|
||||
mobj_t *missile = NULL;
|
||||
if (mu2 < mu)
|
||||
mu2 = mu;
|
||||
ev = (50*FRACUNIT - (mu/25))/50;
|
||||
|
@ -2062,45 +2095,48 @@ boolean P_PlayerHitFloor(player_t *player)
|
|||
P_ReturnThrustY(missile, throwang, mu)); // side to side component
|
||||
P_Thrust(missile, player->drawangle, mu2); // forward component
|
||||
P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true);
|
||||
missile->momz += player->mo->pmomz;
|
||||
missile->fuse = TICRATE/2;
|
||||
missile->extravalue2 = ev;
|
||||
|
||||
i++;
|
||||
throwang += ANG30;
|
||||
}
|
||||
if (mobjinfo[type].seesound)
|
||||
if (mobjinfo[type].seesound && missile)
|
||||
S_StartSound(missile, missile->info->seesound);
|
||||
}
|
||||
}
|
||||
else if (player->pflags & PF_JUMPED || !(player->pflags & PF_SPINNING)
|
||||
}
|
||||
else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2)
|
||||
;
|
||||
else if (player->pflags & PF_JUMPED || !(player->pflags & PF_SPINNING)
|
||||
|| player->powers[pw_tailsfly] || player->mo->state-states == S_PLAY_FLY_TIRED)
|
||||
{
|
||||
if (player->cmomx || player->cmomy)
|
||||
{
|
||||
if (player->cmomx || player->cmomy)
|
||||
{
|
||||
if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
|
||||
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
|
||||
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
|
||||
else if ((player->rmomx || player->rmomy)
|
||||
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
|
||||
else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
|
||||
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
|
||||
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
|
||||
else if ((player->mo->momx || player->mo->momy)
|
||||
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
|
||||
else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
}
|
||||
if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
|
||||
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
|
||||
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
|
||||
else if ((player->rmomx || player->rmomy)
|
||||
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
|
||||
else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
|
||||
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
|
||||
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
|
||||
else if ((player->mo->momx || player->mo->momy)
|
||||
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
|
||||
else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2320,7 +2356,7 @@ static void P_CheckBustableBlocks(player_t *player)
|
|||
//if (metalrecording)
|
||||
// G_RecordBustup(rover);
|
||||
|
||||
EV_CrumbleChain(node->m_sector, rover);
|
||||
EV_CrumbleChain(NULL, rover); // node->m_sector
|
||||
|
||||
// Run a linedef executor??
|
||||
if (rover->master->flags & ML_EFFECT5)
|
||||
|
@ -2537,7 +2573,7 @@ static void P_CheckQuicksand(player_t *player)
|
|||
player->mo->z = ceilingheight - player->mo->height;
|
||||
|
||||
if (player->mo->momz <= 0)
|
||||
P_PlayerHitFloor(player);
|
||||
P_PlayerHitFloor(player, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2549,7 +2585,7 @@ static void P_CheckQuicksand(player_t *player)
|
|||
player->mo->z = floorheight;
|
||||
|
||||
if (player->mo->momz >= 0)
|
||||
P_PlayerHitFloor(player);
|
||||
P_PlayerHitFloor(player, false);
|
||||
}
|
||||
|
||||
friction = abs(rover->master->v1->y - rover->master->v2->y)>>6;
|
||||
|
@ -4410,6 +4446,10 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
|
|||
{
|
||||
player->mo->z += P_MobjFlip(player->mo);
|
||||
P_SetObjectMomZ(player->mo, player->mindash, false);
|
||||
if (P_MobjFlip(player->mo)*player->mo->pmomz > 0)
|
||||
player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump.
|
||||
else
|
||||
player->mo->pmomz = 0;
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
player->mo->momz >>= 1;
|
||||
#if 0
|
||||
|
@ -11641,7 +11681,6 @@ void P_PlayerAfterThink(player_t *player)
|
|||
player->followmobj->threshold = player->mo->z;
|
||||
player->followmobj->movecount = player->panim;
|
||||
player->followmobj->angle = horizangle;
|
||||
player->followmobj->scale = player->mo->scale;
|
||||
P_SetScale(player->followmobj, player->mo->scale);
|
||||
player->followmobj->destscale = player->mo->destscale;
|
||||
player->followmobj->radius = player->mo->radius;
|
||||
|
|
|
@ -486,7 +486,11 @@ void R_InitSprites(void)
|
|||
// it can be is do before loading config for skin cvar possible value
|
||||
R_InitSkins();
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
{
|
||||
R_AddSkins((UINT16)i);
|
||||
R_PatchSkins((UINT16)i);
|
||||
}
|
||||
ST_ReloadSkinFaceGraphics();
|
||||
|
||||
//
|
||||
// check if all sprites have frames
|
||||
|
@ -2446,9 +2450,11 @@ static void R_DrawMaskedList (drawnode_t* head)
|
|||
|
||||
void R_DrawMasked(maskcount_t* masks, UINT8 nummasks)
|
||||
{
|
||||
drawnode_t heads[nummasks]; /**< Drawnode lists; as many as number of views/portals. */
|
||||
drawnode_t *heads; /**< Drawnode lists; as many as number of views/portals. */
|
||||
SINT8 i;
|
||||
|
||||
heads = calloc(nummasks, sizeof(drawnode_t));
|
||||
|
||||
for (i = 0; i < nummasks; i++)
|
||||
{
|
||||
heads[i].next = heads[i].prev = &heads[i];
|
||||
|
@ -2474,6 +2480,8 @@ void R_DrawMasked(maskcount_t* masks, UINT8 nummasks)
|
|||
R_DrawMaskedList(&heads[nummasks - 1]);
|
||||
R_ClearDrawNodes(&heads[nummasks - 1]);
|
||||
}
|
||||
|
||||
free(heads);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
@ -2503,6 +2511,9 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
|||
if (!skin)
|
||||
return 0;
|
||||
|
||||
if ((spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
return 0;
|
||||
|
||||
while (!(skin->sprites[spr2].numframes)
|
||||
&& spr2 != SPR2_STND
|
||||
&& ++i < 32) // recursion limiter
|
||||
|
@ -2525,8 +2536,10 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
|||
& SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL;
|
||||
break;
|
||||
case SPR2_TIRE:
|
||||
spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||
break;
|
||||
spr2 = ((player
|
||||
? player->charability
|
||||
: skin->ability)
|
||||
== CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||
|
||||
// Use the handy list, that's what it's there for!
|
||||
default:
|
||||
|
@ -2537,6 +2550,9 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
|||
spr2 |= super;
|
||||
}
|
||||
|
||||
if (i >= 32) // probably an infinite loop...
|
||||
return 0;
|
||||
|
||||
return spr2;
|
||||
}
|
||||
|
||||
|
@ -2556,9 +2572,6 @@ static void Sk_SetDefaultValue(skin_t *skin)
|
|||
|
||||
strcpy(skin->realname, "Someone");
|
||||
strcpy(skin->hudname, "???");
|
||||
strncpy(skin->charsel, "CHRSONIC", 9);
|
||||
strncpy(skin->face, "MISSING", 8);
|
||||
strncpy(skin->superface, "MISSING", 8);
|
||||
|
||||
skin->starttranscolor = 96;
|
||||
skin->prefcolor = SKINCOLOR_GREEN;
|
||||
|
@ -2988,7 +3001,7 @@ void R_AddSkins(UINT16 wadnum)
|
|||
char *value;
|
||||
size_t size;
|
||||
skin_t *skin;
|
||||
boolean hudname, realname, superface;
|
||||
boolean hudname, realname;
|
||||
|
||||
//
|
||||
// search for all skin markers in pwad
|
||||
|
@ -3018,7 +3031,7 @@ void R_AddSkins(UINT16 wadnum)
|
|||
skin = &skins[numskins];
|
||||
Sk_SetDefaultValue(skin);
|
||||
skin->wadnum = wadnum;
|
||||
hudname = realname = superface = false;
|
||||
hudname = realname = false;
|
||||
// parse
|
||||
stoken = strtok (buf2, "\r\n= ");
|
||||
while (stoken)
|
||||
|
@ -3094,24 +3107,6 @@ void R_AddSkins(UINT16 wadnum)
|
|||
if (!realname)
|
||||
STRBUFCPY(skin->realname, skin->hudname);
|
||||
}
|
||||
else if (!stricmp(stoken, "charsel"))
|
||||
{
|
||||
strupr(value);
|
||||
strncpy(skin->charsel, value, sizeof skin->charsel);
|
||||
}
|
||||
else if (!stricmp(stoken, "face"))
|
||||
{
|
||||
strupr(value);
|
||||
strncpy(skin->face, value, sizeof skin->face);
|
||||
if (!superface)
|
||||
strncpy(skin->superface, value, sizeof skin->superface);
|
||||
}
|
||||
else if (!stricmp(stoken, "superface"))
|
||||
{
|
||||
superface = true;
|
||||
strupr(value);
|
||||
strncpy(skin->superface, value, sizeof skin->superface);
|
||||
}
|
||||
else if (!stricmp(stoken, "availability"))
|
||||
{
|
||||
skin->availability = atoi(value);
|
||||
|
@ -3130,6 +3125,7 @@ next_token:
|
|||
|
||||
// Add sprites
|
||||
R_LoadSkinSprites(wadnum, &lump, &lastlump, skin);
|
||||
//ST_LoadFaceGraphics(numskins); -- nah let's do this elsewhere
|
||||
|
||||
R_FlushTranslationColormapCache();
|
||||
|
||||
|
@ -3140,9 +3136,6 @@ next_token:
|
|||
skin_cons_t[numskins].strvalue = skin->name;
|
||||
#endif
|
||||
|
||||
// add face graphics
|
||||
ST_LoadFaceGraphics(skin->face, skin->superface, numskins);
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
HWR_AddPlayerMD2(numskins);
|
||||
|
@ -3265,6 +3258,9 @@ next_token:
|
|||
|
||||
// Patch sprites
|
||||
R_LoadSkinSprites(wadnum, &lump, &lastlump, skin);
|
||||
//ST_LoadFaceGraphics(skinnum); -- nah let's do this elsewhere
|
||||
|
||||
R_FlushTranslationColormapCache();
|
||||
|
||||
if (!skin->availability) // Safe to print...
|
||||
CONS_Printf(M_GetText("Patched skin '%s'\n"), skin->name);
|
||||
|
|
|
@ -88,7 +88,6 @@ typedef struct
|
|||
|
||||
char realname[SKINNAMESIZE+1]; // Display name for level completion.
|
||||
char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long)
|
||||
char charsel[9], face[9], superface[9]; // Arbitrarily named patch lumps
|
||||
|
||||
UINT8 ability; // ability definition
|
||||
UINT8 ability2; // secondary ability definition
|
||||
|
|
|
@ -524,6 +524,7 @@ void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan)
|
|||
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
{
|
||||
INT32 sep, pitch, priority, cnum;
|
||||
const sfxenum_t actual_id = sfx_id;
|
||||
sfxinfo_t *sfx;
|
||||
|
||||
const mobj_t *origin = (const mobj_t *)origin_p;
|
||||
|
@ -662,7 +663,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
|||
#endif
|
||||
|
||||
// Handle closed caption input.
|
||||
S_StartCaption(sfx_id, cnum, MAXCAPTIONTICS);
|
||||
S_StartCaption(actual_id, cnum, MAXCAPTIONTICS);
|
||||
|
||||
// Assigns the handle to one of the channels in the
|
||||
// mix/output buffer.
|
||||
|
@ -715,7 +716,7 @@ dontplay:
|
|||
#endif
|
||||
|
||||
// Handle closed caption input.
|
||||
S_StartCaption(sfx_id, cnum, MAXCAPTIONTICS);
|
||||
S_StartCaption(actual_id, cnum, MAXCAPTIONTICS);
|
||||
|
||||
// Assigns the handle to one of the channels in the
|
||||
// mix/output buffer.
|
||||
|
@ -1675,7 +1676,17 @@ void S_StopMusic(void)
|
|||
if (cv_closedcaptioning.value)
|
||||
{
|
||||
if (closedcaptions[0].s-S_sfx == sfx_None)
|
||||
closedcaptions[0].t = CAPTIONFADETICS;
|
||||
{
|
||||
if (gamestate != wipegamestate)
|
||||
{
|
||||
closedcaptions[0].c = NULL;
|
||||
closedcaptions[0].s = NULL;
|
||||
closedcaptions[0].t = 0;
|
||||
closedcaptions[0].b = 0;
|
||||
}
|
||||
else
|
||||
closedcaptions[0].t = CAPTIONFADETICS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1982,8 +1993,10 @@ void GameMIDIMusic_OnChange(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENMPT
|
||||
void ModFilter_OnChange(void)
|
||||
{
|
||||
if (openmpt_mhandle)
|
||||
openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value);
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -438,7 +438,9 @@ void SCR_ClosedCaptions(void)
|
|||
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
if (splitscreen)
|
||||
if (promptactive)
|
||||
basey -= 28;
|
||||
else if (splitscreen)
|
||||
basey -= 8;
|
||||
else if ((modeattacking == ATTACKING_NIGHTS)
|
||||
|| (!(maptol & TOL_NIGHTS)
|
||||
|
|
|
@ -277,6 +277,7 @@
|
|||
<ClInclude Include="..\r_local.h" />
|
||||
<ClInclude Include="..\r_main.h" />
|
||||
<ClInclude Include="..\r_plane.h" />
|
||||
<ClInclude Include="..\r_portal.h" />
|
||||
<ClInclude Include="..\r_segs.h" />
|
||||
<ClInclude Include="..\r_sky.h" />
|
||||
<ClInclude Include="..\r_splats.h" />
|
||||
|
@ -430,6 +431,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\r_main.c" />
|
||||
<ClCompile Include="..\r_plane.c" />
|
||||
<ClCompile Include="..\r_portal.c" />
|
||||
<ClCompile Include="..\r_segs.c" />
|
||||
<ClCompile Include="..\r_sky.c" />
|
||||
<ClCompile Include="..\r_splats.c" />
|
||||
|
|
|
@ -453,6 +453,9 @@
|
|||
<ClInclude Include="..\hardware\hw_clip.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\r_portal.h">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\tmap.nas">
|
||||
|
@ -894,6 +897,10 @@
|
|||
<ClCompile Include="..\hardware\hw_clip.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\apng.c" />
|
||||
<ClCompile Include="..\r_portal.c">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Srb2SDL.ico">
|
||||
|
|
|
@ -196,7 +196,7 @@ consvar_t cv_miditimiditypath = {"midisoundbank", "./timidity", CV_SAVE, NULL, N
|
|||
|
||||
static void var_cleanup(void)
|
||||
{
|
||||
loop_point = song_length = 0.0f;
|
||||
song_length = loop_point = 0.0f;
|
||||
music_bytes = fading_source = fading_target =\
|
||||
fading_timer = fading_duration = 0;
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ static patch_t *orngstat;
|
|||
static patch_t *redstat;
|
||||
static patch_t *yelstat;
|
||||
static patch_t *nbracket;
|
||||
static patch_t *nring;
|
||||
static patch_t *nhud[12];
|
||||
static patch_t *nsshud;
|
||||
static patch_t *nbon[12];
|
||||
|
@ -226,7 +227,7 @@ void ST_doPaletteStuff(void)
|
|||
|
||||
void ST_UnloadGraphics(void)
|
||||
{
|
||||
Z_FreeTags(PU_HUDGFX, PU_HUDGFX);
|
||||
Z_FreeTag(PU_HUDGFX);
|
||||
}
|
||||
|
||||
void ST_LoadGraphics(void)
|
||||
|
@ -311,6 +312,7 @@ void ST_LoadGraphics(void)
|
|||
redstat = W_CachePatchName("REDSTAT", PU_HUDGFX);
|
||||
yelstat = W_CachePatchName("YELSTAT", PU_HUDGFX);
|
||||
nbracket = W_CachePatchName("NBRACKET", PU_HUDGFX);
|
||||
nring = W_CachePatchName("NRNG1", PU_HUDGFX);
|
||||
for (i = 0; i < 12; ++i)
|
||||
{
|
||||
nhud[i] = W_CachePatchName(va("NHUD%d", i+1), PU_HUDGFX);
|
||||
|
@ -341,10 +343,24 @@ void ST_LoadGraphics(void)
|
|||
}
|
||||
|
||||
// made separate so that skins code can reload custom face graphics
|
||||
void ST_LoadFaceGraphics(char *facestr, char *superstr, INT32 skinnum)
|
||||
void ST_LoadFaceGraphics(INT32 skinnum)
|
||||
{
|
||||
faceprefix[skinnum] = W_CachePatchName(facestr, PU_HUDGFX);
|
||||
superprefix[skinnum] = W_CachePatchName(superstr, PU_HUDGFX);
|
||||
if (skins[skinnum].sprites[SPR2_XTRA].numframes)
|
||||
{
|
||||
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||
spriteframe_t *sprframe = &sprdef->spriteframes[0];
|
||||
faceprefix[skinnum] = W_CachePatchNum(sprframe->lumppat[0], PU_HUDGFX);
|
||||
if (skins[skinnum].sprites[(SPR2_XTRA|FF_SPR2SUPER)].numframes)
|
||||
{
|
||||
sprdef = &skins[skinnum].sprites[SPR2_XTRA|FF_SPR2SUPER];
|
||||
sprframe = &sprdef->spriteframes[0];
|
||||
superprefix[skinnum] = W_CachePatchNum(sprframe->lumppat[0], PU_HUDGFX);
|
||||
}
|
||||
else
|
||||
superprefix[skinnum] = faceprefix[skinnum]; // not manually freed, okay to set to same pointer
|
||||
}
|
||||
else
|
||||
faceprefix[skinnum] = superprefix[skinnum] = W_CachePatchName("MISSING", PU_HUDGFX); // ditto
|
||||
facefreed[skinnum] = false;
|
||||
}
|
||||
|
||||
|
@ -353,7 +369,7 @@ void ST_ReloadSkinFaceGraphics(void)
|
|||
INT32 i;
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
ST_LoadFaceGraphics(skins[i].face, skins[i].superface, i);
|
||||
ST_LoadFaceGraphics(i);
|
||||
}
|
||||
|
||||
static inline void ST_InitData(void)
|
||||
|
@ -1545,7 +1561,7 @@ static void ST_drawNiGHTSLink(void)
|
|||
static void ST_drawNiGHTSHUD(void)
|
||||
{
|
||||
INT32 origamount;
|
||||
INT32 total_spherecount;
|
||||
INT32 total_spherecount, total_ringcount;
|
||||
const boolean oldspecialstage = (G_IsSpecialStage(gamemap) && !(maptol & TOL_NIGHTS));
|
||||
|
||||
// Drill meter
|
||||
|
@ -1617,33 +1633,28 @@ static void ST_drawNiGHTSHUD(void)
|
|||
#endif
|
||||
ST_DrawTopLeftOverlayPatch(16, 8, nbracket);
|
||||
if (G_IsSpecialStage(gamemap))
|
||||
#ifdef MANIASPHERES
|
||||
ST_DrawTopLeftOverlayPatch(24, 16, (
|
||||
(stplyr->bonustime && (leveltime & 4)) ? nssbon : nsshud));
|
||||
#else
|
||||
ST_DrawTopLeftOverlayPatch(24, 16, (nsshud));
|
||||
#endif
|
||||
(stplyr->bonustime && (leveltime & 4) && (states[S_BLUESPHEREBONUS].frame & FF_ANIMATE)) ? nssbon : nsshud));
|
||||
else
|
||||
ST_DrawTopLeftOverlayPatch(24, 16, *(((stplyr->bonustime) ? nbon : nhud)+((leveltime/2)%12)));
|
||||
|
||||
if (G_IsSpecialStage(gamemap))
|
||||
{
|
||||
INT32 i;
|
||||
total_spherecount = 0;
|
||||
total_spherecount = total_ringcount = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/ && players[i].spheres)
|
||||
total_spherecount += players[i].spheres;
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
total_spherecount += players[i].spheres;
|
||||
total_ringcount += players[i].rings;
|
||||
}
|
||||
}
|
||||
else
|
||||
total_spherecount = stplyr->spheres;
|
||||
|
||||
/*if (oldspecialstage)
|
||||
{
|
||||
if (total_spherecount < ssspheres)
|
||||
total_spherecount = ssspheres - total_spherecount;
|
||||
else
|
||||
total_spherecount = 0;
|
||||
}*/
|
||||
total_spherecount = stplyr->spheres;
|
||||
total_ringcount = stplyr->spheres;
|
||||
}
|
||||
|
||||
if (stplyr->capsule)
|
||||
{
|
||||
|
@ -1731,6 +1742,27 @@ static void ST_drawNiGHTSHUD(void)
|
|||
else
|
||||
ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[8]);
|
||||
|
||||
if (oldspecialstage)
|
||||
{
|
||||
// invert for s3k style junk
|
||||
total_spherecount = ssspheres - total_spherecount;
|
||||
if (total_spherecount < 0)
|
||||
total_spherecount = 0;
|
||||
|
||||
if (nummaprings > 0) // don't count down if there ISN'T a valid maximum number of rings, like sonic 3
|
||||
{
|
||||
total_ringcount = nummaprings - total_ringcount;
|
||||
if (total_ringcount < 0)
|
||||
total_ringcount = 0;
|
||||
}
|
||||
|
||||
// now rings! you know, for that perfect bonus.
|
||||
V_DrawScaledPatch(272, 8, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT|V_HUDTRANS, nbracket);
|
||||
V_DrawScaledPatch(280, 16+1, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT|V_HUDTRANS, nring);
|
||||
V_DrawScaledPatch(280, 8+5, V_FLIP|V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT|V_HUDTRANS, narrow[8]);
|
||||
V_DrawTallNum(272, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT|V_HUDTRANS, total_ringcount);
|
||||
}
|
||||
|
||||
if (total_spherecount >= 100)
|
||||
V_DrawTallNum((total_spherecount >= 1000) ? 76 : 72, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_spherecount);
|
||||
else
|
||||
|
|
|
@ -42,7 +42,7 @@ void ST_UnloadGraphics(void);
|
|||
void ST_LoadGraphics(void);
|
||||
|
||||
// face load graphics, called when skin changes
|
||||
void ST_LoadFaceGraphics(char *facestr, char *superstr, INT32 playernum);
|
||||
void ST_LoadFaceGraphics(INT32 playernum);
|
||||
void ST_ReloadSkinFaceGraphics(void);
|
||||
|
||||
void ST_doPaletteStuff(void);
|
||||
|
|
341
src/v_video.c
341
src/v_video.c
|
@ -309,12 +309,14 @@ static boolean InitCube(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef BACKWARDSCOMPATCORRECTION
|
||||
/*
|
||||
So it turns out that the way gamma was implemented previously, the default
|
||||
colour profile of the game was messed up. Since this bad decision has been
|
||||
around for a long time, and the intent is to keep the base game looking the
|
||||
same, I'm not gonna be the one to remove this base modification.
|
||||
toast 20/04/17
|
||||
... welp yes i am (27/07/19, see the ifdef around it)
|
||||
*/
|
||||
const UINT8 correctiontable[256] =
|
||||
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
|
||||
|
@ -333,6 +335,7 @@ const UINT8 correctiontable[256] =
|
|||
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
|
||||
#endif
|
||||
|
||||
// keep a copy of the palette so that we can get the RGB value for a color index at any time.
|
||||
static void LoadPalette(const char *lumpname)
|
||||
|
@ -351,12 +354,18 @@ static void LoadPalette(const char *lumpname)
|
|||
pal = W_CacheLumpNum(lumpnum, PU_CACHE);
|
||||
for (i = 0; i < palsize; i++)
|
||||
{
|
||||
#ifdef BACKWARDSCOMPATCORRECTION
|
||||
pMasterPalette[i].s.red = pLocalPalette[i].s.red = correctiontable[*pal++];
|
||||
pMasterPalette[i].s.green = pLocalPalette[i].s.green = correctiontable[*pal++];
|
||||
pMasterPalette[i].s.blue = pLocalPalette[i].s.blue = correctiontable[*pal++];
|
||||
#else
|
||||
pMasterPalette[i].s.red = pLocalPalette[i].s.red = *pal++;
|
||||
pMasterPalette[i].s.green = pLocalPalette[i].s.green = *pal++;
|
||||
pMasterPalette[i].s.blue = pLocalPalette[i].s.blue = *pal++;
|
||||
#endif
|
||||
pMasterPalette[i].s.alpha = pLocalPalette[i].s.alpha = 0xFF;
|
||||
|
||||
// lerp of colour cubing!
|
||||
// lerp of colour cubing! if you want, make it smoother yourself
|
||||
if (cube)
|
||||
{
|
||||
float working[4][3];
|
||||
|
@ -732,12 +741,15 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
|
|||
// Center it if necessary
|
||||
if (!(scrn & V_SCALEPATCHMASK))
|
||||
{
|
||||
// if it's meant to cover the whole screen, black out the rest
|
||||
// if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT)
|
||||
if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT)
|
||||
{
|
||||
column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[0]));
|
||||
source = (const UINT8 *)(column) + 3;
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
||||
if (!column->topdelta)
|
||||
{
|
||||
source = (const UINT8 *)(column) + 3;
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, source[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (vid.width != BASEVIDWIDTH * dupx)
|
||||
|
@ -984,12 +996,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
|
|||
if (!(scrn & V_SCALEPATCHMASK))
|
||||
{
|
||||
// if it's meant to cover the whole screen, black out the rest
|
||||
if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT)
|
||||
{
|
||||
column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[0]));
|
||||
source = (const UINT8 *)(column) + 3;
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
||||
}
|
||||
// no the patch is cropped do not do this ever
|
||||
|
||||
if (vid.width != BASEVIDWIDTH * dupx)
|
||||
{
|
||||
|
@ -1349,13 +1356,16 @@ static UINT32 V_GetHWConsBackColor(void)
|
|||
|
||||
|
||||
// THANK YOU MPC!!!
|
||||
// and thanks toaster for cleaning it up.
|
||||
|
||||
void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
||||
{
|
||||
UINT8 *dest;
|
||||
INT32 u, v;
|
||||
const UINT8 *deststop;
|
||||
INT32 u;
|
||||
UINT8 *fadetable;
|
||||
UINT32 alphalevel = 0;
|
||||
UINT8 perplayershuffle = 0;
|
||||
|
||||
if (rendermode == render_none)
|
||||
return;
|
||||
|
@ -1369,16 +1379,91 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
|||
}
|
||||
#endif
|
||||
|
||||
if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT)))
|
||||
{
|
||||
if (alphalevel == 13)
|
||||
alphalevel = hudminusalpha[cv_translucenthud.value];
|
||||
else if (alphalevel == 14)
|
||||
alphalevel = 10 - cv_translucenthud.value;
|
||||
else if (alphalevel == 15)
|
||||
alphalevel = hudplusalpha[cv_translucenthud.value];
|
||||
|
||||
if (alphalevel >= 10)
|
||||
return; // invis
|
||||
}
|
||||
|
||||
if (splitscreen && (c & V_PERPLAYER))
|
||||
{
|
||||
fixed_t adjusty = ((c & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)>>1;
|
||||
h >>= 1;
|
||||
y >>= 1;
|
||||
#ifdef QUADS
|
||||
if (splitscreen > 1) // 3 or 4 players
|
||||
{
|
||||
fixed_t adjustx = ((c & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)>>1;
|
||||
w >>= 1;
|
||||
x >>= 1;
|
||||
if (stplyr == &players[displayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 4;
|
||||
c &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT;
|
||||
}
|
||||
else if (stplyr == &players[secondarydisplayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 8;
|
||||
x += adjustx;
|
||||
c &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT;
|
||||
}
|
||||
else if (stplyr == &players[thirddisplayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 4;
|
||||
y += adjusty;
|
||||
c &= ~V_SNAPTOTOP|V_SNAPTORIGHT;
|
||||
}
|
||||
else //if (stplyr == &players[fourthdisplayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 8;
|
||||
x += adjustx;
|
||||
y += adjusty;
|
||||
c &= ~V_SNAPTOTOP|V_SNAPTOLEFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// 2 players
|
||||
{
|
||||
if (stplyr == &players[displayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
c &= ~V_SNAPTOBOTTOM;
|
||||
}
|
||||
else //if (stplyr == &players[secondarydisplayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
y += adjusty;
|
||||
c &= ~V_SNAPTOTOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(c & V_NOSCALESTART))
|
||||
{
|
||||
INT32 dupx = vid.dupx, dupy = vid.dupy;
|
||||
|
||||
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
|
||||
{ // Clear the entire screen, from dest to deststop. Yes, this really works.
|
||||
memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp);
|
||||
return;
|
||||
}
|
||||
|
||||
x *= dupx;
|
||||
y *= dupy;
|
||||
w *= dupx;
|
||||
|
@ -1393,6 +1478,10 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
|||
x += (vid.width - (BASEVIDWIDTH * dupx));
|
||||
else if (!(c & V_SNAPTOLEFT))
|
||||
x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
|
||||
if (perplayershuffle & 4)
|
||||
x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4;
|
||||
else if (perplayershuffle & 8)
|
||||
x += (vid.width - (BASEVIDWIDTH * dupx)) / 4;
|
||||
}
|
||||
if (vid.height != BASEVIDHEIGHT * dupy)
|
||||
{
|
||||
|
@ -1401,6 +1490,10 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
|||
y += (vid.height - (BASEVIDHEIGHT * dupy));
|
||||
else if (!(c & V_SNAPTOTOP))
|
||||
y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
|
||||
if (perplayershuffle & 1)
|
||||
y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4;
|
||||
else if (perplayershuffle & 2)
|
||||
y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1423,34 +1516,206 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
|||
h = vid.height-y;
|
||||
|
||||
dest = screens[0] + y*vid.width + x;
|
||||
|
||||
if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT)))
|
||||
{
|
||||
if (alphalevel == 13)
|
||||
alphalevel = hudminusalpha[cv_translucenthud.value];
|
||||
else if (alphalevel == 14)
|
||||
alphalevel = 10 - cv_translucenthud.value;
|
||||
else if (alphalevel == 15)
|
||||
alphalevel = hudplusalpha[cv_translucenthud.value];
|
||||
|
||||
if (alphalevel >= 10)
|
||||
return; // invis
|
||||
}
|
||||
deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
|
||||
c &= 255;
|
||||
|
||||
// Jimita (12-04-2018)
|
||||
w = min(w, vid.width);
|
||||
h = min(h, vid.height);
|
||||
fadetable = ((UINT8 *)transtables + ((alphalevel-1)<<FF_TRANSSHIFT) + (c*256));
|
||||
for (v = 0; v < h; v++, dest += vid.width)
|
||||
for (u = 0; u < w; u++)
|
||||
if (alphalevel)
|
||||
{
|
||||
fadetable = ((UINT8 *)transtables + ((alphalevel-1)<<FF_TRANSSHIFT) + (c*256));
|
||||
for (;(--h >= 0) && dest < deststop; dest += vid.width)
|
||||
{
|
||||
if (!alphalevel)
|
||||
dest[u] = consolebgmap[dest[u]];
|
||||
else
|
||||
u = 0;
|
||||
while (u < w)
|
||||
{
|
||||
dest[u] = fadetable[consolebgmap[dest[u]]];
|
||||
u++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (;(--h >= 0) && dest < deststop; dest += vid.width)
|
||||
{
|
||||
u = 0;
|
||||
while (u < w)
|
||||
{
|
||||
dest[u] = consolebgmap[dest[u]];
|
||||
u++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If color is 0x00 to 0xFF, draw transtable (strength range 0-9).
|
||||
// Else, use COLORMAP lump (strength range 0-31).
|
||||
// c is not color, it is for flags only. transparency flags will be ignored.
|
||||
// IF YOU ARE NOT CAREFUL, THIS CAN AND WILL CRASH!
|
||||
// I have kept the safety checks for strength out of this function;
|
||||
// I don't trust Lua users with it, so it doesn't matter.
|
||||
//
|
||||
void V_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c, UINT16 color, UINT8 strength)
|
||||
{
|
||||
UINT8 *dest;
|
||||
const UINT8 *deststop;
|
||||
INT32 u;
|
||||
UINT8 *fadetable;
|
||||
UINT8 perplayershuffle = 0;
|
||||
|
||||
if (rendermode == render_none)
|
||||
return;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft && rendermode != render_none)
|
||||
{
|
||||
// ughhhhh please can someone else do this? thanks ~toast 25/7/19 in 38 degrees centigrade w/o AC
|
||||
HWR_DrawFadeFill(x, y, w, h, c, color, strength); // toast two days later - left above comment in 'cause it's funny
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (splitscreen && (c & V_PERPLAYER))
|
||||
{
|
||||
fixed_t adjusty = ((c & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)>>1;
|
||||
h >>= 1;
|
||||
y >>= 1;
|
||||
#ifdef QUADS
|
||||
if (splitscreen > 1) // 3 or 4 players
|
||||
{
|
||||
fixed_t adjustx = ((c & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)>>1;
|
||||
w >>= 1;
|
||||
x >>= 1;
|
||||
if (stplyr == &players[displayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 4;
|
||||
c &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT;
|
||||
}
|
||||
else if (stplyr == &players[secondarydisplayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 8;
|
||||
x += adjustx;
|
||||
c &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT;
|
||||
}
|
||||
else if (stplyr == &players[thirddisplayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 4;
|
||||
y += adjusty;
|
||||
c &= ~V_SNAPTOTOP|V_SNAPTORIGHT;
|
||||
}
|
||||
else //if (stplyr == &players[fourthdisplayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
||||
perplayershuffle |= 8;
|
||||
x += adjustx;
|
||||
y += adjusty;
|
||||
c &= ~V_SNAPTOTOP|V_SNAPTOLEFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// 2 players
|
||||
{
|
||||
if (stplyr == &players[displayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 1;
|
||||
c &= ~V_SNAPTOBOTTOM;
|
||||
}
|
||||
else //if (stplyr == &players[secondarydisplayplayer])
|
||||
{
|
||||
if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
||||
perplayershuffle |= 2;
|
||||
y += adjusty;
|
||||
c &= ~V_SNAPTOTOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(c & V_NOSCALESTART))
|
||||
{
|
||||
INT32 dupx = vid.dupx, dupy = vid.dupy;
|
||||
|
||||
x *= dupx;
|
||||
y *= dupy;
|
||||
w *= dupx;
|
||||
h *= dupy;
|
||||
|
||||
// Center it if necessary
|
||||
if (vid.width != BASEVIDWIDTH * dupx)
|
||||
{
|
||||
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
|
||||
// so center this imaginary screen
|
||||
if (c & V_SNAPTORIGHT)
|
||||
x += (vid.width - (BASEVIDWIDTH * dupx));
|
||||
else if (!(c & V_SNAPTOLEFT))
|
||||
x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
|
||||
if (perplayershuffle & 4)
|
||||
x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4;
|
||||
else if (perplayershuffle & 8)
|
||||
x += (vid.width - (BASEVIDWIDTH * dupx)) / 4;
|
||||
}
|
||||
if (vid.height != BASEVIDHEIGHT * dupy)
|
||||
{
|
||||
// same thing here
|
||||
if (c & V_SNAPTOBOTTOM)
|
||||
y += (vid.height - (BASEVIDHEIGHT * dupy));
|
||||
else if (!(c & V_SNAPTOTOP))
|
||||
y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
|
||||
if (perplayershuffle & 1)
|
||||
y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4;
|
||||
else if (perplayershuffle & 2)
|
||||
y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (x >= vid.width || y >= vid.height)
|
||||
return; // off the screen
|
||||
if (x < 0) {
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if (w <= 0 || h <= 0)
|
||||
return; // zero width/height wouldn't draw anything
|
||||
if (x + w > vid.width)
|
||||
w = vid.width-x;
|
||||
if (y + h > vid.height)
|
||||
h = vid.height-y;
|
||||
|
||||
dest = screens[0] + y*vid.width + x;
|
||||
deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
|
||||
c &= 255;
|
||||
|
||||
fadetable = ((color & 0xFF00) // Color is not palette index?
|
||||
? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade.
|
||||
: ((UINT8 *)transtables + ((9-strength)<<FF_TRANSSHIFT) + color*256)); // Else, do TRANSMAP** fade.
|
||||
for (;(--h >= 0) && dest < deststop; dest += vid.width)
|
||||
{
|
||||
u = 0;
|
||||
while (u < w)
|
||||
{
|
||||
dest[u] = fadetable[dest[u]];
|
||||
u++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -158,6 +158,8 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum);
|
|||
|
||||
// fade down the screen buffer before drawing the menu over
|
||||
void V_DrawFadeScreen(UINT16 color, UINT8 strength);
|
||||
// available to lua over my dead body, which will probably happen in this heat
|
||||
void V_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c, UINT16 color, UINT8 strength);
|
||||
|
||||
void V_DrawFadeConsBack(INT32 plines);
|
||||
void V_DrawPromptBack(INT32 boxheight, INT32 color);
|
||||
|
|
|
@ -293,6 +293,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\r_main.c" />
|
||||
<ClCompile Include="..\r_plane.c" />
|
||||
<ClCompile Include="..\r_portal.c" />
|
||||
<ClCompile Include="..\r_segs.c" />
|
||||
<ClCompile Include="..\r_sky.c" />
|
||||
<ClCompile Include="..\r_splats.c" />
|
||||
|
@ -443,6 +444,7 @@
|
|||
<ClInclude Include="..\r_local.h" />
|
||||
<ClInclude Include="..\r_main.h" />
|
||||
<ClInclude Include="..\r_plane.h" />
|
||||
<ClInclude Include="..\r_portal.h" />
|
||||
<ClInclude Include="..\r_segs.h" />
|
||||
<ClInclude Include="..\r_sky.h" />
|
||||
<ClInclude Include="..\r_splats.h" />
|
||||
|
|
|
@ -456,6 +456,10 @@
|
|||
<ClCompile Include="..\hardware\hw_clip.c">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\apng.c" />
|
||||
<ClCompile Include="..\r_portal.c">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="afxres.h">
|
||||
|
@ -857,6 +861,10 @@
|
|||
<ClInclude Include="..\hardware\hw_clip.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\apng.h" />
|
||||
<ClInclude Include="..\r_portal.h">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Srb2win.ico">
|
||||
|
|
151
src/y_inter.c
151
src/y_inter.c
|
@ -86,8 +86,8 @@ typedef union
|
|||
INT32 passedx3;
|
||||
INT32 passedx4;
|
||||
|
||||
y_bonus_t bonus;
|
||||
patch_t *bonuspatch;
|
||||
y_bonus_t bonuses[2];
|
||||
patch_t *bonuspatches[2];
|
||||
|
||||
patch_t *pscore; // SCORE
|
||||
UINT32 score; // fake score
|
||||
|
@ -326,34 +326,36 @@ void Y_IntermissionDrawer(void)
|
|||
// draw the header
|
||||
if (intertic <= 2*TICRATE)
|
||||
animatetic = 0;
|
||||
else if (!animatetic && data.spec.bonus.points == 0 && data.spec.passed3[0] != '\0')
|
||||
else if (!animatetic && data.spec.bonuses[0].points == 0 && data.spec.bonuses[1].points == 0 && data.spec.passed3[0] != '\0')
|
||||
animatetic = intertic + TICRATE;
|
||||
|
||||
if (animatetic && (tic_t)intertic >= animatetic)
|
||||
{
|
||||
const INT32 scradjust = (vid.width/vid.dupx)>>3; // 40 for BASEVIDWIDTH
|
||||
INT32 animatetimer = (intertic - animatetic);
|
||||
if (animatetimer <= 14)
|
||||
if (animatetimer <= 16)
|
||||
{
|
||||
xoffset1 = -(animatetimer * scradjust);
|
||||
xoffset2 = -((animatetimer-2) * scradjust);
|
||||
xoffset3 = -((animatetimer-4) * scradjust);
|
||||
xoffset4 = -((animatetimer-6) * scradjust);
|
||||
xoffset5 = -((animatetimer-8) * scradjust);
|
||||
xoffset1 = -(animatetimer * scradjust);
|
||||
xoffset2 = -((animatetimer- 2) * scradjust);
|
||||
xoffset3 = -((animatetimer- 4) * scradjust);
|
||||
xoffset4 = -((animatetimer- 6) * scradjust);
|
||||
xoffset5 = -((animatetimer- 8) * scradjust);
|
||||
xoffset6 = -((animatetimer-10) * scradjust);
|
||||
if (xoffset2 > 0) xoffset2 = 0;
|
||||
if (xoffset3 > 0) xoffset3 = 0;
|
||||
if (xoffset4 > 0) xoffset4 = 0;
|
||||
if (xoffset5 > 0) xoffset5 = 0;
|
||||
if (xoffset6 > 0) xoffset6 = 0;
|
||||
}
|
||||
else if (animatetimer < 32)
|
||||
else if (animatetimer < 34)
|
||||
{
|
||||
drawsection = 1;
|
||||
xoffset1 = (22-animatetimer) * scradjust;
|
||||
xoffset2 = (24-animatetimer) * scradjust;
|
||||
xoffset3 = (26-animatetimer) * scradjust;
|
||||
xoffset4 = (28-animatetimer) * scradjust;
|
||||
xoffset5 = (30-animatetimer) * scradjust;
|
||||
xoffset6 = (32-animatetimer) * scradjust;
|
||||
xoffset1 = (24-animatetimer) * scradjust;
|
||||
xoffset2 = (26-animatetimer) * scradjust;
|
||||
xoffset3 = (28-animatetimer) * scradjust;
|
||||
xoffset4 = (30-animatetimer) * scradjust;
|
||||
xoffset5 = (32-animatetimer) * scradjust;
|
||||
xoffset6 = (34-animatetimer) * scradjust;
|
||||
if (xoffset1 < 0) xoffset1 = 0;
|
||||
if (xoffset2 < 0) xoffset2 = 0;
|
||||
if (xoffset3 < 0) xoffset3 = 0;
|
||||
|
@ -370,9 +372,9 @@ void Y_IntermissionDrawer(void)
|
|||
|
||||
if (drawsection == 1)
|
||||
{
|
||||
const char *ringtext = "\x86" "50 RINGS, NO SHIELD";
|
||||
const char *tut1text = "\x86" "PRESS " "\x82" "SPIN";
|
||||
const char *tut2text = "\x86" "MID-" "\x82" "JUMP";
|
||||
const char *ringtext = "\x82" "50 RINGS, NO SHIELD";
|
||||
const char *tut1text = "\x82" "PRESS " "\x80" "SPIN";
|
||||
const char *tut2text = "\x82" "MID-" "\x80" "JUMP";
|
||||
ttheight = 16;
|
||||
V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
|
||||
ttheight += V_LevelNameHeight(data.spec.passed3) + 2;
|
||||
|
@ -389,6 +391,7 @@ void Y_IntermissionDrawer(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
INT32 yoffset = 0;
|
||||
if (data.spec.passed1[0] != '\0')
|
||||
{
|
||||
ttheight = 24;
|
||||
|
@ -402,22 +405,31 @@ void Y_IntermissionDrawer(void)
|
|||
V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2);
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(152 + xoffset3, 108, 0, data.spec.bonuspatch);
|
||||
V_DrawTallNum(BASEVIDWIDTH + xoffset3 - 68, 109, 0, data.spec.bonus.points);
|
||||
V_DrawScaledPatch(152 + xoffset4, 124, 0, data.spec.pscore);
|
||||
V_DrawTallNum(BASEVIDWIDTH + xoffset4 - 68, 125, 0, data.spec.score);
|
||||
V_DrawScaledPatch(152 + xoffset3, 108, 0, data.spec.bonuspatches[0]);
|
||||
V_DrawTallNum(BASEVIDWIDTH + xoffset3 - 68, 109, 0, data.spec.bonuses[0].points);
|
||||
if (data.spec.bonuses[1].display)
|
||||
{
|
||||
V_DrawScaledPatch(152 + xoffset4, 124, 0, data.spec.bonuspatches[1]);
|
||||
V_DrawTallNum(BASEVIDWIDTH + xoffset4 - 68, 125, 0, data.spec.bonuses[1].points);
|
||||
yoffset = 16;
|
||||
// hack; pass the buck along...
|
||||
xoffset4 = xoffset5;
|
||||
xoffset5 = xoffset6;
|
||||
}
|
||||
V_DrawScaledPatch(152 + xoffset4, 124+yoffset, 0, data.spec.pscore);
|
||||
V_DrawTallNum(BASEVIDWIDTH + xoffset4 - 68, 125+yoffset, 0, data.spec.score);
|
||||
|
||||
// Draw continues!
|
||||
if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay
|
||||
{
|
||||
UINT8 continues = data.spec.continues & 0x7F;
|
||||
|
||||
V_DrawScaledPatch(152 + xoffset5, 150, 0, data.spec.pcontinues);
|
||||
V_DrawScaledPatch(152 + xoffset5, 150+yoffset, 0, data.spec.pcontinues);
|
||||
for (i = 0; i < continues; ++i)
|
||||
{
|
||||
if ((data.spec.continues & 0x80) && i == continues-1 && (endtic < 0 || intertic%20 < 10))
|
||||
break;
|
||||
V_DrawContinueIcon(246 + xoffset5 - (i*12), 162, 0, *data.spec.playerchar, *data.spec.playercolor);
|
||||
V_DrawContinueIcon(246 + xoffset5 - (i*12), 162+yoffset, 0, *data.spec.playerchar, *data.spec.playercolor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -904,7 +916,7 @@ void Y_Ticker(void)
|
|||
{
|
||||
INT32 i;
|
||||
UINT32 oldscore = data.spec.score;
|
||||
boolean skip = false, super = false;
|
||||
boolean skip = false, super = false, anybonuses = false;
|
||||
|
||||
if (!intertic) // first time only
|
||||
{
|
||||
|
@ -946,16 +958,26 @@ void Y_Ticker(void)
|
|||
return;
|
||||
}
|
||||
|
||||
// ring bonus counts down by 222 each tic
|
||||
data.spec.bonus.points -= 222;
|
||||
data.spec.score += 222;
|
||||
if (data.spec.bonus.points < 0 || skip == true) // went too far
|
||||
// bonuses count down by 222 each tic
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
data.spec.score += data.spec.bonus.points;
|
||||
data.spec.bonus.points = 0;
|
||||
if (!data.spec.bonuses[i].points)
|
||||
continue;
|
||||
|
||||
data.spec.bonuses[i].points -= 222;
|
||||
data.spec.score += 222;
|
||||
if (data.spec.bonuses[i].points < 0 || skip == true) // too far?
|
||||
{
|
||||
data.spec.score += data.spec.bonuses[i].points;
|
||||
data.spec.bonuses[i].points = 0;
|
||||
}
|
||||
if (data.spec.score > MAXSCORE)
|
||||
data.spec.score = MAXSCORE;
|
||||
if (data.spec.bonuses[i].points > 0)
|
||||
anybonuses = true;
|
||||
}
|
||||
|
||||
if (!data.spec.bonus.points)
|
||||
if (!anybonuses)
|
||||
{
|
||||
tallydonetic = intertic;
|
||||
if (!((data.spec.continues & 0x80) || (super && ALL7EMERALDS(emeralds)))) // don't set endtic yet!
|
||||
|
@ -1301,7 +1323,9 @@ void Y_StartIntermission(void)
|
|||
// give out ring bonuses
|
||||
Y_AwardSpecialStageBonus();
|
||||
|
||||
data.spec.bonuspatch = W_CachePatchName(data.spec.bonus.patch, PU_STATIC);
|
||||
for (i = 0; i < 2; ++i)
|
||||
data.spec.bonuspatches[i] = W_CachePatchName(data.spec.bonuses[i].patch, PU_STATIC);
|
||||
|
||||
data.spec.pscore = W_CachePatchName("YB_SCORE", PU_STATIC);
|
||||
data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_STATIC);
|
||||
|
||||
|
@ -1831,7 +1855,7 @@ static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct)
|
|||
memset(bstruct, 0, sizeof(y_bonus_t));
|
||||
strncpy(bstruct->patch, "YB_PERFE", sizeof(bstruct->patch));
|
||||
|
||||
if (data.coop.gotperfbonus == -1)
|
||||
if (intertype != int_coop || data.coop.gotperfbonus == -1)
|
||||
{
|
||||
INT32 sharedringtotal = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -1840,15 +1864,33 @@ static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct)
|
|||
sharedringtotal += players[i].rings;
|
||||
}
|
||||
if (!sharedringtotal || nummaprings == -1 || sharedringtotal < nummaprings)
|
||||
data.coop.gotperfbonus = 0;
|
||||
bstruct->display = false;
|
||||
else
|
||||
data.coop.gotperfbonus = 1;
|
||||
{
|
||||
bstruct->display = true;
|
||||
bstruct->points = 50000;
|
||||
}
|
||||
}
|
||||
if (!data.coop.gotperfbonus)
|
||||
if (intertype != int_coop)
|
||||
return;
|
||||
|
||||
data.coop.gotperfbonus = (bstruct->display ? 1 : 0);
|
||||
}
|
||||
|
||||
static void Y_SetSpecialRingBonus(player_t *player, y_bonus_t *bstruct)
|
||||
{
|
||||
INT32 i, sharedringtotal = 0;
|
||||
|
||||
(void)player;
|
||||
strncpy(bstruct->patch, "YB_RING", sizeof(bstruct->patch));
|
||||
bstruct->display = true;
|
||||
bstruct->points = 50000;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i]) continue;
|
||||
sharedringtotal += players[i].rings;
|
||||
}
|
||||
bstruct->points = max(0, (sharedringtotal) * 100);
|
||||
}
|
||||
|
||||
// This list can be extended in the future with SOC/Lua, perhaps.
|
||||
|
@ -1953,23 +1995,33 @@ static void Y_AwardCoopBonuses(void)
|
|||
static void Y_AwardSpecialStageBonus(void)
|
||||
{
|
||||
INT32 i, oldscore, ptlives;
|
||||
y_bonus_t localbonus;
|
||||
y_bonus_t localbonuses[2];
|
||||
|
||||
data.spec.score = players[consoleplayer].score;
|
||||
memset(&data.spec.bonus, 0, sizeof(data.spec.bonus));
|
||||
data.spec.bonuspatch = NULL;
|
||||
memset(data.spec.bonuses, 0, sizeof(data.spec.bonuses));
|
||||
memset(data.spec.bonuspatches, 0, sizeof(data.coop.bonuspatches));
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
oldscore = players[i].score;
|
||||
|
||||
if (!playeringame[i] || players[i].lives < 1) // not active or game over
|
||||
Y_SetNullBonus(&players[i], &localbonus);
|
||||
else if (maptol & TOL_NIGHTS) // Mare score instead of Rings
|
||||
Y_SetNightsBonus(&players[i], &localbonus);
|
||||
{
|
||||
Y_SetNullBonus(&players[i], &localbonuses[0]);
|
||||
Y_SetNullBonus(&players[i], &localbonuses[1]);
|
||||
}
|
||||
else if (maptol & TOL_NIGHTS) // NiGHTS bonus score instead of Rings
|
||||
{
|
||||
Y_SetNightsBonus(&players[i], &localbonuses[0]);
|
||||
Y_SetNullBonus(&players[i], &localbonuses[1]);
|
||||
}
|
||||
else
|
||||
Y_SetRingBonus(&players[i], &localbonus);
|
||||
players[i].score += localbonus.points;
|
||||
{
|
||||
Y_SetSpecialRingBonus(&players[i], &localbonuses[0]);
|
||||
Y_SetPerfectBonus(&players[i], &localbonuses[1]);
|
||||
}
|
||||
players[i].score += localbonuses[0].points;
|
||||
players[i].score += localbonuses[1].points;
|
||||
if (players[i].score > MAXSCORE)
|
||||
players[i].score = MAXSCORE;
|
||||
|
||||
|
@ -1982,7 +2034,7 @@ static void Y_AwardSpecialStageBonus(void)
|
|||
if (i == consoleplayer)
|
||||
{
|
||||
data.spec.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives);
|
||||
M_Memcpy(&data.spec.bonus, &localbonus, sizeof(data.spec.bonus));
|
||||
M_Memcpy(&data.spec.bonuses, &localbonuses, sizeof(data.spec.bonuses));
|
||||
|
||||
// Continues related
|
||||
data.spec.continues = min(players[i].continues, 8);
|
||||
|
@ -2057,7 +2109,8 @@ static void Y_UnloadData(void)
|
|||
// unload the special stage patches
|
||||
//UNLOAD(data.spec.cemerald);
|
||||
//UNLOAD(data.spec.nowsuper);
|
||||
UNLOAD(data.spec.bonuspatch);
|
||||
UNLOAD(data.spec.bonuspatches[1]);
|
||||
UNLOAD(data.spec.bonuspatches[0]);
|
||||
UNLOAD(data.spec.pscore);
|
||||
UNLOAD(data.spec.pcontinues);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue