diff --git a/src/am_map.c b/src/am_map.c index 9c2aee2c..70714fac 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -25,36 +25,64 @@ #endif // For use if I do walls with outsides/insides -static const UINT8 GREENS = (10*16); -static const UINT8 GREENRANGE = 16; -static const UINT8 GRAYS = (0*16); -static const UINT8 GRAYSRANGE = 16; -static const UINT8 DBLACK = 31; -static const UINT8 DWHITE = 0; +static const UINT8 REDS = (8*16); +static const UINT8 REDRANGE = 16; +static const UINT8 GRAYS = (1*16); +static const UINT8 GRAYSRANGE = 16; +static const UINT8 BROWNS = (3*16); +static const UINT8 BROWNRANGE = 16; +static const UINT8 YELLOWS = (7*16); +static const UINT8 YELLOWRANGE = 8; +static const UINT8 GREENS = (10*16); +static const UINT8 GREENRANGE = 16; +static const UINT8 DBLACK = 31; +static const UINT8 DWHITE = 0; + +static const UINT8 NOCLIMBREDS = 248; +static const UINT8 NOCLIMBREDRANGE = 8; +static const UINT8 NOCLIMBGRAYS = 204; +static const UINT8 NOCLIMBGRAYSRANGE = 4; +static const UINT8 NOCLIMBBROWNS = (2*16); +static const UINT8 NOCLIMBBROWNRANGE = 16; +static const UINT8 NOCLIMBYELLOWS = (11*16); +static const UINT8 NOCLIMBYELLOWRANGE = 8; + #ifdef _NDS #undef BACKGROUND #endif // Automap colors -#define BACKGROUND DBLACK -#define YOURCOLORS DWHITE -#define YOURRANGE 0 -#define WALLCOLORS REDS -#define WALLRANGE REDRANGE -#define TSWALLCOLORS GRAYS -#define TSWALLRANGE GRAYSRANGE -#define FDWALLCOLORS BROWNS -#define FDWALLRANGE BROWNRANGE -#define CDWALLCOLORS YELLOWS -#define CDWALLRANGE YELLOWRANGE -#define THINGCOLORS GREENS -#define THINGRANGE GREENRANGE -#define SECRETWALLCOLORS WALLCOLORS -#define SECRETWALLRANGE WALLRANGE -#define GRIDCOLORS (GRAYS + GRAYSRANGE/2) -#define GRIDRANGE 0 -#define XHAIRCOLORS GRAYS +#define BACKGROUND DBLACK +#define YOURCOLORS DWHITE +#define YOURRANGE 0 +#define WALLCOLORS (REDS + REDRANGE/2) +#define WALLRANGE (REDRANGE/2) +#define NOCLIMBWALLCOLORS (NOCLIMBREDS + NOCLIMBREDRANGE/2) +#define NOCLIMBWALLRANGE (NOCLIMBREDRANGE/2) +#define THOKWALLCOLORS REDS +#define THOKWALLRANGE REDRANGE +#define NOCLIMBTHOKWALLCOLORS NOCLIMBREDS +#define NOCLIMBTHOKWALLRANGE NOCLIMBREDRANGE +#define TSWALLCOLORS GRAYS +#define TSWALLRANGE GRAYSRANGE +#define NOCLIMBTSWALLCOLORS NOCLIMBGRAYS +#define NOCLIMBTSWALLRANGE NOCLIMBGRAYSRANGE +#define FDWALLCOLORS BROWNS +#define FDWALLRANGE BROWNRANGE +#define NOCLIMBFDWALLCOLORS NOCLIMBBROWNS +#define NOCLIMBFDWALLRANGE NOCLIMBBROWNRANGE +#define CDWALLCOLORS YELLOWS +#define CDWALLRANGE YELLOWRANGE +#define NOCLIMBCDWALLCOLORS NOCLIMBYELLOWS +#define NOCLIMBCDWALLRANGE NOCLIMBYELLOWRANGE +#define THINGCOLORS GREENS +#define THINGRANGE GREENRANGE +#define SECRETWALLCOLORS WALLCOLORS +#define SECRETWALLRANGE WALLRANGE +#define GRIDCOLORS (GRAYS + GRAYSRANGE/2) +#define GRIDRANGE 0 +#define XHAIRCOLORS GRAYS // drawing stuff #define FB 0 @@ -1009,7 +1037,75 @@ static inline void AM_drawWalls(void) l.b.x = lines[i].v2->x; l.b.y = lines[i].v2->y; - AM_drawMline(&l, GRAYS + 3); +// AM_drawMline(&l, GRAYS + 3); // Old, everything-is-gray automap + if (!lines[i].backsector) // 1-sided + { + if (lines[i].flags & ML_NOCLIMB) + { + AM_drawMline(&l, NOCLIMBWALLCOLORS+lightlev); + } + else + { + AM_drawMline(&l, WALLCOLORS+lightlev); + } + } + else if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight // Back is thok barrier + || lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // Front is thok barrier + { + if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight + && lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // BOTH are thok barriers + { + if (lines[i].flags & ML_NOCLIMB) + { + AM_drawMline(&l, NOCLIMBTSWALLCOLORS+lightlev); + } + else + { + AM_drawMline(&l, TSWALLCOLORS+lightlev); + } + } + else + { + if (lines[i].flags & ML_NOCLIMB) + { + AM_drawMline(&l, NOCLIMBTHOKWALLCOLORS+lightlev); + } + else + { + AM_drawMline(&l, THOKWALLCOLORS+lightlev); + } + } + } + else + { + if (lines[i].flags & ML_NOCLIMB) { + if (lines[i].backsector->floorheight + != lines[i].frontsector->floorheight) { + AM_drawMline(&l, NOCLIMBFDWALLCOLORS + lightlev); // floor level change + } + else if (lines[i].backsector->ceilingheight + != lines[i].frontsector->ceilingheight) { + AM_drawMline(&l, NOCLIMBCDWALLCOLORS+lightlev); // ceiling level change + } + else { + AM_drawMline(&l, NOCLIMBTSWALLCOLORS+lightlev); + } + } + else + { + if (lines[i].backsector->floorheight + != lines[i].frontsector->floorheight) { + AM_drawMline(&l, FDWALLCOLORS + lightlev); // floor level change + } + else if (lines[i].backsector->ceilingheight + != lines[i].frontsector->ceilingheight) { + AM_drawMline(&l, CDWALLCOLORS+lightlev); // ceiling level change + } + else { + AM_drawMline(&l, TSWALLCOLORS+lightlev); + } + } + } } } diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 46a711aa..c6008e86 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -759,7 +759,10 @@ static inline void resynch_write_ctf(resynchend_pak *rst) // Should be held by a player for (j = 0; j < MAXPLAYERS; ++j) { - if (!playeringame[j] || players[j].gotflag != i) + // GF_REDFLAG is 1, GF_BLUEFLAG is 2 + // redflag handling is i=0, blueflag is i=1 + // so check for gotflag == (i+1) + if (!playeringame[j] || players[j].gotflag != (i+1)) continue; rst->flagplayer[i] = (SINT8)j; break; @@ -2229,7 +2232,11 @@ static void CL_RemovePlayer(INT32 playernum) void CL_Reset(void) { - if (demorecording || metalrecording) + if (metalrecording) + G_StopMetalRecording(); + if (metalplayback) + G_StopMetalDemo(); + if (demorecording) G_CheckDemoStatus(); // reset client/server code @@ -2954,8 +2961,10 @@ boolean Playing(void) boolean SV_SpawnServer(void) { - if (demoplayback || metalplayback) + if (demoplayback) G_StopDemo(); // reset engine parameter + if (metalplayback) + G_StopMetalDemo(); if (!serverrunning) { diff --git a/src/d_main.c b/src/d_main.c index 02590390..bd8e12f2 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1090,14 +1090,14 @@ void D_SRB2Main(void) #endif D_CleanFile(); -#if 1 // md5s last updated 3/18/14 +#if 1 // md5s last updated 3/22/14 // Check MD5s of autoloaded files W_VerifyFileMD5(0, "ac309fb3c7d4b5b685e2cd26beccf0e8"); // srb2.srb/srb2.wad W_VerifyFileMD5(1, "a894044b555dfcc71865cee16a996e88"); // zones.dta W_VerifyFileMD5(2, "4c410c1de6e0440cc5b2858dcca80c3e"); // player.dta W_VerifyFileMD5(3, "85901ad4bf94637e5753d2ac2c03ea26"); // rings.dta - W_VerifyFileMD5(4, "e868046d2d2da1d8c706c900edfb03f8"); // patch.dta + W_VerifyFileMD5(4, "4d56695e194a6fd3bc5c87610a215186"); // patch.dta // don't check music.dta because people like to modify it, and it doesn't matter if they do // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for. diff --git a/src/d_net.c b/src/d_net.c index d93b80c9..906c5389 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -129,10 +129,10 @@ boolean Net_GetNetStat(void) // ----------------------------------------------------------------- // Some structs and functions for acknowledgement of packets // ----------------------------------------------------------------- -#define MAXACKPACKETS 64 // minimum number of nodes -#define MAXACKTOSEND 64 -#define URGENTFREESLOTENUM 6 -#define ACKTOSENDTIMEOUT (TICRATE/17) +#define MAXACKPACKETS 96 // minimum number of nodes +#define MAXACKTOSEND 96 +#define URGENTFREESLOTENUM 10 +#define ACKTOSENDTIMEOUT (TICRATE/11) #ifndef NONET typedef struct diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 06c6fcb0..6b74e602 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1575,15 +1575,18 @@ static void Command_Playdemo_f(void) return; } - // disconnect from server here? - if (demoplayback || metalplayback) - G_StopDemo(); if (netgame) { CONS_Printf(M_GetText("You can't play a demo while in a netgame.\n")); return; } + // disconnect from server here? + if (demoplayback) + G_StopDemo(); + if (metalplayback) + G_StopMetalDemo(); + // open the demo file strcpy(name, COM_Argv(1)); // dont add .lmp so internal game demos can be played @@ -1603,15 +1606,18 @@ static void Command_Timedemo_f(void) return; } - // disconnect from server here? - if (demoplayback || metalplayback) - G_StopDemo(); if (netgame) { CONS_Printf(M_GetText("You can't play a demo while in a netgame.\n")); return; } + // disconnect from server here? + if (demoplayback) + G_StopDemo(); + if (metalplayback) + G_StopMetalDemo(); + // open the demo file strcpy (name, COM_Argv(1)); // dont add .lmp so internal game demos can be played @@ -1970,6 +1976,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) if (demorecording) // Okay, level loaded, character spawned and skinned, G_BeginRecording(); // I AM NOW READY TO RECORD. demo_start = true; + metal_start = true; } static void Command_Pause(void) diff --git a/src/d_ticcmd.h b/src/d_ticcmd.h index 41d25f2e..edbba552 100644 --- a/src/d_ticcmd.h +++ b/src/d_ticcmd.h @@ -36,8 +36,11 @@ typedef enum BT_CAMRIGHT = 1<<9, // turn camera right BT_TOSSFLAG = 1<<10, BT_JUMP = 1<<11, - BT_FIRENORMAL = 1<<12 // Fire a normal ring no matter what - // free: up to and including 1<<15 + BT_FIRENORMAL = 1<<12, // Fire a normal ring no matter what + + BT_CUSTOM1 = 1<<13, + BT_CUSTOM2 = 1<<14, + BT_CUSTOM3 = 1<<15, } buttoncode_t; // The data sampled per tick (single player) diff --git a/src/dehacked.c b/src/dehacked.c index 6eae1ce2..35e672eb 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7101,6 +7101,7 @@ static const char *const MOBJFLAG_LIST[] = { "STICKY", "NIGHTSITEM", "NOCLIPTHING", + "GRENADEBOUNCE", "RUNSPAWNFUNC", NULL }; @@ -7648,6 +7649,9 @@ struct { {"BT_TOSSFLAG",BT_TOSSFLAG}, {"BT_JUMP",BT_JUMP}, {"BT_FIRENORMAL",BT_FIRENORMAL}, // Fire a normal ring no matter what + {"BT_CUSTOM1",BT_CUSTOM1}, // Lua customizable + {"BT_CUSTOM2",BT_CUSTOM2}, // Lua customizable + {"BT_CUSTOM3",BT_CUSTOM3}, // Lua customizable // cvflags_t {"CV_SAVE",CV_SAVE}, diff --git a/src/doomdef.h b/src/doomdef.h index a5454851..6c9d7ebe 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -144,8 +144,8 @@ extern FILE *logstream; #define VERSIONSTRING "Trunk" #else #define VERSION 201 // Game version -#define SUBVERSION 4 // more precise version number -#define VERSIONSTRING "v2.1.4" +#define SUBVERSION 5 // more precise version number +#define VERSIONSTRING "v2.1.5" #endif // Modification options @@ -201,7 +201,7 @@ extern FILE *logstream; // it's only for detection of the version the player is using so the MS can alert them of an update. // Only set it higher, not lower, obviously. // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". -#define MODVERSION 9 +#define MODVERSION 10 diff --git a/src/g_game.c b/src/g_game.c index dfd9aacd..8f0d5b91 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -231,14 +231,17 @@ boolean demorecording; boolean demoplayback; boolean titledemo; // Title Screen demo can be cancelled by any key static UINT8 *demobuffer = NULL; -static UINT8 *metalbuffer = NULL; -static UINT8 *demo_p, *metal_p, *demotime_p; +static UINT8 *demo_p, *demotime_p; static UINT8 *demoend; static UINT8 demoflags; boolean singledemo; // quit after playing a demo from cmdline +boolean demo_start; // don't start playing demo right away + boolean metalrecording; // recording as metal sonic mobj_t *metalplayback; -boolean demo_start; // don't start playing demo right away +static UINT8 *metalbuffer = NULL; +static UINT8 *metal_p; +boolean metal_start; // extra data stuff (events registered this frame while recording) static struct { @@ -1046,8 +1049,16 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if (PLAYER1INPUTDOWN(gc_tossflag)) cmd->buttons |= BT_TOSSFLAG; + // Lua scriptable buttons + if (PLAYER1INPUTDOWN(gc_custom1)) + cmd->buttons |= BT_CUSTOM1; + if (PLAYER1INPUTDOWN(gc_custom2)) + cmd->buttons |= BT_CUSTOM2; + if (PLAYER1INPUTDOWN(gc_custom3)) + cmd->buttons |= BT_CUSTOM3; + // use with any button/key - if (PLAYER1INPUTDOWN(gc_use) && !(player->pflags & PF_MACESPIN)) + if (PLAYER1INPUTDOWN(gc_use)) cmd->buttons |= BT_USE; // Camera Controls @@ -1315,6 +1326,14 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) if (PLAYER2INPUTDOWN(gc_tossflag)) cmd->buttons |= BT_TOSSFLAG; + // Lua scriptable buttons + if (PLAYER2INPUTDOWN(gc_custom1)) + cmd->buttons |= BT_CUSTOM1; + if (PLAYER2INPUTDOWN(gc_custom2)) + cmd->buttons |= BT_CUSTOM2; + if (PLAYER2INPUTDOWN(gc_custom3)) + cmd->buttons |= BT_CUSTOM3; + // use with any button/key if (PLAYER2INPUTDOWN(gc_use)) cmd->buttons |= BT_USE; @@ -2645,8 +2664,10 @@ static void G_DoCompleted(void) gameaction = ga_nothing; - if (metalrecording || metalplayback) - G_CheckDemoStatus(); + if (metalplayback) + G_StopMetalDemo(); + if (metalrecording) + G_StopMetalRecording(); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) @@ -4200,7 +4221,7 @@ void G_ReadMetalTic(mobj_t *metal) UINT16 speed; UINT8 statetype; - if (!metal_p || !demo_start) + if (!metal_p || !metal_start) return; ziptic = READUINT8(metal_p); @@ -4289,7 +4310,7 @@ void G_ReadMetalTic(mobj_t *metal) if (*metal_p == DEMOMARKER) { // end of demo data stream - G_CheckDemoStatus(); + G_StopMetalDemo(); return; } } @@ -4396,7 +4417,7 @@ void G_WriteMetalTic(mobj_t *metal) // latest demos with mouse aiming byte in ticcmd if (demo_p >= demoend - 32) { - G_CheckDemoStatus(); // no more space + G_StopMetalRecording(); // no more space return; } } @@ -4871,6 +4892,7 @@ void G_DoPlayDemo(char *defdemoname) // didn't start recording right away. demo_start = false; + metal_start = false; #ifdef HAVE_BLUA LUAh_MapChange(); @@ -4916,6 +4938,7 @@ void G_DoPlayDemo(char *defdemoname) players[0].jumpfactor = jumpfactor; demo_start = true; + metal_start = true; } void G_AddGhost(char *defdemoname) @@ -5168,6 +5191,7 @@ void G_DoPlayMetal(void) if (!mo) { CONS_Alert(CONS_ERROR, M_GetText("Failed to find bot entity.\n")); + Z_Free(metalbuffer); return; } @@ -5215,18 +5239,46 @@ void G_DoneLevelLoad(void) =================== */ +// Stops metal sonic's demo. Separate from other functions because metal + replays can coexist +void G_StopMetalDemo(void) +{ + + // Metal Sonic finishing doesn't end the game, dammit. + Z_Free(metalbuffer); + metalbuffer = NULL; + metalplayback = NULL; + metal_p = NULL; +} + +// Stops metal sonic recording. +ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void) +{ + boolean saved = false; + if (demo_p) + { + UINT8 *p = demobuffer+16; // checksum position +#ifdef NOMD5 + UINT8 i; + WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker + for (i = 0; i < 16; i++, p++) + *p = P_Random(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. +#else + WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker + md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. +#endif + saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. + } + free(demobuffer); + metalrecording = false; + if (saved) + I_Error("Saved to %sMS.LMP", G_BuildMapName(gamemap)); + I_Error("Failed to save demo!"); +} + // reset engine variable set for the demos // called from stopdemo command, map command, and g_checkdemoStatus. void G_StopDemo(void) { - if (metalplayback) - { // Metal Sonic finishing doesn't end the game, dammit. - Z_Free(metalbuffer); - metalbuffer = NULL; - metalplayback = NULL; - if (!demoplayback) - return; - } Z_Free(demobuffer); demobuffer = NULL; demoplayback = false; @@ -5250,31 +5302,7 @@ boolean G_CheckDemoStatus(void) if(ghosts) // ... ... ... ghosts = NULL; // :) - if (metalrecording) - { - saved = false; - if (demo_p) - { - UINT8 *p = demobuffer+16; // checksum position -#ifdef NOMD5 - UINT8 i; - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - for (i = 0; i < 16; i++, p++) - *p = P_Random(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. -#else - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. -#endif - saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. - } - free(demobuffer); - metalrecording = false; - if (saved) - I_Error("Saved to %sMS.LMP", G_BuildMapName(gamemap)); - else - I_Error("Failed to save demo!"); - return true; - } + // DO NOT end metal sonic demos here if (timingdemo) { @@ -5334,12 +5362,6 @@ boolean G_CheckDemoStatus(void) return true; } - if (metalplayback) - { - G_StopDemo(); - return false; - } - return false; } diff --git a/src/g_game.h b/src/g_game.h index d57b6ebd..af37fc8a 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -37,12 +37,14 @@ extern boolean playeringame[MAXPLAYERS]; // demoplaying back and demo recording extern boolean demoplayback, titledemo, demorecording, timingdemo; -extern mobj_t *metalplayback; // Quit after playing a demo from cmdline. extern boolean singledemo; extern boolean demo_start; +extern mobj_t *metalplayback; +extern boolean metal_start; + // gametic at level start extern tic_t levelstarttic; @@ -150,6 +152,8 @@ void G_TimeDemo(const char *name); void G_AddGhost(char *defdemoname); void G_DoPlayMetal(void); void G_DoneLevelLoad(void); +void G_StopMetalDemo(void); +ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void); void G_StopDemo(void); boolean G_CheckDemoStatus(void); diff --git a/src/g_input.c b/src/g_input.c index 29d13dce..f8170dd3 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -989,6 +989,9 @@ static const char *gamecontrolname[num_gamecontrols] = "jump", "console", "pause", + "custom1", + "custom2", + "custom3", }; #define NUMKEYNAMES (sizeof (keynames)/sizeof (keyname_t)) diff --git a/src/g_input.h b/src/g_input.h index 334b7ad9..699542a8 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -118,6 +118,9 @@ typedef enum gc_jump, gc_console, gc_pause, + gc_custom1, // Lua scriptable + gc_custom2, // Lua scriptable + gc_custom3, // Lua scriptable num_gamecontrols } gamecontrols_e; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 14f6d54a..96902c73 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1714,19 +1714,19 @@ static void HU_DrawCoopOverlay(void) #endif if (emeralds & EMERALD1) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)-32, V_TRANSLUCENT, emeraldpics[0]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)-32, 0, emeraldpics[0]); if (emeralds & EMERALD2) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)-16, V_TRANSLUCENT, emeraldpics[1]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[1]); if (emeralds & EMERALD3) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)+16, V_TRANSLUCENT, emeraldpics[2]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[2]); if (emeralds & EMERALD4) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)+32, V_TRANSLUCENT, emeraldpics[3]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)+32, 0, emeraldpics[3]); if (emeralds & EMERALD5) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)+16, V_TRANSLUCENT, emeraldpics[4]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[4]); if (emeralds & EMERALD6) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)-16, V_TRANSLUCENT, emeraldpics[5]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[5]); if (emeralds & EMERALD7) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3) , V_TRANSLUCENT, emeraldpics[6]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3) , 0, emeraldpics[6]); } static void HU_DrawNetplayCoopOverlay(void) @@ -1741,7 +1741,7 @@ static void HU_DrawNetplayCoopOverlay(void) for (i = 0; i < 7; ++i) { if (emeralds & (1 << i)) - V_DrawScaledPatch(20 + (i * 20), 6, V_TRANSLUCENT, emeraldpics[i]); + V_DrawScaledPatch(20 + (i * 20), 6, 0, emeraldpics[i]); } } diff --git a/src/info.c b/src/info.c index e69d84f0..d0ba598b 100644 --- a/src/info.c +++ b/src/info.c @@ -4817,10 +4817,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - 100, // mass + 20*TICRATE, // mass 48*FRACUNIT, // damage sfx_s3k5d, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_BOUNCE, // flags + MF_NOBLOCKMAP|MF_MISSILE|MF_BOUNCE|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, @@ -11936,7 +11936,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 6*TICRATE, // mass (<-- Looking for the Grenade Ring's fuse? It's right here!) 1, // damage sfx_s3k5d, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_BOUNCE, // flags + MF_NOBLOCKMAP|MF_MISSILE|MF_BOUNCE|MF_GRENADEBOUNCE, // flags S_NULL // raisestate }, diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 47bd4370..38b06961 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -195,6 +195,15 @@ static int patch_set(lua_State *L) // lib_draw // +static int libd_patchExists(lua_State *L) +{ + if (!hud_running) + return luaL_error(L, "HUD rendering code should not be called outside of rendering hooks!"); + + lua_pushboolean(L, W_CheckNumForName(luaL_checkstring(L, 1)) != LUMPERROR); + return 1; +} + static int libd_cachePatch(lua_State *L) { if (!hud_running) @@ -342,6 +351,7 @@ static int libd_stringWidth(lua_State *L) } static luaL_Reg lib_draw[] = { + {"patchExists", libd_patchExists}, {"cachePatch", libd_cachePatch}, {"draw", libd_draw}, {"drawScaled", libd_drawScaled}, diff --git a/src/m_menu.c b/src/m_menu.c index 0676bb52..30876cbc 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1037,6 +1037,10 @@ static menuitem_t OP_CameraControlsMenu[] = static menuitem_t OP_MiscControlsMenu[] = { + {IT_CALL | IT_STRING2, NULL, "Custom Action 1", M_ChangeControl, gc_custom1 }, + {IT_CALL | IT_STRING2, NULL, "Custom Action 2", M_ChangeControl, gc_custom2 }, + {IT_CALL | IT_STRING2, NULL, "Custom Action 3", M_ChangeControl, gc_custom3 }, + {IT_CALL | IT_STRING2, NULL, "Pause", M_ChangeControl, gc_pause }, {IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console }, }; @@ -3764,8 +3768,8 @@ static void M_Options(INT32 choice) // if the player is not admin or server, disable server options OP_MainMenu[5].status = (Playing() && !(server || adminplayer == consoleplayer)) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); - // if the player is playing _at all_, disable data options - OP_MainMenu[3].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); + // if the player is playing _at all_, disable the erase data options + OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); OP_MainDef.prevMenu = currentMenu; M_SetupNextMenu(&OP_MainDef); @@ -5709,7 +5713,7 @@ static void M_DrawConnectMenu(void) // Room name if (ms_RoomId < 0) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_room].alphaKey, - V_YELLOWMAP, ""); + V_YELLOWMAP, (itemOn == mp_connect_room) ? "" : ""); else V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey, V_YELLOWMAP, room_list[menuRoomIndex].name); @@ -6560,8 +6566,9 @@ static void M_Setup1PControlsMenu(INT32 choice) OP_MPControlsMenu[0].status = IT_CALL|IT_STRING2; OP_MPControlsMenu[1].status = IT_CALL|IT_STRING2; OP_MPControlsMenu[2].status = IT_CALL|IT_STRING2; - // Unhide the entire misc menu - OP_ControlListMenu[3].status = IT_SUBMENU | IT_STRING; + // Unide the pause/console controls too + OP_MiscControlsMenu[3].status = IT_CALL|IT_STRING2; + OP_MiscControlsMenu[4].status = IT_CALL|IT_STRING2; OP_ControlListDef.prevMenu = &OP_P1ControlsDef; M_SetupNextMenu(&OP_ControlListDef); @@ -6578,8 +6585,9 @@ static void M_Setup2PControlsMenu(INT32 choice) OP_MPControlsMenu[0].status = IT_GRAYEDOUT2; OP_MPControlsMenu[1].status = IT_GRAYEDOUT2; OP_MPControlsMenu[2].status = IT_GRAYEDOUT2; - // Hide the entire misc menu - OP_ControlListMenu[3].status = IT_GRAYEDOUT; + // Hide the pause/console controls too + OP_MiscControlsMenu[3].status = IT_GRAYEDOUT2; + OP_MiscControlsMenu[4].status = IT_GRAYEDOUT2; OP_ControlListDef.prevMenu = &OP_P2ControlsDef; M_SetupNextMenu(&OP_ControlListDef); diff --git a/src/p_inter.c b/src/p_inter.c index 03ad7c46..398ad493 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1861,7 +1861,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) if (target->player && !target->player->spectator) { if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording! - G_CheckDemoStatus(); + G_StopMetalRecording(); #ifdef CHAOSISNOTDEADYET if (gametype == GT_CHAOS) target->player->score /= 2; // Halve the player's score in Chaos Mode diff --git a/src/p_mobj.c b/src/p_mobj.c index b973c6cc..a7dc363f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1669,16 +1669,21 @@ static boolean P_ZMovement(mobj_t *mo) // another to prevent them from turning into hockey pucks. // I'm sorry in advance. -SH // PS: Oh, and Brak's napalm bombs too, now. - if (mo->type == MT_THROWNGRENADE || mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE) + if (mo->flags & MF_GRENADEBOUNCE) { - if (mo->momz <= 0) + // Going down? (Or up in reverse gravity?) + if (mo->momz*P_MobjFlip(mo) < 0) { - if (mo->momz >= -FixedMul(FRACUNIT, mo->scale)) + // If going slower than a fracunit, just stop. + if (abs(mo->momz) < FixedMul(FRACUNIT, mo->scale)) { mo->momx = mo->momy = mo->momz = 0; - if (mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE) - P_SetMobjState(mo, mo->info->deathstate); + + // Napalm hack + if (mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE && mo->fuse) + mo->fuse = 1; } + // Otherwise bounce up at half speed. else mo->momz = -FixedMul(mo->momz, FRACUNIT/2); S_StartSound(mo, mo->info->activesound); @@ -4595,7 +4600,7 @@ static void P_Boss9Thinker(mobj_t *mobj) // This is below threshold because we don't want to bob while zipping around // Ohh you're in for it now.. - if (mobj->flags2 & MF2_FRET && mobj->health <= 3) + if (mobj->flags2 & MF2_FRET && mobj->health <= mobj->info->damage) mobj->fuse = 0; // reactiontime is used for delays. @@ -4657,11 +4662,13 @@ static void P_Boss9Thinker(mobj_t *mobj) case 1: { // Okay, we're up? Good, time to gather energy... - if (mobj->health > mobj->info->damage) { // No more bubble if we're broken (pinch phase) + if (mobj->health > mobj->info->damage) + { // No more bubble if we're broken (pinch phase) mobj_t *shield = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_MSSHIELD_FRONT); P_SetTarget(&mobj->tracer, shield); P_SetTarget(&shield->target, mobj); - } else + } + else P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); mobj->fuse = 4*TICRATE; mobj->flags |= MF_PAIN; @@ -4673,8 +4680,12 @@ static void P_Boss9Thinker(mobj_t *mobj) case 2: // We're all charged and ready now! Unleash the fury!! - P_RemoveMobj(mobj->tracer); - P_SetTarget(&mobj->tracer, mobj->hnext); + if (mobj->health > mobj->info->damage) + { + mobj_t *removemobj = mobj->tracer; + P_SetTarget(&mobj->tracer, mobj->hnext); + P_RemoveMobj(removemobj); + } if (mobj->health <= mobj->info->damage) { // Attack 1: Pinball dash! if (mobj->health == 1) @@ -6483,6 +6494,7 @@ void P_MobjThinker(mobj_t *mobj) { // gargoyle and snowman handled in P_PushableThinker, not here case MT_THROWNGRENADE: + case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: P_SetMobjState(mobj, mobj->info->deathstate); break; case MT_BLUEFLAG: @@ -7231,6 +7243,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) #endif switch (mobj->type) { + case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: + mobj->fuse = mobj->info->mass; case MT_BLACKEGGMAN: { mobj_t *spawn = P_SpawnMobj(mobj->x, mobj->z, mobj->z+mobj->height-16*FRACUNIT, MT_BLACKEGGMAN_HELPER); @@ -9445,7 +9459,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) boolean P_CheckMissileSpawn(mobj_t *th) { // move a little forward so an angle can be computed if it immediately explodes - if (th->type != MT_THROWNGRENADE) // hack: bad! should be a flag. + if (th->flags & MF_GRENADEBOUNCE) // hack: bad! should be a flag. { th->x += th->momx>>1; th->y += th->momy>>1; diff --git a/src/p_mobj.h b/src/p_mobj.h index 84d22301..6d120c47 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -156,9 +156,11 @@ typedef enum // for chase camera, don't be blocked by things (partial clipping) // (need comma at end of this for SOC editor) MF_NOCLIPTHING = 1<<27, + // Missile bounces like a grenade. + MF_GRENADEBOUNCE = 1<<28, // Run the action thinker on spawn. - MF_RUNSPAWNFUNC = 1<<28, - // free: to and including 1<<31 + MF_RUNSPAWNFUNC = 1<<29, + // free: 1<<30 and 1<<31 } mobjflag_t; typedef enum diff --git a/src/p_setup.c b/src/p_setup.c index 25bcd0d5..9b32d4a0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2315,7 +2315,7 @@ boolean P_SetupLevel(boolean skipprecip) cv_debug = botskin = 0; if (metalplayback) - G_StopDemo(); + G_StopMetalDemo(); // Clear CECHO messages HU_ClearCEcho(); diff --git a/src/p_user.c b/src/p_user.c index ac026a11..d5c17e00 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3178,12 +3178,26 @@ static void P_DoSuperStuff(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_STND); P_RestoreMusic(player); P_SpawnShieldOrb(player); + + // Restore color + if (player->powers[pw_shield] & SH_FIREFLOWER) + { + player->mo->color = SKINCOLOR_WHITE; + G_GhostAddColor(GHC_FIREFLOWER); + } + else + { + player->mo->color = player->skincolor; + G_GhostAddColor(GHC_NORMAL); + } + if (gametype != GT_COOP) { HU_SetCEchoFlags(0); HU_SetCEchoDuration(5); HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players])); } + return; } // Deplete one ring every second while super @@ -3200,7 +3214,7 @@ static void P_DoSuperStuff(player_t *player) G_GhostAddColor(GHC_SUPER); // Ran out of rings while super! - if ((player->powers[pw_super]) && (player->health <= 1 || player->exiting)) + if (player->powers[pw_super] && (player->health <= 1 || player->exiting)) { player->powers[pw_emeralds] = 0; // lost the power stones P_SpawnGhostMobj(player->mo); @@ -9194,7 +9208,7 @@ void P_PlayerAfterThink(player_t *player) } } } - else if ((player->pflags & PF_MACESPIN) && player->mo->tracer) + else if ((player->pflags & PF_MACESPIN) && player->mo->tracer && player->mo->tracer->target) { player->mo->height = P_GetPlayerSpinHeight(player); // tracer is what you're hanging onto.... @@ -9214,11 +9228,6 @@ void P_PlayerAfterThink(player_t *player) if (!(player->mo->tracer->target->flags & MF_SLIDEME) // Noclimb on chain parameters gives this && !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode? { - if (cmd->buttons & BT_USE) // do we actually still want this? - { - player->mo->tracer->target->health += 50; - player->mo->angle += 50< ANGLE_MAX - } player->mo->tracer->target->health += cmd->sidemove; player->mo->angle += cmd->sidemove< ANGLE_MAX diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 9c0f521f..1e03edd8 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2278,8 +2278,12 @@ void I_Quit(void) G_SaveGameData(); // Tails 12-08-2002 //added:16-02-98: when recording a demo, should exit using 'q' key, // but sometimes we forget and use 'F10'.. so save here too. - if (demorecording || metalrecording) + + if (demorecording) G_CheckDemoStatus(); + if (metalrecording) + G_StopMetalRecording(); + D_QuitNetGame(); I_ShutdownMusic(); I_ShutdownSound(); @@ -2431,8 +2435,10 @@ void I_Error(const char *error, ...) G_SaveGameData(); // Tails 12-08-2002 // Shutdown. Here might be other errors. - if (demorecording || metalrecording) + if (demorecording) G_CheckDemoStatus(); + if (metalrecording) + G_StopMetalRecording(); D_QuitNetGame(); I_ShutdownMusic(); diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index f31b8b1c..efb0be46 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -665,8 +665,10 @@ void I_Error(const char *error, ...) // save demo, could be useful for debug // NOTE: demos are normally not saved here. - if (demorecording || metalrecording) + if (demorecording) G_CheckDemoStatus(); + if (metalrecording) + G_StopMetalRecording(); D_QuitNetGame(); @@ -749,8 +751,10 @@ void I_Quit(void) DWORD mode; // when recording a demo, should exit using 'q', // but sometimes we forget and use Alt+F4, so save here too. - if (demorecording || metalrecording) + if (demorecording) G_CheckDemoStatus(); + if (metalrecording) + G_StopMetalRecording(); M_SaveConfig(NULL); // save game config, cvars.. #ifndef NONET