From 3723eff9f7c2a95a444e9472cf1d0d06cfdae17e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 May 2017 15:33:35 +0100 Subject: [PATCH 01/61] The start of the Co-Op revamp! Not tested over netplay yet, but uses TD's implementation of various Co-op friendly things as a reference (or in one place an outright code steal, thanks Sryder!) * cv_sharedstarposts - Makes everyone share starposts, defaults to "On" * cv_respawntype - Defaults to "Starpost". If set to that, people respawn at the starpost you just hit (assuming cv_sharedstarposts is on - may have to combine the two variables later, but seperate for testing for now). The other option is the old, unrestricted spawning. We COULD add TD bubble spawning at a later time using this variable, though. The level DOES reset if everyone dies, but not in a way which allows for Mystic Realm style non-resetting resets. I'll handle that later. --- src/d_netcmd.c | 9 +++++- src/d_netcmd.h | 2 +- src/g_game.c | 76 ++++++++++++++++++++++++++++++++++++++++++++------ src/p_enemy.c | 30 ++++++++++++++++---- src/p_inter.c | 41 ++++++++++++++++++++++----- src/p_user.c | 68 ++++++++++++++++++++++++++++++++++---------- 6 files changed, 188 insertions(+), 38 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 125e9d2c3..bb376132c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -347,7 +347,12 @@ consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NUL #endif // Intermission time Tails 04-19-2002 static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; -consvar_t cv_inttime = {"inttime", "20", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_sharedstarposts = {"sharedstarposts", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +static CV_PossibleValue_t respawntype_cons_t[] = {{0, "Request"}, {1, "Starpost"}, {0, NULL}}; +consvar_t cv_respawntype = {"respawntype", "Starpost", CV_NETVAR|CV_CHEAT, respawntype_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -500,6 +505,8 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_hidetime); CV_RegisterVar(&cv_inttime); + CV_RegisterVar(&cv_sharedstarposts); + CV_RegisterVar(&cv_respawntype); CV_RegisterVar(&cv_advancemap); CV_RegisterVar(&cv_playersforexit); CV_RegisterVar(&cv_timelimit); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 80481c6a5..8f9717840 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -89,7 +89,7 @@ extern consvar_t cv_recycler; extern consvar_t cv_itemfinder; -extern consvar_t cv_inttime, cv_advancemap, cv_playersforexit; +extern consvar_t cv_inttime, cv_sharedstarposts, cv_respawntype, cv_advancemap, cv_playersforexit; extern consvar_t cv_overtime; extern consvar_t cv_startinglives; diff --git a/src/g_game.c b/src/g_game.c index 40878a70f..0a571c7fe 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2486,6 +2486,19 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo) } } +#ifdef HAVE_BLUA +#define RESETMAP {\ + LUAh_MapChange();\ + G_DoLoadLevel(true);\ + return;\ + } +#else +#define RESETMAP {\ + G_DoLoadLevel(true);\ + return;\ + } +#endif + // // G_DoReborn // @@ -2575,20 +2588,33 @@ void G_DoReborn(INT32 playernum) } } else -#ifdef HAVE_BLUA - { - LUAh_MapChange(); -#endif - G_DoLoadLevel(true); -#ifdef HAVE_BLUA - } -#endif + RESETMAP; } else { // respawn at the start mobj_t *oldmo = NULL; + if (gametype == GT_COOP && (netgame || multiplayer) && cv_respawntype.value == 1) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!(playeringame[i] && players[i].mo && players[i].mo->health && players[i].playerstate == PST_LIVE)) + continue; + + if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators + continue; + + if (players[i].bot) // ignore dumb, stupid tails + continue; + + break; + } + if (i == MAXPLAYERS) + RESETMAP; + } + if (player->starposttime) starpost = true; @@ -2608,10 +2634,44 @@ void G_DoReborn(INT32 playernum) void G_AddPlayer(INT32 playernum) { + INT32 countplayers = 0, notexiting = 0; + player_t *p = &players[playernum]; + // Go through the current players and make sure you have the latest starpost set + if (G_PlatformGametype() && (netgame || multiplayer)) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].bot) // ignore dumb, stupid tails + continue; + + countplayers++; + + if (!players->exiting) + notexiting++; + + if (!(cv_sharedstarposts.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum))) + continue; + + p->starposttime = players[i].starposttime; + p->starpostx = players[i].starpostx; + p->starposty = players[i].starposty; + p->starpostz = players[i].starpostz; + p->starpostangle = players[i].starpostangle; + p->starpostnum = players[i].starpostnum; + } + } + p->jointime = 0; p->playerstate = PST_REBORN; + + if (countplayers && !notexiting) + P_DoPlayerExit(p); } void G_ExitLevel(void) diff --git a/src/p_enemy.c b/src/p_enemy.c index 4b8d14170..860feb916 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2835,8 +2835,8 @@ void A_BossDeath(mobj_t *mo) // make sure there is a player alive for victory for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && ((players[i].mo && players[i].mo->health > 0) - || ((netgame || multiplayer) && (players[i].lives > 0 || players[i].continues > 0)))) + if (playeringame[i] && ((players[i].mo && players[i].mo->health) + || ((netgame || multiplayer) && (players[i].lives || players[i].continues)))) break; if (i == MAXPLAYERS) @@ -3280,10 +3280,28 @@ void A_ExtraLife(mobj_t *actor) // In shooter gametypes, give the player 100 rings instead of an extra life. if (gametype != GT_COOP && gametype != GT_COMPETITION) + { P_GivePlayerRings(player, 100); + P_PlayLivesJingle(player); + } else - P_GivePlayerLives(player, 1); - P_PlayLivesJingle(player); + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators + continue; + + if (players[i].bot) + continue; + + P_GivePlayerLives(&players[i], 1); + P_PlayLivesJingle(&players[i]); + } + } } // Function: A_BombShield @@ -9389,8 +9407,8 @@ void A_ForceWin(mobj_t *actor) for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && ((players[i].mo && players[i].mo->health > 0) - || ((netgame || multiplayer) && (players[i].lives > 0 || players[i].continues > 0)))) + if (playeringame[i] && ((players[i].mo && players[i].mo->health) + || ((netgame || multiplayer) && (players[i].lives || players[i].continues)))) break; } diff --git a/src/p_inter.c b/src/p_inter.c index 2b8006534..02ed67a12 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1293,13 +1293,40 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->starpostnum >= special->health) return; // Already hit this post - // Save the player's time and position. - player->starposttime = leveltime; - player->starpostx = toucher->x>>FRACBITS; - player->starposty = toucher->y>>FRACBITS; - player->starpostz = special->z>>FRACBITS; - player->starpostangle = special->angle; - player->starpostnum = special->health; + if (cv_sharedstarposts.value && gametype == GT_COOP && (netgame || multiplayer)) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + { + if (players[i].bot) // ignore dumb, stupid tails + continue; + + players[i].starposttime = leveltime; + players[i].starpostx = player->mo->x>>FRACBITS; + players[i].starposty = player->mo->y>>FRACBITS; + players[i].starpostz = special->z>>FRACBITS; + players[i].starpostangle = special->angle; + players[i].starpostnum = special->health; + + if (cv_respawntype.value == 1 && players[i].playerstate == PST_DEAD) + players[i].playerstate = PST_REBORN; + } + } + S_StartSound(NULL, special->info->painsound); + } + else + { + // Save the player's time and position. + player->starposttime = leveltime; + player->starpostx = toucher->x>>FRACBITS; + player->starposty = toucher->y>>FRACBITS; + player->starpostz = special->z>>FRACBITS; + player->starpostangle = special->angle; + player->starpostnum = special->health; + S_StartSound(toucher, special->info->painsound); + } + P_ClearStarPost(special->health); // Find all starposts in the level with this value. diff --git a/src/p_user.c b/src/p_user.c index 8ce1d08d7..63e9feae7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8105,22 +8105,60 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; else if (player->lives > 0 && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! { - // Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes. - if ((cmd->buttons & BT_JUMP) && player->deadtimer > cv_respawntime.value*TICRATE - && gametype != GT_RACE && gametype != GT_COOP) - player->playerstate = PST_REBORN; + if (gametype == GT_COOP && (netgame || multiplayer) && cv_respawntype.value == 1) // Shamelessly lifted from TD. Thanks, Sryder! + { + INT32 i, lastdeadplayer = -1, deadtimercheck = INT32_MAX; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; - // Instant respawn in race or if you're spectating. - if ((cmd->buttons & BT_JUMP) && (gametype == GT_RACE || player->spectator)) - player->playerstate = PST_REBORN; + if (players[i].spectator) // Ignore spectators + continue; - // One second respawn in coop. - if ((cmd->buttons & BT_JUMP) && player->deadtimer > TICRATE && (gametype == GT_COOP || gametype == GT_COMPETITION)) - player->playerstate = PST_REBORN; + if (players[i].bot) // ignore dumb, stupid tails + continue; - // Single player auto respawn - if (!(netgame || multiplayer) && player->deadtimer > 5*TICRATE) - player->playerstate = PST_REBORN; + if (players[i].playerstate != PST_DEAD) + break; + + if (players[i].lives && players[i].deadtimer < deadtimercheck) + { + lastdeadplayer = i; + deadtimercheck = players[i].deadtimer; + } + } + + if (i == MAXPLAYERS && lastdeadplayer != -1 && deadtimercheck > 2*TICRATE) // the last killed player will reset the level in G_DoReborn + players[lastdeadplayer].playerstate = PST_REBORN; + } + else + { + // Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes. + if (cmd->buttons & BT_JUMP) + { + if (player->spectator) + player->playerstate = PST_REBORN; + else switch(gametype) { + case GT_COOP: + case GT_COMPETITION: + if (player->deadtimer > TICRATE) + player->playerstate = PST_REBORN; + break; + case GT_RACE: + player->playerstate = PST_REBORN; + break; + default: + if (player->deadtimer > cv_respawntime.value*TICRATE) + player->playerstate = PST_REBORN; + break; + } + } + + // Single player auto respawn + if (!(netgame || multiplayer) && player->deadtimer > 5*TICRATE) + player->playerstate = PST_REBORN; + } } else if ((netgame || multiplayer) && player->deadtimer == 8*TICRATE) { @@ -8130,7 +8168,7 @@ static void P_DeathThink(player_t *player) INT32 i; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && !players[i].exiting && players[i].lives > 0) + if (playeringame[i] && !players[i].exiting && players[i].lives) break; if (i == MAXPLAYERS) @@ -8147,7 +8185,7 @@ static void P_DeathThink(player_t *player) INT32 i; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && (players[i].exiting || players[i].lives > 0)) + if (playeringame[i] && (players[i].exiting || players[i].lives)) break; if (i == MAXPLAYERS) From c508695c5aa79240b7e5ea2ad64d2719d41392a6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 May 2017 16:05:55 +0100 Subject: [PATCH 02/61] LF2_NORELOAD support --- src/g_game.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 0a571c7fe..b52a24cf7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2547,11 +2547,8 @@ void G_DoReborn(INT32 playernum) if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD)) { INT32 i; - player->playerstate = PST_REBORN; - P_LoadThingsOnly(); - P_ClearStarPost(player->starpostnum); // Do a wipe @@ -2567,7 +2564,7 @@ void G_DoReborn(INT32 playernum) // clear cmd building stuff memset(gamekeydown, 0, sizeof (gamekeydown)); - for (i = 0;i < JOYAXISSET; i++) + for (i = 0; i < JOYAXISSET; i++) { joyxmove[i] = joyymove[i] = 0; joy2xmove[i] = joy2ymove[i] = 0; @@ -2600,10 +2597,10 @@ void G_DoReborn(INT32 playernum) INT32 i; for (i = 0; i < MAXPLAYERS; i++) { - if (!(playeringame[i] && players[i].mo && players[i].mo->health && players[i].playerstate == PST_LIVE)) + if (!(playeringame[i] && players[i].playerstate == PST_LIVE)) continue; - if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators + if (players[i].spectator) // Ignore spectators continue; if (players[i].bot) // ignore dumb, stupid tails @@ -2612,7 +2609,57 @@ void G_DoReborn(INT32 playernum) break; } if (i == MAXPLAYERS) - RESETMAP; + { + if (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD) + { + INT32 j; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + players[i].playerstate = PST_REBORN; + } + + P_LoadThingsOnly(); + P_ClearStarPost(player->starpostnum); + + // Do a wipe + wipegamestate = -1; + + if (camera.chase) + P_ResetCamera(&players[displayplayer], &camera); + if (camera2.chase && splitscreen) + P_ResetCamera(&players[secondarydisplayplayer], &camera2); + + // clear cmd building stuff + memset(gamekeydown, 0, sizeof (gamekeydown)); + for (j = 0; j < JOYAXISSET; j++) + { + joyxmove[j] = joyymove[j] = 0; + joy2xmove[j] = joy2ymove[j] = 0; + } + mousex = mousey = 0; + mouse2x = mouse2y = 0; + + // clear hud messages remains (usually from game startup) + CON_ClearHUD(); + + // Starpost support + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + G_SpawnPlayer(i, (players[i].starposttime != 0)); + } + + return; + } + else + RESETMAP; + } } if (player->starposttime) From 965e1f6b4507fe3f050a814bef734485cabaf65a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 May 2017 17:07:20 +0100 Subject: [PATCH 03/61] * Make 100 rings give everyone a oneup in New Coop. * Make oneup boxes only give everyone a oneup in New Coop. --- src/p_enemy.c | 26 ++++++++++++++++---------- src/p_user.c | 21 +++++++++++++++++++-- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 860feb916..7bc6090e4 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3286,20 +3286,26 @@ void A_ExtraLife(mobj_t *actor) } else { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) + if (!((netgame || multiplayer) && gametype == GT_COOP)) + P_GivePlayerLives(player, 1); + P_PlayLivesJingle(player); + else { - if (!playeringame[i]) - continue; + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; - if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators - continue; + if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators + continue; - if (players[i].bot) - continue; + if (players[i].bot) + continue; - P_GivePlayerLives(&players[i], 1); - P_PlayLivesJingle(&players[i]); + P_GivePlayerLives(&players[i], 1); + P_PlayLivesJingle(&players[i]); + } } } } diff --git a/src/p_user.c b/src/p_user.c index 63e9feae7..9a68efef3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -933,8 +933,25 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (gainlives) { - P_GivePlayerLives(player, gainlives); - P_PlayLivesJingle(player); + INT32 i; + if (!((netgame || multiplayer) && gametype == GT_COOP)) + P_GivePlayerLives(player, gainlives); + P_PlayLivesJingle(player); + else + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators + continue; + + if (players[i].bot) + continue; + + P_GivePlayerLives(&players[i], gainlives); + P_PlayLivesJingle(&players[i]); + } } } } From ce181da83c8cd0d736af3708bbe2ba69c4237735 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 May 2017 17:08:41 +0100 Subject: [PATCH 04/61] ...i am fool --- src/p_enemy.c | 2 ++ src/p_user.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 7bc6090e4..dca5024bc 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3287,8 +3287,10 @@ void A_ExtraLife(mobj_t *actor) else { if (!((netgame || multiplayer) && gametype == GT_COOP)) + { P_GivePlayerLives(player, 1); P_PlayLivesJingle(player); + } else { INT32 i; diff --git a/src/p_user.c b/src/p_user.c index 9a68efef3..bfad339c0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -933,11 +933,14 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (gainlives) { - INT32 i; if (!((netgame || multiplayer) && gametype == GT_COOP)) + { P_GivePlayerLives(player, gainlives); P_PlayLivesJingle(player); + } else + { + INT32 i; for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) @@ -952,6 +955,7 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) P_GivePlayerLives(&players[i], gainlives); P_PlayLivesJingle(&players[i]); } + } } } } From 27658689404de2d2a5b92c57bda4ee113e509cbc Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 May 2017 18:09:05 +0100 Subject: [PATCH 05/61] * Add new cvars to menu. * Don't try to respawn on a checkpoint if you don't have any lives. --- src/m_menu.c | 40 ++++++++++++++++++++++------------------ src/p_inter.c | 2 +- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index b7f9e8802..a2af1158e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1388,31 +1388,35 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Item respawn delay", &cv_itemrespawntime, 76}, {IT_STRING | IT_SUBMENU, NULL, "Random Item Box Toggles...", &OP_MonitorToggleDef, 81}, - {IT_HEADER, NULL, "Platform (Coop, Race, Competition)", NULL, 90}, + {IT_HEADER, NULL, "Cooperative", NULL, 90}, {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96}, - {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 101}, - {IT_STRING | IT_CVAR, NULL, "Item Boxes", &cv_competitionboxes, 106}, + {IT_STRING | IT_CVAR, NULL, "Respawn mechanic", &cv_respawntype, 101}, + {IT_STRING | IT_CVAR, NULL, "Shared starposts", &cv_sharedstarposts, 106}, - {IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 115}, - {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 121}, - {IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 126}, - {IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 131}, - {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 136}, + {IT_HEADER, NULL, "Race, Competition", NULL, 115}, + {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 121}, + {IT_STRING | IT_CVAR, NULL, "Item Boxes", &cv_competitionboxes, 126}, - {IT_STRING | IT_CVAR, NULL, "Item Boxes", &cv_matchboxes, 146}, - {IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 151}, - {IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 156}, + {IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 135}, + {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 141}, + {IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 146}, + {IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 151}, + {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 156}, - {IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 166}, - {IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 171}, + {IT_STRING | IT_CVAR, NULL, "Item Boxes", &cv_matchboxes, 166}, + {IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 171}, + {IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 176}, - {IT_STRING | IT_CVAR, NULL, "Autobalance Teams", &cv_autobalance, 181}, - {IT_STRING | IT_CVAR, NULL, "Scramble Teams on Map Change", &cv_scrambleonchange, 186}, + {IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 186}, + {IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 191}, + + {IT_STRING | IT_CVAR, NULL, "Autobalance Teams", &cv_autobalance, 201}, + {IT_STRING | IT_CVAR, NULL, "Scramble Teams on Map Change", &cv_scrambleonchange, 206}, #ifndef NONET - {IT_HEADER, NULL, "Advanced", NULL, 195}, - {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 201}, - {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 215}, + {IT_HEADER, NULL, "Advanced", NULL, 215}, + {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 221}, + {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 235}, #endif }; diff --git a/src/p_inter.c b/src/p_inter.c index 02ed67a12..73dd9906b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1309,7 +1309,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) players[i].starpostangle = special->angle; players[i].starpostnum = special->health; - if (cv_respawntype.value == 1 && players[i].playerstate == PST_DEAD) + if (cv_respawntype.value == 1 && && players[i].lives > 0 && players[i].playerstate == PST_DEAD) players[i].playerstate = PST_REBORN; } } From f9120e3a44792d8a70a79db27a6e1d4ec0938ffa Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 May 2017 21:43:53 +0100 Subject: [PATCH 06/61] Some corrections. --- src/m_menu.c | 10 +++++----- src/p_inter.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index a2af1158e..dc888cb2d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7473,8 +7473,8 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[ 2].status = IT_GRAYEDOUT; // Max players OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow WAD downloading OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join - OP_ServerOptionsMenu[30].status = IT_GRAYEDOUT; // Master server - OP_ServerOptionsMenu[31].status = IT_GRAYEDOUT; // Attempts to resynchronise + OP_ServerOptionsMenu[33].status = IT_GRAYEDOUT; // Master server + OP_ServerOptionsMenu[34].status = IT_GRAYEDOUT; // Attempts to resynchronise } else { @@ -7483,10 +7483,10 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[ 3].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[ 4].status = IT_STRING | IT_CVAR; if (netgame) - OP_ServerOptionsMenu[30].status = IT_GRAYEDOUT; + OP_ServerOptionsMenu[33].status = IT_GRAYEDOUT; else - OP_ServerOptionsMenu[30].status = IT_STRING | IT_CVAR | IT_CV_STRING; - OP_ServerOptionsMenu[31].status = IT_STRING | IT_CVAR; + OP_ServerOptionsMenu[33].status = IT_STRING | IT_CVAR | IT_CV_STRING; + OP_ServerOptionsMenu[34].status = IT_STRING | IT_CVAR; } #endif diff --git a/src/p_inter.c b/src/p_inter.c index 73dd9906b..93a33e984 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1309,7 +1309,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) players[i].starpostangle = special->angle; players[i].starpostnum = special->health; - if (cv_respawntype.value == 1 && && players[i].lives > 0 && players[i].playerstate == PST_DEAD) + if (cv_respawntype.value == 1 && players[i].lives > 0 && players[i].playerstate == PST_DEAD) players[i].playerstate = PST_REBORN; } } From 4239036cec07f371e06daba307f64325f48f62a1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 28 May 2017 21:55:41 +0100 Subject: [PATCH 07/61] Life theft! No menu item, but anything is possible with zombocom. cv_steallives, defaults to "On" --- src/d_netcmd.c | 8 ++++-- src/d_netcmd.h | 2 +- src/p_inter.c | 2 +- src/p_local.h | 1 + src/p_user.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++- src/st_stuff.c | 49 +++++++++++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 5 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index bb376132c..b4e256d4d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -354,6 +354,8 @@ consvar_t cv_sharedstarposts = {"sharedstarposts", "On", CV_NETVAR, CV_OnOff, NU static CV_PossibleValue_t respawntype_cons_t[] = {{0, "Request"}, {1, "Starpost"}, {0, NULL}}; consvar_t cv_respawntype = {"respawntype", "Starpost", CV_NETVAR|CV_CHEAT, respawntype_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_steallives = {"steallives", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "All"}, {0, NULL}}; @@ -505,8 +507,6 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_hidetime); CV_RegisterVar(&cv_inttime); - CV_RegisterVar(&cv_sharedstarposts); - CV_RegisterVar(&cv_respawntype); CV_RegisterVar(&cv_advancemap); CV_RegisterVar(&cv_playersforexit); CV_RegisterVar(&cv_timelimit); @@ -514,6 +514,10 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_forceskin); CV_RegisterVar(&cv_downloading); + CV_RegisterVar(&cv_sharedstarposts); + CV_RegisterVar(&cv_respawntype); + CV_RegisterVar(&cv_steallives); + CV_RegisterVar(&cv_specialrings); CV_RegisterVar(&cv_powerstones); CV_RegisterVar(&cv_competitionboxes); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 8f9717840..0695d503d 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -89,7 +89,7 @@ extern consvar_t cv_recycler; extern consvar_t cv_itemfinder; -extern consvar_t cv_inttime, cv_sharedstarposts, cv_respawntype, cv_advancemap, cv_playersforexit; +extern consvar_t cv_inttime, cv_sharedstarposts, cv_respawntype, cv_steallives, cv_advancemap, cv_playersforexit; extern consvar_t cv_overtime; extern consvar_t cv_startinglives; diff --git a/src/p_inter.c b/src/p_inter.c index 93a33e984..cf3f29993 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1309,7 +1309,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) players[i].starpostangle = special->angle; players[i].starpostnum = special->health; - if (cv_respawntype.value == 1 && players[i].lives > 0 && players[i].playerstate == PST_DEAD) + if (cv_respawntype.value == 1 && (P_GetLives(&players[i]) || players[i].lives > 0) && players[i].playerstate == PST_DEAD) players[i].playerstate = PST_REBORN; } } diff --git a/src/p_local.h b/src/p_local.h index a2831222a..117eaee1d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -198,6 +198,7 @@ void P_PlayLivesJingle(player_t *player); #define P_PlayDeathSound(s) S_StartSound(s, sfx_altdi1 + P_RandomKey(4)); #define P_PlayVictorySound(s) S_StartSound(s, sfx_victr1 + P_RandomKey(4)); +boolean P_GetLives(player_t *player); // // P_MOBJ diff --git a/src/p_user.c b/src/p_user.c index bfad339c0..66233568f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8098,6 +8098,51 @@ void P_FindEmerald(void) return; } +// +// P_GetLives +// Steal lives if you're allowed to. +// + +boolean P_GetLives(player_t *player) +{ + INT32 i, maxlivesplayer = -1, livescheck = 1; + if (!(cv_steallives.value + && (gametype == GT_COOP) + && (netgame || multiplayer))) + return true; + + if (player->lives > 0) + return true; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].spectator) // Ignore spectators + continue; + + if (players[i].lives > livescheck) + { + maxlivesplayer = i; + livescheck = players[i].lives; + } + } + if (maxlivesplayer != -1) + { + if (players[maxlivesplayer].mo) + S_StartSound(players[maxlivesplayer].mo, sfx_jshard); // placeholder + P_GivePlayerLives(&players[maxlivesplayer], -1); + P_GivePlayerLives(player, 1); + if (netgame && P_IsLocalPlayer(player)) + S_ChangeMusic(mapmusname, mapmusflags, true); + else if (player == &players[displayplayer] || player == &players[secondarydisplayplayer]) + P_RestoreMusic(player); + return true; + } + return false; +} + // // P_DeathThink // Fall on your face when dying. @@ -8106,6 +8151,8 @@ void P_FindEmerald(void) static void P_DeathThink(player_t *player) { + INT32 j = MAXPLAYERS; + ticcmd_t *cmd = &player->cmd; player->deltaviewheight = 0; @@ -8121,10 +8168,31 @@ static void P_DeathThink(player_t *player) G_UseContinue(); // Even if we don't have one this handles ending the game } + if (cv_steallives.value + && (gametype == GT_COOP) + && (netgame || multiplayer) + && (player->lives <= 0)) + { + for (j = 0; j < MAXPLAYERS; j++) + { + if (!playeringame[j]) + continue; + + if (players[j].spectator) // Ignore spectators + continue; + + if (players[j].bot) // ignore dumb, stupid tails + continue; + + if (players[j].lives > 1) + break; + } + } + // Force respawn if idle for more than 30 seconds in shooter modes. if (player->deadtimer > 30*TICRATE && !G_PlatformGametype()) player->playerstate = PST_REBORN; - else if (player->lives > 0 && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! + else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! { if (gametype == GT_COOP && (netgame || multiplayer) && cv_respawntype.value == 1) // Shamelessly lifted from TD. Thanks, Sryder! { @@ -8162,6 +8230,9 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; else switch(gametype) { case GT_COOP: + if (player->deadtimer > TICRATE && P_GetLives(player)) + player->playerstate = PST_REBORN; + break; case GT_COMPETITION: if (player->deadtimer > TICRATE) player->playerstate = PST_REBORN; diff --git a/src/st_stuff.c b/src/st_stuff.c index 8e40f138c..f6dedf449 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -731,6 +731,31 @@ static void ST_drawLives(void) // lives V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, va("%d",stplyr->lives)); + + if (cv_steallives.value + && (gametype == GT_COOP) + && (netgame || multiplayer)) + { + INT32 i, sum = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].spectator) // Ignore spectators + continue; + + if (&players[i] == stplyr) + continue; + + if (players[i].lives < 2) + continue; + + sum += (players[i].lives - 1); + } + V_DrawString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF|v_splitflag, va("/%d",sum)); + } } static void ST_drawLevelTitle(void) @@ -1826,6 +1851,30 @@ static void ST_overlayDrawer(void) p = sboover; V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, STRINGY(BASEVIDHEIGHT/2 - (SHORT(p->height)/2)), 0, p); + + if (cv_steallives.value + && (gametype == GT_COOP) + && (netgame || multiplayer)) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].spectator) // Ignore spectators + continue; + + if (&players[i] == stplyr) + continue; + + if (players[i].lives > 1) + break; + } + + if (i != MAXPLAYERS) + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(BASEVIDHEIGHT/2 + (SHORT(p->height)/2)) + 15, 0, M_GetText("You'll steal a life on respawn.")); + } } From 964df31ee59295fca82a59b96cb3ae309d0d8107 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 29 May 2017 00:03:46 +0100 Subject: [PATCH 08/61] * Combine cv_sharedstarposts and cv_respawntype into cv_playstyle (Individual, Sharing, Together). * Put steallives on menu. --- src/d_netcmd.c | 11 ++++------- src/d_netcmd.h | 2 +- src/g_game.c | 4 ++-- src/m_menu.c | 4 ++-- src/p_inter.c | 4 ++-- src/p_user.c | 2 +- src/st_stuff.c | 2 +- 7 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b4e256d4d..309bdc36e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -349,12 +349,10 @@ consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NUL static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_sharedstarposts = {"sharedstarposts", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t playstyle_cons_t[] = {{0, "Individual"}, {1, "Sharing"}, {2, "Together"}, {0, NULL}}; +consvar_t cv_playstyle = {"playstyle", "Together", CV_NETVAR|CV_CHEAT, playstyle_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t respawntype_cons_t[] = {{0, "Request"}, {1, "Starpost"}, {0, NULL}}; -consvar_t cv_respawntype = {"respawntype", "Starpost", CV_NETVAR|CV_CHEAT, respawntype_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_steallives = {"steallives", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_steallives = {"steallives", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -514,8 +512,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_forceskin); CV_RegisterVar(&cv_downloading); - CV_RegisterVar(&cv_sharedstarposts); - CV_RegisterVar(&cv_respawntype); + CV_RegisterVar(&cv_playstyle); CV_RegisterVar(&cv_steallives); CV_RegisterVar(&cv_specialrings); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 0695d503d..c25b29d04 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -89,7 +89,7 @@ extern consvar_t cv_recycler; extern consvar_t cv_itemfinder; -extern consvar_t cv_inttime, cv_sharedstarposts, cv_respawntype, cv_steallives, cv_advancemap, cv_playersforexit; +extern consvar_t cv_inttime, cv_playstyle, cv_steallives, cv_advancemap, cv_playersforexit; extern consvar_t cv_overtime; extern consvar_t cv_startinglives; diff --git a/src/g_game.c b/src/g_game.c index b52a24cf7..2ea0fe63f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2592,7 +2592,7 @@ void G_DoReborn(INT32 playernum) // respawn at the start mobj_t *oldmo = NULL; - if (gametype == GT_COOP && (netgame || multiplayer) && cv_respawntype.value == 1) + if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) @@ -2702,7 +2702,7 @@ void G_AddPlayer(INT32 playernum) if (!players->exiting) notexiting++; - if (!(cv_sharedstarposts.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum))) + if (!(cv_playstyle.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum))) continue; p->starposttime = players[i].starposttime; diff --git a/src/m_menu.c b/src/m_menu.c index dc888cb2d..796b17101 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1390,8 +1390,8 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_HEADER, NULL, "Cooperative", NULL, 90}, {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96}, - {IT_STRING | IT_CVAR, NULL, "Respawn mechanic", &cv_respawntype, 101}, - {IT_STRING | IT_CVAR, NULL, "Shared starposts", &cv_sharedstarposts, 106}, + {IT_STRING | IT_CVAR, NULL, "Play style", &cv_playstyle, 101}, + {IT_STRING | IT_CVAR, NULL, "Steal lives on game over", &cv_steallives, 106}, {IT_HEADER, NULL, "Race, Competition", NULL, 115}, {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 121}, diff --git a/src/p_inter.c b/src/p_inter.c index cf3f29993..0e3d3f3d8 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1293,7 +1293,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->starpostnum >= special->health) return; // Already hit this post - if (cv_sharedstarposts.value && gametype == GT_COOP && (netgame || multiplayer)) + if (cv_playstyle.value && gametype == GT_COOP && (netgame || multiplayer)) { for (i = 0; i < MAXPLAYERS; i++) { @@ -1309,7 +1309,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) players[i].starpostangle = special->angle; players[i].starpostnum = special->health; - if (cv_respawntype.value == 1 && (P_GetLives(&players[i]) || players[i].lives > 0) && players[i].playerstate == PST_DEAD) + if (cv_playstyle.value == 2 && (P_GetLives(&players[i]) || players[i].lives > 0) && players[i].playerstate == PST_DEAD) players[i].playerstate = PST_REBORN; } } diff --git a/src/p_user.c b/src/p_user.c index 66233568f..bd7b686dc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8194,7 +8194,7 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! { - if (gametype == GT_COOP && (netgame || multiplayer) && cv_respawntype.value == 1) // Shamelessly lifted from TD. Thanks, Sryder! + if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) // Shamelessly lifted from TD. Thanks, Sryder! { INT32 i, lastdeadplayer = -1, deadtimercheck = INT32_MAX; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/st_stuff.c b/src/st_stuff.c index f6dedf449..a9c563244 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1873,7 +1873,7 @@ static void ST_overlayDrawer(void) } if (i != MAXPLAYERS) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(BASEVIDHEIGHT/2 + (SHORT(p->height)/2)) + 15, 0, M_GetText("You'll steal a life on respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(BASEVIDHEIGHT/2 + (SHORT(p->height)/2)) + 14, 0, M_GetText("You'll steal a life on respawn.")); } } From 726cd9757ba2e3ae68ad56c4a0989735606284ea Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 29 May 2017 21:23:00 +0100 Subject: [PATCH 09/61] Spectators in new Coop instead of staring at a dead screen all the time! Needs a bunch of changes to HUD rendering, especially in splitscreen, which doesn't try to show spectator stuff whatsoever. Also, if you're the player whose respawn determines when the map reloads, you'll see the spectator text during the front half of the fade. Unless, of course, it's 2-player mode. --- src/g_game.c | 15 ++---- src/p_enemy.c | 6 --- src/p_inter.c | 4 +- src/p_local.h | 1 + src/p_mobj.c | 7 ++- src/p_user.c | 126 ++++++++++++++++++++++++++----------------------- src/st_stuff.c | 8 +--- 7 files changed, 81 insertions(+), 86 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 2ea0fe63f..273aa87c3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2205,8 +2205,8 @@ void G_PlayerReborn(INT32 player) p->rings = 0; // 0 rings p->panim = PA_IDLE; // standing animation - if ((netgame || multiplayer) && !p->spectator) - p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent + //if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there + //p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent if (p-players == consoleplayer) { @@ -2597,16 +2597,11 @@ void G_DoReborn(INT32 playernum) INT32 i; for (i = 0; i < MAXPLAYERS; i++) { - if (!(playeringame[i] && players[i].playerstate == PST_LIVE)) + if (!playeringame[i]) continue; - if (players[i].spectator) // Ignore spectators - continue; - - if (players[i].bot) // ignore dumb, stupid tails - continue; - - break; + if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) + break; } if (i == MAXPLAYERS) { diff --git a/src/p_enemy.c b/src/p_enemy.c index dca5024bc..b206a7c89 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3299,12 +3299,6 @@ void A_ExtraLife(mobj_t *actor) if (!playeringame[i]) continue; - if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators - continue; - - if (players[i].bot) - continue; - P_GivePlayerLives(&players[i], 1); P_PlayLivesJingle(&players[i]); } diff --git a/src/p_inter.c b/src/p_inter.c index 0e3d3f3d8..d0998eca2 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1309,8 +1309,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) players[i].starpostangle = special->angle; players[i].starpostnum = special->health; - if (cv_playstyle.value == 2 && (P_GetLives(&players[i]) || players[i].lives > 0) && players[i].playerstate == PST_DEAD) - players[i].playerstate = PST_REBORN; + if (cv_playstyle.value == 2 && (P_GetLives(&players[i]) || players[i].lives > 0) && (players[i].playerstate == PST_DEAD || players[i].spectator)) + P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN; } } S_StartSound(NULL, special->info->painsound); diff --git a/src/p_local.h b/src/p_local.h index 117eaee1d..2cf6dbb98 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -199,6 +199,7 @@ void P_PlayLivesJingle(player_t *player); #define P_PlayVictorySound(s) S_StartSound(s, sfx_victr1 + P_RandomKey(4)); boolean P_GetLives(player_t *player); +boolean P_SpectatorJoinGame(player_t *player); // // P_MOBJ diff --git a/src/p_mobj.c b/src/p_mobj.c index 8820eac76..b8d850857 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9086,7 +9086,9 @@ void P_SpawnPlayer(INT32 playernum) { // Special case for (NiGHTS) special stages! // if stage has already started, force players to become spectators until the next stage - if (multiplayer && netgame && G_IsSpecialStage(gamemap) && useNightsSS && leveltime > 0) + if (((multiplayer || netgame) && leveltime > 0) + && ((G_IsSpecialStage(gamemap) && useNightsSS) + || (gametype == GT_COOP && cv_playstyle.value == 2 && (p->jointime < 1 || p->spectator)))) p->spectator = true; else p->spectator = false; @@ -9134,6 +9136,9 @@ void P_SpawnPlayer(INT32 playernum) p->skincolor = skincolor_blueteam; } + if ((netgame || multiplayer) && !p->spectator) + p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent + mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); (mobj->player = p)->mo = mobj; diff --git a/src/p_user.c b/src/p_user.c index bd7b686dc..2045e8fea 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -946,12 +946,6 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (!playeringame[i]) continue; - if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators - continue; - - if (players[i].bot) - continue; - P_GivePlayerLives(&players[i], gainlives); P_PlayLivesJingle(&players[i]); } @@ -8119,9 +8113,6 @@ boolean P_GetLives(player_t *player) if (!playeringame[i]) continue; - if (players[i].spectator) // Ignore spectators - continue; - if (players[i].lives > livescheck) { maxlivesplayer = i; @@ -8143,6 +8134,41 @@ boolean P_GetLives(player_t *player) return false; } +// +// P_ConsiderAllGone +// Shamelessly lifted from TD. Thanks, Sryder! +// + +static void P_ConsiderAllGone(void) +{ + INT32 i, lastdeadplayer = -1, deadtimercheck = INT32_MAX; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) + break; + + if (players[i].lives > 0) + { + if (players[i].spectator && lastdeadplayer == -1) + ; + else if (players[i].deadtimer < deadtimercheck) + deadtimercheck = players[i].deadtimer; + else + continue; + lastdeadplayer = i; + } + } + + if (i == MAXPLAYERS && lastdeadplayer != -1 && deadtimercheck > 2*TICRATE) // the last killed player will reset the level in G_DoReborn + { + players[lastdeadplayer].spectator = true; + players[lastdeadplayer].playerstate = PST_REBORN; + } +} + // // P_DeathThink // Fall on your face when dying. @@ -8173,17 +8199,11 @@ static void P_DeathThink(player_t *player) && (netgame || multiplayer) && (player->lives <= 0)) { - for (j = 0; j < MAXPLAYERS; j++) + for (; j < MAXPLAYERS; j++) { if (!playeringame[j]) continue; - if (players[j].spectator) // Ignore spectators - continue; - - if (players[j].bot) // ignore dumb, stupid tails - continue; - if (players[j].lives > 1) break; } @@ -8195,38 +8215,18 @@ static void P_DeathThink(player_t *player) else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! { if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) // Shamelessly lifted from TD. Thanks, Sryder! - { - INT32 i, lastdeadplayer = -1, deadtimercheck = INT32_MAX; - for (i = 0; i < MAXPLAYERS; i++) + P_ConsiderAllGone(); + if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))) { - if (!playeringame[i]) - continue; - - if (players[i].spectator) // Ignore spectators - continue; - - if (players[i].bot) // ignore dumb, stupid tails - continue; - - if (players[i].playerstate != PST_DEAD) - break; - - if (players[i].lives && players[i].deadtimer < deadtimercheck) - { - lastdeadplayer = i; - deadtimercheck = players[i].deadtimer; - } + player->spectator = true; + player->playerstate = PST_REBORN; } - - if (i == MAXPLAYERS && lastdeadplayer != -1 && deadtimercheck > 2*TICRATE) // the last killed player will reset the level in G_DoReborn - players[lastdeadplayer].playerstate = PST_REBORN; - } else { // Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes. if (cmd->buttons & BT_JUMP) { - if (player->spectator) + if (gametype != GT_COOP && player->spectator) player->playerstate = PST_REBORN; else switch(gametype) { case GT_COOP: @@ -8254,33 +8254,39 @@ static void P_DeathThink(player_t *player) } else if ((netgame || multiplayer) && player->deadtimer == 8*TICRATE) { + + INT32 i, deadtimercheck = INT32_MAX; + // In a net/multiplayer game, and out of lives if (gametype == GT_COMPETITION) { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) + { if (playeringame[i] && !players[i].exiting && players[i].lives) break; + if (players[i].deadtimer < deadtimercheck) + deadtimercheck = players[i].deadtimer; + } - if (i == MAXPLAYERS) + if (i == MAXPLAYERS && deadtimercheck == 8*TICRATE) { // Everyone's either done with the race, or dead. if (!countdown2 || countdown2 > 1*TICRATE) countdown2 = 1*TICRATE; } } - // In a coop game, and out of lives - if (gametype == GT_COOP) + else if (gametype == GT_COOP) { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) + { if (playeringame[i] && (players[i].exiting || players[i].lives)) break; + if (players[i].deadtimer < deadtimercheck) + deadtimercheck = players[i].deadtimer; + } - if (i == MAXPLAYERS) + if (i == MAXPLAYERS && deadtimercheck == 8*TICRATE) { // They're dead, Jim. //nextmapoverride = spstage_start; @@ -8991,16 +8997,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall return (x == thiscam->x && y == thiscam->y && z == thiscam->z && angle == thiscam->aiming); } -static boolean P_SpectatorJoinGame(player_t *player) +boolean P_SpectatorJoinGame(player_t *player) { - if (!G_GametypeHasSpectators() && G_IsSpecialStage(gamemap) && useNightsSS) // Special Stage spectators should NEVER be allowed to rejoin the game - { - if (P_IsLocalPlayer(player)) - CONS_Printf(M_GetText("You cannot enter the game while a special stage is in progress.\n")); - player->powers[pw_flashing] += 2*TICRATE; //to prevent message spam. - } - - else if (!cv_allowteamchange.value) + if (gametype != GT_COOP && !cv_allowteamchange.value) { if (P_IsLocalPlayer(player)) CONS_Printf(M_GetText("Server does not allow team change.\n")); @@ -9088,7 +9087,8 @@ static boolean P_SpectatorJoinGame(player_t *player) if (P_IsLocalPlayer(player) && displayplayer != consoleplayer) displayplayer = consoleplayer; - CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); + if (gametype != GT_COOP) + CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); return true; // no more player->mo, cannot continue. } else @@ -9401,6 +9401,8 @@ void P_PlayerThink(player_t *player) if (!player->spectator) P_PlayerInSpecialSector(player); + else if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) + P_ConsiderAllGone(); if (player->playerstate == PST_DEAD) { @@ -9446,7 +9448,11 @@ void P_PlayerThink(player_t *player) player->realtime = leveltime; } - if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]) + if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing] + && (G_GametypeHasSpectators() + || !((G_IsSpecialStage(gamemap) && useNightsSS) + || (gametype == GT_COOP && cv_playstyle.value == 2) + ))) { if (P_SpectatorJoinGame(player)) return; // player->mo was removed. diff --git a/src/st_stuff.c b/src/st_stuff.c index a9c563244..30b9bdb04 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -742,9 +742,6 @@ static void ST_drawLives(void) if (!playeringame[i]) continue; - if (players[i].spectator) // Ignore spectators - continue; - if (&players[i] == stplyr) continue; @@ -1862,9 +1859,6 @@ static void ST_overlayDrawer(void) if (!playeringame[i]) continue; - if (players[i].spectator) // Ignore spectators - continue; - if (&players[i] == stplyr) continue; @@ -1988,7 +1982,7 @@ static void ST_overlayDrawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); else if (G_IsSpecialStage(gamemap) && useNightsSS) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot join the game until the stage has ended.")); - else + else if (!gametype == GT_COOP) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(148), V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(164), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); From da05371e69472d25ed268a9811c1ac8325ee92f7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 29 May 2017 21:24:09 +0100 Subject: [PATCH 10/61] woops --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 2045e8fea..53988e37b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8199,7 +8199,7 @@ static void P_DeathThink(player_t *player) && (netgame || multiplayer) && (player->lives <= 0)) { - for (; j < MAXPLAYERS; j++) + for (j = 0; j < MAXPLAYERS; j++) { if (!playeringame[j]) continue; From fd873185ae2aff471f89cce7793a291f60a0e8fe Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 29 May 2017 21:59:24 +0100 Subject: [PATCH 11/61] * Respawn players that are spectators if it's not a special stage. * No need to call a function for changing the number of lives when we're within bounds. --- src/d_netcmd.c | 27 ++++++++++++++++++++++++++- src/p_user.c | 4 ++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 309bdc36e..b76586249 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -84,6 +84,8 @@ static void TeamScramble_OnChange(void); static void NetTimeout_OnChange(void); static void JoinTimeout_OnChange(void); +static void PlayStyle_OnChange(void); + static void Ringslinger_OnChange(void); static void Gravity_OnChange(void); static void ForceSkin_OnChange(void); @@ -350,7 +352,7 @@ static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NUL consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t playstyle_cons_t[] = {{0, "Individual"}, {1, "Sharing"}, {2, "Together"}, {0, NULL}}; -consvar_t cv_playstyle = {"playstyle", "Together", CV_NETVAR|CV_CHEAT, playstyle_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playstyle = {"playstyle", "Together", CV_NETVAR|CV_CHEAT|CV_CALL, playstyle_cons_t, PlayStyle_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_steallives = {"steallives", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3402,6 +3404,29 @@ static void JoinTimeout_OnChange(void) jointimeout = (tic_t)cv_jointimeout.value; } +static void PlayStyle_OnChange(void) +{ + if (!(netgame || multiplayer) || gametype != GT_COOP || G_IsSpecialStage(gamemap)) + return; + if (cv_playstyle.value != 2) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (!players[i].spectator) + continue; + + if (players[i].lives <= 0) + continue; + + players[i].playerstate = PST_REBORN; + } + } +} + UINT32 timelimitintics = 0; /** Deals with a timelimit change by printing the change to the console. diff --git a/src/p_user.c b/src/p_user.c index 53988e37b..a3bb7e4b6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8123,8 +8123,8 @@ boolean P_GetLives(player_t *player) { if (players[maxlivesplayer].mo) S_StartSound(players[maxlivesplayer].mo, sfx_jshard); // placeholder - P_GivePlayerLives(&players[maxlivesplayer], -1); - P_GivePlayerLives(player, 1); + players[maxlivesplayer].lives--; + player->lives++; if (netgame && P_IsLocalPlayer(player)) S_ChangeMusic(mapmusname, mapmusflags, true); else if (player == &players[displayplayer] || player == &players[secondarydisplayplayer]) From 2f3e4c3c65c1287a6aab4a3c5587da58ca4323b6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 29 May 2017 22:18:02 +0100 Subject: [PATCH 12/61] * Per Mystic's request, made lives for 100 rings individual. * P_GiveCoopLives bundles the coop lives reward for everyone versus reward for one person in other gametypes thing into one function. Available in Lua. --- src/lua_baselib.c | 14 ++++++++++++++ src/p_enemy.c | 20 +------------------- src/p_local.h | 1 + src/p_user.c | 42 +++++++++++++++++++++++++----------------- 4 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 93f2979fa..025b7fe0d 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -978,6 +978,19 @@ static int lib_pGivePlayerLives(lua_State *L) return 0; } +static int lib_pGiveCoopLives(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + INT32 numlives = (INT32)luaL_checkinteger(L, 2); + boolean sound = (boolean)lua_opttrueboolean(L, 3); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_GiveCoopLives(player, numlives, sound); + return 0; +} + static int lib_pResetScore(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -2428,6 +2441,7 @@ static luaL_Reg lib[] = { {"P_SpawnGhostMobj",lib_pSpawnGhostMobj}, {"P_GivePlayerRings",lib_pGivePlayerRings}, {"P_GivePlayerLives",lib_pGivePlayerLives}, + {"P_GiveCoopLives",lib_pGiveCoopLives}, {"P_ResetScore",lib_pResetScore}, {"P_DoJumpShield",lib_pDoJumpShield}, {"P_DoBubbleBounce",lib_pDoBubbleBounce}, diff --git a/src/p_enemy.c b/src/p_enemy.c index b206a7c89..c0451adf3 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3285,25 +3285,7 @@ void A_ExtraLife(mobj_t *actor) P_PlayLivesJingle(player); } else - { - if (!((netgame || multiplayer) && gametype == GT_COOP)) - { - P_GivePlayerLives(player, 1); - P_PlayLivesJingle(player); - } - else - { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - P_GivePlayerLives(&players[i], 1); - P_PlayLivesJingle(&players[i]); - } - } - } + P_GiveCoopLives(player, 1, true); } // Function: A_BombShield diff --git a/src/p_local.h b/src/p_local.h index 2cf6dbb98..f34ed1307 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -148,6 +148,7 @@ void P_SwitchShield(player_t *player, UINT16 shieldtype); mobj_t *P_SpawnGhostMobj(mobj_t *mobj); void P_GivePlayerRings(player_t *player, INT32 num_rings); void P_GivePlayerLives(player_t *player, INT32 numlives); +void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound); UINT8 P_GetNextEmerald(void); void P_GiveEmerald(boolean spawnObj); #if 0 diff --git a/src/p_user.c b/src/p_user.c index a3bb7e4b6..0be95e761 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -933,23 +933,8 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (gainlives) { - if (!((netgame || multiplayer) && gametype == GT_COOP)) - { - P_GivePlayerLives(player, gainlives); - P_PlayLivesJingle(player); - } - else - { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - P_GivePlayerLives(&players[i], gainlives); - P_PlayLivesJingle(&players[i]); - } - } + P_GivePlayerLives(player, gainlives); + P_PlayLivesJingle(player); } } } @@ -970,6 +955,29 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) player->lives = 1; } +void P_GiveCoopLives(player_t player, INT32 numlives, boolean sound) +{ + if (!((netgame || multiplayer) && gametype == GT_COOP && cv_playstyle.value)) + { + P_GivePlayerLives(player, 1); + if (sound) + P_PlayLivesJingle(player); + } + else + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + P_GivePlayerLives(&players[i], 1); + if (sound) + P_PlayLivesJingle(&players[i]); + } + } +} + // // P_DoSuperTransformation // From ff7ee4aa12b259ca5ced8c74186e619bee81895b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 29 May 2017 22:19:31 +0100 Subject: [PATCH 13/61] ...forgot to check in these changes --- src/p_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 0be95e761..1158f7ea7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -955,11 +955,11 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) player->lives = 1; } -void P_GiveCoopLives(player_t player, INT32 numlives, boolean sound) +void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound) { if (!((netgame || multiplayer) && gametype == GT_COOP && cv_playstyle.value)) { - P_GivePlayerLives(player, 1); + P_GivePlayerLives(player, numlives); if (sound) P_PlayLivesJingle(player); } @@ -971,7 +971,7 @@ void P_GiveCoopLives(player_t player, INT32 numlives, boolean sound) if (!playeringame[i]) continue; - P_GivePlayerLives(&players[i], 1); + P_GivePlayerLives(&players[i], numlives); if (sound) P_PlayLivesJingle(&players[i]); } From 947e9ed34f1b4b36fc55df6c22fbfed0aa9729e1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 29 May 2017 22:43:22 +0100 Subject: [PATCH 14/61] Stop rolling sound spam by not doing some stuff that probably shouldn't be happening. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b8d850857..3186236b3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3216,7 +3216,7 @@ static void P_PlayerZMovement(mobj_t *mo) } } - if (mo->health && !P_CheckDeathPitCollide(mo)) + if (mo->health && !mo->player->spectator && !P_CheckDeathPitCollide(mo)) { if (mo->player->pflags & PF_GLIDING) // ground gliding { From 9fbcd6e8835897f5c0580bd65457c98f713a01bb Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 30 May 2017 17:07:37 +0100 Subject: [PATCH 15/61] Accidentially broke game overs. Fixed now. --- src/p_user.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 1158f7ea7..0f8fb29ae 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8260,7 +8260,7 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; } } - else if ((netgame || multiplayer) && player->deadtimer == 8*TICRATE) + else if ((netgame || multiplayer) && player->deadtimer >= 8*TICRATE) { INT32 i, deadtimercheck = INT32_MAX; @@ -8270,7 +8270,9 @@ static void P_DeathThink(player_t *player) { for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && !players[i].exiting && players[i].lives) + if (!playeringame[i]) + continue; + if (!players[i].exiting && players[i].lives) break; if (players[i].deadtimer < deadtimercheck) deadtimercheck = players[i].deadtimer; @@ -8288,7 +8290,9 @@ static void P_DeathThink(player_t *player) { for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && (players[i].exiting || players[i].lives)) + if (!playeringame[i]) + continue; + if (players[i].exiting || players[i].lives) break; if (players[i].deadtimer < deadtimercheck) deadtimercheck = players[i].deadtimer; From 4353fa65a252688da4d132263ba43a331c6feb7c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 30 May 2017 20:31:51 +0100 Subject: [PATCH 16/61] * Spectatoring for game over supported. * Don't lose lives when you die as a spectator. --- src/g_game.c | 150 +++++++++++++++++++++++++++++++------------------- src/p_inter.c | 2 +- src/p_mobj.c | 9 ++- src/p_setup.c | 15 ++++- src/p_user.c | 37 +++++++++---- 5 files changed, 139 insertions(+), 74 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 273aa87c3..a3eb8d6c1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2592,68 +2592,104 @@ void G_DoReborn(INT32 playernum) // respawn at the start mobj_t *oldmo = NULL; - if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) + if (gametype == GT_COOP && (netgame || multiplayer)) { INT32 i; - for (i = 0; i < MAXPLAYERS; i++) + if (player->lives <= 0) // consider game over first { - if (!playeringame[i]) - continue; - - if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) - break; - } - if (i == MAXPLAYERS) - { - if (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD) + INT32 deadtimercheck = INT32_MAX; + for (i = 0; i < MAXPLAYERS; i++) { - INT32 j; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - players[i].playerstate = PST_REBORN; - } - - P_LoadThingsOnly(); - P_ClearStarPost(player->starpostnum); - - // Do a wipe - wipegamestate = -1; - - if (camera.chase) - P_ResetCamera(&players[displayplayer], &camera); - if (camera2.chase && splitscreen) - P_ResetCamera(&players[secondarydisplayplayer], &camera2); - - // clear cmd building stuff - memset(gamekeydown, 0, sizeof (gamekeydown)); - for (j = 0; j < JOYAXISSET; j++) - { - joyxmove[j] = joyymove[j] = 0; - joy2xmove[j] = joy2ymove[j] = 0; - } - mousex = mousey = 0; - mouse2x = mouse2y = 0; - - // clear hud messages remains (usually from game startup) - CON_ClearHUD(); - - // Starpost support - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - G_SpawnPlayer(i, (players[i].starposttime != 0)); - } - - return; + if (!playeringame[i]) + continue; + if (players[i].exiting || players[i].lives) + break; + if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck) + deadtimercheck = players[i].deadtimer; + } + + if (i == MAXPLAYERS && deadtimercheck >= 8*TICRATE) + { + // They're dead, Jim. + //nextmapoverride = spstage_start; + nextmapoverride = gamemap; + countdown2 = 1*TICRATE; + skipstats = true; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + players[i].score = 0; + } + + //emeralds = 0; + tokenbits = 0; + tokenlist = 0; + token = 0; + } + } + if (cv_playstyle.value == 2) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) + break; + } + if (i == MAXPLAYERS) + { + if (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD) + { + INT32 j; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + players[i].playerstate = PST_REBORN; + } + + P_LoadThingsOnly(); + P_ClearStarPost(player->starpostnum); + + // Do a wipe + wipegamestate = -1; + + if (camera.chase) + P_ResetCamera(&players[displayplayer], &camera); + if (camera2.chase && splitscreen) + P_ResetCamera(&players[secondarydisplayplayer], &camera2); + + // clear cmd building stuff + memset(gamekeydown, 0, sizeof (gamekeydown)); + for (j = 0; j < JOYAXISSET; j++) + { + joyxmove[j] = joyymove[j] = 0; + joy2xmove[j] = joy2ymove[j] = 0; + } + mousex = mousey = 0; + mouse2x = mouse2y = 0; + + // clear hud messages remains (usually from game startup) + CON_ClearHUD(); + + // Starpost support + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + G_SpawnPlayer(i, (players[i].starposttime != 0)); + } + + return; + } + else + RESETMAP; } - else - RESETMAP; } } diff --git a/src/p_inter.c b/src/p_inter.c index d0998eca2..036063b89 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2246,7 +2246,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; P_SetThingPosition(target); - if (!target->player->bot && !G_IsSpecialStage(gamemap) + if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives()) { target->player->lives -= 1; // Lose a life Tails 03-11-2000 diff --git a/src/p_mobj.c b/src/p_mobj.c index 3186236b3..b291bb667 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9084,11 +9084,10 @@ void P_SpawnPlayer(INT32 playernum) // spawn as spectator determination if (!G_GametypeHasSpectators()) { - // Special case for (NiGHTS) special stages! - // if stage has already started, force players to become spectators until the next stage - if (((multiplayer || netgame) && leveltime > 0) - && ((G_IsSpecialStage(gamemap) && useNightsSS) - || (gametype == GT_COOP && cv_playstyle.value == 2 && (p->jointime < 1 || p->spectator)))) + if (((multiplayer || netgame) && gametype == GT_COOP && leveltime > 0) + && ((G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage + || (cv_playstyle.value == 2 && (p->jointime < 1 || p->spectator)) // late join or die in new coop + || (p->jointime > 0 && p->lives <= 0))) // game over p->spectator = true; else p->spectator = false; diff --git a/src/p_setup.c b/src/p_setup.c index 4f11c10d0..f7a202aea 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2181,6 +2181,7 @@ lumpnum_t lastloadedmaplumpnum; // for comparative savegame static void P_LevelInitStuff(void) { INT32 i; + boolean canresetlives = true; leveltime = 0; @@ -2220,9 +2221,21 @@ static void P_LevelInitStuff(void) // earthquake camera memset(&quake,0,sizeof(struct quake)); + if ((netgame || multiplayer) && gametype == GT_COOP && cv_playstyle.value == 2) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].lives > 0) + { + canresetlives = false; + break; + } + } + } + for (i = 0; i < MAXPLAYERS; i++) { - if ((netgame || multiplayer) && (gametype == GT_COMPETITION || players[i].lives <= 0)) + if (canresetlives && (netgame || multiplayer) && playeringame[i] && (gametype == GT_COMPETITION || players[i].lives <= 0)) { // In Co-Op, replenish a user's lives if they are depleted. players[i].lives = cv_startinglives.value; diff --git a/src/p_user.c b/src/p_user.c index 0f8fb29ae..e95d5f586 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8222,7 +8222,7 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! { - if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) // Shamelessly lifted from TD. Thanks, Sryder! + if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) P_ConsiderAllGone(); if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))) { @@ -8286,7 +8286,7 @@ static void P_DeathThink(player_t *player) } } // In a coop game, and out of lives - else if (gametype == GT_COOP) + /*else if (gametype == GT_COOP) { for (i = 0; i < MAXPLAYERS; i++) { @@ -8294,7 +8294,7 @@ static void P_DeathThink(player_t *player) continue; if (players[i].exiting || players[i].lives) break; - if (players[i].deadtimer < deadtimercheck) + if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck) deadtimercheck = players[i].deadtimer; } @@ -8317,7 +8317,13 @@ static void P_DeathThink(player_t *player) tokenlist = 0; token = 0; } - } + }*/ + } + + if (gametype == GT_COOP && (player->lives <= 0) && (player->deadtimer > gameovertics || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) + { + player->spectator = true; + player->playerstate = PST_REBORN; } if (gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame))) @@ -9427,16 +9433,27 @@ void P_PlayerThink(player_t *player) // Make sure spectators always have a score and ring count of 0. if (player->spectator) { - player->score = 0; + if (gametype != GT_COOP) + player->score = 0; player->mo->health = 1; player->rings = 0; } - - if ((netgame || multiplayer) && player->lives <= 0) + else if ((netgame || multiplayer) && player->lives <= 0) { - // In Co-Op, replenish a user's lives if they are depleted. - // of course, this is just a cheap hack, meh... - player->lives = cv_startinglives.value; + if (gametype == GT_COOP) + { + if (!cv_steallives.value || !P_GetLives(player)) + { + player->spectator = true; + player->playerstate = PST_REBORN; + } + } + else + { + // Outside of Co-Op, replenish a user's lives if they are depleted. + // of course, this is just a cheap hack, meh... + player->lives = cv_startinglives.value; + } } if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) From 464699fce2053cb2e62d5bb5608a16f2fd0c2e21 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 31 May 2017 17:07:24 +0100 Subject: [PATCH 17/61] * Make handling of life theft more consistent. * Make sure that a life theft always takes you from 0 (or less) lives to 1 life. * Fix a bracket level typo that meant new Co-op style respawning was being done for all gametypes. --- src/p_mobj.c | 4 ++-- src/p_user.c | 25 ++++++++----------------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b291bb667..70e94d234 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9084,10 +9084,10 @@ void P_SpawnPlayer(INT32 playernum) // spawn as spectator determination if (!G_GametypeHasSpectators()) { - if (((multiplayer || netgame) && gametype == GT_COOP && leveltime > 0) + if ( ((multiplayer || netgame) && gametype == GT_COOP && leveltime > 0) && ((G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage || (cv_playstyle.value == 2 && (p->jointime < 1 || p->spectator)) // late join or die in new coop - || (p->jointime > 0 && p->lives <= 0))) // game over + || (p->lives <= 0 && (!cv_steallives.value || !P_GetLives(p)))) ) // game over p->spectator = true; else p->spectator = false; diff --git a/src/p_user.c b/src/p_user.c index e95d5f586..964c4ba73 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8132,7 +8132,7 @@ boolean P_GetLives(player_t *player) if (players[maxlivesplayer].mo) S_StartSound(players[maxlivesplayer].mo, sfx_jshard); // placeholder players[maxlivesplayer].lives--; - player->lives++; + player->lives = 1; if (netgame && P_IsLocalPlayer(player)) S_ChangeMusic(mapmusname, mapmusflags, true); else if (player == &players[displayplayer] || player == &players[secondarydisplayplayer]) @@ -8223,12 +8223,14 @@ static void P_DeathThink(player_t *player) else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! { if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) + { P_ConsiderAllGone(); if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))) { player->spectator = true; player->playerstate = PST_REBORN; } + } else { // Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes. @@ -8238,7 +8240,7 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; else switch(gametype) { case GT_COOP: - if (player->deadtimer > TICRATE && P_GetLives(player)) + if (player->deadtimer > TICRATE) player->playerstate = PST_REBORN; break; case GT_COMPETITION: @@ -9438,22 +9440,11 @@ void P_PlayerThink(player_t *player) player->mo->health = 1; player->rings = 0; } - else if ((netgame || multiplayer) && player->lives <= 0) + else if ((netgame || multiplayer) && player->lives <= 0 && gametype != GT_COOP) { - if (gametype == GT_COOP) - { - if (!cv_steallives.value || !P_GetLives(player)) - { - player->spectator = true; - player->playerstate = PST_REBORN; - } - } - else - { - // Outside of Co-Op, replenish a user's lives if they are depleted. - // of course, this is just a cheap hack, meh... - player->lives = cv_startinglives.value; - } + // Outside of Co-Op, replenish a user's lives if they are depleted. + // of course, this is just a cheap hack, meh... + player->lives = cv_startinglives.value; } if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) From 3857b720cdf2e79cbb926a2c424213ef41d1ac1a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 1 Jun 2017 18:44:19 +0100 Subject: [PATCH 18/61] * Make music reset when game over is dealt with more consistent. * Make setting steallives to true respawn every game overed spectator. * Make a minimum on the number of lives GetLives can get you. * Add "You'll steal a life on respawn" to spectator screen. --- src/d_netcmd.c | 30 ++++++++++++++++-- src/g_game.c | 4 +++ src/p_local.h | 1 + src/p_user.c | 83 +++++++++++++++----------------------------------- src/st_stuff.c | 22 +++++++++++++ 5 files changed, 79 insertions(+), 61 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b76586249..ff78cfb49 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -85,6 +85,7 @@ static void NetTimeout_OnChange(void); static void JoinTimeout_OnChange(void); static void PlayStyle_OnChange(void); +static void StealLives_OnChange(void); static void Ringslinger_OnChange(void); static void Gravity_OnChange(void); @@ -352,9 +353,9 @@ static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NUL consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t playstyle_cons_t[] = {{0, "Individual"}, {1, "Sharing"}, {2, "Together"}, {0, NULL}}; -consvar_t cv_playstyle = {"playstyle", "Together", CV_NETVAR|CV_CHEAT|CV_CALL, playstyle_cons_t, PlayStyle_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playstyle = {"playstyle", "Together", CV_NETVAR|CV_CALL|CV_CHEAT, playstyle_cons_t, PlayStyle_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_steallives = {"steallives", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_steallives = {"steallives", "Yes", CV_NETVAR|CV_CALL, CV_YesNo, StealLives_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3419,7 +3420,30 @@ static void PlayStyle_OnChange(void) if (!players[i].spectator) continue; - if (players[i].lives <= 0) + if (players[i].lives <= 0 && !cv_steallives.value) + continue; + + players[i].playerstate = PST_REBORN; + } + } +} + +static void StealLives_OnChange(void) +{ + if (!(netgame || multiplayer) || gametype != GT_COOP) + return; + if (cv_playstyle.value != 2 && cv_steallives.value) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (!players[i].spectator) + continue; + + if (players[i].lives > 0) continue; players[i].playerstate = PST_REBORN; diff --git a/src/g_game.c b/src/g_game.c index a3eb8d6c1..2e4dc6dd6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2592,6 +2592,10 @@ void G_DoReborn(INT32 playernum) // respawn at the start mobj_t *oldmo = NULL; + // Return to level music + if (player->lives <= 0) + P_RestoreMultiMusic(player); + if (gametype == GT_COOP && (netgame || multiplayer)) { INT32 i; diff --git a/src/p_local.h b/src/p_local.h index f34ed1307..a579eaeff 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -201,6 +201,7 @@ void P_PlayLivesJingle(player_t *player); boolean P_GetLives(player_t *player); boolean P_SpectatorJoinGame(player_t *player); +void P_RestoreMultiMusic(player_t *player); // // P_MOBJ diff --git a/src/p_user.c b/src/p_user.c index 964c4ba73..9589bafbe 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8132,11 +8132,9 @@ boolean P_GetLives(player_t *player) if (players[maxlivesplayer].mo) S_StartSound(players[maxlivesplayer].mo, sfx_jshard); // placeholder players[maxlivesplayer].lives--; - player->lives = 1; - if (netgame && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusname, mapmusflags, true); - else if (player == &players[displayplayer] || player == &players[secondarydisplayplayer]) - P_RestoreMusic(player); + player->lives++; + if (player->lives < 1) + player->lives = 1; return true; } return false; @@ -8177,6 +8175,24 @@ static void P_ConsiderAllGone(void) } } +void P_RestoreMultiMusic(player_t *player) +{ + if (netgame) + { + if (P_IsLocalPlayer(player)) + S_ChangeMusic(mapmusname, mapmusflags, true); + } + else if (multiplayer) // local multiplayer only + { + // Restore the other player's music once we're dead for long enough + // -- that is, as long as they aren't dead too + if (player == &players[displayplayer] && players[secondarydisplayplayer].lives > 0) + P_RestoreMusic(&players[secondarydisplayplayer]); + else if (player == &players[secondarydisplayplayer] && players[displayplayer].lives > 0) + P_RestoreMusic(&players[displayplayer]); + } +} + // // P_DeathThink // Fall on your face when dying. @@ -8287,42 +8303,10 @@ static void P_DeathThink(player_t *player) countdown2 = 1*TICRATE; } } - // In a coop game, and out of lives - /*else if (gametype == GT_COOP) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - if (players[i].exiting || players[i].lives) - break; - if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck) - deadtimercheck = players[i].deadtimer; - } - - if (i == MAXPLAYERS && deadtimercheck == 8*TICRATE) - { - // They're dead, Jim. - //nextmapoverride = spstage_start; - nextmapoverride = gamemap; - countdown2 = 1*TICRATE; - skipstats = true; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - players[i].score = 0; - } - - //emeralds = 0; - tokenbits = 0; - tokenlist = 0; - token = 0; - } - }*/ + //else if (gametype == GT_COOP) -- moved to G_DoReborn } - if (gametype == GT_COOP && (player->lives <= 0) && (player->deadtimer > gameovertics || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) + if (gametype == GT_COOP && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) { player->spectator = true; player->playerstate = PST_REBORN; @@ -8345,25 +8329,8 @@ static void P_DeathThink(player_t *player) } // Return to level music - if (player->lives <= 0) - { - if (netgame) - { - if (player->deadtimer == gameovertics && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusname, mapmusflags, true); - } - else if (multiplayer) // local multiplayer only - { - if (player->deadtimer != gameovertics) - ; - // Restore the other player's music once we're dead for long enough - // -- that is, as long as they aren't dead too - else if (player == &players[displayplayer] && players[secondarydisplayplayer].lives > 0) - P_RestoreMusic(&players[secondarydisplayplayer]); - else if (player == &players[secondarydisplayplayer] && players[displayplayer].lives > 0) - P_RestoreMusic(&players[displayplayer]); - } - } + if (player->lives <= 0 && player->deadtimer == gameovertics) + P_RestoreMultiMusic(player); } if (!player->mo) diff --git a/src/st_stuff.c b/src/st_stuff.c index 30b9bdb04..a447025c6 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1982,6 +1982,28 @@ static void ST_overlayDrawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); else if (G_IsSpecialStage(gamemap) && useNightsSS) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot join the game until the stage has ended.")); + else if (gametype == GT_COOP) + { + if (cv_steallives.value + && (netgame || multiplayer)) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (&players[i] == stplyr) + continue; + + if (players[i].lives > 1) + break; + } + + if (i != MAXPLAYERS) + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); + } + } else if (!gametype == GT_COOP) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(148), V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); From 51f0d6f2e272a1516657ee5c2d44eab0181da6b4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 1 Jun 2017 22:20:36 +0100 Subject: [PATCH 19/61] Import some NiGHTS stuff from some-more-nights-fixes, so I can delete that old branch. --- src/d_clisrv.c | 12 ++++++++++-- src/p_user.c | 3 ++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 929b821eb..187d6f857 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -768,8 +768,16 @@ static void resynch_read_player(resynch_pak *rsp) players[i].mo->scalespeed = LONG(rsp->scalespeed); // And finally, SET THE MOBJ SKIN damn it. - players[i].mo->skin = &skins[players[i].skin]; - players[i].mo->color = players[i].skincolor; + if ((players[i].powers[pw_carry] == CR_NIGHTSMODE) && (skins[players[i].skin].sprites[SPR2_NGT0].numframes == 0)) + { + players[i].mo->skin = &skins[DEFAULTNIGHTSSKIN]; + players[i].mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor; // this will be corrected by thinker to super flash + } + else + { + players[i].mo->skin = &skins[players[i].skin]; + players[i].mo->color = players[i].skincolor; // this will be corrected by thinker to super flash/mario star + } P_SetThingPosition(players[i].mo); } diff --git a/src/p_user.c b/src/p_user.c index 9589bafbe..8c9426cfe 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -666,7 +666,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) if (skins[player->skin].sprites[SPR2_NGT0].numframes == 0) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. { player->mo->skin = &skins[DEFAULTNIGHTSSKIN]; - player->mo->color = ((skin_t *)(player->mo->skin))->prefcolor; + player->mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor; + player->mo->radius = FixedMul(skins[DEFAULTNIGHTSSKIN].radius, player->mo->scale); } player->nightstime = player->startedtime = nighttime*TICRATE; From 25a1ffe02a371153f604b0e0752e2973d49376fe Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 1 Jun 2017 22:21:02 +0100 Subject: [PATCH 20/61] Make it such that you only flash on game join in Co-op, not on all spawns. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 70e94d234..9f48cfbea 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9135,7 +9135,7 @@ void P_SpawnPlayer(INT32 playernum) p->skincolor = skincolor_blueteam; } - if ((netgame || multiplayer) && !p->spectator) + if ((netgame || multiplayer) && !p->spectator && (gametype != GT_COOP || ((p->jointime < 1) && !(G_IsSpecialStage(gamemap) && useNightsSS)))) p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); From f3cad19184247bd156359e7d4309fb2ea6f0b90c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Jun 2017 12:26:42 +0100 Subject: [PATCH 21/61] * Renamed "steallives" to "lifedistribution". * Gave lifedistribution a "Sharing" option to go along with its previous individual and stealing options. * Made the game over graphic and music only happen if everyone's out of lives if you're sharing or stealing lives. * Fixed a bug where game over wouldn't come to fruition because it kept on happening each tic of the countdown2. * Made spectator stuff display in Co-op splitscreen. --- src/d_netcmd.c | 40 +++++++++---------- src/d_netcmd.h | 2 +- src/g_game.c | 16 ++++---- src/m_menu.c | 2 +- src/p_inter.c | 22 +++++++++- src/p_mobj.c | 8 ++-- src/p_user.c | 24 +++++------ src/st_stuff.c | 106 ++++++++++++++++++++++++++++++++----------------- 8 files changed, 135 insertions(+), 85 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ff78cfb49..442749920 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -85,7 +85,7 @@ static void NetTimeout_OnChange(void); static void JoinTimeout_OnChange(void); static void PlayStyle_OnChange(void); -static void StealLives_OnChange(void); +static void LifeDistribution_OnChange(void); static void Ringslinger_OnChange(void); static void Gravity_OnChange(void); @@ -355,7 +355,8 @@ consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NUL static CV_PossibleValue_t playstyle_cons_t[] = {{0, "Individual"}, {1, "Sharing"}, {2, "Together"}, {0, NULL}}; consvar_t cv_playstyle = {"playstyle", "Together", CV_NETVAR|CV_CALL|CV_CHEAT, playstyle_cons_t, PlayStyle_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_steallives = {"steallives", "Yes", CV_NETVAR|CV_CALL, CV_YesNo, StealLives_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t lifedistribution_cons_t[] = {{0, "Individual"}, {1, "Stealing"}, {2, "Sharing"}, {0, NULL}}; +consvar_t cv_lifedistribution = {"lifedistribution", "Stealing", CV_NETVAR|CV_CALL, lifedistribution_cons_t, LifeDistribution_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -516,7 +517,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_downloading); CV_RegisterVar(&cv_playstyle); - CV_RegisterVar(&cv_steallives); + CV_RegisterVar(&cv_lifedistribution); CV_RegisterVar(&cv_specialrings); CV_RegisterVar(&cv_powerstones); @@ -3407,32 +3408,31 @@ static void JoinTimeout_OnChange(void) static void PlayStyle_OnChange(void) { - if (!(netgame || multiplayer) || gametype != GT_COOP || G_IsSpecialStage(gamemap)) + INT32 i; + + if (!(netgame || multiplayer) || gametype != GT_COOP || cv_playstyle.value == 2 || G_IsSpecialStage(gamemap)) return; - if (cv_playstyle.value != 2) + + for (i = 0; i < MAXPLAYERS; i++) { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; + if (!playeringame[i]) + continue; - if (!players[i].spectator) - continue; + if (!players[i].spectator) + continue; - if (players[i].lives <= 0 && !cv_steallives.value) - continue; + if (players[i].lives <= 0 && !cv_lifedistribution.value) + continue; - players[i].playerstate = PST_REBORN; - } + P_SpectatorJoinGame(&players[i]); } } -static void StealLives_OnChange(void) +static void LifeDistribution_OnChange(void) { - if (!(netgame || multiplayer) || gametype != GT_COOP) + if (!(netgame || multiplayer) || gametype != GT_COOP || cv_playstyle.value == 2) return; - if (cv_playstyle.value != 2 && cv_steallives.value) + if (cv_lifedistribution.value) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) @@ -3446,7 +3446,7 @@ static void StealLives_OnChange(void) if (players[i].lives > 0) continue; - players[i].playerstate = PST_REBORN; + P_SpectatorJoinGame(&players[i]); } } } diff --git a/src/d_netcmd.h b/src/d_netcmd.h index c25b29d04..f23ff0bc1 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -89,7 +89,7 @@ extern consvar_t cv_recycler; extern consvar_t cv_itemfinder; -extern consvar_t cv_inttime, cv_playstyle, cv_steallives, cv_advancemap, cv_playersforexit; +extern consvar_t cv_inttime, cv_playstyle, cv_lifedistribution, cv_advancemap, cv_playersforexit; extern consvar_t cv_overtime; extern consvar_t cv_startinglives; diff --git a/src/g_game.c b/src/g_game.c index 2e4dc6dd6..5a63f515d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2592,10 +2592,6 @@ void G_DoReborn(INT32 playernum) // respawn at the start mobj_t *oldmo = NULL; - // Return to level music - if (player->lives <= 0) - P_RestoreMultiMusic(player); - if (gametype == GT_COOP && (netgame || multiplayer)) { INT32 i; @@ -2606,18 +2602,18 @@ void G_DoReborn(INT32 playernum) { if (!playeringame[i]) continue; - if (players[i].exiting || players[i].lives) + if (players[i].exiting || players[i].lives > 0) break; if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck) deadtimercheck = players[i].deadtimer; } - if (i == MAXPLAYERS && deadtimercheck >= 8*TICRATE) + if (!countdown2 && i == MAXPLAYERS && deadtimercheck >= 8*TICRATE) { // They're dead, Jim. //nextmapoverride = spstage_start; nextmapoverride = gamemap; - countdown2 = 1*TICRATE; + countdown2 = TICRATE; skipstats = true; for (i = 0; i < MAXPLAYERS; i++) @@ -2697,6 +2693,12 @@ void G_DoReborn(INT32 playernum) } } + // Not resetting map, so return to level music + if (!countdown2 + && player->lives <= 0 + && !cv_lifedistribution.value) // not allowed for life steal because no way to come back from zero group lives without addons, which should call this anyways + P_RestoreMultiMusic(player); + if (player->starposttime) starpost = true; diff --git a/src/m_menu.c b/src/m_menu.c index 796b17101..2b036f361 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1391,7 +1391,7 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_HEADER, NULL, "Cooperative", NULL, 90}, {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96}, {IT_STRING | IT_CVAR, NULL, "Play style", &cv_playstyle, 101}, - {IT_STRING | IT_CVAR, NULL, "Steal lives on game over", &cv_steallives, 106}, + {IT_STRING | IT_CVAR, NULL, "Life distribution", &cv_lifedistribution, 106}, {IT_HEADER, NULL, "Race, Competition", NULL, 115}, {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 121}, diff --git a/src/p_inter.c b/src/p_inter.c index 036063b89..8db063ce1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1309,7 +1309,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) players[i].starpostangle = special->angle; players[i].starpostnum = special->health; - if (cv_playstyle.value == 2 && (P_GetLives(&players[i]) || players[i].lives > 0) && (players[i].playerstate == PST_DEAD || players[i].spectator)) + if (cv_playstyle.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i])) P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN; } } @@ -2253,7 +2253,25 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->player->lives <= 0) // Tails 03-14-2000 { - if (P_IsLocalPlayer(target->player)/* && target->player == &players[consoleplayer] */) + boolean gameovermus = false; + if ((netgame || multiplayer) && (gametype == GT_COOP) && cv_lifedistribution.value) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].lives > 0) + break; + } + if (i == MAXPLAYERS) + gameovermus = true; + } + else if (P_IsLocalPlayer(target->player)) + gameovermus = true; + + if (gameovermus) { S_StopMusic(); // Stop the Music! Tails 03-14-2000 S_ChangeMusicInternal("_gover", false); // Yousa dead now, Okieday? Tails 03-14-2000 diff --git a/src/p_mobj.c b/src/p_mobj.c index 9f48cfbea..d90069586 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9084,10 +9084,10 @@ void P_SpawnPlayer(INT32 playernum) // spawn as spectator determination if (!G_GametypeHasSpectators()) { - if ( ((multiplayer || netgame) && gametype == GT_COOP && leveltime > 0) - && ((G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage - || (cv_playstyle.value == 2 && (p->jointime < 1 || p->spectator)) // late join or die in new coop - || (p->lives <= 0 && (!cv_steallives.value || !P_GetLives(p)))) ) // game over + if ( ( (multiplayer || netgame) && gametype == GT_COOP && leveltime > 0) // only question status in coop + && ( (G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage + || (cv_playstyle.value == 2 && (p->jointime < 1 || p->spectator) ) // late join or die in new coop + || ((!cv_lifedistribution.value || !P_GetLives(p)) && p->lives <= 0))) // game over and can't redistribute lives p->spectator = true; else p->spectator = false; diff --git a/src/p_user.c b/src/p_user.c index 8c9426cfe..abd3bb8be 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -958,7 +958,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound) { - if (!((netgame || multiplayer) && gametype == GT_COOP && cv_playstyle.value)) + if (!((netgame || multiplayer) && gametype == GT_COOP)) { P_GivePlayerLives(player, numlives); if (sound) @@ -8109,12 +8109,12 @@ void P_FindEmerald(void) boolean P_GetLives(player_t *player) { INT32 i, maxlivesplayer = -1, livescheck = 1; - if (!(cv_steallives.value + if (!(cv_lifedistribution.value && (gametype == GT_COOP) && (netgame || multiplayer))) return true; - if (player->lives > 0) + if (cv_lifedistribution.value == 1 && player->lives > 0) return true; for (i = 0; i < MAXPLAYERS; i++) @@ -8128,17 +8128,17 @@ boolean P_GetLives(player_t *player) livescheck = players[i].lives; } } - if (maxlivesplayer != -1) + if (maxlivesplayer != -1 && &players[maxlivesplayer] != player) { - if (players[maxlivesplayer].mo) - S_StartSound(players[maxlivesplayer].mo, sfx_jshard); // placeholder + if (cv_lifedistribution.value == 1 && P_IsLocalPlayer(&players[maxlivesplayer])) + S_StartSound(NULL, sfx_jshard); // placeholder players[maxlivesplayer].lives--; player->lives++; if (player->lives < 1) player->lives = 1; return true; } - return false; + return (player->lives > 0); } // @@ -8219,7 +8219,7 @@ static void P_DeathThink(player_t *player) G_UseContinue(); // Even if we don't have one this handles ending the game } - if (cv_steallives.value + if (cv_lifedistribution.value && (gametype == GT_COOP) && (netgame || multiplayer) && (player->lives <= 0)) @@ -8330,7 +8330,7 @@ static void P_DeathThink(player_t *player) } // Return to level music - if (player->lives <= 0 && player->deadtimer == gameovertics) + if (gametype != GT_COOP && player->lives <= 0 && player->deadtimer == gameovertics) P_RestoreMultiMusic(player); } @@ -9436,11 +9436,7 @@ void P_PlayerThink(player_t *player) player->realtime = leveltime; } - if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing] - && (G_GametypeHasSpectators() - || !((G_IsSpecialStage(gamemap) && useNightsSS) - || (gametype == GT_COOP && cv_playstyle.value == 2) - ))) + if (player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing] && G_GametypeHasSpectators()) { if (P_SpectatorJoinGame(player)) return; // player->mo was removed. diff --git a/src/st_stuff.c b/src/st_stuff.c index a447025c6..d2db20431 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -728,31 +728,59 @@ static void ST_drawLives(void) // x V_DrawScaledPatch(hudinfo[HUD_LIVESX].x, hudinfo[HUD_LIVESX].y + (v_splitflag ? -4 : 0), V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, stlivex); - // lives - V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, va("%d",stplyr->lives)); - if (cv_steallives.value - && (gametype == GT_COOP) - && (netgame || multiplayer)) + // lives number + if ((netgame || multiplayer) && gametype == GT_COOP) { - INT32 i, sum = 0; - for (i = 0; i < MAXPLAYERS; i++) + switch (cv_lifedistribution.value) { - if (!playeringame[i]) - continue; + case 2: + { + INT32 i, sum = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; - if (&players[i] == stplyr) - continue; + if (players[i].lives < 1) + continue; - if (players[i].lives < 2) - continue; + sum += (players[i].lives); + } + V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, + va("%d",(sum))); + return; + } + case 1: + { + INT32 i, sum = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; - sum += (players[i].lives - 1); + if (&players[i] == stplyr) + continue; + + if (players[i].lives < 2) + continue; + + sum += (players[i].lives - 1); + } + V_DrawString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF|v_splitflag, va("/%d",sum)); + } + // intentional fallthrough + default: + // don't return so the SP one can be drawn below + break; } - V_DrawString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF|v_splitflag, va("/%d",sum)); } + + V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, + va("%d",stplyr->lives)); } static void ST_drawLevelTitle(void) @@ -1847,11 +1875,8 @@ static void ST_overlayDrawer(void) else p = sboover; - V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, STRINGY(BASEVIDHEIGHT/2 - (SHORT(p->height)/2)), 0, p); - - if (cv_steallives.value - && (gametype == GT_COOP) - && (netgame || multiplayer)) + if (cv_lifedistribution.value + && gametype == GT_COOP) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) @@ -1862,13 +1887,16 @@ static void ST_overlayDrawer(void) if (&players[i] == stplyr) continue; - if (players[i].lives > 1) + if (players[i].lives > 0) + { + p = NULL; break; + } } - - if (i != MAXPLAYERS) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(BASEVIDHEIGHT/2 + (SHORT(p->height)/2)) + 14, 0, M_GetText("You'll steal a life on respawn.")); } + + if (p) + V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, STRINGY(BASEVIDHEIGHT/2 - (SHORT(p->height)/2)), (stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p); } @@ -1953,15 +1981,16 @@ static void ST_overlayDrawer(void) ) ST_drawLevelTitle(); - if (!hu_showscores && !splitscreen && netgame && displayplayer == consoleplayer) + if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer) { - if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); + if (!splitscreen && G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) + V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); else if (gametype == GT_HIDEANDSEEK && (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) { V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding.")); - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); + if (!splitscreen) + V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); } else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. { @@ -1971,20 +2000,20 @@ static void ST_overlayDrawer(void) else V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); } - else if (stplyr->spectator + else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE) #ifdef HAVE_BLUA && LUA_HudEnabled(hud_textspectator) #endif ) { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), V_HUDTRANSHALF, M_GetText("You are a spectator.")); + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60)+(splitscreen ? 4 : 0), V_HUDTRANSHALF, M_GetText("You are a spectator.")); if (G_GametypeHasTeams()) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); else if (G_IsSpecialStage(gamemap) && useNightsSS) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot join the game until the stage has ended.")); else if (gametype == GT_COOP) { - if (cv_steallives.value + if (cv_lifedistribution.value == 1 && (netgame || multiplayer)) { INT32 i; @@ -2001,13 +2030,18 @@ static void ST_overlayDrawer(void) } if (i != MAXPLAYERS) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132)-(splitscreen ? 8 : 0), V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); } } else if (!gametype == GT_COOP) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(148), V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(164), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); + if (!splitscreen) + { + V_DrawCenteredString(BASEVIDWIDTH/2, 148, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); + } + else + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(144), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); } } From ae3441659eaa058a2ffae03ce2695771f7303c28 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Jun 2017 13:47:08 +0100 Subject: [PATCH 22/61] Unrelated to the branch, but I was messing around with heights and shadow.wad and figured I might as well tweak it whilst I remember. --- src/p_user.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index abd3bb8be..3dbaf2024 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4310,11 +4310,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->mo->momy /= 3; } - if (player->mo->info->attacksound && !player->spectator) - S_StartSound(player->mo, player->mo->info->attacksound); // Play the THOK sound - - P_SpawnThokMobj(player); - if (player->charability == CA_HOMINGTHOK) { P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockon)); @@ -4327,10 +4322,16 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) { P_SetPlayerMobjState(player->mo, S_PLAY_FALL); player->pflags &= ~PF_JUMPED; + player->mo->height = P_GetPlayerHeight(player); } player->pflags &= ~PF_NOJUMPDAMAGE; } + if (player->mo->info->attacksound && !player->spectator) + S_StartSound(player->mo, player->mo->info->attacksound); // Play the THOK sound + + P_SpawnThokMobj(player); + player->pflags &= ~(PF_SPINNING|PF_STARTDASH); player->pflags |= PF_THOKKED; } From 8d8ae2b5388a5d6884c7edd407a8fa8eeec6dfce Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Jun 2017 17:55:03 +0100 Subject: [PATCH 23/61] Renamed again, and this time I'm happy with it. * "playstyle" to "coopstarposts" * "lifedistribution" to "cooplives" --- src/d_netcmd.c | 28 ++++++++++++++-------------- src/d_netcmd.h | 2 +- src/g_game.c | 6 +++--- src/m_menu.c | 4 ++-- src/p_inter.c | 6 +++--- src/p_mobj.c | 4 ++-- src/p_setup.c | 2 +- src/p_user.c | 12 ++++++------ src/st_stuff.c | 6 +++--- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 442749920..c4100a0f9 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -84,8 +84,8 @@ static void TeamScramble_OnChange(void); static void NetTimeout_OnChange(void); static void JoinTimeout_OnChange(void); -static void PlayStyle_OnChange(void); -static void LifeDistribution_OnChange(void); +static void CoopStarposts_OnChange(void); +static void CoopLives_OnChange(void); static void Ringslinger_OnChange(void); static void Gravity_OnChange(void); @@ -352,11 +352,11 @@ consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NUL static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t playstyle_cons_t[] = {{0, "Individual"}, {1, "Sharing"}, {2, "Together"}, {0, NULL}}; -consvar_t cv_playstyle = {"playstyle", "Together", CV_NETVAR|CV_CALL|CV_CHEAT, playstyle_cons_t, PlayStyle_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t coopstarposts_cons_t[] = {{0, "Individual"}, {1, "Sharing"}, {2, "Together"}, {0, NULL}}; +consvar_t cv_coopstarposts = {"coopstarposts", "Together", CV_NETVAR|CV_CALL|CV_CHEAT, coopstarposts_cons_t, CoopStarposts_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t lifedistribution_cons_t[] = {{0, "Individual"}, {1, "Stealing"}, {2, "Sharing"}, {0, NULL}}; -consvar_t cv_lifedistribution = {"lifedistribution", "Stealing", CV_NETVAR|CV_CALL, lifedistribution_cons_t, LifeDistribution_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t cooplives_cons_t[] = {{0, "Individual"}, {1, "Stealing"}, {2, "Sharing"}, {0, NULL}}; +consvar_t cv_cooplives = {"cooplives", "Stealing", CV_NETVAR|CV_CALL, cooplives_cons_t, CoopLives_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -516,8 +516,8 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_forceskin); CV_RegisterVar(&cv_downloading); - CV_RegisterVar(&cv_playstyle); - CV_RegisterVar(&cv_lifedistribution); + CV_RegisterVar(&cv_coopstarposts); + CV_RegisterVar(&cv_cooplives); CV_RegisterVar(&cv_specialrings); CV_RegisterVar(&cv_powerstones); @@ -3406,11 +3406,11 @@ static void JoinTimeout_OnChange(void) jointimeout = (tic_t)cv_jointimeout.value; } -static void PlayStyle_OnChange(void) +static void CoopStarposts_OnChange(void) { INT32 i; - if (!(netgame || multiplayer) || gametype != GT_COOP || cv_playstyle.value == 2 || G_IsSpecialStage(gamemap)) + if (!(netgame || multiplayer) || gametype != GT_COOP || cv_coopstarposts.value == 2 || G_IsSpecialStage(gamemap)) return; for (i = 0; i < MAXPLAYERS; i++) @@ -3421,18 +3421,18 @@ static void PlayStyle_OnChange(void) if (!players[i].spectator) continue; - if (players[i].lives <= 0 && !cv_lifedistribution.value) + if (players[i].lives <= 0 && !cv_cooplives.value) continue; P_SpectatorJoinGame(&players[i]); } } -static void LifeDistribution_OnChange(void) +static void CoopLives_OnChange(void) { - if (!(netgame || multiplayer) || gametype != GT_COOP || cv_playstyle.value == 2) + if (!(netgame || multiplayer) || gametype != GT_COOP || cv_coopstarposts.value == 2) return; - if (cv_lifedistribution.value) + if (cv_cooplives.value) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index f23ff0bc1..9ab59f6ee 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -89,7 +89,7 @@ extern consvar_t cv_recycler; extern consvar_t cv_itemfinder; -extern consvar_t cv_inttime, cv_playstyle, cv_lifedistribution, cv_advancemap, cv_playersforexit; +extern consvar_t cv_inttime, cv_coopstarposts, cv_cooplives, cv_advancemap, cv_playersforexit; extern consvar_t cv_overtime; extern consvar_t cv_startinglives; diff --git a/src/g_game.c b/src/g_game.c index 5a63f515d..566d536c1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2628,7 +2628,7 @@ void G_DoReborn(INT32 playernum) token = 0; } } - if (cv_playstyle.value == 2) + if (cv_coopstarposts.value == 2) { for (i = 0; i < MAXPLAYERS; i++) { @@ -2696,7 +2696,7 @@ void G_DoReborn(INT32 playernum) // Not resetting map, so return to level music if (!countdown2 && player->lives <= 0 - && !cv_lifedistribution.value) // not allowed for life steal because no way to come back from zero group lives without addons, which should call this anyways + && !cv_cooplives.value) // not allowed for life steal because no way to come back from zero group lives without addons, which should call this anyways P_RestoreMultiMusic(player); if (player->starposttime) @@ -2739,7 +2739,7 @@ void G_AddPlayer(INT32 playernum) if (!players->exiting) notexiting++; - if (!(cv_playstyle.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum))) + if (!(cv_coopstarposts.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum))) continue; p->starposttime = players[i].starposttime; diff --git a/src/m_menu.c b/src/m_menu.c index 2b036f361..0b601a3de 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1390,8 +1390,8 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_HEADER, NULL, "Cooperative", NULL, 90}, {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96}, - {IT_STRING | IT_CVAR, NULL, "Play style", &cv_playstyle, 101}, - {IT_STRING | IT_CVAR, NULL, "Life distribution", &cv_lifedistribution, 106}, + {IT_STRING | IT_CVAR, NULL, "Starposts", &cv_coopstarposts, 101}, + {IT_STRING | IT_CVAR, NULL, "Life distribution", &cv_cooplives, 106}, {IT_HEADER, NULL, "Race, Competition", NULL, 115}, {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 121}, diff --git a/src/p_inter.c b/src/p_inter.c index 8db063ce1..5f730bd6c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1293,7 +1293,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->starpostnum >= special->health) return; // Already hit this post - if (cv_playstyle.value && gametype == GT_COOP && (netgame || multiplayer)) + if (cv_coopstarposts.value && gametype == GT_COOP && (netgame || multiplayer)) { for (i = 0; i < MAXPLAYERS; i++) { @@ -1309,7 +1309,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) players[i].starpostangle = special->angle; players[i].starpostnum = special->health; - if (cv_playstyle.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i])) + if (cv_coopstarposts.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i])) P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN; } } @@ -2254,7 +2254,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->player->lives <= 0) // Tails 03-14-2000 { boolean gameovermus = false; - if ((netgame || multiplayer) && (gametype == GT_COOP) && cv_lifedistribution.value) + if ((netgame || multiplayer) && (gametype == GT_COOP) && cv_cooplives.value) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/p_mobj.c b/src/p_mobj.c index d90069586..aa76cddf1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9086,8 +9086,8 @@ void P_SpawnPlayer(INT32 playernum) { if ( ( (multiplayer || netgame) && gametype == GT_COOP && leveltime > 0) // only question status in coop && ( (G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage - || (cv_playstyle.value == 2 && (p->jointime < 1 || p->spectator) ) // late join or die in new coop - || ((!cv_lifedistribution.value || !P_GetLives(p)) && p->lives <= 0))) // game over and can't redistribute lives + || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->spectator) ) // late join or die in new coop + || ((!cv_cooplives.value || !P_GetLives(p)) && p->lives <= 0))) // game over and can't redistribute lives p->spectator = true; else p->spectator = false; diff --git a/src/p_setup.c b/src/p_setup.c index f7a202aea..3f346523b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2221,7 +2221,7 @@ static void P_LevelInitStuff(void) // earthquake camera memset(&quake,0,sizeof(struct quake)); - if ((netgame || multiplayer) && gametype == GT_COOP && cv_playstyle.value == 2) + if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) { for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/p_user.c b/src/p_user.c index 3dbaf2024..8868a558b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8110,12 +8110,12 @@ void P_FindEmerald(void) boolean P_GetLives(player_t *player) { INT32 i, maxlivesplayer = -1, livescheck = 1; - if (!(cv_lifedistribution.value + if (!(cv_cooplives.value && (gametype == GT_COOP) && (netgame || multiplayer))) return true; - if (cv_lifedistribution.value == 1 && player->lives > 0) + if (cv_cooplives.value == 1 && player->lives > 0) return true; for (i = 0; i < MAXPLAYERS; i++) @@ -8131,7 +8131,7 @@ boolean P_GetLives(player_t *player) } if (maxlivesplayer != -1 && &players[maxlivesplayer] != player) { - if (cv_lifedistribution.value == 1 && P_IsLocalPlayer(&players[maxlivesplayer])) + if (cv_cooplives.value == 1 && P_IsLocalPlayer(&players[maxlivesplayer])) S_StartSound(NULL, sfx_jshard); // placeholder players[maxlivesplayer].lives--; player->lives++; @@ -8220,7 +8220,7 @@ static void P_DeathThink(player_t *player) G_UseContinue(); // Even if we don't have one this handles ending the game } - if (cv_lifedistribution.value + if (cv_cooplives.value && (gametype == GT_COOP) && (netgame || multiplayer) && (player->lives <= 0)) @@ -8240,7 +8240,7 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! { - if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) + if (gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2) { P_ConsiderAllGone(); if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))) @@ -9390,7 +9390,7 @@ void P_PlayerThink(player_t *player) if (!player->spectator) P_PlayerInSpecialSector(player); - else if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) + else if (gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2) P_ConsiderAllGone(); if (player->playerstate == PST_DEAD) diff --git a/src/st_stuff.c b/src/st_stuff.c index d2db20431..b2ef0bf28 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -732,7 +732,7 @@ static void ST_drawLives(void) // lives number if ((netgame || multiplayer) && gametype == GT_COOP) { - switch (cv_lifedistribution.value) + switch (cv_cooplives.value) { case 2: { @@ -1875,7 +1875,7 @@ static void ST_overlayDrawer(void) else p = sboover; - if (cv_lifedistribution.value + if (cv_cooplives.value && gametype == GT_COOP) { INT32 i; @@ -2013,7 +2013,7 @@ static void ST_overlayDrawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot join the game until the stage has ended.")); else if (gametype == GT_COOP) { - if (cv_lifedistribution.value == 1 + if (cv_cooplives.value == 1 && (netgame || multiplayer)) { INT32 i; From a872f1c68f16a97acc62d87a876d3ec594c1638a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Jun 2017 22:14:20 +0100 Subject: [PATCH 24/61] I'm starting to actually test this via netgame instead of just in splitscreen! * Fixed oversight where late joiners may not actually get lives. * Fixed oversight where zero-livers could spawn in. * Reinstated flashing because a crawla walked onto one of the spawnpoints and we immediately got a game over. * Rejiggered the overlay drawer so the printing was consistent between normal spectatorship and game overness. --- src/g_game.c | 3 +++ src/p_mobj.c | 9 +++++---- src/st_stuff.c | 6 +++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 566d536c1..942ea4d64 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2754,6 +2754,9 @@ void G_AddPlayer(INT32 playernum) p->jointime = 0; p->playerstate = PST_REBORN; + if (G_GametypeUsesLives()) + p->lives = cv_startinglives.value; + if (countplayers && !notexiting) P_DoPlayerExit(p); } diff --git a/src/p_mobj.c b/src/p_mobj.c index aa76cddf1..f93bafe7e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9084,9 +9084,10 @@ void P_SpawnPlayer(INT32 playernum) // spawn as spectator determination if (!G_GametypeHasSpectators()) { - if ( ( (multiplayer || netgame) && gametype == GT_COOP && leveltime > 0) // only question status in coop - && ( (G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage - || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->spectator) ) // late join or die in new coop + if (((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop + && ((leveltime > 0 + && ((G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage + || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->spectator)))) // late join or die in new coop || ((!cv_cooplives.value || !P_GetLives(p)) && p->lives <= 0))) // game over and can't redistribute lives p->spectator = true; else @@ -9135,7 +9136,7 @@ void P_SpawnPlayer(INT32 playernum) p->skincolor = skincolor_blueteam; } - if ((netgame || multiplayer) && !p->spectator && (gametype != GT_COOP || ((p->jointime < 1) && !(G_IsSpecialStage(gamemap) && useNightsSS)))) + if ((netgame || multiplayer) && !p->spectator) p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); diff --git a/src/st_stuff.c b/src/st_stuff.c index b2ef0bf28..fb099c7c4 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1983,7 +1983,7 @@ static void ST_overlayDrawer(void) if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer) { - if (!splitscreen && G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) + if (!splitscreen && gametype != GT_COOP && G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); else if (gametype == GT_HIDEANDSEEK && (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) @@ -2010,8 +2010,8 @@ static void ST_overlayDrawer(void) if (G_GametypeHasTeams()) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); else if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot join the game until the stage has ended.")); - else if (gametype == GT_COOP) + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); + else if (gametype == GT_COOP && stplyr->lives <= 0) { if (cv_cooplives.value == 1 && (netgame || multiplayer)) From 5136bf440415869a152bdd4deb05f8c29f0b92e4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Jun 2017 22:27:40 +0100 Subject: [PATCH 25/61] * Make shared lives counter greyed out if you can't respawn, to counteract the fact that it's lit up for lives in use. * More splitscreen tweaks. --- src/st_stuff.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index fb099c7c4..938207cbb 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -748,7 +748,7 @@ static void ST_drawLives(void) sum += (players[i].lives); } V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|((stplyr->lives > 0) ? V_HUDTRANS : V_HUDTRANSHALF)|v_splitflag, va("%d",(sum))); return; } @@ -2030,7 +2030,7 @@ static void ST_overlayDrawer(void) } if (i != MAXPLAYERS) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132)-(splitscreen ? 8 : 0), V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132)-(splitscreen ? 12 : 0), V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); } } else if (!gametype == GT_COOP) @@ -2041,7 +2041,7 @@ static void ST_overlayDrawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); } else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(144), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(128), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); } } From 9d0212b9ec8082969a602cec73765f0de9f8b0aa Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Jun 2017 22:43:35 +0100 Subject: [PATCH 26/61] Console messages for the new cvars, ala other stuff in d_netcmd.c. --- src/d_netcmd.c | 59 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c4100a0f9..8ddc1e142 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3410,7 +3410,23 @@ static void CoopStarposts_OnChange(void) { INT32 i; - if (!(netgame || multiplayer) || gametype != GT_COOP || cv_coopstarposts.value == 2 || G_IsSpecialStage(gamemap)) + if (!(netgame || multiplayer) || gametype != GT_COOP) + return; + + switch (cv_coopstarposts.value) + { + case 0: + CONS_Printf(M_GetText("Starposts are now per-player.\n")); + break; + case 1: + CONS_Printf(M_GetText("Starposts are now shared between players.\n")); + break; + case 2: + CONS_Printf(M_GetText("Players now only spawn when starposts are hit.\n")); + return; + } + + if (G_IsSpecialStage(gamemap)) return; for (i = 0; i < MAXPLAYERS; i++) @@ -3430,24 +3446,39 @@ static void CoopStarposts_OnChange(void) static void CoopLives_OnChange(void) { - if (!(netgame || multiplayer) || gametype != GT_COOP || cv_coopstarposts.value == 2) + INT32 i; + + if (!(netgame || multiplayer) || gametype != GT_COOP) return; - if (cv_cooplives.value) + + switch (cv_cooplives.value) { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; + case 0: + CONS_Printf(M_GetText("Lives are now per-player.\n")); + return; + case 1: + CONS_Printf(M_GetText("Players can now steal lives to avoid game over.\n")); + break; + case 2: + CONS_Printf(M_GetText("Lives are now shared between players.\n")); + break; + } - if (!players[i].spectator) - continue; + if (cv_coopstarposts.value == 2) + return; - if (players[i].lives > 0) - continue; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; - P_SpectatorJoinGame(&players[i]); - } + if (!players[i].spectator) + continue; + + if (players[i].lives > 0) + continue; + + P_SpectatorJoinGame(&players[i]); } } From 1eaf35854d2ac26ce729d8ea7cf0b7ca69a47254 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 4 Jun 2017 00:43:34 +0100 Subject: [PATCH 27/61] Fixed that issue with spectators not being able to go above FOFs. I guess it just wasn't getting initialised properly on first join! --- src/g_game.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 942ea4d64..f574094b8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2754,6 +2754,8 @@ void G_AddPlayer(INT32 playernum) p->jointime = 0; p->playerstate = PST_REBORN; + p->height = mobjinfo[MT_PLAYER].height; + if (G_GametypeUsesLives()) p->lives = cv_startinglives.value; From faabca552fa6fe5a0952395fd08cbdf3740caaa4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 4 Jun 2017 00:48:32 +0100 Subject: [PATCH 28/61] Okay, I guess this DID need to be done. (Something from the old nights fixes branch which I didn't port over initially.) --- src/p_user.c | 1 - src/r_things.c | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 8868a558b..7ea6c9269 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -667,7 +667,6 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) { player->mo->skin = &skins[DEFAULTNIGHTSSKIN]; player->mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor; - player->mo->radius = FixedMul(skins[DEFAULTNIGHTSSKIN].radius, player->mo->scale); } player->nightstime = player->startedtime = nighttime*TICRATE; diff --git a/src/r_things.c b/src/r_things.c index d71a7e7a1..3b50eb106 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2669,16 +2669,17 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) if (player->mo) { + fixed_t radius = FixedMul(skin->radius, player->mo->scale); if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NGT0].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. { skin = &skins[DEFAULTNIGHTSSKIN]; - newcolor = ((skin->flags & SF_SUPER) ? skin->supercolor : skin->prefcolor); + newcolor = skin->prefcolor; // will be updated in thinker to flashing } player->mo->skin = skin; if (newcolor) player->mo->color = newcolor; P_SetScale(player->mo, player->mo->scale); - player->mo->radius = FixedMul(skin->radius, player->mo->scale); + player->mo->radius = radius; P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames } From 50496970d143a8a6faefa86ffeda518d81970675 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 3 Jul 2017 15:43:29 +0100 Subject: [PATCH 29/61] Fix weird visual artifacting caused by restarting the level in co-op, which was a direct result of my code being messy. This is significantly better to deal with, anyways. --- src/d_clisrv.c | 5 ++ src/d_clisrv.h | 1 + src/d_player.h | 1 + src/g_game.c | 195 ++++++++++++++++++------------------------------- src/p_mobj.c | 10 +-- src/p_user.c | 11 ++- 6 files changed, 88 insertions(+), 135 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 6705e6dcd..673b00957 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -891,6 +891,7 @@ static inline void resynch_write_others(resynchend_pak *rst) UINT8 i; rst->ingame = 0; + rst->outofcoop = 0; for (i = 0; i < MAXPLAYERS; ++i) { @@ -907,6 +908,8 @@ static inline void resynch_write_others(resynchend_pak *rst) if (!players[i].spectator) rst->ingame |= (1<outofcoop |= (1<ctfteam[i] = (INT32)LONG(players[i].ctfteam); rst->score[i] = (UINT32)LONG(players[i].score); rst->numboxes[i] = SHORT(players[i].numboxes); @@ -923,11 +926,13 @@ static inline void resynch_read_others(resynchend_pak *p) { UINT8 i; UINT32 loc_ingame = (UINT32)LONG(p->ingame); + UINT32 loc_outofcoop = (UINT32)LONG(p->outofcoop); for (i = 0; i < MAXPLAYERS; ++i) { // We don't care if they're in the game or not, just write all the data. players[i].spectator = !(loc_ingame & (1<ctfteam[i]); // no, 0 does not mean spectator, at least not in Match players[i].score = (UINT32)LONG(p->score[i]); players[i].numboxes = SHORT(p->numboxes[i]); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 1ca82fdc5..fdee80c5e 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -136,6 +136,7 @@ typedef struct fixed_t flagz[2]; UINT32 ingame; // Spectator bit for each player + UINT32 outofcoop; // outofcoop bit for each player INT32 ctfteam[MAXPLAYERS]; // Which team? (can't be 1 bit, since in regular Match there are no teams) // Resynch game scores and the like all at once diff --git a/src/d_player.h b/src/d_player.h index 4e4a53a08..98af2a267 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -471,6 +471,7 @@ typedef struct player_s angle_t awayviewaiming; // Used for cut-away view boolean spectator; + boolean outofcoop; UINT8 bot; tic_t jointime; // Timer when player joins game to change skin/color diff --git a/src/g_game.c b/src/g_game.c index ec41449d8..b5b0b5f99 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2090,6 +2090,7 @@ void G_PlayerReborn(INT32 player) UINT32 availabilities; tic_t jointime; boolean spectator; + boolean outofcoop; INT16 bot; SINT8 pity; @@ -2100,6 +2101,7 @@ void G_PlayerReborn(INT32 player) exiting = players[player].exiting; jointime = players[player].jointime; spectator = players[player].spectator; + outofcoop = players[player].outofcoop; pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_ANALOGMODE)); // As long as we're not in multiplayer, carry over cheatcodes from map to map @@ -2154,6 +2156,7 @@ void G_PlayerReborn(INT32 player) p->ctfteam = ctfteam; p->jointime = jointime; p->spectator = spectator; + p->outofcoop = outofcoop; // save player config truth reborn p->skincolor = skincolor; @@ -2489,26 +2492,13 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo) } } -#ifdef HAVE_BLUA -#define RESETMAP {\ - LUAh_MapChange();\ - G_DoLoadLevel(true);\ - return;\ - } -#else -#define RESETMAP {\ - G_DoLoadLevel(true);\ - return;\ - } -#endif - // // G_DoReborn // void G_DoReborn(INT32 playernum) { player_t *player = &players[playernum]; - boolean starpost = false; + boolean resetlevel = false; if (modeattacking) { @@ -2534,8 +2524,64 @@ void G_DoReborn(INT32 playernum) B_RespawnBot(playernum); if (oldmo) G_ChangePlayerReferences(oldmo, players[playernum].mo); + + return; } - else if (countdowntimeup || (!multiplayer && gametype == GT_COOP)) + + if (countdowntimeup || (!multiplayer && gametype == GT_COOP)) + resetlevel = true; + else if (gametype == GT_COOP && (netgame || multiplayer)) + { + INT32 i; + if (player->lives <= 0) // consider game over first + { + INT32 deadtimercheck = INT32_MAX; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (players[i].exiting || players[i].lives > 0) + break; + if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck) + deadtimercheck = players[i].deadtimer; + } + + if (!countdown2 && i == MAXPLAYERS && deadtimercheck >= 8*TICRATE) + { + // They're dead, Jim. + //nextmapoverride = spstage_start; + nextmapoverride = gamemap; + countdown2 = TICRATE; + skipstats = true; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + players[i].score = 0; + } + + //emeralds = 0; + tokenbits = 0; + tokenlist = 0; + token = 0; + } + } + if (cv_coopstarposts.value == 2) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) + break; + } + if (i == MAXPLAYERS) + resetlevel = true; + } + } + + if (resetlevel) { // reload the level from scratch if (countdowntimeup) @@ -2557,9 +2603,6 @@ void G_DoReborn(INT32 playernum) // Do a wipe wipegamestate = -1; - if (player->starposttime) - starpost = true; - if (camera.chase) P_ResetCamera(&players[displayplayer], &camera); if (camera2.chase && splitscreen) @@ -2579,7 +2622,7 @@ void G_DoReborn(INT32 playernum) CON_ClearHUD(); // Starpost support - G_SpawnPlayer(playernum, starpost); + G_SpawnPlayer(playernum, (player->starposttime)); if (botingame) { // Bots respawn next to their master. @@ -2588,123 +2631,25 @@ void G_DoReborn(INT32 playernum) } } else - RESETMAP; + { +#ifdef HAVE_BLUA + LUAh_MapChange(); +#endif + G_DoLoadLevel(true); + return; + } } else { // respawn at the start mobj_t *oldmo = NULL; - if (gametype == GT_COOP && (netgame || multiplayer)) - { - INT32 i; - if (player->lives <= 0) // consider game over first - { - INT32 deadtimercheck = INT32_MAX; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - if (players[i].exiting || players[i].lives > 0) - break; - if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck) - deadtimercheck = players[i].deadtimer; - } - - if (!countdown2 && i == MAXPLAYERS && deadtimercheck >= 8*TICRATE) - { - // They're dead, Jim. - //nextmapoverride = spstage_start; - nextmapoverride = gamemap; - countdown2 = TICRATE; - skipstats = true; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - players[i].score = 0; - } - - //emeralds = 0; - tokenbits = 0; - tokenlist = 0; - token = 0; - } - } - if (cv_coopstarposts.value == 2) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) - break; - } - if (i == MAXPLAYERS) - { - if (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD) - { - INT32 j; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - players[i].playerstate = PST_REBORN; - } - - P_LoadThingsOnly(); - P_ClearStarPost(player->starpostnum); - - // Do a wipe - wipegamestate = -1; - - if (camera.chase) - P_ResetCamera(&players[displayplayer], &camera); - if (camera2.chase && splitscreen) - P_ResetCamera(&players[secondarydisplayplayer], &camera2); - - // clear cmd building stuff - memset(gamekeydown, 0, sizeof (gamekeydown)); - for (j = 0; j < JOYAXISSET; j++) - { - joyxmove[j] = joyymove[j] = 0; - joy2xmove[j] = joy2ymove[j] = 0; - } - mousex = mousey = 0; - mouse2x = mouse2y = 0; - - // clear hud messages remains (usually from game startup) - CON_ClearHUD(); - - // Starpost support - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - G_SpawnPlayer(i, (players[i].starposttime != 0)); - } - - return; - } - else - RESETMAP; - } - } - } - // Not resetting map, so return to level music if (!countdown2 && player->lives <= 0 && !cv_cooplives.value) // not allowed for life steal because no way to come back from zero group lives without addons, which should call this anyways P_RestoreMultiMusic(player); - if (player->starposttime) - starpost = true; - // first dissasociate the corpse if (player->mo) { @@ -2713,7 +2658,7 @@ void G_DoReborn(INT32 playernum) P_RemoveMobj(player->mo); } - G_SpawnPlayer(playernum, starpost); + G_SpawnPlayer(playernum, (player->starposttime)); if (oldmo) G_ChangePlayerReferences(oldmo, players[playernum].mo); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 3e698990f..5b5fceec3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9099,14 +9099,12 @@ void P_SpawnPlayer(INT32 playernum) // spawn as spectator determination if (!G_GametypeHasSpectators()) { - if (((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop + p->spectator = p->outofcoop = + (((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop && ((leveltime > 0 && ((G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage - || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->spectator)))) // late join or die in new coop - || ((!cv_cooplives.value || !P_GetLives(p)) && p->lives <= 0))) // game over and can't redistribute lives - p->spectator = true; - else - p->spectator = false; + || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop + || ((!cv_cooplives.value || !P_GetLives(p)) && p->lives <= 0))); // game over and can't redistribute lives } else if (netgame && p->jointime < 1) p->spectator = true; diff --git a/src/p_user.c b/src/p_user.c index 736e514dd..427023048 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8214,7 +8214,8 @@ static void P_ConsiderAllGone(void) if (i == MAXPLAYERS && lastdeadplayer != -1 && deadtimercheck > 2*TICRATE) // the last killed player will reset the level in G_DoReborn { - players[lastdeadplayer].spectator = true; + //players[lastdeadplayer].spectator = true; + players[lastdeadplayer].outofcoop = true; players[lastdeadplayer].playerstate = PST_REBORN; } } @@ -8287,7 +8288,8 @@ static void P_DeathThink(player_t *player) P_ConsiderAllGone(); if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))) { - player->spectator = true; + //player->spectator = true; + player->outofcoop = true; player->playerstate = PST_REBORN; } } @@ -8352,7 +8354,8 @@ static void P_DeathThink(player_t *player) if (gametype == GT_COOP && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) { - player->spectator = true; + //player->spectator = true; + player->outofcoop = true; player->playerstate = PST_REBORN; } @@ -9099,7 +9102,7 @@ boolean P_SpectatorJoinGame(player_t *player) P_RemoveMobj(player->mo); player->mo = NULL; } - player->spectator = false; + player->spectator = player->outofcoop = false; player->playerstate = PST_REBORN; if (gametype == GT_TAG) From 2fd6a20be088f0f0f2e694e073f5d0d314d7ff1d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 3 Jul 2017 16:33:52 +0100 Subject: [PATCH 30/61] * Fix some HUD offsets. * Don't attempt to respawn anybody when changing cv_coopstarposts and nobody CAN be respawned. * Make Rings transparent (and not flash) when you're a spectator. --- src/d_netcmd.c | 17 +++++++++++++++++ src/st_stuff.c | 52 +++++++++++++++++++++++++------------------------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 692f6b714..57a8e1d64 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3456,6 +3456,23 @@ static void CoopStarposts_OnChange(void) if (G_IsSpecialStage(gamemap)) return; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (!players[i].spectator) + continue; + + if (players[i].lives <= 0) + continue; + + break; + } + + if (i == MAXPLAYERS) + return; + for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) diff --git a/src/st_stuff.c b/src/st_stuff.c index 938207cbb..231715bca 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -501,12 +501,12 @@ static INT32 SCR(INT32 r) #define ST_DrawPaddedOverlayNum(x,y,n,d) V_DrawPaddedTallNum(x, y, V_NOSCALESTART|V_HUDTRANS, n, d) #define ST_DrawOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_NOSCALESTART|V_HUDTRANS, p) #define ST_DrawMappedOverlayPatch(x,y,p,c) V_DrawMappedScaledPatch(x, y, V_NOSCALESTART|V_HUDTRANS, p, c) -#define ST_DrawNumFromHud(h,n) V_DrawTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|V_HUDTRANS, n) -#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|V_HUDTRANS, n, q) -#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|V_HUDTRANS, p) -#define ST_DrawNumFromHudWS(h,n) V_DrawTallNum(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|V_HUDTRANS, n) -#define ST_DrawPadNumFromHudWS(h,n,q) V_DrawPaddedTallNum(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|V_HUDTRANS, n, q) -#define ST_DrawPatchFromHudWS(h,p) V_DrawScaledPatch(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|V_HUDTRANS, p) +#define ST_DrawNumFromHud(h,n,f) V_DrawTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|f, n) +#define ST_DrawPadNumFromHud(h,n,q,f) V_DrawPaddedTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|f, n, q) +#define ST_DrawPatchFromHud(h,p,f) V_DrawScaledPatch(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|f, p) +#define ST_DrawNumFromHudWS(h,n,f) V_DrawTallNum(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|f, n) +#define ST_DrawPadNumFromHudWS(h,n,q,f) V_DrawPaddedTallNum(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|f, n, q) +#define ST_DrawPatchFromHudWS(h,p,f) V_DrawScaledPatch(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|f, p) // Draw a number, scaled, over the view, maybe with set translucency // Always draw the number completely since it's overlay @@ -618,16 +618,16 @@ static void ST_drawDebugInfo(void) static void ST_drawScore(void) { // SCORE: - ST_DrawPatchFromHud(HUD_SCORE, sboscore); + ST_DrawPatchFromHud(HUD_SCORE, sboscore, V_HUDTRANS); if (objectplacing) { if (op_displayflags > UINT16_MAX) ST_DrawOverlayPatch(SCX(hudinfo[HUD_SCORENUM].x-tallminus->width), SCY(hudinfo[HUD_SCORENUM].y), tallminus); else - ST_DrawNumFromHud(HUD_SCORENUM, op_displayflags); + ST_DrawNumFromHud(HUD_SCORENUM, op_displayflags, V_HUDTRANS); } else - ST_DrawNumFromHud(HUD_SCORENUM, stplyr->score); + ST_DrawNumFromHud(HUD_SCORENUM, stplyr->score,V_HUDTRANS); } static void ST_drawTime(void) @@ -635,7 +635,7 @@ static void ST_drawTime(void) INT32 seconds, minutes, tictrn, tics; // TIME: - ST_DrawPatchFromHudWS(HUD_TIME, sbotime); + ST_DrawPatchFromHudWS(HUD_TIME, sbotime, V_HUDTRANS); if (objectplacing) { @@ -653,17 +653,17 @@ static void ST_drawTime(void) } if (cv_timetic.value == 1) // Tics only -- how simple is this? - ST_DrawNumFromHudWS(HUD_SECONDS, tics); + ST_DrawNumFromHudWS(HUD_SECONDS, tics, V_HUDTRANS); else { - ST_DrawNumFromHudWS(HUD_MINUTES, minutes); // Minutes - ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon); // Colon - ST_DrawPadNumFromHudWS(HUD_SECONDS, seconds, 2); // Seconds + ST_DrawNumFromHudWS(HUD_MINUTES, minutes, V_HUDTRANS); // Minutes + ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon + ST_DrawPadNumFromHudWS(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds if (!splitscreen && (cv_timetic.value == 2 || modeattacking)) // there's not enough room for tics in splitscreen, don't even bother trying! { - ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period - ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics + ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod, V_HUDTRANS); // Period + ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2, V_HUDTRANS); // Tics } } } @@ -672,7 +672,7 @@ static inline void ST_drawRings(void) { INT32 ringnum = max(stplyr->rings, 0); - ST_DrawPatchFromHudWS(HUD_RINGS, ((stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings)); + ST_DrawPatchFromHudWS(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); if (objectplacing) ringnum = op_currentdoomednum; @@ -685,7 +685,7 @@ static inline void ST_drawRings(void) ringnum += players[i].rings; } - ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum); + ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); } static void ST_drawLives(void) @@ -1689,21 +1689,21 @@ static inline void ST_drawTeamName(void) static void ST_drawSpecialStageHUD(void) { if (totalrings > 0) - ST_DrawNumFromHudWS(HUD_SS_TOTALRINGS, totalrings); + ST_DrawNumFromHudWS(HUD_SS_TOTALRINGS, totalrings, V_HUDTRANS); if (leveltime < 5*TICRATE && totalrings > 0) { - ST_DrawPatchFromHud(HUD_GETRINGS, getall); - ST_DrawNumFromHud(HUD_GETRINGSNUM, totalrings); + ST_DrawPatchFromHud(HUD_GETRINGS, getall, V_HUDTRANS); + ST_DrawNumFromHud(HUD_GETRINGSNUM, totalrings, V_HUDTRANS); } if (sstimer) { V_DrawString(hudinfo[HUD_TIMELEFT].x, STRINGY(hudinfo[HUD_TIMELEFT].y), V_HUDTRANS, M_GetText("TIME LEFT")); - ST_DrawNumFromHud(HUD_TIMELEFTNUM, sstimer/TICRATE); + ST_DrawNumFromHud(HUD_TIMELEFTNUM, sstimer/TICRATE, V_HUDTRANS); } else - ST_DrawPatchFromHud(HUD_TIMEUP, timeup); + ST_DrawPatchFromHud(HUD_TIMEUP, timeup, V_HUDTRANS); } static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offset) @@ -1896,7 +1896,7 @@ static void ST_overlayDrawer(void) } if (p) - V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, STRINGY(BASEVIDHEIGHT/2 - (SHORT(p->height)/2)), (stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p); + V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, STRINGY(BASEVIDHEIGHT/2 - (SHORT(p->height)/2)) - (splitscreen ? 4 : 0), (stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p); } @@ -2006,7 +2006,7 @@ static void ST_overlayDrawer(void) #endif ) { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60)+(splitscreen ? 4 : 0), V_HUDTRANSHALF, M_GetText("You are a spectator.")); + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), V_HUDTRANSHALF, M_GetText("You are a spectator.")); if (G_GametypeHasTeams()) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); else if (G_IsSpecialStage(gamemap) && useNightsSS) @@ -2041,7 +2041,7 @@ static void ST_overlayDrawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); } else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(128), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(136), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); } } From bc066a16a0c4c52b7a8316b71f058a9250ca8945 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 13:17:29 +0100 Subject: [PATCH 31/61] Whoops, I did some menu stuff in here. Oh well. NEW COOP BASED: * Add "Infinite" option to cv_cooplives, inspired by SUBARASHII. Lives still exist, but are hidden from the player's view, and are prevented from falling below 1 at any cost. As a result, made the variable CV_CHEAT. OTHER MULTIPLAYER BASED (semi-related): * Made cv_autobalance an on/off switch which determines the allowed difference based on the number of people in the server, instead of a weird and opaque number from 0-4. MENU BASED (not related): * Add horizontal arrows to menu options which respond to the arrow keys. * Make the menu arrows bob. * Switch out the seperate arrows for combination arrows on the joystick menus. * Minor cvar description tweaks. --- src/d_netcmd.c | 25 ++++--- src/g_game.c | 6 +- src/hu_stuff.h | 2 +- src/m_menu.c | 188 +++++++++++++++++++++++++++++++++++-------------- src/p_inter.c | 6 +- src/p_mobj.c | 2 +- src/p_tick.c | 5 +- src/p_user.c | 20 ++++-- src/st_stuff.c | 18 +++-- 9 files changed, 186 insertions(+), 86 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 57a8e1d64..36f428b13 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -187,7 +187,6 @@ static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"}, #define usejoystick_cons_t NULL #endif -static CV_PossibleValue_t autobalance_cons_t[] = {{0, "MIN"}, {4, "MAX"}, {0, NULL}}; static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}}; static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; @@ -305,7 +304,7 @@ consvar_t cv_countdowntime = {"countdowntime", "60", CV_NETVAR|CV_CHEAT, minitim consvar_t cv_touchtag = {"touchtag", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_hidetime = {"hidetime", "30", CV_NETVAR|CV_CALL, minitimelimit_cons_t, Hidetime_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_autobalance = {"autobalance", "0", CV_NETVAR|CV_CALL, autobalance_cons_t, AutoBalance_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_autobalance = {"autobalance", "Off", CV_NETVAR|CV_CALL, CV_OnOff, AutoBalance_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_teamscramble = {"teamscramble", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, teamscramble_cons_t, TeamScramble_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_scrambleonchange = {"scrambleonchange", "Off", CV_NETVAR, teamscramble_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -355,8 +354,8 @@ consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NUL static CV_PossibleValue_t coopstarposts_cons_t[] = {{0, "Individual"}, {1, "Sharing"}, {2, "Together"}, {0, NULL}}; consvar_t cv_coopstarposts = {"coopstarposts", "Together", CV_NETVAR|CV_CALL|CV_CHEAT, coopstarposts_cons_t, CoopStarposts_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t cooplives_cons_t[] = {{0, "Individual"}, {1, "Stealing"}, {2, "Sharing"}, {0, NULL}}; -consvar_t cv_cooplives = {"cooplives", "Stealing", CV_NETVAR|CV_CALL, cooplives_cons_t, CoopLives_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t cooplives_cons_t[] = {{0, "Infinite"}, {1, "Individual"}, {2, "Stealing"}, {3, "Sharing"}, {0, NULL}}; +consvar_t cv_cooplives = {"cooplives", "Stealing", CV_NETVAR|CV_CALL|CV_CHEAT, cooplives_cons_t, CoopLives_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3481,7 +3480,7 @@ static void CoopStarposts_OnChange(void) if (!players[i].spectator) continue; - if (players[i].lives <= 0 && !cv_cooplives.value) + if (players[i].lives <= 0 && (cv_cooplives.value == 1)) continue; P_SpectatorJoinGame(&players[i]); @@ -3498,12 +3497,15 @@ static void CoopLives_OnChange(void) switch (cv_cooplives.value) { case 0: - CONS_Printf(M_GetText("Lives are now per-player.\n")); + CONS_Printf(M_GetText("Players can now respawn indefinitely.\n")); return; case 1: + CONS_Printf(M_GetText("Lives are now per-player.\n")); + return; + case 2: CONS_Printf(M_GetText("Players can now steal lives to avoid game over.\n")); break; - case 2: + case 3: CONS_Printf(M_GetText("Lives are now shared between players.\n")); break; } @@ -3816,7 +3818,7 @@ retryscramble: { if (red == maxcomposition) newteam = 2; - else if (blue == maxcomposition) + else //if (blue == maxcomposition) newteam = 1; repick = false; @@ -3857,14 +3859,11 @@ retryscramble: newteam = (INT16)((M_RandomByte() % 2) + 1); repick = false; } - else + else if (i != 2) // Mystic's secret sauce - ABBA is better than ABAB, so team B doesn't get worse players all around { // We will only randomly pick the team for the first guy. // Otherwise, just alternate back and forth, distributing players. - if (newteam == 1) - newteam = 2; - else - newteam = 1; + newteam = 3 - newteam; } scrambleteams[i] = newteam; diff --git a/src/g_game.c b/src/g_game.c index b5b0b5f99..db75edd07 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2533,7 +2533,9 @@ void G_DoReborn(INT32 playernum) else if (gametype == GT_COOP && (netgame || multiplayer)) { INT32 i; - if (player->lives <= 0) // consider game over first + if (cv_cooplives.value == 0) + ; + else if (player->lives <= 0) // consider game over first { INT32 deadtimercheck = INT32_MAX; for (i = 0; i < MAXPLAYERS; i++) @@ -2647,7 +2649,7 @@ void G_DoReborn(INT32 playernum) // Not resetting map, so return to level music if (!countdown2 && player->lives <= 0 - && !cv_cooplives.value) // not allowed for life steal because no way to come back from zero group lives without addons, which should call this anyways + && cv_cooplives.value == 1) // not allowed for life steal because no way to come back from zero group lives without addons, which should call this anyways P_RestoreMultiMusic(player); // first dissasociate the corpse diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 9bfb42912..e757db85a 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -21,7 +21,7 @@ //------------------------------------ // heads up font //------------------------------------ -#define HU_FONTSTART '\x19' // the first font character +#define HU_FONTSTART '\x16' // the first font character #define HU_FONTEND '~' #define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1) diff --git a/src/m_menu.c b/src/m_menu.c index 0b601a3de..7dc943662 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -922,7 +922,7 @@ static menuitem_t MP_ServerMenu[] = {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 10}, {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 20}, {IT_STRING|IT_CVAR, NULL, "Max Players", &cv_maxplayers, 46}, - {IT_STRING|IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 56}, + {IT_STRING|IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 56}, #endif {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_GameTypeChange, 100}, {IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130}, @@ -1114,23 +1114,23 @@ static menuitem_t OP_ChangeControlsMenu[] = static menuitem_t OP_Joystick1Menu[] = { {IT_STRING | IT_CALL, NULL, "Select Joystick...", M_Setup1PJoystickMenu, 10}, - {IT_STRING | IT_CVAR, NULL, "Move \x1A \x1B Axis" , &cv_moveaxis , 30}, - {IT_STRING | IT_CVAR, NULL, "Move \x1C \x1D Axis" , &cv_sideaxis , 40}, - {IT_STRING | IT_CVAR, NULL, "Camera \x1A \x1B Axis" , &cv_lookaxis , 50}, - {IT_STRING | IT_CVAR, NULL, "Camera \x1C \x1D Axis" , &cv_turnaxis , 60}, - {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis , 70}, - {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis , 80}, + {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis , 30}, + {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis , 40}, + {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis , 50}, + {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis , 60}, + {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis , 70}, + {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis , 80}, }; static menuitem_t OP_Joystick2Menu[] = { {IT_STRING | IT_CALL, NULL, "Select Joystick...", M_Setup2PJoystickMenu, 10}, - {IT_STRING | IT_CVAR, NULL, "Move \x1A \x1B Axis" , &cv_moveaxis2 , 30}, - {IT_STRING | IT_CVAR, NULL, "Move \x1C \x1D Axis" , &cv_sideaxis2 , 40}, - {IT_STRING | IT_CVAR, NULL, "Camera \x1A \x1B Axis" , &cv_lookaxis2 , 50}, - {IT_STRING | IT_CVAR, NULL, "Camera \x1C \x1D Axis" , &cv_turnaxis2 , 60}, - {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis2 , 70}, - {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis2 , 80}, + {IT_STRING | IT_CVAR, NULL, "Move \x17 Axis" , &cv_moveaxis2 , 30}, + {IT_STRING | IT_CVAR, NULL, "Move \x18 Axis" , &cv_sideaxis2 , 40}, + {IT_STRING | IT_CVAR, NULL, "Camera \x17 Axis" , &cv_lookaxis2 , 50}, + {IT_STRING | IT_CVAR, NULL, "Camera \x18 Axis" , &cv_turnaxis2 , 60}, + {IT_STRING | IT_CVAR, NULL, "Fire Axis" , &cv_fireaxis2 , 70}, + {IT_STRING | IT_CVAR, NULL, "Fire Normal Axis" , &cv_firenaxis2 , 80}, }; static menuitem_t OP_JoystickSetMenu[] = @@ -1374,7 +1374,7 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Server name", &cv_servername, 7}, {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21}, - {IT_STRING | IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 26}, + {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26}, {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31}, #endif {IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 36}, @@ -1410,13 +1410,14 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 186}, {IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 191}, - {IT_STRING | IT_CVAR, NULL, "Autobalance Teams", &cv_autobalance, 201}, - {IT_STRING | IT_CVAR, NULL, "Scramble Teams on Map Change", &cv_scrambleonchange, 206}, + {IT_HEADER, NULL, "Teams", NULL, 200}, + {IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 206}, + {IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 211}, #ifndef NONET - {IT_HEADER, NULL, "Advanced", NULL, 215}, - {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 221}, - {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 235}, + {IT_HEADER, NULL, "Advanced", NULL, 220}, + {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 226}, + {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 240}, #endif }; @@ -2952,7 +2953,7 @@ static void M_DrawThermo(INT32 x, INT32 y, consvar_t *cv) } // A smaller 'Thermo', with range given as percents (0-100) -static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv) +static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop) { INT32 i; INT32 range; @@ -2966,6 +2967,14 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv) for (i = 1; i < SLIDER_RANGE; i++) V_DrawScaledPatch (x+i*8, y, 0,p); + if (ontop) + { + V_DrawCharacter(x - 6 - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(x+i*8 + 8 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } + p = W_CachePatchName("M_SLIDER", PU_CACHE); V_DrawScaledPatch(x+i*8, y, 0, p); @@ -3215,7 +3224,7 @@ static void M_DrawGenericMenu(void) switch (currentMenu->menuitems[i].status & IT_CVARTYPE) { case IT_CV_SLIDER: - M_DrawSlider(x, y, cv); + M_DrawSlider(x, y, cv, (i == itemOn)); case IT_CV_NOPRINT: // color use this case IT_CV_INVISSLIDER: // monitor toggles use this break; @@ -3230,6 +3239,13 @@ static void M_DrawGenericMenu(void) default: V_DrawRightAlignedString(BASEVIDWIDTH - x, y, ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? V_REDMAP : V_YELLOWMAP), cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } break; } break; @@ -3324,9 +3340,9 @@ static void M_DrawGenericScrollMenu(void) } if (i) - V_DrawString(currentMenu->x - 20, currentMenu->y, V_YELLOWMAP, "\x1A"); // up arrow + V_DrawString(currentMenu->x - 20, currentMenu->y - (skullAnimCounter/5), V_YELLOWMAP, "\x1A"); // up arrow if (max != bottom) - V_DrawString(currentMenu->x - 20, currentMenu->y + 2*scrollareaheight, V_YELLOWMAP, "\x1B"); // down arrow + V_DrawString(currentMenu->x - 20, currentMenu->y + 2*scrollareaheight + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); // down arrow // draw title (or big pic) M_DrawMenuTitle(); @@ -3364,7 +3380,7 @@ static void M_DrawGenericScrollMenu(void) switch (currentMenu->menuitems[i].status & IT_CVARTYPE) { case IT_CV_SLIDER: - M_DrawSlider(x, y, cv); + M_DrawSlider(x, y, cv, (i == itemOn)); case IT_CV_NOPRINT: // color use this case IT_CV_INVISSLIDER: // monitor toggles use this break; @@ -3393,6 +3409,13 @@ static void M_DrawGenericScrollMenu(void) default: V_DrawRightAlignedString(BASEVIDWIDTH - x, y, ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? V_REDMAP : V_YELLOWMAP), cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } break; } break; @@ -3620,7 +3643,7 @@ static void M_DrawCenteredMenu(void) switch(currentMenu->menuitems[i].status & IT_CVARTYPE) { case IT_CV_SLIDER: - M_DrawSlider(x, y, cv); + M_DrawSlider(x, y, cv, (i == itemOn)); case IT_CV_NOPRINT: // color use this break; case IT_CV_STRING: @@ -3634,6 +3657,13 @@ static void M_DrawCenteredMenu(void) default: V_DrawString(BASEVIDWIDTH - x - V_StringWidth(cv->string, 0), y, ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? V_REDMAP : V_YELLOWMAP), cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } break; } break; @@ -4834,13 +4864,21 @@ static void M_HandleChecklist(INT32 choice) { case KEY_DOWNARROW: S_StartSound(NULL, sfx_menu1); - if (checklist_cangodown) + if ((check_on != MAXUNLOCKABLES) && checklist_cangodown) { for (j = check_on+1; j < MAXUNLOCKABLES; j++) { - if (!(unlockables[j].name[0] == 0 //|| unlockables[j].nochecklist - || !unlockables[j].conditionset || unlockables[j].conditionset > MAXCONDITIONSETS)) - break; + if (!unlockables[j].name[0]) + continue; + // if (unlockables[j].nochecklist) + // continue; + if (!unlockables[j].conditionset) + continue; + if (unlockables[j].conditionset > MAXCONDITIONSETS) + continue; + if (unlockables[j].conditionset == unlockables[check_on].conditionset) + continue; + break; } if (j != MAXUNLOCKABLES) check_on = j; @@ -4849,14 +4887,25 @@ static void M_HandleChecklist(INT32 choice) case KEY_UPARROW: S_StartSound(NULL, sfx_menu1); - for (j = check_on-1; j > -1; j--) + if (check_on) { - if (!(unlockables[j].name[0] == 0 //|| unlockables[j].nochecklist - || !unlockables[j].conditionset || unlockables[j].conditionset > MAXCONDITIONSETS)) + for (j = check_on-1; j > -1; j--) + { + if (!unlockables[j].name[0]) + continue; + // if (unlockables[j].nochecklist) + // continue; + if (!unlockables[j].conditionset) + continue; + if (unlockables[j].conditionset > MAXCONDITIONSETS) + continue; + if (j && unlockables[j].conditionset == unlockables[j-1].conditionset) + continue; break; + } + if (j != -1) + check_on = j; } - if (j != -1) - check_on = j; return; case KEY_ESCAPE: @@ -4882,7 +4931,7 @@ static void M_DrawChecklist(void) M_DrawMenuTitle(); if (check_on) - V_DrawString(10, y, V_YELLOWMAP, "\x1A"); + V_DrawString(10, y-(skullAnimCounter/5), V_YELLOWMAP, "\x1A"); while (i < MAXUNLOCKABLES) { @@ -5141,7 +5190,7 @@ static void M_DrawChecklist(void) finishchecklist: if ((checklist_cangodown = ((y - currentMenu->y) > (scrollareaheight*2)))) // haaaaaaacks. { - V_DrawString(10, currentMenu->y+(scrollareaheight*2), V_YELLOWMAP, "\x1B"); + V_DrawString(10, currentMenu->y+(scrollareaheight*2)+(skullAnimCounter/5), V_YELLOWMAP, "\x1B"); } } @@ -6173,7 +6222,7 @@ static void M_DrawStatsMaps(int location) boolean dotopname = true, dobottomarrow = (location < statsMax); if (location) - V_DrawString(10, y, V_YELLOWMAP, "\x1A"); + V_DrawString(10, y-(skullAnimCounter/5), V_YELLOWMAP, "\x1A"); while (statsMapList[++i] != -1) { @@ -6250,7 +6299,7 @@ static void M_DrawStatsMaps(int location) } bottomarrow: if (dobottomarrow) - V_DrawString(10, y-8, V_YELLOWMAP, "\x1B"); + V_DrawString(10, y-8 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); } static void M_DrawLevelStats(void) @@ -6419,6 +6468,13 @@ void M_DrawTimeAttackMenu(void) // Should see nothing but strings V_DrawString(BASEVIDWIDTH - x - soffset - V_StringWidth(cv->string, 0), y, V_YELLOWMAP, cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } } } @@ -6601,6 +6657,13 @@ void M_DrawNightsAttackMenu(void) // Should see nothing but strings V_DrawString(BASEVIDWIDTH - x - soffset - V_StringWidth(cv->string, 0), y, V_YELLOWMAP, cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } } } @@ -7471,10 +7534,10 @@ static void M_ServerOptions(INT32 choice) { OP_ServerOptionsMenu[ 1].status = IT_GRAYEDOUT; // Server name OP_ServerOptionsMenu[ 2].status = IT_GRAYEDOUT; // Max players - OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow WAD downloading + OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join - OP_ServerOptionsMenu[33].status = IT_GRAYEDOUT; // Master server - OP_ServerOptionsMenu[34].status = IT_GRAYEDOUT; // Attempts to resynchronise + OP_ServerOptionsMenu[34].status = IT_GRAYEDOUT; // Master server + OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Attempts to resynchronise } else { @@ -7482,11 +7545,10 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[ 2].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[ 3].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[ 4].status = IT_STRING | IT_CVAR; - if (netgame) - OP_ServerOptionsMenu[33].status = IT_GRAYEDOUT; - else - OP_ServerOptionsMenu[33].status = IT_STRING | IT_CVAR | IT_CV_STRING; - OP_ServerOptionsMenu[34].status = IT_STRING | IT_CVAR; + OP_ServerOptionsMenu[34].status = (netgame + ? IT_GRAYEDOUT + : (IT_STRING | IT_CVAR | IT_CV_STRING)); + OP_ServerOptionsMenu[35].status = IT_STRING | IT_CVAR; } #endif @@ -8137,9 +8199,9 @@ static void M_DrawControl(void) "PRESS ENTER TO CHANGE, BACKSPACE TO CLEAR")); if (i) - V_DrawString(currentMenu->x - 16, y, V_YELLOWMAP, "\x1A"); // up arrow + V_DrawString(currentMenu->x - 16, y-(skullAnimCounter/5), V_YELLOWMAP, "\x1A"); // up arrow if (max != currentMenu->numitems) - V_DrawString(currentMenu->x - 16, y+(SMALLLINEHEIGHT*(controlheight-1)), V_YELLOWMAP, "\x1B"); // down arrow + V_DrawString(currentMenu->x - 16, y+(SMALLLINEHEIGHT*(controlheight-1))+(skullAnimCounter/5), V_YELLOWMAP, "\x1B"); // down arrow for (; i < max; i++) { @@ -8292,6 +8354,7 @@ void M_DrawSoundMenu(void) { const char* onstring = "ON"; const char* offstring = "OFF"; + INT32 lengthstring; M_DrawGenericMenu(); V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, @@ -8308,6 +8371,20 @@ void M_DrawSoundMenu(void) currentMenu->y+currentMenu->menuitems[4].alphaKey, (nomidimusic ? V_REDMAP : V_YELLOWMAP), ((nomidimusic || music_disabled) ? offstring : onstring)); + + if (itemOn == 0) + lengthstring = ((nosound || sound_disabled) ? 3 : 2); + else if (itemOn == 2) + lengthstring = ((nodigimusic || digital_disabled) ? 3 : 2); + else if (itemOn == 4) + lengthstring = ((nomidimusic || music_disabled) ? 3 : 2); + else + return; + + V_DrawCharacter(BASEVIDWIDTH - currentMenu->x - 10 - (lengthstring*8) - (skullAnimCounter/5), currentMenu->y+currentMenu->menuitems[itemOn].alphaKey, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - currentMenu->x + 2 + (skullAnimCounter/5), currentMenu->y+currentMenu->menuitems[itemOn].alphaKey, + '\x1D' | V_YELLOWMAP, false); } // Toggles sound systems in-game. @@ -8681,9 +8758,9 @@ static void M_DrawColorMenu(void) } if (i) - V_DrawString(currentMenu->x - 20, currentMenu->y, V_YELLOWMAP, "\x1A"); // up arrow + V_DrawString(currentMenu->x - 20, currentMenu->y - (skullAnimCounter/5), V_YELLOWMAP, "\x1A"); // up arrow if (max != currentMenu->numitems) - V_DrawString(currentMenu->x - 20, currentMenu->y + 2*scrollareaheight, V_YELLOWMAP, "\x1B"); // down arrow + V_DrawString(currentMenu->x - 20, currentMenu->y + 2*scrollareaheight + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); // down arrow // draw title (or big pic) M_DrawMenuTitle(); @@ -8721,7 +8798,7 @@ static void M_DrawColorMenu(void) switch (currentMenu->menuitems[i].status & IT_CVARTYPE) { case IT_CV_SLIDER: - M_DrawSlider(x, y, cv); + M_DrawSlider(x, y, cv, (i == itemOn)); case IT_CV_NOPRINT: // color use this case IT_CV_INVISSLIDER: // monitor toggles use this break; @@ -8738,6 +8815,13 @@ static void M_DrawColorMenu(void) default: V_DrawRightAlignedString(BASEVIDWIDTH - x, y, ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? V_REDMAP : V_YELLOWMAP), cv->string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } break; } break; @@ -8880,7 +8964,7 @@ static void M_DrawMonitorToggles(void) continue; y = currentMenu->y + currentMenu->menuitems[i].alphaKey; - M_DrawSlider(currentMenu->x + 20, y, cv); + M_DrawSlider(currentMenu->x + 20, y, cv, (i == itemOn)); if (!cv->value) V_DrawRightAlignedString(312, y, V_OLDSPACING|((i == itemOn) ? V_YELLOWMAP : 0), "None"); diff --git a/src/p_inter.c b/src/p_inter.c index 5f730bd6c..1f7b22425 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2246,7 +2246,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; P_SetThingPosition(target); - if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) + if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0)) + ; + else if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives()) { target->player->lives -= 1; // Lose a life Tails 03-11-2000 @@ -2254,7 +2256,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->player->lives <= 0) // Tails 03-14-2000 { boolean gameovermus = false; - if ((netgame || multiplayer) && (gametype == GT_COOP) && cv_cooplives.value) + if ((netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value != 1)) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5b5fceec3..d67d2631f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9104,7 +9104,7 @@ void P_SpawnPlayer(INT32 playernum) && ((leveltime > 0 && ((G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop - || ((!cv_cooplives.value || !P_GetLives(p)) && p->lives <= 0))); // game over and can't redistribute lives + || (((cv_cooplives.value == 1) || !P_GetLives(p)) && p->lives <= 0))); // game over and can't redistribute lives } else if (netgame && p->jointime < 1) p->spectator = true; diff --git a/src/p_tick.c b/src/p_tick.c index 5235a1a03..1ef91ca82 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -359,7 +359,7 @@ static void P_DoAutobalanceTeams(void) totalred = red + redflagcarrier; totalblue = blue + blueflagcarrier; - if ((abs(totalred - totalblue) > cv_autobalance.value)) + if ((abs(totalred - totalblue) > max(1, (totalred + totalblue) / 8))) { if (totalred > totalblue) { @@ -372,8 +372,7 @@ static void P_DoAutobalanceTeams(void) usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); } - - if (totalblue > totalred) + else //if (totalblue > totalred) { i = M_RandomKey(blue); NetPacket.packet.newteam = 1; diff --git a/src/p_user.c b/src/p_user.c index 427023048..58e168a69 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8146,20 +8146,26 @@ void P_FindEmerald(void) // // P_GetLives -// Steal lives if you're allowed to. +// Get extra lives in new co-op if you're allowed to. // boolean P_GetLives(player_t *player) { INT32 i, maxlivesplayer = -1, livescheck = 1; - if (!(cv_cooplives.value - && (gametype == GT_COOP) - && (netgame || multiplayer))) + if (!(netgame || multiplayer) + || (gametype != GT_COOP) + || (cv_cooplives.value == 1)) return true; - if (cv_cooplives.value == 1 && player->lives > 0) + if ((cv_cooplives.value == 2 || cv_cooplives.value == 0) && player->lives > 0) return true; + if (cv_cooplives.value == 0) // infinite lives + { + player->lives++; + return true; + } + for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) @@ -8173,7 +8179,7 @@ boolean P_GetLives(player_t *player) } if (maxlivesplayer != -1 && &players[maxlivesplayer] != player) { - if (cv_cooplives.value == 1 && P_IsLocalPlayer(&players[maxlivesplayer])) + if (cv_cooplives.value == 2 && P_IsLocalPlayer(&players[maxlivesplayer])) S_StartSound(NULL, sfx_jshard); // placeholder players[maxlivesplayer].lives--; player->lives++; @@ -8263,7 +8269,7 @@ static void P_DeathThink(player_t *player) G_UseContinue(); // Even if we don't have one this handles ending the game } - if (cv_cooplives.value + if ((cv_cooplives.value != 1) && (gametype == GT_COOP) && (netgame || multiplayer) && (player->lives <= 0)) diff --git a/src/st_stuff.c b/src/st_stuff.c index 231715bca..9c43534be 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -734,7 +734,10 @@ static void ST_drawLives(void) { switch (cv_cooplives.value) { - case 2: + case 0: + V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, false); + return; + case 3: { INT32 i, sum = 0; for (i = 0; i < MAXPLAYERS; i++) @@ -752,7 +755,7 @@ static void ST_drawLives(void) va("%d",(sum))); return; } - case 1: + case 2: { INT32 i, sum = 0; for (i = 0; i < MAXPLAYERS; i++) @@ -1866,7 +1869,11 @@ static void ST_overlayDrawer(void) } // GAME OVER pic - if (G_GametypeUsesLives() && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) + if ((gametype == GT_COOP) + && (netgame || multiplayer) + && (cv_cooplives.value == 0)) + ; + else if (G_GametypeUsesLives() && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) { patch_t *p; @@ -1875,8 +1882,9 @@ static void ST_overlayDrawer(void) else p = sboover; - if (cv_cooplives.value - && gametype == GT_COOP) + if ((gametype == GT_COOP) + && (netgame || multiplayer) + && (cv_cooplives.value != 1)) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) From a65598a97af67b65b3cde1cd8fd4ec9bcb3c9161 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 14:57:22 +0100 Subject: [PATCH 32/61] Fixed Game Over being broken in singleplayer. Woopsie doodle! --- src/g_game.c | 2 +- src/p_user.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index db75edd07..11ae16394 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2528,7 +2528,7 @@ void G_DoReborn(INT32 playernum) return; } - if (countdowntimeup || (!multiplayer && gametype == GT_COOP)) + if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP)) resetlevel = true; else if (gametype == GT_COOP && (netgame || multiplayer)) { diff --git a/src/p_user.c b/src/p_user.c index 58e168a69..86359cd83 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8358,7 +8358,7 @@ static void P_DeathThink(player_t *player) //else if (gametype == GT_COOP) -- moved to G_DoReborn } - if (gametype == GT_COOP && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) + if (gametype == GT_COOP && (multiplayer || netgame) && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) { //player->spectator = true; player->outofcoop = true; From dad6ce979650235c14ef65a7a17ed9a96c49804e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 14:58:58 +0100 Subject: [PATCH 33/61] * Tweaked some monitor toggle names I forgot to modify. * Added arrows to the "sky room" menu. --- src/m_menu.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 7dc943662..4867806ef 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1426,11 +1426,11 @@ static menuitem_t OP_MonitorToggleMenu[] = // Printing handled by drawing function {IT_STRING|IT_CALL, NULL, "Reset to defaults", M_ResetCvars, 15}, {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Recycler", &cv_recycler, 30}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Teleporters", &cv_teleporters, 40}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Teleport", &cv_teleporters, 40}, {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Super Ring", &cv_superring, 50}, {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Super Sneakers", &cv_supersneakers, 60}, {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Invincibility", &cv_invincibility, 70}, - {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Jump Shield", &cv_jumpshield, 80}, + {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Whirlwind Shield", &cv_jumpshield, 80}, {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Elemental Shield", &cv_watershield, 90}, {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Attraction Shield", &cv_ringshield, 100}, {IT_STRING|IT_CVAR|IT_CV_INVISSLIDER, NULL, "Force Shield", &cv_forceshield, 110}, @@ -5262,6 +5262,13 @@ static void M_DrawSkyRoom(void) return; V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + y, V_YELLOWMAP, cv_soundtest.string); + if (i == itemOn) + { + V_DrawCharacter(BASEVIDWIDTH - currentMenu->x - 10 - V_StringWidth(cv_soundtest.string, 0) - (skullAnimCounter/5), currentMenu->y + y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - currentMenu->x + 2 + (skullAnimCounter/5), currentMenu->y + y, + '\x1D' | V_YELLOWMAP, false); + } if (cv_soundtest.value) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + y + 8, V_YELLOWMAP, S_sfx[cv_soundtest.value].name); } From e5eb6720f0ee1a23b83cb55c7b3416df52a83b6c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 14:58:58 +0100 Subject: [PATCH 34/61] Change how countdowns are presented. I would have changed how they actually worked, too, but I ended up breaking it and getting too frustrated/tired to continue. --- src/st_stuff.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 9c43534be..aeee7d15c 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -68,6 +68,7 @@ static patch_t *sboover; static patch_t *timeover; static patch_t *stlivex; static patch_t *sboredrings; +static patch_t *sboredtime; static patch_t *getall; // Special Stage HUD static patch_t *timeup; // Special Stage HUD static patch_t *hunthoming[6]; @@ -251,6 +252,7 @@ void ST_LoadGraphics(void) sboredrings = W_CachePatchName("STTRRING", PU_HUDGFX); sboscore = W_CachePatchName("STTSCORE", PU_HUDGFX); sbotime = W_CachePatchName("STTTIME", PU_HUDGFX); // Time logo + sboredtime = W_CachePatchName("STTRTIME", PU_HUDGFX); sbocolon = W_CachePatchName("STTCOLON", PU_HUDGFX); // Colon for time sboperiod = W_CachePatchName("STTPERIO", PU_HUDGFX); // Period for time centiseconds @@ -635,7 +637,7 @@ static void ST_drawTime(void) INT32 seconds, minutes, tictrn, tics; // TIME: - ST_DrawPatchFromHudWS(HUD_TIME, sbotime, V_HUDTRANS); + ST_DrawPatchFromHudWS(HUD_TIME, ((mapheaderinfo[gamemap-1]->countdown && countdowntimer < 11*TICRATE && leveltime/5 & 1) ? sboredtime : sbotime), V_HUDTRANS); if (objectplacing) { @@ -646,7 +648,7 @@ static void ST_drawTime(void) } else { - tics = stplyr->realtime; + tics = (mapheaderinfo[gamemap-1]->countdown ? countdowntimer : stplyr->realtime); seconds = G_TicsToSeconds(tics); minutes = G_TicsToMinutes(tics, true); tictrn = G_TicsToCentiseconds(tics); From 125646e521f5bffa3ccf67a181557d9019cd6261 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 14:58:58 +0100 Subject: [PATCH 35/61] Some minor tweaks to make countdown not COMPLETELY broken. --- src/g_game.c | 18 ++++++++++-------- src/p_setup.c | 11 +++++++++++ src/p_tick.c | 4 +++- src/p_user.c | 3 --- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 11ae16394..abffed4d2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2499,6 +2499,7 @@ void G_DoReborn(INT32 playernum) { player_t *player = &players[playernum]; boolean resetlevel = false; + INT32 i; if (modeattacking) { @@ -2532,7 +2533,6 @@ void G_DoReborn(INT32 playernum) resetlevel = true; else if (gametype == GT_COOP && (netgame || multiplayer)) { - INT32 i; if (cv_cooplives.value == 0) ; else if (player->lives <= 0) // consider game over first @@ -2588,16 +2588,18 @@ void G_DoReborn(INT32 playernum) // reload the level from scratch if (countdowntimeup) { - player->starpostangle = 0; - player->starposttime = 0; - player->starpostx = 0; - player->starposty = 0; - player->starpostz = 0; - player->starpostnum = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + players[i].starpostangle = 0; + players[i].starposttime = 0; + players[i].starpostx = 0; + players[i].starposty = 0; + players[i].starpostz = 0; + players[i].starpostnum = 0; + } } if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD)) { - INT32 i; player->playerstate = PST_REBORN; P_LoadThingsOnly(); P_ClearStarPost(player->starpostnum); diff --git a/src/p_setup.c b/src/p_setup.c index 3f346523b..49ee5e196 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2199,7 +2199,18 @@ static void P_LevelInitStuff(void) // map time limit if (mapheaderinfo[gamemap-1]->countdown) + { + tic_t maxtime = 0; countdowntimer = mapheaderinfo[gamemap-1]->countdown * TICRATE; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (players[i].starposttime > maxtime) + maxtime = players[i].starposttime; + } + countdowntimer -= maxtime; + } else countdowntimer = 0; countdowntimeup = false; diff --git a/src/p_tick.c b/src/p_tick.c index 1ef91ca82..a79d71ef4 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -650,7 +650,7 @@ void P_Ticker(boolean run) if (run) { - if (countdowntimer && --countdowntimer <= 0) + if (countdowntimer && G_PlatformGametype() && (gametype == GT_COOP || leveltime >= 4*TICRATE) && --countdowntimer <= 0) { countdowntimer = 0; countdowntimeup = true; @@ -662,6 +662,8 @@ void P_Ticker(boolean run) if (!players[i].mo) continue; + if (multiplayer || netgame) + players[i].exiting = 0; P_DamageMobj(players[i].mo, NULL, NULL, 1, DMG_INSTAKILL); } } diff --git a/src/p_user.c b/src/p_user.c index 86359cd83..21db4143b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6690,9 +6690,6 @@ static void P_MovePlayer(player_t *player) fixed_t runspd; - if (countdowntimeup) - return; - if (player->mo->state >= &states[S_PLAY_SUPER_TRANS] && player->mo->state <= &states[S_PLAY_SUPER_TRANS9]) { player->mo->momx = player->mo->momy = player->mo->momz = 0; From fa42875aee72c8d82dc97bd99218034ea0d8fa06 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 14:58:58 +0100 Subject: [PATCH 36/61] Better setting names/values for various new and old console variables impacted by this branch. --- src/d_netcmd.c | 14 +++++++------- src/m_menu.c | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 36f428b13..880d5d770 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -191,10 +191,10 @@ static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2 static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; static CV_PossibleValue_t sleeping_cons_t[] = {{-1, "MIN"}, {1000/TICRATE, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, //{2, "Teleports"}, +static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Unknown"}, //{2, "Teleport"}, {3, "None"}, {0, NULL}}; -static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Non-Random"}, +static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Unknown"}, {2, "Never changing"}, {3, "None"}, {0, NULL}}; static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}}; @@ -216,7 +216,7 @@ consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT, starting static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; consvar_t cv_respawntime = {"respawndelay", "3", CV_NETVAR|CV_CHEAT, respawntime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_competitionboxes = {"competitionboxes", "Random", CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_competitionboxes = {"competitionboxes", "Unknown", CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef SEENAMES static CV_PossibleValue_t seenames_cons_t[] = {{0, "Off"}, {1, "Colorless"}, {2, "Team"}, {3, "Ally/Foe"}, {0, NULL}}; @@ -351,11 +351,11 @@ consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NUL static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t coopstarposts_cons_t[] = {{0, "Individual"}, {1, "Sharing"}, {2, "Together"}, {0, NULL}}; -consvar_t cv_coopstarposts = {"coopstarposts", "Together", CV_NETVAR|CV_CALL|CV_CHEAT, coopstarposts_cons_t, CoopStarposts_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t coopstarposts_cons_t[] = {{0, "Per-player"}, {1, "Shared"}, {2, "Teamwork"}, {0, NULL}}; +consvar_t cv_coopstarposts = {"coopstarposts", "Teamwork", CV_NETVAR|CV_CALL|CV_CHEAT, coopstarposts_cons_t, CoopStarposts_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t cooplives_cons_t[] = {{0, "Infinite"}, {1, "Individual"}, {2, "Stealing"}, {3, "Sharing"}, {0, NULL}}; -consvar_t cv_cooplives = {"cooplives", "Stealing", CV_NETVAR|CV_CALL|CV_CHEAT, cooplives_cons_t, CoopLives_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t cooplives_cons_t[] = {{0, "Infinite"}, {1, "Per-player"}, {2, "Avoid Game Over"}, {3, "Single pool"}, {0, NULL}}; +consvar_t cv_cooplives = {"cooplives", "Avoid Game Over", CV_NETVAR|CV_CALL|CV_CHEAT, cooplives_cons_t, CoopLives_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/m_menu.c b/src/m_menu.c index 4867806ef..6e3c3e9d4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1386,16 +1386,16 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_HEADER, NULL, "Items", NULL, 70}, {IT_STRING | IT_CVAR, NULL, "Item respawn delay", &cv_itemrespawntime, 76}, - {IT_STRING | IT_SUBMENU, NULL, "Random Item Box Toggles...", &OP_MonitorToggleDef, 81}, + {IT_STRING | IT_SUBMENU, NULL, "Unknown Item Monitor Toggles...", &OP_MonitorToggleDef, 81}, {IT_HEADER, NULL, "Cooperative", NULL, 90}, {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96}, {IT_STRING | IT_CVAR, NULL, "Starposts", &cv_coopstarposts, 101}, - {IT_STRING | IT_CVAR, NULL, "Life distribution", &cv_cooplives, 106}, + {IT_STRING | IT_CVAR, NULL, "Life sharing", &cv_cooplives, 106}, {IT_HEADER, NULL, "Race, Competition", NULL, 115}, {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 121}, - {IT_STRING | IT_CVAR, NULL, "Item Boxes", &cv_competitionboxes, 126}, + {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_competitionboxes, 126}, {IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 135}, {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 141}, @@ -1403,7 +1403,7 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 151}, {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 156}, - {IT_STRING | IT_CVAR, NULL, "Item Boxes", &cv_matchboxes, 166}, + {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_matchboxes, 166}, {IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 171}, {IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 176}, From e55f24419ee3b26f316ffbb7e9aa27281363cb29 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 14:58:58 +0100 Subject: [PATCH 37/61] Additional opportunity for F12 message exposure pounced upon. --- src/st_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index aeee7d15c..7a145d956 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1993,7 +1993,7 @@ static void ST_overlayDrawer(void) if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer) { - if (!splitscreen && gametype != GT_COOP && G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) + if (!splitscreen && ((stplyr->exiting && (gametype != GT_COOP || cv_playersforexit.value)) || (gametype != GT_COOP && G_GametypeUsesLives() && stplyr->lives <= 0)) && countdown != 1) V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); else if (gametype == GT_HIDEANDSEEK && (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) From 014c1d8f03117e46fa0d36c58e8bcec0504246f7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 14:58:58 +0100 Subject: [PATCH 38/61] https://cdn.discordapp.com/attachments/297148222332469249/332227405747847168/unknown.png betterexit integration! --- src/d_netcmd.c | 2 +- src/p_user.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 880d5d770..b84d44494 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -359,7 +359,7 @@ consvar_t cv_cooplives = {"cooplives", "Avoid Game Over", CV_NETVAR|CV_CALL|CV_C static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "All"}, {0, NULL}}; +static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "1/4"}, {2, "Half"}, {3, "3/4"}, {4, "All"}, {0, NULL}}; consvar_t cv_playersforexit = {"playersforexit", "One", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_runscripts = {"runscripts", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/p_user.c b/src/p_user.c index 21db4143b..08c1a7724 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9419,7 +9419,7 @@ void P_PlayerThink(player_t *player) { if (cv_playersforexit.value) // Count to be sure everyone's exited { - INT32 i; + INT32 i, total = 0, exiting = 0; for (i = 0; i < MAXPLAYERS; i++) { @@ -9428,11 +9428,12 @@ void P_PlayerThink(player_t *player) if (players[i].lives <= 0) continue; + total++; if (!players[i].exiting || players[i].exiting > 3) - break; + exiting++; } - if (i == MAXPLAYERS) + if (((4*exiting)/total) >= cv_playersforexit.value) { if (server) SendNetXCmd(XD_EXITLEVEL, NULL, 0); From 0bf676498ae9799cef39c7e7467c4a310adbb888 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 14:58:58 +0100 Subject: [PATCH 39/61] woops, the check was accidentially inverted --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 08c1a7724..a6795eadb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9429,7 +9429,7 @@ void P_PlayerThink(player_t *player) continue; total++; - if (!players[i].exiting || players[i].exiting > 3) + if (players[i].exiting && players[i].exiting < 4) exiting++; } From f809923f6984007bb345056f6dd8269b661d536e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 14:58:58 +0100 Subject: [PATCH 40/61] * If cv_playersforexit != "One", add a count of the number of players required to exit to the end tally. * Make the default value of cv_playersforexit "All". * Correct the greying out of the lives counter for cv_cooplives == "Single pool" to only be when you can't respawn. --- src/d_netcmd.c | 2 +- src/st_stuff.c | 40 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b84d44494..fb09718c1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -360,7 +360,7 @@ consvar_t cv_cooplives = {"cooplives", "Avoid Game Over", CV_NETVAR|CV_CALL|CV_C static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "1/4"}, {2, "Half"}, {3, "3/4"}, {4, "All"}, {0, NULL}}; -consvar_t cv_playersforexit = {"playersforexit", "One", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playersforexit = {"playersforexit", "All", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_runscripts = {"runscripts", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/st_stuff.c b/src/st_stuff.c index 7a145d956..db2dcdba0 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -742,6 +742,7 @@ static void ST_drawLives(void) case 3: { INT32 i, sum = 0; + boolean canrespawn = (stplyr->lives > 0); for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) @@ -750,11 +751,14 @@ static void ST_drawLives(void) if (players[i].lives < 1) continue; + if (players[i].lives > 1) + canrespawn = true; + sum += (players[i].lives); } V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|((stplyr->lives > 0) ? V_HUDTRANS : V_HUDTRANSHALF)|v_splitflag, - va("%d",(sum))); + V_SNAPTOLEFT|V_SNAPTOBOTTOM|(canrespawn ? V_HUDTRANS : V_HUDTRANSHALF)|v_splitflag, + va("%d",sum)); return; } case 2: @@ -1993,7 +1997,37 @@ static void ST_overlayDrawer(void) if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer) { - if (!splitscreen && ((stplyr->exiting && (gametype != GT_COOP || cv_playersforexit.value)) || (gametype != GT_COOP && G_GametypeUsesLives() && stplyr->lives <= 0)) && countdown != 1) + if (stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP) + { + INT32 i, total = 0, exiting = 0; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + if (players[i].lives <= 0) + continue; + + total++; + if (players[i].exiting) + exiting++; + } + + total *= cv_playersforexit.value; + if (total % 4) total += 4; // round up + total /= 4; + + if (exiting >= total) + ; + else + { + total -= exiting; + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(124), 0, va(M_GetText("%d more player%s required to exit."), total, ((total == 1) ? "" : "s"))); + if (!splitscreen) + V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); + } + } + else if (!splitscreen && gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); else if (gametype == GT_HIDEANDSEEK && (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) From 1a7a0662ba43b9493013f80fb9a09b84f38a17f1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 4 Jul 2017 14:58:58 +0100 Subject: [PATCH 41/61] * Set player->outofcoop to false if it's not a coop gametype. * Expose player->outofcoop to Lua. --- src/lua_playerlib.c | 4 ++++ src/p_mobj.c | 48 ++++++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 622309425..b8a6ea4fd 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -320,6 +320,8 @@ static int player_get(lua_State *L) lua_pushangle(L, plr->awayviewaiming); else if (fastcmp(field,"spectator")) lua_pushboolean(L, plr->spectator); + else if (fastcmp(field,"outofcoop")) + lua_pushboolean(L, plr->outofcoop); else if (fastcmp(field,"bot")) lua_pushinteger(L, plr->bot); else if (fastcmp(field,"jointime")) @@ -597,6 +599,8 @@ static int player_set(lua_State *L) plr->awayviewaiming = luaL_checkangle(L, 3); else if (fastcmp(field,"spectator")) plr->spectator = lua_toboolean(L, 3); + else if (fastcmp(field,"outofcoop")) + plr->outofcoop = lua_toboolean(L, 3); else if (fastcmp(field,"bot")) return NOSET; else if (fastcmp(field,"jointime")) diff --git a/src/p_mobj.c b/src/p_mobj.c index d67d2631f..590cce2d3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9106,33 +9106,37 @@ void P_SpawnPlayer(INT32 playernum) || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop || (((cv_cooplives.value == 1) || !P_GetLives(p)) && p->lives <= 0))); // game over and can't redistribute lives } - else if (netgame && p->jointime < 1) - p->spectator = true; - else if (multiplayer && !netgame) + else { - // If you're in a team game and you don't have a team assigned yet... - if (G_GametypeHasTeams() && p->ctfteam == 0) - { - changeteam_union NetPacket; - UINT16 usvalue; - NetPacket.value.l = NetPacket.value.b = 0; - - // Spawn as a spectator, - // yes even in splitscreen mode + p->outofcoop = false; + if (netgame && p->jointime < 1) p->spectator = true; - if (playernum&1) p->skincolor = skincolor_redteam; - else p->skincolor = skincolor_blueteam; + else if (multiplayer && !netgame) + { + // If you're in a team game and you don't have a team assigned yet... + if (G_GametypeHasTeams() && p->ctfteam == 0) + { + changeteam_union NetPacket; + UINT16 usvalue; + NetPacket.value.l = NetPacket.value.b = 0; - // but immediately send a team change packet. - NetPacket.packet.playernum = playernum; - NetPacket.packet.verification = true; - NetPacket.packet.newteam = !(playernum&1) + 1; + // Spawn as a spectator, + // yes even in splitscreen mode + p->spectator = true; + if (playernum&1) p->skincolor = skincolor_redteam; + else p->skincolor = skincolor_blueteam; - usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); - SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); + // but immediately send a team change packet. + NetPacket.packet.playernum = playernum; + NetPacket.packet.verification = true; + NetPacket.packet.newteam = !(playernum&1) + 1; + + usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); + SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); + } + else // Otherwise, never spectator. + p->spectator = false; } - else // Otherwise, never spectator. - p->spectator = false; } if (G_GametypeHasTeams()) From 88546abb0868d1dff4dea1b0a5ec3a1a5d6111b0 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 7 Jul 2017 13:35:48 +0100 Subject: [PATCH 42/61] Fix a few things noted during a test netgame with Salt and FuriousFox. * Hide the individual lives on the tab menu whenever they're irrelevant. * Make co-op spectators appear on the tab menu. * Hide one frame of spectatorhood stuff in splitscreen. * Fix joining netgames whilst in a special stage not giving the startinglives. * Make monitors that don't appear to do anything play the failure sound. * Only make players flash if they're REspawning, rather than spawning into a fresh level - unless it's a NiGHTS level, in which case never. --- src/g_game.c | 4 +- src/hu_stuff.c | 149 ++++++++++++++++++++++++++++--------------------- src/p_enemy.c | 9 +++ src/p_mobj.c | 2 +- src/p_user.c | 6 +- src/sounds.c | 2 +- src/st_stuff.c | 4 +- 7 files changed, 104 insertions(+), 72 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index abffed4d2..0d89c3643 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2708,7 +2708,7 @@ void G_AddPlayer(INT32 playernum) p->height = mobjinfo[MT_PLAYER].height; - if (G_GametypeUsesLives()) + if (G_GametypeUsesLives() || ((netgame || multiplayer) && gametype == GT_COOP)) p->lives = cv_startinglives.value; if (countplayers && !notexiting) @@ -3710,7 +3710,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean if (netgame || multiplayer) { - if (!FLS || (players[i].lives < cv_startinglives.value)) + if (!FLS || (players[i].lives < 1)) players[i].lives = cv_startinglives.value; players[i].continues = 0; } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 365ea093b..4eb3fad01 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1176,6 +1176,9 @@ void HU_Erase(void) // IN-LEVEL MULTIPLAYER RANKINGS //====================================================================== +#define supercheckdef ((players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS] || players[tab[i].num].mo->state > &states[S_PLAY_SUPER_TRANS9])) || (players[tab[i].num].powers[pw_carry] == CR_NIGHTSMODE && skins[players[tab[i].num].skin].flags & SF_SUPER)) +#define greycheckdef ((players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) || players[tab[i].num].spectator) + // // HU_DrawTabRankings // @@ -1183,6 +1186,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I { INT32 i; const UINT8 *colormap; + boolean greycheck, supercheck; //this function is designed for 9 or less score lines only I_Assert(scorelines <= 9); @@ -1191,12 +1195,15 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I for (i = 0; i < scorelines; i++) { - if (players[tab[i].num].spectator) + if (players[tab[i].num].spectator && gametype != GT_COOP) continue; //ignore them. + greycheck = greycheckdef; + supercheck = supercheckdef; + V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS) + | (greycheck ? V_60TRANS : 0) | V_ALLOWLOWERCASE, tab[i].name); // Draw emeralds @@ -1206,7 +1213,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I HU_DrawEmeralds(x-12,y+2,tab[i].emeralds); } - if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) + if (greycheck) V_DrawSmallTranslucentPatch (x, y-4, V_80TRANS, livesback); else V_DrawSmallScaledPatch (x, y-4, 0, livesback); @@ -1214,11 +1221,11 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I if (tab[i].color == 0) { colormap = colormaps; - if (players[tab[i].num].powers[pw_super]) + if (supercheck) V_DrawSmallScaledPatch(x, y-4, 0, superprefix[players[tab[i].num].skin]); else { - if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) + if (greycheck) V_DrawSmallTranslucentPatch(x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin]); else V_DrawSmallScaledPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin]); @@ -1226,7 +1233,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } else { - if (players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS] || players[tab[i].num].mo->state > &states[S_PLAY_SUPER_TRANS9])) + if (supercheck) { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE); V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap); @@ -1234,18 +1241,18 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) + if (greycheck) V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); } } - if (G_GametypeUsesLives()) //show lives - V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%dx", players[tab[i].num].lives)); + if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3))) //show lives + V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) { - if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) + if (greycheck) V_DrawSmallTranslucentPatch(x-32, y-4, V_60TRANS, tagico); else V_DrawSmallScaledPatch(x-32, y-4, 0, tagico); @@ -1258,13 +1265,13 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I if (players[tab[i].num].exiting) V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+240, y, (greycheck ? V_60TRANS : 0), va("%u", tab[i].count)); } else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedString(x+240, y, (greycheck ? V_60TRANS : 0), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); } else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+240, y, (greycheck ? V_60TRANS : 0), va("%u", tab[i].count)); y += 16; } @@ -1279,6 +1286,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) INT32 redplayers = 0, blueplayers = 0; const UINT8 *colormap; char name[MAXPLAYERNAME+1]; + boolean greycheck, supercheck; V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two teams. V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T. @@ -1306,10 +1314,13 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) else //er? not on red or blue, so ignore them continue; + greycheck = greycheckdef; + supercheck = supercheckdef; + strlcpy(name, tab[i].name, 9); V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT) + | (greycheck ? V_TRANSLUCENT : 0) | V_ALLOWLOWERCASE, name); if (gametype == GT_CTF) @@ -1327,7 +1338,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) HU_DrawEmeralds(x-12,y+2,tab[i].emeralds); } - if (players[tab[i].num].powers[pw_super]) + if (supercheck) { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap); @@ -1335,12 +1346,12 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) - V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); + if (greycheck) + V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); } - V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+120, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count)); } } @@ -1352,6 +1363,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline INT32 i; const UINT8 *colormap; char name[MAXPLAYERNAME+1]; + boolean greycheck, supercheck; V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two sides. V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T. @@ -1359,16 +1371,19 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline for (i = 0; i < scorelines; i++) { - if (players[tab[i].num].spectator) + if (players[tab[i].num].spectator && gametype != GT_COOP) continue; //ignore them. + greycheck = greycheckdef; + supercheck = supercheckdef; + strlcpy(name, tab[i].name, 9); V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT) + | (greycheck ? V_TRANSLUCENT : 0) | V_ALLOWLOWERCASE, name); - if (G_GametypeUsesLives()) //show lives + if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3))) //show lives V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) V_DrawSmallScaledPatch(x-28, y-4, 0, tagico); @@ -1384,19 +1399,19 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline if (tab[i].color == 0) { colormap = colormaps; - if (players[tab[i].num].powers[pw_super]) + if (supercheck) V_DrawSmallScaledPatch (x, y-4, 0, superprefix[players[tab[i].num].skin]); else { - if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) - V_DrawSmallTranslucentPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]); + if (greycheck) + V_DrawSmallTranslucentPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin]); else V_DrawSmallScaledPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]); } } else { - if (players[tab[i].num].powers[pw_super]) + if (supercheck) { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap); @@ -1404,8 +1419,8 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline else { colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE); - if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) - V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); + if (greycheck) + V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap); else V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap); } @@ -1419,13 +1434,13 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline if (players[tab[i].num].exiting) V_DrawRightAlignedThinString(x+156, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+156, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count)); } else - V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); + V_DrawRightAlignedThinString(x+156, y, (greycheck ? V_TRANSLUCENT : 0), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); } else - V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); + V_DrawRightAlignedThinString(x+120, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count)); y += 16; if (y > 160) @@ -1622,61 +1637,67 @@ static void HU_DrawRankings(void) for (j = 0; j < MAXPLAYERS; j++) { - if (!playeringame[j] || players[j].spectator) + if (!playeringame[j]) + continue; + + if (gametype != GT_COOP && players[j].spectator) continue; for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && !players[i].spectator) + if (!playeringame[i]) + continue; + + if (gametype != GT_COOP && players[i].spectator) + continue; + + if (gametype == GT_RACE) { - if (gametype == GT_RACE) + if (circuitmap) { - if (circuitmap) + if ((unsigned)players[i].laps+1 >= tab[scorelines].count && completed[i] == false) { - if ((unsigned)players[i].laps+1 >= tab[scorelines].count && completed[i] == false) - { - tab[scorelines].count = players[i].laps+1; - tab[scorelines].num = i; - tab[scorelines].color = players[i].skincolor; - tab[scorelines].name = player_names[i]; - } - } - else - { - if (players[i].realtime <= tab[scorelines].count && completed[i] == false) - { - tab[scorelines].count = players[i].realtime; - tab[scorelines].num = i; - tab[scorelines].color = players[i].skincolor; - tab[scorelines].name = player_names[i]; - } - } - } - else if (gametype == GT_COMPETITION) - { - // todo put something more fitting for the gametype here, such as current - // number of categories led - if (players[i].score >= tab[scorelines].count && completed[i] == false) - { - tab[scorelines].count = players[i].score; + tab[scorelines].count = players[i].laps+1; tab[scorelines].num = i; tab[scorelines].color = players[i].skincolor; tab[scorelines].name = player_names[i]; - tab[scorelines].emeralds = players[i].powers[pw_emeralds]; } } else { - if (players[i].score >= tab[scorelines].count && completed[i] == false) + if (players[i].realtime <= tab[scorelines].count && completed[i] == false) { - tab[scorelines].count = players[i].score; + tab[scorelines].count = players[i].realtime; tab[scorelines].num = i; tab[scorelines].color = players[i].skincolor; tab[scorelines].name = player_names[i]; - tab[scorelines].emeralds = players[i].powers[pw_emeralds]; } } } + else if (gametype == GT_COMPETITION) + { + // todo put something more fitting for the gametype here, such as current + // number of categories led + if (players[i].score >= tab[scorelines].count && completed[i] == false) + { + tab[scorelines].count = players[i].score; + tab[scorelines].num = i; + tab[scorelines].color = players[i].skincolor; + tab[scorelines].name = player_names[i]; + tab[scorelines].emeralds = players[i].powers[pw_emeralds]; + } + } + else + { + if (players[i].score >= tab[scorelines].count && completed[i] == false) + { + tab[scorelines].count = players[i].score; + tab[scorelines].num = i; + tab[scorelines].color = players[i].skincolor; + tab[scorelines].name = player_names[i]; + tab[scorelines].emeralds = players[i].powers[pw_emeralds]; + } + } } completed[tab[scorelines].num] = true; scorelines++; diff --git a/src/p_enemy.c b/src/p_enemy.c index c0451adf3..f9cfde5f2 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5629,7 +5629,10 @@ void A_MixUp(mobj_t *actor) } if (numplayers <= 1) // Not enough players to mix up. + { + S_StartSound(actor, sfx_lose); return; + } else if (numplayers == 2) // Special case -- simple swap { fixed_t x, y, z; @@ -5875,7 +5878,10 @@ void A_RecyclePowers(mobj_t *actor) #endif if (!multiplayer) + { + S_StartSound(actor, sfx_lose); return; + } numplayers = 0; @@ -5911,7 +5917,10 @@ void A_RecyclePowers(mobj_t *actor) } if (numplayers <= 1) + { + S_StartSound(actor, sfx_lose); return; //nobody to touch! + } //shuffle the post scramble list, whee! // hardcoded 0-1 to 1-0 for two players diff --git a/src/p_mobj.c b/src/p_mobj.c index 590cce2d3..afeb27868 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9153,7 +9153,7 @@ void P_SpawnPlayer(INT32 playernum) p->skincolor = skincolor_blueteam; } - if ((netgame || multiplayer) && !p->spectator) + if ((netgame || multiplayer) && leveltime && !p->spectator && !(maptol & TOL_NIGHTS)) p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); diff --git a/src/p_user.c b/src/p_user.c index a6795eadb..9ede28f96 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1150,7 +1150,9 @@ void P_PlayLivesJingle(player_t *player) if (player && !P_IsLocalPlayer(player)) return; - if (use1upSound) + if (gametype == GT_COOP && (netgame || multiplayer) && cv_cooplives.value == 0) + S_StartSound(NULL, sfx_lose); + else if (use1upSound) S_StartSound(NULL, sfx_oneup); else if (mariomode) S_StartSound(NULL, sfx_marioa); @@ -2335,7 +2337,7 @@ static void P_DoBubbleBreath(player_t *player) if (player->charflags & SF_MACHINE) { - if (P_RandomChance((128-(player->powers[pw_underwater]/4))*FRACUNIT/256)) + if (player->powers[pw_underwater] && P_RandomChance((128-(player->powers[pw_underwater]/4))*FRACUNIT/256)) { fixed_t r = player->mo->radius>>FRACBITS; x += (P_RandomRange(r, -r)<powers[pw_flashing] > TICRATE ) // was hit + if (stplyr->powers[pw_flashing] > TICRATE) // was hit { UINT16 flashingLeft = stplyr->powers[pw_flashing]-(TICRATE); if (flashingLeft < TICRATE/2) // Start fading out @@ -1995,7 +1995,7 @@ static void ST_overlayDrawer(void) ) ST_drawLevelTitle(); - if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer) + if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer && (!stplyr->spectator || gametype == GT_COOP)) { if (stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP) { From 54a8602c4cadf95ba9f21ba00b1ebcb46b6653a9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 7 Jul 2017 14:39:51 +0100 Subject: [PATCH 43/61] Woops, forgot about other gametype spawncamping. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index afeb27868..26f127f32 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9153,7 +9153,7 @@ void P_SpawnPlayer(INT32 playernum) p->skincolor = skincolor_blueteam; } - if ((netgame || multiplayer) && leveltime && !p->spectator && !(maptol & TOL_NIGHTS)) + if ((netgame || multiplayer) && (gametype != GT_COOP || leveltime) && !p->spectator && !(maptol & TOL_NIGHTS)) p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); From 5cc1b0dcd0b7d0149c474881b6464870c99f81e2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 8 Jul 2017 11:41:20 +0100 Subject: [PATCH 44/61] Exiting icon on the tab menu! (Requires new patch.dta) --- src/hu_stuff.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 4eb3fad01..e92b96995 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -92,6 +92,7 @@ patch_t *emeraldpics[7]; patch_t *tinyemeraldpics[7]; static patch_t *emblemicon; patch_t *tokenicon; +static patch_t *exiticon; //------------------------------------------- // misc vars @@ -245,6 +246,7 @@ void HU_LoadGraphics(void) emblemicon = W_CachePatchName("EMBLICON", PU_HUDGFX); tokenicon = W_CachePatchName("TOKNICON", PU_HUDGFX); + exiticon = W_CachePatchName("EXITICON", PU_HUDGFX); emeraldpics[0] = W_CachePatchName("CHAOS1", PU_HUDGFX); emeraldpics[1] = W_CachePatchName("CHAOS2", PU_HUDGFX); @@ -1258,6 +1260,9 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I V_DrawSmallScaledPatch(x-32, y-4, 0, tagico); } + if (players[tab[i].num].exiting) + V_DrawSmallScaledPatch(x - SHORT(exiticon->width)/2 - 1, y-3, 0, exiticon); + if (gametype == GT_RACE) { if (circuitmap) @@ -1388,6 +1393,9 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) V_DrawSmallScaledPatch(x-28, y-4, 0, tagico); + if (players[tab[i].num].exiting) + V_DrawSmallScaledPatch(x - SHORT(exiticon->width)/2 - 1, y-3, 0, exiticon); + // Draw emeralds if (!players[tab[i].num].powers[pw_super] || ((leveltime/7) & 1)) From b197dcdb1fccfb5eb2196c3faf79dee0ccf14405 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 8 Jul 2017 11:41:20 +0100 Subject: [PATCH 45/61] A little bit of monitor love. * Rename "Unknown" options to "Mystery". * Make Random monitors work consistently in singleplayer if hacked/SOC'd in. --- src/d_netcmd.c | 6 +++--- src/m_menu.c | 4 ++-- src/p_enemy.c | 28 ++++++++++++++++++++++++++++ src/p_mobj.c | 10 +++++----- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index fb09718c1..9371727be 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -191,10 +191,10 @@ static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2 static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; static CV_PossibleValue_t sleeping_cons_t[] = {{-1, "MIN"}, {1000/TICRATE, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Unknown"}, //{2, "Teleport"}, +static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Mystery"}, //{2, "Teleport"}, {3, "None"}, {0, NULL}}; -static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Unknown"}, {2, "Never changing"}, +static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Mystery"}, {2, "Unchanging"}, {3, "None"}, {0, NULL}}; static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}}; @@ -216,7 +216,7 @@ consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT, starting static CV_PossibleValue_t respawntime_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; consvar_t cv_respawntime = {"respawndelay", "3", CV_NETVAR|CV_CHEAT, respawntime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_competitionboxes = {"competitionboxes", "Unknown", CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_competitionboxes = {"competitionboxes", "Mystery", CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef SEENAMES static CV_PossibleValue_t seenames_cons_t[] = {{0, "Off"}, {1, "Colorless"}, {2, "Team"}, {3, "Ally/Foe"}, {0, NULL}}; diff --git a/src/m_menu.c b/src/m_menu.c index 6e3c3e9d4..fc59325a7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1374,7 +1374,7 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Server name", &cv_servername, 7}, {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21}, - {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26}, + {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26}, {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31}, #endif {IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 36}, @@ -1386,7 +1386,7 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_HEADER, NULL, "Items", NULL, 70}, {IT_STRING | IT_CVAR, NULL, "Item respawn delay", &cv_itemrespawntime, 76}, - {IT_STRING | IT_SUBMENU, NULL, "Unknown Item Monitor Toggles...", &OP_MonitorToggleDef, 81}, + {IT_STRING | IT_SUBMENU, NULL, "Mystery Item Monitor Toggles...", &OP_MonitorToggleDef, 81}, {IT_HEADER, NULL, "Cooperative", NULL, 90}, {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96}, diff --git a/src/p_enemy.c b/src/p_enemy.c index f9cfde5f2..ee18985aa 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -841,6 +841,34 @@ static mobjtype_t P_DoRandomBoxChances(void) mobjtype_t spawnchance[256]; INT32 numchoices = 0, i = 0; + if (!(netgame || multiplayer)) + { + switch (P_RandomKey(10)) + { + case 0: + return MT_RING_ICON; + case 1: + return MT_SNEAKERS_ICON; + case 2: + return MT_INVULN_ICON; + case 3: + return MT_WHIRLWIND_ICON; + case 4: + return MT_ELEMENTAL_ICON; + case 5: + return MT_ATTRACT_ICON; + case 6: + return MT_FORCE_ICON; + case 7: + return MT_ARMAGEDDON_ICON; + case 8: + return MT_1UP_ICON; + case 9: + return MT_EGGMAN_ICON; + } + return MT_NULL; + } + #define QUESTIONBOXCHANCES(type, cvar) \ for (i = cvar.value; i; --i) spawnchance[numchoices++] = type QUESTIONBOXCHANCES(MT_RING_ICON, cv_superring); diff --git a/src/p_mobj.c b/src/p_mobj.c index 26f127f32..6836e3329 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9546,9 +9546,9 @@ void P_SpawnMapThing(mapthing_t *mthing) if (gametype == GT_COMPETITION || gametype == GT_RACE) { // Set powerup boxes to user settings for competition. - if (cv_competitionboxes.value == 1) // Random + if (cv_competitionboxes.value == 1) // Mystery i = MT_MYSTERY_BOX; - else if (cv_competitionboxes.value == 2) // Teleports + else if (cv_competitionboxes.value == 2) // Teleport i = MT_MIXUP_BOX; else if (cv_competitionboxes.value == 3) // None return; // Don't spawn! @@ -9557,12 +9557,12 @@ void P_SpawnMapThing(mapthing_t *mthing) // Set powerup boxes to user settings for other netplay modes else if (gametype != GT_COOP) { - if (cv_matchboxes.value == 1) // Random + if (cv_matchboxes.value == 1) // Mystery i = MT_MYSTERY_BOX; - else if (cv_matchboxes.value == 2) // Non-Random + else if (cv_matchboxes.value == 2) // Unchanging { if (i == MT_MYSTERY_BOX) - return; // don't spawn in Non-Random + return; // don't spawn mthing->options &= ~(MTF_AMBUSH|MTF_OBJECTSPECIAL); // no random respawning! } else if (cv_matchboxes.value == 3) // Don't spawn From 317259a459ac3e7b050070a78b2a42746228851e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 8 Jul 2017 11:41:20 +0100 Subject: [PATCH 46/61] Two fixes to playersforexit changes. * Crash prevention if total somehow becomes zero. * Don't waste time multiplying and demultiplying the HUD check if it's just gonna net you the same number. --- src/p_user.c | 2 +- src/st_stuff.c | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 9ede28f96..052018c1e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9435,7 +9435,7 @@ void P_PlayerThink(player_t *player) exiting++; } - if (((4*exiting)/total) >= cv_playersforexit.value) + if (!total || ((4*exiting)/total) >= cv_playersforexit.value) { if (server) SendNetXCmd(XD_EXITLEVEL, NULL, 0); diff --git a/src/st_stuff.c b/src/st_stuff.c index 7a49b0402..33192eedb 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2013,9 +2013,12 @@ static void ST_overlayDrawer(void) exiting++; } - total *= cv_playersforexit.value; - if (total % 4) total += 4; // round up - total /= 4; + if (cv_playersforexit.value != 4) + { + total *= cv_playersforexit.value; + if (total % 4) total += 4; // round up + total /= 4; + } if (exiting >= total) ; From a0cf28671cff76b4a26eddf34bb40fd55254e3a4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 8 Jul 2017 11:41:20 +0100 Subject: [PATCH 47/61] Remove some jankiness from spectators. --- src/p_user.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 052018c1e..0affcef5b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5207,16 +5207,16 @@ static void P_SpectatorMovement(player_t *player) if (!(cmd->angleturn & TICCMD_RECEIVED)) ticmiss++; - if (player->mo->z > player->mo->ceilingz - player->mo->height) - player->mo->z = player->mo->ceilingz - player->mo->height; - if (player->mo->z < player->mo->floorz) - player->mo->z = player->mo->floorz; - if (cmd->buttons & BT_JUMP) player->mo->z += FRACUNIT*16; else if (cmd->buttons & BT_USE) player->mo->z -= FRACUNIT*16; + if (player->mo->z > player->mo->ceilingz - player->mo->height) + player->mo->z = player->mo->ceilingz - player->mo->height; + if (player->mo->z < player->mo->floorz) + player->mo->z = player->mo->floorz; + // Aiming needed for SEENAMES, etc. // We may not need to fire as a spectator, but this is still handy! player->aiming = cmd->aiming<spectator) { + player->mo->eflags &= ~MFE_VERTICALFLIP; // deflip... P_SpectatorMovement(player); return; } From fb006913240f3636189f42e7f33ea3d93c0722a9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 8 Jul 2017 11:41:20 +0100 Subject: [PATCH 48/61] Fix a bug in a testing netgame where we were able to game over and yet ended up just resetting the map normally. --- src/g_game.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 0d89c3643..4ef3d44a8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2533,42 +2533,44 @@ void G_DoReborn(INT32 playernum) resetlevel = true; else if (gametype == GT_COOP && (netgame || multiplayer)) { - if (cv_cooplives.value == 0) - ; - else if (player->lives <= 0) // consider game over first + boolean notgameover = true; + + if (cv_cooplives.value != 0 && player->lives <= 0) // consider game over first { - INT32 deadtimercheck = INT32_MAX; for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) continue; if (players[i].exiting || players[i].lives > 0) break; - if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck) - deadtimercheck = players[i].deadtimer; } - if (!countdown2 && i == MAXPLAYERS && deadtimercheck >= 8*TICRATE) + if (i == MAXPLAYERS) { - // They're dead, Jim. - //nextmapoverride = spstage_start; - nextmapoverride = gamemap; - countdown2 = TICRATE; - skipstats = true; - - for (i = 0; i < MAXPLAYERS; i++) + notgameover = false; + if (!countdown2) { - if (playeringame[i]) - players[i].score = 0; - } + // They're dead, Jim. + //nextmapoverride = spstage_start; + nextmapoverride = gamemap; + countdown2 = TICRATE; + skipstats = true; - //emeralds = 0; - tokenbits = 0; - tokenlist = 0; - token = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + players[i].score = 0; + } + + //emeralds = 0; + tokenbits = 0; + tokenlist = 0; + token = 0; + } } } - if (cv_coopstarposts.value == 2) + + if (notgameover && cv_coopstarposts.value == 2) { for (i = 0; i < MAXPLAYERS; i++) { From 1f2743ce649fcbe350fbc7145170bf4c60067dd2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 8 Jul 2017 11:41:20 +0100 Subject: [PATCH 49/61] Clean up the event and caption when a life is transferred. --- src/p_user.c | 2 +- src/sounds.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 0affcef5b..5506925e0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8179,7 +8179,7 @@ boolean P_GetLives(player_t *player) } if (maxlivesplayer != -1 && &players[maxlivesplayer] != player) { - if (cv_cooplives.value == 2 && P_IsLocalPlayer(&players[maxlivesplayer])) + if (cv_cooplives.value == 2 && (P_IsLocalPlayer(player) || P_IsLocalPlayer(&players[maxlivesplayer]))) S_StartSound(NULL, sfx_jshard); // placeholder players[maxlivesplayer].lives--; player->lives++; diff --git a/src/sounds.c b/src/sounds.c index bb050538c..2c1c5f3af 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -154,7 +154,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"gravch", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Recycler"}, {"itemup", true, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, {"jet", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jet engine"}, - {"jshard", true, 167, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got shard"}, + {"jshard", true, 167, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Life transfer"}, // placeholder repurpose; original string was "Got Shard" {"lose" , false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Failure"}, {"lvpass", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spinning signpost"}, {"mindig", false, 8, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Tunnelling"}, From 9b506b2fde2c12ab1552d2fc3819373e472e3c17 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 17 Jul 2017 18:16:41 +0100 Subject: [PATCH 50/61] I legitimately cannot remember for the life of me why I added this check. It broke spectator text in gametypes outside of co-op, so... --- src/st_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 33192eedb..06877bbb3 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1995,7 +1995,7 @@ static void ST_overlayDrawer(void) ) ST_drawLevelTitle(); - if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer && (!stplyr->spectator || gametype == GT_COOP)) + if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer) { if (stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP) { From 6250266af56fa6b6ef1b3a6b1f9f6819d30a9c2e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 17 Jul 2017 23:26:24 +0100 Subject: [PATCH 51/61] Preparatory work for the contestesque implementation. --- src/d_clisrv.c | 2 +- src/d_netcmd.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1e56467e5..3878d8795 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1332,7 +1332,7 @@ static void SV_SendPlayerInfo(INT32 node) netbuffer->u.playerinfo[i].skin = (UINT8)players[i].skin; // Extra data - netbuffer->u.playerinfo[i].data = players[i].skincolor; + netbuffer->u.playerinfo[i].data = 0; //players[i].skincolor; if (players[i].pflags & PF_TAGIT) netbuffer->u.playerinfo[i].data |= 0x20; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 9371727be..185fb4127 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1175,7 +1175,7 @@ static void SendNameAndColor(void) { CV_StealthSetValue(&cv_playercolor, skins[cv_skin.value].prefcolor); - players[consoleplayer].skincolor = (cv_playercolor.value&0x1F) % MAXSKINCOLORS; + players[consoleplayer].skincolor = cv_playercolor.value % MAXSKINCOLORS; if (players[consoleplayer].mo) players[consoleplayer].mo->color = (UINT8)players[consoleplayer].skincolor; @@ -1302,7 +1302,7 @@ static void SendNameAndColor2(void) { CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor); - players[secondplaya].skincolor = (cv_playercolor2.value&0x1F) % MAXSKINCOLORS; + players[secondplaya].skincolor = cv_playercolor2.value % MAXSKINCOLORS; if (players[secondplaya].mo) players[secondplaya].mo->color = players[secondplaya].skincolor; From 8941379c64cf131bf7396c5d384858d2b5a0b8db Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 22 Jul 2017 23:24:12 +0100 Subject: [PATCH 52/61] Implementation of all the new skincolours. No new exe yet, though, since I'm still doin' stuff. --- src/dehacked.c | 189 ++++--- src/doomdata.h | 3 +- src/doomdef.h | 58 ++- src/g_game.c | 2 +- src/hardware/hw_md2.c | 242 +-------- src/p_enemy.c | 8 +- src/p_user.c | 2 +- src/r_draw.c | 1141 ++++++++++------------------------------- 8 files changed, 457 insertions(+), 1188 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 1279d7bd0..809cdfac0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6770,91 +6770,130 @@ static const char *const ML_LIST[16] = { // This DOES differ from r_draw's Color_Names, unfortunately. // Also includes Super colors static const char *COLOR_ENUMS[] = { - "NONE", // SKINCOLOR_NONE - "WHITE", // SKINCOLOR_WHITE - "SILVER", // SKINCOLOR_SILVER - "GREY", // SKINCOLOR_GREY - "BLACK", // SKINCOLOR_BLACK - "BEIGE", // SKINCOLOR_BEIGE - "PEACH", // SKINCOLOR_PEACH - "BROWN", // SKINCOLOR_BROWN - "RED", // SKINCOLOR_RED - "CRIMSON", // SKINCOLOR_CRIMSON - "ORANGE", // SKINCOLOR_ORANGE - "RUST", // SKINCOLOR_RUST - "GOLD", // SKINCOLOR_GOLD - "YELLOW", // SKINCOLOR_YELLOW - "TAN", // SKINCOLOR_TAN - "MOSS", // SKINCOLOR_MOSS - "PERIDOT", // SKINCOLOR_PERIDOT - "GREEN", // SKINCOLOR_GREEN - "EMERALD", // SKINCOLOR_EMERALD - "AQUA", // SKINCOLOR_AQUA - "TEAL", // SKINCOLOR_TEAL - "CYAN", // SKINCOLOR_CYAN - "BLUE", // SKINCOLOR_BLUE - "AZURE", // SKINCOLOR_AZURE - "PASTEL", // SKINCOLOR_PASTEL - "PURPLE", // SKINCOLOR_PURPLE - "LAVENDER", // SKINCOLOR_LAVENDER - "MAGENTA", // SKINCOLOR_MAGENTA - "PINK", // SKINCOLOR_PINK - "ROSY", // SKINCOLOR_ROSY + "NONE", // SKINCOLOR_NONE, + + // Greyscale ranges + "WHITE", // SKINCOLOR_WHITE, + "BONE", // SKINCOLOR_BONE, + "SILVER", // SKINCOLOR_SILVER, + "GREY", // SKINCOLOR_GREY, + "CLOUDY", // SKINCOLOR_CLOUDY, + "CARBON", // SKINCOLOR_CARBON, + "JET", // SKINCOLOR_JET, + "BLACK", // SKINCOLOR_BLACK, + + // Desaturated + "AETHER", // SKINCOLOR_AETHER, + "SLATE", // SKINCOLOR_SLATE, + "PINK", // SKINCOLOR_PINK, + "YOGURT", // SKINCOLOR_YOGURT, + "BROWN", // SKINCOLOR_BROWN, + "TAN", // SKINCOLOR_TAN, + "BEIGE", // SKINCOLOR_BEIGE, + "MOSS", // SKINCOLOR_MOSS, + "AZURE", // SKINCOLOR_AZURE, + "LAVENDER", // SKINCOLOR_LAVENDER, + + // Viv's vivid colours (toast 21/07/17) + "RUBY", // SKINCOLOR_RUBY, + "SALMON", // SKINCOLOR_SALMON, + "RED", // SKINCOLOR_RED, + "CRIMSON", // SKINCOLOR_CRIMSON, + "FLAME", // SKINCOLOR_FLAME, + "PEACHY", // SKINCOLOR_PEACHY, + "QUAIL", // SKINCOLOR_QUAIL, + "SUNSET", // SKINCOLOR_SUNSET, + "APRICOT", // SKINCOLOR_APRICOT, + "ORANGE", // SKINCOLOR_ORANGE, + "RUST", // SKINCOLOR_RUST, + "GOLD", // SKINCOLOR_GOLD, + "SANDY", // SKINCOLOR_SANDY, + "YELLOW", // SKINCOLOR_YELLOW, + "OLIVE", // SKINCOLOR_OLIVE, + "LIME", // SKINCOLOR_LIME, + "PERIDOT", // SKINCOLOR_PERIDOT, + "GREEN", // SKINCOLOR_GREEN, + "FOREST", // SKINCOLOR_FOREST, + "EMERALD", // SKINCOLOR_EMERALD, + "MINT", // SKINCOLOR_MINT, + "SEAFOAM", // SKINCOLOR_SEAFOAM, + "AQUA", // SKINCOLOR_AQUA, + "TEAL", // SKINCOLOR_TEAL, + "WAVE", // SKINCOLOR_WAVE, + "CYAN", // SKINCOLOR_CYAN, + "SKY", // SKINCOLOR_SKY, + "CERULEAN", // SKINCOLOR_CERULEAN, + "ICY", // SKINCOLOR_ICY, + "SAPPHIRE", // SKINCOLOR_SAPPHIRE, + "CORNFLOWER", // SKINCOLOR_CORNFLOWER, + "BLUE", // SKINCOLOR_BLUE, + "COBALT", // SKINCOLOR_COBALT, + "VAPOR", // SKINCOLOR_VAPOR, + "DUSK", // SKINCOLOR_DUSK, + "PASTEL", // SKINCOLOR_PASTEL, + "PURPLE", // SKINCOLOR_PURPLE, + "BUBBLEGUM", // SKINCOLOR_BUBBLEGUM, + "MAGENTA", // SKINCOLOR_MAGENTA, + "NEON", // SKINCOLOR_NEON, + "VIOLET", // SKINCOLOR_VIOLET, + "LILAC", // SKINCOLOR_LILAC, + "PLUM", // SKINCOLOR_PLUM, + "ROSY", // SKINCOLOR_ROSY, // Super special awesome Super flashing colors! - "SUPERSILVER1", // SKINCOLOR_SUPERSILVER1 - "SUPERSILVER2", // SKINCOLOR_SUPERSILVER2, - "SUPERSILVER3", // SKINCOLOR_SUPERSILVER3, - "SUPERSILVER4", // SKINCOLOR_SUPERSILVER4, - "SUPERSILVER5", // SKINCOLOR_SUPERSILVER5, + "SUPERSILVER1", // SKINCOLOR_SUPERSILVER1 + "SUPERSILVER2", // SKINCOLOR_SUPERSILVER2, + "SUPERSILVER3", // SKINCOLOR_SUPERSILVER3, + "SUPERSILVER4", // SKINCOLOR_SUPERSILVER4, + "SUPERSILVER5", // SKINCOLOR_SUPERSILVER5, - "SUPERRED1", // SKINCOLOR_SUPERRED1 - "SUPERRED2", // SKINCOLOR_SUPERRED2, - "SUPERRED3", // SKINCOLOR_SUPERRED3, - "SUPERRED4", // SKINCOLOR_SUPERRED4, - "SUPERRED5", // SKINCOLOR_SUPERRED5, + "SUPERRED1", // SKINCOLOR_SUPERRED1 + "SUPERRED2", // SKINCOLOR_SUPERRED2, + "SUPERRED3", // SKINCOLOR_SUPERRED3, + "SUPERRED4", // SKINCOLOR_SUPERRED4, + "SUPERRED5", // SKINCOLOR_SUPERRED5, - "SUPERORANGE1", // SKINCOLOR_SUPERORANGE1 - "SUPERORANGE2", // SKINCOLOR_SUPERORANGE2, - "SUPERORANGE3", // SKINCOLOR_SUPERORANGE3, - "SUPERORANGE4", // SKINCOLOR_SUPERORANGE4, - "SUPERORANGE5", // SKINCOLOR_SUPERORANGE5, + "SUPERORANGE1", // SKINCOLOR_SUPERORANGE1 + "SUPERORANGE2", // SKINCOLOR_SUPERORANGE2, + "SUPERORANGE3", // SKINCOLOR_SUPERORANGE3, + "SUPERORANGE4", // SKINCOLOR_SUPERORANGE4, + "SUPERORANGE5", // SKINCOLOR_SUPERORANGE5, - "SUPERGOLD1", // SKINCOLOR_SUPERGOLD1 - "SUPERGOLD2", // SKINCOLOR_SUPERGOLD2, - "SUPERGOLD3", // SKINCOLOR_SUPERGOLD3, - "SUPERGOLD4", // SKINCOLOR_SUPERGOLD4, - "SUPERGOLD5", // SKINCOLOR_SUPERGOLD5, + "SUPERGOLD1", // SKINCOLOR_SUPERGOLD1 + "SUPERGOLD2", // SKINCOLOR_SUPERGOLD2, + "SUPERGOLD3", // SKINCOLOR_SUPERGOLD3, + "SUPERGOLD4", // SKINCOLOR_SUPERGOLD4, + "SUPERGOLD5", // SKINCOLOR_SUPERGOLD5, - "SUPERPERIDOT1", // SKINCOLOR_SUPERPERIDOT1 - "SUPERPERIDOT2", // SKINCOLOR_SUPERPERIDOT2, - "SUPERPERIDOT3", // SKINCOLOR_SUPERPERIDOT3, - "SUPERPERIDOT4", // SKINCOLOR_SUPERPERIDOT4, - "SUPERPERIDOT5", // SKINCOLOR_SUPERPERIDOT5, + "SUPERPERIDOT1", // SKINCOLOR_SUPERPERIDOT1 + "SUPERPERIDOT2", // SKINCOLOR_SUPERPERIDOT2, + "SUPERPERIDOT3", // SKINCOLOR_SUPERPERIDOT3, + "SUPERPERIDOT4", // SKINCOLOR_SUPERPERIDOT4, + "SUPERPERIDOT5", // SKINCOLOR_SUPERPERIDOT5, - "SUPERCYAN1", // SKINCOLOR_SUPERCYAN1 - "SUPERCYAN2", // SKINCOLOR_SUPERCYAN2, - "SUPERCYAN3", // SKINCOLOR_SUPERCYAN3, - "SUPERCYAN4", // SKINCOLOR_SUPERCYAN4, - "SUPERCYAN5", // SKINCOLOR_SUPERCYAN5, + "SUPERCYAN1", // SKINCOLOR_SUPERCYAN1 + "SUPERCYAN2", // SKINCOLOR_SUPERCYAN2, + "SUPERCYAN3", // SKINCOLOR_SUPERCYAN3, + "SUPERCYAN4", // SKINCOLOR_SUPERCYAN4, + "SUPERCYAN5", // SKINCOLOR_SUPERCYAN5, - "SUPERPURPLE1", // SKINCOLOR_SUPERPURPLE1, - "SUPERPURPLE2", // SKINCOLOR_SUPERPURPLE2, - "SUPERPURPLE3", // SKINCOLOR_SUPERPURPLE3, - "SUPERPURPLE4", // SKINCOLOR_SUPERPURPLE4, - "SUPERPURPLE5", // SKINCOLOR_SUPERPURPLE5, + "SUPERPURPLE1", // SKINCOLOR_SUPERPURPLE1, + "SUPERPURPLE2", // SKINCOLOR_SUPERPURPLE2, + "SUPERPURPLE3", // SKINCOLOR_SUPERPURPLE3, + "SUPERPURPLE4", // SKINCOLOR_SUPERPURPLE4, + "SUPERPURPLE5", // SKINCOLOR_SUPERPURPLE5, - "SUPERRUST1", // SKINCOLOR_SUPERRUST1 - "SUPERRUST2", // SKINCOLOR_SUPERRUST2, - "SUPERRUST3", // SKINCOLOR_SUPERRUST3, - "SUPERRUST4", // SKINCOLOR_SUPERRUST4, - "SUPERRUST5", // SKINCOLOR_SUPERRUST5, + "SUPERRUST1", // SKINCOLOR_SUPERRUST1 + "SUPERRUST2", // SKINCOLOR_SUPERRUST2, + "SUPERRUST3", // SKINCOLOR_SUPERRUST3, + "SUPERRUST4", // SKINCOLOR_SUPERRUST4, + "SUPERRUST5", // SKINCOLOR_SUPERRUST5, - "SUPERTAN1", // SKINCOLOR_SUPERTAN1 - "SUPERTAN2", // SKINCOLOR_SUPERTAN2, - "SUPERTAN3", // SKINCOLOR_SUPERTAN3, - "SUPERTAN4", // SKINCOLOR_SUPERTAN4, - "SUPERTAN5" // SKINCOLOR_SUPERTAN5, + "SUPERTAN1", // SKINCOLOR_SUPERTAN1 + "SUPERTAN2", // SKINCOLOR_SUPERTAN2, + "SUPERTAN3", // SKINCOLOR_SUPERTAN3, + "SUPERTAN4", // SKINCOLOR_SUPERTAN4, + "SUPERTAN5" // SKINCOLOR_SUPERTAN5, }; static const char *const POWERS_LIST[] = { diff --git a/src/doomdata.h b/src/doomdata.h index 033cc71b3..c0586fd65 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -207,8 +207,9 @@ typedef struct #define ZSHIFT 4 +extern const UINT8 Color_Index[MAXTRANSLATIONS-1][16]; extern const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS]; -extern const UINT8 Color_Opposite[MAXSKINCOLORS*2]; +extern const UINT8 Color_Opposite[(MAXSKINCOLORS - 1)*2]; #define NUMMAPS 1035 diff --git a/src/doomdef.h b/src/doomdef.h index 16d7fa218..1d8f99a7a 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -229,39 +229,77 @@ extern FILE *logstream; typedef enum { SKINCOLOR_NONE = 0, + + // Greyscale ranges SKINCOLOR_WHITE, + SKINCOLOR_BONE, SKINCOLOR_SILVER, SKINCOLOR_GREY, + SKINCOLOR_CLOUDY, + SKINCOLOR_CARBON, + SKINCOLOR_JET, SKINCOLOR_BLACK, - SKINCOLOR_BEIGE, - SKINCOLOR_PEACH, + + // Desaturated + SKINCOLOR_AETHER, + SKINCOLOR_SLATE, + SKINCOLOR_PINK, + SKINCOLOR_YOGURT, SKINCOLOR_BROWN, + SKINCOLOR_TAN, + SKINCOLOR_BEIGE, + SKINCOLOR_MOSS, + SKINCOLOR_AZURE, + SKINCOLOR_LAVENDER, + + // Viv's vivid colours (toast 21/07/17) + SKINCOLOR_RUBY, + SKINCOLOR_SALMON, SKINCOLOR_RED, SKINCOLOR_CRIMSON, + SKINCOLOR_FLAME, + SKINCOLOR_PEACHY, + SKINCOLOR_QUAIL, + SKINCOLOR_SUNSET, + SKINCOLOR_APRICOT, SKINCOLOR_ORANGE, SKINCOLOR_RUST, SKINCOLOR_GOLD, + SKINCOLOR_SANDY, SKINCOLOR_YELLOW, - SKINCOLOR_TAN, - SKINCOLOR_MOSS, + SKINCOLOR_OLIVE, + SKINCOLOR_LIME, SKINCOLOR_PERIDOT, SKINCOLOR_GREEN, + SKINCOLOR_FOREST, SKINCOLOR_EMERALD, + SKINCOLOR_MINT, + SKINCOLOR_SEAFOAM, SKINCOLOR_AQUA, SKINCOLOR_TEAL, + SKINCOLOR_WAVE, SKINCOLOR_CYAN, + SKINCOLOR_SKY, + SKINCOLOR_CERULEAN, + SKINCOLOR_ICY, + SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave – slender aphrodite has overcome me with longing for a girl + SKINCOLOR_CORNFLOWER, SKINCOLOR_BLUE, - SKINCOLOR_AZURE, + SKINCOLOR_COBALT, + SKINCOLOR_VAPOR, + SKINCOLOR_DUSK, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, - SKINCOLOR_LAVENDER, + SKINCOLOR_BUBBLEGUM, SKINCOLOR_MAGENTA, - SKINCOLOR_PINK, + SKINCOLOR_NEON, + SKINCOLOR_VIOLET, + SKINCOLOR_LILAC, + SKINCOLOR_PLUM, SKINCOLOR_ROSY, - //SKINCOLOR_? - //SKINCOLOR_? - // Careful! MAXSKINCOLORS cannot be greater than 0x20! Two slots left... + // SKINCOLOR_? - one left before we bump up against 0x39, which isn't a HARD limit anymore but would be excessive + MAXSKINCOLORS, // Super special awesome Super flashing colors! diff --git a/src/g_game.c b/src/g_game.c index 4ef3d44a8..6e43aeb8b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4514,7 +4514,7 @@ void G_GhostTicker(void) g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); break; case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) - g->mo->color = (UINT8)(SKINCOLOR_RED + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RED))); // Passes through all saturated colours + g->mo->color = (UINT8)(SKINCOLOR_RUBY + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RUBY))); // Passes through all saturated colours break; default: break; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 7edf02db0..c7d35e913 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -961,244 +961,10 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, image = gpatch->mipmap.grInfo.data; blendimage = blendgpatch->mipmap.grInfo.data; - switch (color) - { - case SKINCOLOR_WHITE: - blendcolor = V_GetColor(3); - break; - case SKINCOLOR_SILVER: - blendcolor = V_GetColor(10); - break; - case SKINCOLOR_GREY: - blendcolor = V_GetColor(15); - break; - case SKINCOLOR_BLACK: - blendcolor = V_GetColor(27); - break; - case SKINCOLOR_BEIGE: - blendcolor = V_GetColor(247); - break; - case SKINCOLOR_PEACH: - blendcolor = V_GetColor(218); - break; - case SKINCOLOR_BROWN: - blendcolor = V_GetColor(234); - break; - case SKINCOLOR_RED: - blendcolor = V_GetColor(38); - break; - case SKINCOLOR_CRIMSON: - blendcolor = V_GetColor(45); - break; - case SKINCOLOR_ORANGE: - blendcolor = V_GetColor(54); - break; - case SKINCOLOR_RUST: - blendcolor = V_GetColor(60); - break; - case SKINCOLOR_GOLD: - blendcolor = V_GetColor(67); - break; - case SKINCOLOR_YELLOW: - blendcolor = V_GetColor(73); - break; - case SKINCOLOR_TAN: - blendcolor = V_GetColor(85); - break; - case SKINCOLOR_MOSS: - blendcolor = V_GetColor(92); - break; - case SKINCOLOR_PERIDOT: - blendcolor = V_GetColor(188); - break; - case SKINCOLOR_GREEN: - blendcolor = V_GetColor(101); - break; - case SKINCOLOR_EMERALD: - blendcolor = V_GetColor(112); - break; - case SKINCOLOR_AQUA: - blendcolor = V_GetColor(122); - break; - case SKINCOLOR_TEAL: - blendcolor = V_GetColor(141); - break; - case SKINCOLOR_CYAN: - blendcolor = V_GetColor(131); - break; - case SKINCOLOR_BLUE: - blendcolor = V_GetColor(152); - break; - case SKINCOLOR_AZURE: - blendcolor = V_GetColor(171); - break; - case SKINCOLOR_PASTEL: - blendcolor = V_GetColor(161); - break; - case SKINCOLOR_PURPLE: - blendcolor = V_GetColor(165); - break; - case SKINCOLOR_LAVENDER: - blendcolor = V_GetColor(195); - break; - case SKINCOLOR_MAGENTA: - blendcolor = V_GetColor(183); - break; - case SKINCOLOR_PINK: - blendcolor = V_GetColor(211); - break; - case SKINCOLOR_ROSY: - blendcolor = V_GetColor(202); - break; - - case SKINCOLOR_SUPERSILVER1: // Super silver - blendcolor = V_GetColor(0); - break; - case SKINCOLOR_SUPERSILVER2: - blendcolor = V_GetColor(2); - break; - case SKINCOLOR_SUPERSILVER3: - blendcolor = V_GetColor(4); - break; - case SKINCOLOR_SUPERSILVER4: - blendcolor = V_GetColor(7); - break; - case SKINCOLOR_SUPERSILVER5: - blendcolor = V_GetColor(10); - break; - - case SKINCOLOR_SUPERRED1: // Super red - blendcolor = V_GetColor(208); - break; - case SKINCOLOR_SUPERRED2: - blendcolor = V_GetColor(210); - break; - case SKINCOLOR_SUPERRED3: - blendcolor = V_GetColor(32); - break; - case SKINCOLOR_SUPERRED4: - blendcolor = V_GetColor(33); - break; - case SKINCOLOR_SUPERRED5: - blendcolor = V_GetColor(35); - break; - - case SKINCOLOR_SUPERORANGE1: // Super orange - blendcolor = V_GetColor(208); - break; - case SKINCOLOR_SUPERORANGE2: - blendcolor = V_GetColor(48); - break; - case SKINCOLOR_SUPERORANGE3: - blendcolor = V_GetColor(50); - break; - case SKINCOLOR_SUPERORANGE4: - blendcolor = V_GetColor(54); - break; - case SKINCOLOR_SUPERORANGE5: - blendcolor = V_GetColor(58); - break; - - case SKINCOLOR_SUPERGOLD1: // Super gold - blendcolor = V_GetColor(80); - break; - case SKINCOLOR_SUPERGOLD2: - blendcolor = V_GetColor(83); - break; - case SKINCOLOR_SUPERGOLD3: - blendcolor = V_GetColor(73); - break; - case SKINCOLOR_SUPERGOLD4: - blendcolor = V_GetColor(64); - break; - case SKINCOLOR_SUPERGOLD5: - blendcolor = V_GetColor(67); - break; - - case SKINCOLOR_SUPERPERIDOT1: // Super peridot - blendcolor = V_GetColor(88); - break; - case SKINCOLOR_SUPERPERIDOT2: - blendcolor = V_GetColor(188); - break; - case SKINCOLOR_SUPERPERIDOT3: - blendcolor = V_GetColor(189); - break; - case SKINCOLOR_SUPERPERIDOT4: - blendcolor = V_GetColor(190); - break; - case SKINCOLOR_SUPERPERIDOT5: - blendcolor = V_GetColor(191); - break; - - case SKINCOLOR_SUPERCYAN1: // Super cyan - blendcolor = V_GetColor(128); - break; - case SKINCOLOR_SUPERCYAN2: - blendcolor = V_GetColor(131); - break; - case SKINCOLOR_SUPERCYAN3: - blendcolor = V_GetColor(133); - break; - case SKINCOLOR_SUPERCYAN4: - blendcolor = V_GetColor(134); - break; - case SKINCOLOR_SUPERCYAN5: - blendcolor = V_GetColor(136); - break; - - case SKINCOLOR_SUPERPURPLE1: // Super purple - blendcolor = V_GetColor(144); - break; - case SKINCOLOR_SUPERPURPLE2: - blendcolor = V_GetColor(162); - break; - case SKINCOLOR_SUPERPURPLE3: - blendcolor = V_GetColor(164); - break; - case SKINCOLOR_SUPERPURPLE4: - blendcolor = V_GetColor(166); - break; - case SKINCOLOR_SUPERPURPLE5: - blendcolor = V_GetColor(168); - break; - - case SKINCOLOR_SUPERRUST1: // Super rust - blendcolor = V_GetColor(51); - break; - case SKINCOLOR_SUPERRUST2: - blendcolor = V_GetColor(54); - break; - case SKINCOLOR_SUPERRUST3: - blendcolor = V_GetColor(68); - break; - case SKINCOLOR_SUPERRUST4: - blendcolor = V_GetColor(70); - break; - case SKINCOLOR_SUPERRUST5: - blendcolor = V_GetColor(234); - break; - - case SKINCOLOR_SUPERTAN1: // Super tan - blendcolor = V_GetColor(80); - break; - case SKINCOLOR_SUPERTAN2: - blendcolor = V_GetColor(82); - break; - case SKINCOLOR_SUPERTAN3: - blendcolor = V_GetColor(84); - break; - case SKINCOLOR_SUPERTAN4: - blendcolor = V_GetColor(87); - break; - case SKINCOLOR_SUPERTAN5: - blendcolor = V_GetColor(247); - break; - - default: - blendcolor = V_GetColor(255); - break; - } + if (color == SKINCOLOR_NONE || color >= MAXTRANSLATIONS) + blendcolor = V_GetColor(0xff); + else + blendcolor = V_GetColor(Color_Index[color-1][4]); while (size--) { diff --git a/src/p_enemy.c b/src/p_enemy.c index ee18985aa..80349a645 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4208,12 +4208,12 @@ void A_SignPlayer(mobj_t *actor) of in the name. If you have a better idea, feel free to let me know. ~toast 2016/07/20 */ - actor->frame += Color_Opposite[Color_Opposite[skin->prefoppositecolor*2]*2+1]; + actor->frame += (15 - Color_Opposite[(Color_Opposite[(skin->prefoppositecolor - 1)*2] - 1)*2 + 1]); } - else // Set the sign to be an appropriate background color for this player's skincolor. + else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor. { - actor->color = Color_Opposite[actor->target->player->skincolor*2]; - actor->frame += Color_Opposite[actor->target->player->skincolor*2+1]; + actor->color = Color_Opposite[(actor->target->player->skincolor - 1)*2]; + actor->frame += (15 - Color_Opposite[(actor->target->player->skincolor - 1)*2 + 1]); } if (skin->sprites[SPR2_SIGN].numframes) diff --git a/src/p_user.c b/src/p_user.c index 5506925e0..adaa78ed4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2280,7 +2280,7 @@ static void P_CheckInvincibilityTimer(player_t *player) return; if (mariomode && !player->powers[pw_super]) - player->mo->color = (UINT8)(SKINCOLOR_RED + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RED))); // Passes through all saturated colours + player->mo->color = (UINT8)(SKINCOLOR_RUBY + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RUBY))); // Passes through all saturated colours else if (leveltime % (TICRATE/7) == 0) { mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); diff --git a/src/r_draw.c b/src/r_draw.c index 30b60a0e0..a884cdf1f 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -126,47 +126,214 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define BOSS_TT_CACHE_INDEX (MAXSKINS + 1) #define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2) #define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3) -#define SKIN_RAMP_LENGTH 16 #define DEFAULT_STARTTRANSCOLOR 96 #define NUM_PALETTE_ENTRIES 256 static UINT8** translationtablecache[MAXSKINS + 4] = {NULL}; +const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = { + // {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_NONE + + // Greyscale ranges + {0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11}, // SKINCOLOR_WHITE + {0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x12}, // SKINCOLOR_BONE + {0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}, // SKINCOLOR_SILVER + {0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}, // SKINCOLOR_GREY + {0x02, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f}, // SKINCOLOR_CLOUDY + {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x17, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1c, 0x1d}, // SKINCOLOR_CARBON + {0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f}, // SKINCOLOR_JET + {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, // SKINCOLOR_BLACK + + // Desaturated + {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, // SKINCOLOR_AETHER + {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, // SKINCOLOR_SLATE + {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, // SKINCOLOR_PINK + {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, // SKINCOLOR_YOGURT + {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, // SKINCOLOR_BROWN + {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, // SKINCOLOR_TAN + {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, // SKINCOLOR_BEIGE + {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, // SKINCOLOR_MOSS + {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, // SKINCOLOR_AZURE + {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, // SKINCOLOR_LAVENDER + + // Viv's vivid colours (toast 21/07/17) + {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, // SKINCOLOR_RUBY + {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, // SKINCOLOR_SALMON + {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, // SKINCOLOR_RED + {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, // SKINCOLOR_CRIMSON + {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, // SKINCOLOR_FLAME + {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, // SKINCOLOR_PEACHY + {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, // SKINCOLOR_QUAIL + {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, // SKINCOLOR_SUNSET + {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, // SKINCOLOR_APRICOT + {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x2c}, // SKINCOLOR_ORANGE + {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, // SKINCOLOR_RUST + {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, // SKINCOLOR_GOLD + {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, // SKINCOLOR_SANDY + {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, // SKINCOLOR_YELLOW + {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, // SKINCOLOR_OLIVE + {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, // SKINCOLOR_LIME + {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, // SKINCOLOR_PERIDOT + {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, // SKINCOLOR_GREEN + {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, // SKINCOLOR_FOREST + {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, // SKINCOLOR_EMERALD + {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, // SKINCOLOR_MINT + {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, // SKINCOLOR_SEAFOAM + {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, // SKINCOLOR_AQUA + {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, // SKINCOLOR_TEAL + {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, // SKINCOLOR_WAVE + {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, // SKINCOLOR_CYAN + {0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, // SKINCOLOR_SKY + {0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, // SKINCOLOR_CERULEAN + {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, // SKINCOLOR_ICY + {0x80, 0x83, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, // SKINCOLOR_SAPPHIRE + {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, // SKINCOLOR_CORNFLOWER + {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, // SKINCOLOR_BLUE + {0x93, 0x94, 0x95, 0x96, 0x98, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfd, 0xfe, 0xfe}, // SKINCOLOR_COBALT + {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, // SKINCOLOR_VAPOR + {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, // SKINCOLOR_DUSK + {0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, // SKINCOLOR_PASTEL + {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, // SKINCOLOR_PURPLE + {0x00, 0xd0, 0xd0, 0xc8, 0xc8, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, // SKINCOLOR_BUBBLEGUM + {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, // SKINCOLOR_MAGENTA + {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, // SKINCOLOR_NEON + {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, // SKINCOLOR_VIOLET + {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, // SKINCOLOR_LILAC + {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, // SKINCOLOR_PLUM + {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, // SKINCOLOR_ROSY + + // {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_? + + // super + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, // SKINCOLOR_SUPERSILVER1 + {0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07}, // SKINCOLOR_SUPERSILVER2 + {0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b}, // SKINCOLOR_SUPERSILVER3 + {0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11}, // SKINCOLOR_SUPERSILVER4 + {0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13}, // SKINCOLOR_SUPERSILVER5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2}, // SKINCOLOR_SUPERRED1 + {0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21}, // SKINCOLOR_SUPERRED2 + {0x00, 0x00, 0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23}, // SKINCOLOR_SUPERRED3 + {0x00, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24}, // SKINCOLOR_SUPERRED4 + {0xd0, 0xd1, 0xd2, 0xd2, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25}, // SKINCOLOR_SUPERRED5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34}, // SKINCOLOR_SUPERORANGE1 + {0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34}, // SKINCOLOR_SUPERORANGE2 + {0x00, 0x00, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35}, // SKINCOLOR_SUPERORANGE3 + {0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERORANGE4 + {0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERORANGE5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48}, // SKINCOLOR_SUPERGOLD1 + {0x00, 0x50, 0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41}, // SKINCOLOR_SUPERGOLD2 + {0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43}, // SKINCOLOR_SUPERGOLD3 + {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERGOLD4 + {0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERGOLD5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, // SKINCOLOR_SUPERPERIDOT1 + {0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, // SKINCOLOR_SUPERPERIDOT2 + {0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf}, // SKINCOLOR_SUPERPERIDOT3 + {0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f}, // SKINCOLOR_SUPERPERIDOT4 + {0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f, 0x77}, // SKINCOLOR_SUPERPERIDOT5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84}, // SKINCOLOR_SUPERCYAN1 + {0x00, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86}, // SKINCOLOR_SUPERCYAN2 + {0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87}, // SKINCOLOR_SUPERCYAN3 + {0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a}, // SKINCOLOR_SUPERCYAN4 + {0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8b}, // SKINCOLOR_SUPERCYAN5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa2}, // SKINCOLOR_SUPERPURPLE1 + {0x00, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5}, // SKINCOLOR_SUPERPURPLE2 + {0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6}, // SKINCOLOR_SUPERPURPLE3 + {0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9}, // SKINCOLOR_SUPERPURPLE4 + {0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xfd}, // SKINCOLOR_SUPERPURPLE5 + + {0x00, 0xd0, 0xd0, 0xd0, 0x30, 0x30, 0x31, 0x32, 0x33, 0x37, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x2e}, // SKINCOLOR_SUPERRUST1 + {0x30, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x3a, 0x44, 0x45, 0x46, 0x47, 0x47, 0x2e}, // SKINCOLOR_SUPERRUST2 + {0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x3a, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x2e, 0x2e}, // SKINCOLOR_SUPERRUST3 + {0x48, 0x40, 0x41, 0x42, 0x43, 0x44, 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x47, 0x2e, 0x2e, 0x2e}, // SKINCOLOR_SUPERRUST4 + {0x41, 0x42, 0x43, 0x43, 0x44, 0x44, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef}, // SKINCOLOR_SUPERRUST5 + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52}, // SKINCOLOR_SUPERTAN1 + {0x00, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5}, // SKINCOLOR_SUPERTAN2 + {0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9}, // SKINCOLOR_SUPERTAN3 + {0x51, 0x52, 0x52, 0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed}, // SKINCOLOR_SUPERTAN4 + {0x52, 0x52, 0x54, 0x54, 0x54, 0x55, 0x56, 0x57, 0xf5, 0xf7, 0xf9, 0xfb, 0xed, 0xee, 0xef, 0xef} // SKINCOLOR_SUPERTAN5 +}; // See also the enum skincolors_t // TODO Callum: Can this be translated? const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] = { - "None", // SKINCOLOR_NONE - "White", // SKINCOLOR_WHITE - "Silver", // SKINCOLOR_SILVER - "Grey", // SKINCOLOR_GREY - "Black", // SKINCOLOR_BLACK - "Beige", // SKINCOLOR_BEIGE - "Peach", // SKINCOLOR_PEACH - "Brown", // SKINCOLOR_BROWN - "Red", // SKINCOLOR_RED - "Crimson", // SKINCOLOR_CRIMSON - "Orange", // SKINCOLOR_ORANGE - "Rust", // SKINCOLOR_RUST - "Gold", // SKINCOLOR_GOLD - "Yellow", // SKINCOLOR_YELLOW - "Tan", // SKINCOLOR_TAN - "Moss", // SKINCOLOR_MOSS - "Peridot", // SKINCOLOR_PERIDOT - "Green", // SKINCOLOR_GREEN - "Emerald", // SKINCOLOR_EMERALD - "Aqua", // SKINCOLOR_AQUA - "Teal", // SKINCOLOR_TEAL - "Cyan", // SKINCOLOR_CYAN - "Blue", // SKINCOLOR_BLUE - "Azure", // SKINCOLOR_AZURE - "Pastel", // SKINCOLOR_PASTEL - "Purple", // SKINCOLOR_PURPLE - "Lavender", // SKINCOLOR_LAVENDER - "Magenta", // SKINCOLOR_MAGENTA - "Pink", // SKINCOLOR_PINK - "Rosy", // SKINCOLOR_ROSY + "None", // SKINCOLOR_NONE, + + // Greyscale ranges + "White", // SKINCOLOR_WHITE, + "Bone", // SKINCOLOR_BONE, + "Siler", // SKINCOLOR_SILVER, + "Grey", // SKINCOLOR_GREY, + "Cloudy", // SKINCOLOR_CLOUDY, + "Carbon", // SKINCOLOR_CARBON, + "Jet", // SKINCOLOR_JET, + "Black", // SKINCOLOR_BLACK, + + // Desaturated + "Aether", // SKINCOLOR_AETHER, + "Slate", // SKINCOLOR_SLATE, + "Pink", // SKINCOLOR_PINK, + "Yogurt", // SKINCOLOR_YOGURT, + "Brown", // SKINCOLOR_BROWN, + "Tan", // SKINCOLOR_TAN, + "Beige", // SKINCOLOR_BEIGE, + "Moss", // SKINCOLOR_MOSS, + "Azure", // SKINCOLOR_AZURE, + "Lavender", // SKINCOLOR_LAVENDER, + + // Viv's vivid colours (toast 21/07/17) + "Ruby", // SKINCOLOR_RUBY, + "Salmon", // SKINCOLOR_SALMON, + "Red", // SKINCOLOR_RED, + "Crimson", // SKINCOLOR_CRIMSON, + "Flame", // SKINCOLOR_FLAME, + "Peachy", // SKINCOLOR_PEACHY, + "Quail", // SKINCOLOR_QUAIL, + "Sunset", // SKINCOLOR_SUNSET, + "Apricot", // SKINCOLOR_APRICOT, + "Orange", // SKINCOLOR_ORANGE, + "Rust", // SKINCOLOR_RUST, + "Gold", // SKINCOLOR_GOLD, + "Sandy", // SKINCOLOR_SANDY, + "Yellow", // SKINCOLOR_YELLOW, + "Olive", // SKINCOLOR_OLIVE, + "Lime", // SKINCOLOR_LIME, + "Peridot", // SKINCOLOR_PERIDOT, + "Green", // SKINCOLOR_GREEN, + "Forest", // SKINCOLOR_FOREST, + "Emerald", // SKINCOLOR_EMERALD, + "Mint", // SKINCOLOR_MINT, + "Seafoam", // SKINCOLOR_SEAFOAM, + "Aqua", // SKINCOLOR_AQUA, + "Teal", // SKINCOLOR_TEAL, + "Wave", // SKINCOLOR_WAVE, + "Cyan", // SKINCOLOR_CYAN, + "Sky", // SKINCOLOR_SKY, + "Cerulean", // SKINCOLOR_CERULEAN, + "Icy", // SKINCOLOR_ICY, + "Sapphire", // SKINCOLOR_SAPPHIRE, + "Cornflower", // SKINCOLOR_CORNFLOWER, + "Blue", // SKINCOLOR_BLUE, + "Cobalt", // SKINCOLOR_COBALT, + "Vapor", // SKINCOLOR_VAPOR, + "Dusk", // SKINCOLOR_DUSK, + "Pastel", // SKINCOLOR_PASTEL, + "Purple", // SKINCOLOR_PURPLE, + "Bubblegum", // SKINCOLOR_BUBBLEGUM, + "Magenta", // SKINCOLOR_MAGENTA, + "Neon", // SKINCOLOR_NEON, + "Violet", // SKINCOLOR_VIOLET, + "Lilac", // SKINCOLOR_LILAC, + "Plum", // SKINCOLOR_PLUM, + "Rosy", // SKINCOLOR_ROSY, + // Super behaves by different rules (one name per 5 colours), and will be accessed exclusively via R_GetSuperColorByName instead of R_GetColorByName. "Silver", // SKINCOLOR_SUPERSILVER1 "Red", // SKINCOLOR_SUPERRED1 @@ -183,38 +350,77 @@ const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] = A word of warning: If the following array is non-symmetrical, A_SignPlayer's prefoppositecolor behaviour will break. */ -const UINT8 Color_Opposite[MAXSKINCOLORS*2] = +const UINT8 Color_Opposite[(MAXSKINCOLORS - 1)*2] = { - SKINCOLOR_NONE,8, // SKINCOLOR_NONE - SKINCOLOR_BLACK,10, // SKINCOLOR_WHITE - SKINCOLOR_GREY,4, // SKINCOLOR_SILVER - SKINCOLOR_SILVER,12, // SKINCOLOR_GREY - SKINCOLOR_WHITE,8, // SKINCOLOR_BLACK - SKINCOLOR_BEIGE,8, // SKINCOLOR_BEIGE - needs new offset - SKINCOLOR_BROWN,8, // SKINCOLOR_PEACH - ditto - SKINCOLOR_PEACH,8, // SKINCOLOR_BROWN - ditto - SKINCOLOR_GREEN,5, // SKINCOLOR_RED - SKINCOLOR_CYAN,8, // SKINCOLOR_CRIMSON - ditto - SKINCOLOR_BLUE,11, // SKINCOLOR_ORANGE - SKINCOLOR_TAN,8, // SKINCOLOR_RUST - ditto - SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD - SKINCOLOR_TEAL,8, // SKINCOLOR_YELLOW - ditto - SKINCOLOR_RUST,8, // SKINCOLOR_TAN - ditto - SKINCOLOR_MAGENTA,3, // SKINCOLOR_MOSS - SKINCOLOR_PURPLE,8, // SKINCOLOR_PERIDOT - ditto - SKINCOLOR_RED,11, // SKINCOLOR_GREEN - SKINCOLOR_PASTEL,8, // SKINCOLOR_EMERALD - ditto - SKINCOLOR_ROSY,8, // SKINCOLOR_AQUA - ditto - SKINCOLOR_YELLOW,8, // SKINCOLOR_TEAL - ditto - SKINCOLOR_CRIMSON,8, // SKINCOLOR_CYAN - ditto - SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE - SKINCOLOR_PINK,8, // SKINCOLOR_AZURE - ditto - SKINCOLOR_EMERALD,8, // SKINCOLOR_PASTEL - ditto - SKINCOLOR_PERIDOT,10, // SKINCOLOR_PURPLE - SKINCOLOR_GOLD,10, // SKINCOLOR_LAVENDER - SKINCOLOR_MOSS,8, // SKINCOLOR_MAGENTA - ditto - SKINCOLOR_AZURE,8, // SKINCOLOR_PINK - ditto - SKINCOLOR_AQUA,14 // SKINCOLOR_ROSY + // SKINCOLOR_NONE,8, // SKINCOLOR_NONE + + // Greyscale ranges + SKINCOLOR_BLACK,5, // SKINCOLOR_WHITE, + SKINCOLOR_JET,7, // SKINCOLOR_BONE, + SKINCOLOR_CARBON,7, // SKINCOLOR_SILVER, + SKINCOLOR_AETHER,12, // SKINCOLOR_GREY, + SKINCOLOR_SLATE,12, // SKINCOLOR_CLOUDY, + SKINCOLOR_SILVER,7, // SKINCOLOR_CARBON, + SKINCOLOR_BONE,7, // SKINCOLOR_JET, + SKINCOLOR_WHITE,7, // SKINCOLOR_BLACK, + + // Desaturated + SKINCOLOR_GREY,15, // SKINCOLOR_AETHER, + SKINCOLOR_CLOUDY,12, // SKINCOLOR_SLATE, + SKINCOLOR_AZURE,9, // SKINCOLOR_PINK, + SKINCOLOR_RUST,7, // SKINCOLOR_YOGURT, + SKINCOLOR_TAN,2, // SKINCOLOR_BROWN, + SKINCOLOR_BROWN,12, // SKINCOLOR_TAN, + SKINCOLOR_MOSS,5, // SKINCOLOR_BEIGE, + SKINCOLOR_BEIGE,13, // SKINCOLOR_MOSS, + SKINCOLOR_PINK,5, // SKINCOLOR_AZURE, + SKINCOLOR_GOLD,4, // SKINCOLOR_LAVENDER, + + // Viv's vivid colours (toast 21/07/17) + SKINCOLOR_EMERALD,10, // SKINCOLOR_RUBY, + SKINCOLOR_FOREST,6, // SKINCOLOR_SALMON, + SKINCOLOR_GREEN,10, // SKINCOLOR_RED, + SKINCOLOR_ICY,10, // SKINCOLOR_CRIMSON, + SKINCOLOR_PURPLE,8, // SKINCOLOR_FLAME, + SKINCOLOR_TEAL,7, // SKINCOLOR_PEACHY, + SKINCOLOR_WAVE,5, // SKINCOLOR_QUAIL, + SKINCOLOR_SAPPHIRE,5, // SKINCOLOR_SUNSET, + SKINCOLOR_CYAN,4, // SKINCOLOR_APRICOT, + SKINCOLOR_BLUE,4, // SKINCOLOR_ORANGE, + SKINCOLOR_YOGURT,8, // SKINCOLOR_RUST, + SKINCOLOR_LAVENDER,10, // SKINCOLOR_GOLD, + SKINCOLOR_SKY,8, // SKINCOLOR_SANDY, + SKINCOLOR_CORNFLOWER,8, // SKINCOLOR_YELLOW, + SKINCOLOR_DUSK,3, // SKINCOLOR_OLIVE, + SKINCOLOR_MAGENTA,9, // SKINCOLOR_LIME, + SKINCOLOR_COBALT,2, // SKINCOLOR_PERIDOT, + SKINCOLOR_RED,6, // SKINCOLOR_GREEN, + SKINCOLOR_SALMON,9, // SKINCOLOR_FOREST, + SKINCOLOR_RUBY,4, // SKINCOLOR_EMERALD, + SKINCOLOR_VIOLET,5, // SKINCOLOR_MINT, + SKINCOLOR_PLUM,6, // SKINCOLOR_SEAFOAM, + SKINCOLOR_ROSY,7, // SKINCOLOR_AQUA, + SKINCOLOR_PEACHY,7, // SKINCOLOR_TEAL, + SKINCOLOR_QUAIL,5, // SKINCOLOR_WAVE, + SKINCOLOR_APRICOT,6, // SKINCOLOR_CYAN, + SKINCOLOR_SANDY,1, // SKINCOLOR_SKY, + SKINCOLOR_NEON,4, // SKINCOLOR_CERULEAN, + SKINCOLOR_CRIMSON,0, // SKINCOLOR_ICY, + SKINCOLOR_SUNSET,5, // SKINCOLOR_SAPPHIRE, + SKINCOLOR_YELLOW,4, // SKINCOLOR_CORNFLOWER, + SKINCOLOR_ORANGE,5, // SKINCOLOR_BLUE, + SKINCOLOR_PERIDOT,5, // SKINCOLOR_COBALT, + SKINCOLOR_LILAC,4, // SKINCOLOR_VAPOR, + SKINCOLOR_OLIVE,0, // SKINCOLOR_DUSK, + SKINCOLOR_BUBBLEGUM,9, // SKINCOLOR_PASTEL, + SKINCOLOR_FLAME,7, // SKINCOLOR_PURPLE, + SKINCOLOR_PASTEL,8, // SKINCOLOR_BUBBLEGUM, + SKINCOLOR_LIME,6, // SKINCOLOR_MAGENTA, + SKINCOLOR_CERULEAN,2, // SKINCOLOR_NEON, + SKINCOLOR_MINT,6, // SKINCOLOR_VIOLET, + SKINCOLOR_VAPOR,4, // SKINCOLOR_LILAC, + SKINCOLOR_MINT,7, // SKINCOLOR_PLUM, + SKINCOLOR_AQUA,1 // SKINCOLOR_ROSY, }; CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; @@ -258,40 +464,7 @@ void R_InitTranslationTables(void) */ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) { - // Table of indices into the palette of the first entries of each translated ramp - const UINT8 skinbasecolors[] = { - 0x00, // SKINCOLOR_WHITE - 0x03, // SKINCOLOR_SILVER - 0x08, // SKINCOLOR_GREY - 0x18, // SKINCOLOR_BLACK - 0xf0, // SKINCOLOR_BEIGE - 0xd8, // SKINCOLOR_PEACH - 0xe0, // SKINCOLOR_BROWN - 0x21, // SKINCOLOR_RED - 0x28, // SKINCOLOR_CRIMSON - 0x31, // SKINCOLOR_ORANGE - 0x3a, // SKINCOLOR_RUST - 0x40, // SKINCOLOR_GOLD - 0x48, // SKINCOLOR_YELLOW - 0x54, // SKINCOLOR_TAN - 0x58, // SKINCOLOR_MOSS - 0xbc, // SKINCOLOR_PERIDOT - 0x60, // SKINCOLOR_GREEN - 0x70, // SKINCOLOR_EMERALD - 0x78, // SKINCOLOR_AQUA - 0x8c, // SKINCOLOR_TEAL - 0x80, // SKINCOLOR_CYAN - 0x92, // SKINCOLOR_BLUE - 0xaa, // SKINCOLOR_AZURE - 0xa0, // SKINCOLOR_PASTEL - 0xa0, // SKINCOLOR_PURPLE - 0xc0, // SKINCOLOR_LAVENDER - 0xb3, // SKINCOLOR_MAGENTA - 0xd0, // SKINCOLOR_PINK - 0xc8, // SKINCOLOR_ROSY - }; - INT32 i; - INT32 starttranscolor; + INT32 i, starttranscolor, skinramplength; // Handle a couple of simple special cases if (skinnum == TC_BOSS || skinnum == TC_ALLWHITE || skinnum == TC_METALSONIC || color == SKINCOLOR_NONE) @@ -311,776 +484,28 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U return; } + if (color >= MAXTRANSLATIONS) + I_Error("Invalid skin color #%hu.", (UINT16)color); + starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR; // Fill in the entries of the palette that are fixed for (i = 0; i < starttranscolor; i++) dest_colormap[i] = (UINT8)i; - for (i = (UINT8)(starttranscolor + 16); i < NUM_PALETTE_ENTRIES; i++) - dest_colormap[i] = (UINT8)i; + i = starttranscolor + 16; + if (i < NUM_PALETTE_ENTRIES) + { + for (i = (UINT8)i; i < NUM_PALETTE_ENTRIES; i++) + dest_colormap[i] = (UINT8)i; + skinramplength = 16; + } + else + skinramplength = i - NUM_PALETTE_ENTRIES; // Build the translated ramp - switch (color) - { - case SKINCOLOR_SILVER: - case SKINCOLOR_GREY: - case SKINCOLOR_BROWN: - case SKINCOLOR_GREEN: - // 16 color ramp - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); - break; - - case SKINCOLOR_WHITE: - case SKINCOLOR_CYAN: - // 12 color ramp - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (12*i/SKIN_RAMP_LENGTH)); - break; - - case SKINCOLOR_BLACK: - case SKINCOLOR_MOSS: - case SKINCOLOR_EMERALD: - case SKINCOLOR_LAVENDER: - case SKINCOLOR_PINK: - // 8 color ramp - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1)); - break; - - case SKINCOLOR_BEIGE: - // 13 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i == 15) - dest_colormap[starttranscolor + i] = 0xed; // Darkest - else if (i <= 6) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + ((i + 1) >> 1)); // Brightest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 3); - } - break; - - case SKINCOLOR_PEACH: - // 11 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i == 0) - dest_colormap[starttranscolor + i] = 0xD0; // Lightest 1 - else if (i == 1) - dest_colormap[starttranscolor + i] = 0x30; // Lightest 2 - else if (i <= 11) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1); - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 7); // Darkest - } - break; - - case SKINCOLOR_RED: - // 16 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i == 13) - dest_colormap[starttranscolor + i] = 0x47; // Semidark - else if (i > 13) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 1); // Darkest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); - } - break; - - case SKINCOLOR_CRIMSON: - // 9 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i/2 == 6) - dest_colormap[starttranscolor + i] = 0x47; // Semidark - else if (i/2 == 7) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 8); // Darkest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1)); - } - break; - - case SKINCOLOR_ORANGE: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i == 15) - dest_colormap[starttranscolor + i] = 0x2c; // Darkest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); - } - break; - - case SKINCOLOR_RUST: - // 10 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i <= 11) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1)); - else if (i == 12) - dest_colormap[starttranscolor + i] = 0x2c; - else if (i <= 14) - dest_colormap[starttranscolor + i] = 0x2d; - else - dest_colormap[starttranscolor + i] = 0x48; - } - break; - - case SKINCOLOR_GOLD: - // 10 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i == 0) - dest_colormap[starttranscolor + i] = 0x50; // Lightest 1 - else if (i == 1) - dest_colormap[starttranscolor + i] = 0x53; // Lightest 2 - else if (i/2 == 7) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 8); //Darkest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1); - } - break; - - case SKINCOLOR_YELLOW: - // 10 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i == 0) - dest_colormap[starttranscolor + i] = 0x53; // Lightest - else if (i == 15) - dest_colormap[starttranscolor + i] = 0xed; // Darkest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1)); - } - break; - - case SKINCOLOR_TAN: - // 8 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i/2 == 0) - dest_colormap[starttranscolor + i] = 0x51; // Lightest - else if (i/2 == 5) - dest_colormap[starttranscolor + i] = 0xf5; // Darkest 1 - else if (i/2 == 6) - dest_colormap[starttranscolor + i] = 0xf9; // Darkest 2 - else if (i/2 == 7) - dest_colormap[starttranscolor + i] = 0xed; // Darkest 3 - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1); - } - break; - - case SKINCOLOR_PERIDOT: - // 8 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i/2 == 0) - dest_colormap[starttranscolor + i] = 0x58; // Lightest - else if (i/2 == 7) - dest_colormap[starttranscolor + i] = 0x77; // Darkest - else if (i/2 >= 5) - dest_colormap[starttranscolor + i] = (UINT8)(0x5e + (i >> 1) - 5); // Semidark - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1); - } - break; - - case SKINCOLOR_AQUA: - // 10 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i == 0) - dest_colormap[starttranscolor + i] = 0x78; // Lightest - else if (i >= 14) - dest_colormap[starttranscolor + i] = (UINT8)(0x76 + i - 14); // Darkest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) + 1); - } - break; - - case SKINCOLOR_TEAL: - // 6 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i <= 1) - dest_colormap[starttranscolor + i] = 0x78; // Lightest - else if (i >= 13) - dest_colormap[starttranscolor + i] = 0x8a; // Darkest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + ((i - 1)/3)); - } - break; - - case SKINCOLOR_AZURE: - // 8 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i <= 3) - dest_colormap[starttranscolor + i] = (UINT8)(0x90 + i/2); // Lightest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 2); - } - break; - - case SKINCOLOR_BLUE: - // 16 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i == 15) - dest_colormap[starttranscolor + i] = 0xfe; //Darkest 1 - else if (i == 14) - dest_colormap[starttranscolor + i] = 0xfd; //Darkest 2 - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); - } - break; - - case SKINCOLOR_PASTEL: - // 10 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i >= 12) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 7); // Darkest - else if (i <= 1) - dest_colormap[starttranscolor + i] = 0x90; // Lightest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1); - } - break; - - case SKINCOLOR_PURPLE: - // 10 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i <= 3) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); // Lightest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) + 2); - } - break; - - case SKINCOLOR_MAGENTA: - // 9 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - if (i == 0) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1]); // Lightest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) + 1); - break; - - case SKINCOLOR_ROSY: - // 9 colors - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - { - if (i == 0) - dest_colormap[starttranscolor + i] = 0xfc; // Lightest - else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + ((i - 1) >> 1)); - } - break; - - // Super colors, from lightest to darkest! - - // Super silvers. - case SKINCOLOR_SUPERSILVER1: - for (i = 0; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 14; i++) - dest_colormap[starttranscolor + i] = (UINT8)1; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(i-12); - break; - - case SKINCOLOR_SUPERSILVER2: - for (i = 0; i < 3; i++) - dest_colormap[starttranscolor + i] = (UINT8)(i); - dest_colormap[starttranscolor + (i++)] = (UINT8)2; - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)3; - for (; i < 14; i++) - dest_colormap[starttranscolor + i] = (UINT8)4; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(i-9); - break; - - case SKINCOLOR_SUPERSILVER3: - dest_colormap[starttranscolor] = (UINT8)1; - for (i = 1; i < 3; i++) - dest_colormap[starttranscolor + i] = (UINT8)2; - for (; i < 6; i++) - dest_colormap[starttranscolor + i] = (UINT8)3; - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)4; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-12)*2)); - break; - - case SKINCOLOR_SUPERSILVER4: - dest_colormap[starttranscolor] = (UINT8)2; - for (i = 1; i < 3; i++) - dest_colormap[starttranscolor + i] = (UINT8)3; - for (; i < 9; i++) - dest_colormap[starttranscolor + i] = (UINT8)4; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-9)*2)); - break; - - case SKINCOLOR_SUPERSILVER5: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)3; - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)4; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-8)*2)); - break; - - // Super reds. - case SKINCOLOR_SUPERRED1: - for (i = 0; i < 10; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-10) >> 1)); - break; - - case SKINCOLOR_SUPERRED2: - for (i = 0; i < 3; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-3) / 3)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-12) >> 1)); - break; - - case SKINCOLOR_SUPERRED3: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-2) >> 1)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-8) >> 1)); - break; - - case SKINCOLOR_SUPERRED4: - dest_colormap[starttranscolor] = (UINT8)0; - for (i = 1; i < 6; i++) - dest_colormap[starttranscolor + i] = (UINT8)(208 + (i >> 1)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-6) >> 1)); - break; - - case SKINCOLOR_SUPERRED5: - dest_colormap[starttranscolor] = (UINT8)208; - for (i = 1; i < 4; i++) - dest_colormap[starttranscolor + i] = (UINT8)(209 + (i >> 1)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-4) >> 1)); - break; - - // Super oranges. - case SKINCOLOR_SUPERORANGE1: - for (i = 0; i < 10; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - dest_colormap[starttranscolor + (i++)] = (UINT8)208; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-11)); - break; - - case SKINCOLOR_SUPERORANGE2: - for (i = 0; i < 4; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 6; i++) - dest_colormap[starttranscolor + i] = (UINT8)208; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(48 + ((i-6) >> 1)); - break; - - case SKINCOLOR_SUPERORANGE3: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 4; i++) - dest_colormap[starttranscolor + i] = (UINT8)208; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(48 + ((i-4) >> 1)); - break; - - case SKINCOLOR_SUPERORANGE4: - dest_colormap[starttranscolor] = (UINT8)0; - dest_colormap[starttranscolor + 1] = (UINT8)208; - for (i = 2; i < 13; i++) - dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-2)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-13)); - break; - - case SKINCOLOR_SUPERORANGE5: - dest_colormap[starttranscolor] = (UINT8)208; - for (i = 1; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-1)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-12)); - break; - - // Super golds. - case SKINCOLOR_SUPERGOLD1: - for (i = 0; i < 10; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; // True white - for (; i < 12; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)80; - for (; i < 15; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)(81 + (i-12)); - dest_colormap[starttranscolor + 15] = (UINT8)72; - break; - - case SKINCOLOR_SUPERGOLD2: - dest_colormap[starttranscolor] = (UINT8)(0); - for (i = 1; i < 4; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1)); - for (; i < 6; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)83; - for (; i < 8; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)72; - for (; i < 14; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)73; - for (; i < 16; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-14)); - break; - - case SKINCOLOR_SUPERGOLD3: - for (i = 0; i < 2; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)(81 + i); - for (; i < 4; i++) - dest_colormap[starttranscolor + i] = (UINT8)83; - for (; i < 6; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)72; - for (; i < 12; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)73; - for (; i < 16; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-12)); - break; - - case SKINCOLOR_SUPERGOLD4: // "The SSNTails" - dest_colormap[starttranscolor] = (UINT8)83; // Golden shine - for (i = 1; i < 3; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(72); - for (; i < 9; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(73); - for (; i < 16; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-9)); - break; - - case SKINCOLOR_SUPERGOLD5: // Golden Delicious - for (i = 0; i < 2; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(72); - for (; i < 8; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(73); - for (; i < 16; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-8)); - break; - - // Super peridots. (nyeheheheh) - case SKINCOLOR_SUPERPERIDOT1: - for (i = 0; i < 10; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 13; i++) - dest_colormap[starttranscolor + i] = (UINT8)88; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)188; - break; - - case SKINCOLOR_SUPERPERIDOT2: - dest_colormap[starttranscolor] = (UINT8)(0); - for (i = 1; i < 4; i++) - dest_colormap[starttranscolor + i] = (UINT8)88; - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)188; - for (; i < 14; i++) - dest_colormap[starttranscolor + i] = (UINT8)189; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)190; - break; - - case SKINCOLOR_SUPERPERIDOT3: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)88; - for (; i < 6; i++) - dest_colormap[starttranscolor + i] = (UINT8)188; - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)189; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-12) >> 1)); - break; - - case SKINCOLOR_SUPERPERIDOT4: - dest_colormap[starttranscolor] = (UINT8)88; - for (i = 1; i < 3; i++) - dest_colormap[starttranscolor + i] = (UINT8)188; - for (; i < 9; i++) - dest_colormap[starttranscolor + i] = (UINT8)189; - for (; i < 13; i++) - dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-9) >> 1)); - for (; i < 15; i++) - dest_colormap[starttranscolor + i] = (UINT8)94; - dest_colormap[starttranscolor + i] = (UINT8)95; - break; - - case SKINCOLOR_SUPERPERIDOT5: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)188; - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)189; - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-8) >> 1)); - for (; i < 14; i++) - dest_colormap[starttranscolor + i] = (UINT8)94; - dest_colormap[starttranscolor + (i++)] = (UINT8)95; - dest_colormap[starttranscolor + i] = (UINT8)119; - break; - - // Super cyans. - case SKINCOLOR_SUPERCYAN1: - for (i = 0; i < 10; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)128; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(129 + (i-12)); - break; - - case SKINCOLOR_SUPERCYAN2: - dest_colormap[starttranscolor] = (UINT8)0; - for (i = 1; i < 4; i++) - dest_colormap[starttranscolor + i] = (UINT8)(128 + (i-1)); - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)(131 + ((i-4) >> 1)); - for (; i < 14; i++) - dest_colormap[starttranscolor + i] = (UINT8)133; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)134; - break; - - case SKINCOLOR_SUPERCYAN3: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)(129 + i); - for (; i < 6; i++) - dest_colormap[starttranscolor + i] = (UINT8)(131 + ((i-2) >> 1)); - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)133; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-12) >> 1)); - break; - - case SKINCOLOR_SUPERCYAN4: - dest_colormap[starttranscolor] = (UINT8)131; - for (i = 1; i < 3; i++) - dest_colormap[starttranscolor + i] = (UINT8)132; - for (; i < 9; i++) - dest_colormap[starttranscolor + i] = (UINT8)133; - for (; i < 13; i++) - dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-9) >> 1)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(136 + (i-13)); - break; - - case SKINCOLOR_SUPERCYAN5: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)132; - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)133; - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-8) >> 1)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(136 + (i-12)); - break; - - // Super purples. - case SKINCOLOR_SUPERPURPLE1: - for (i = 0; i < 10; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)144; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(160 + (i-12)); - break; - - case SKINCOLOR_SUPERPURPLE2: - dest_colormap[starttranscolor] = (UINT8)0; - dest_colormap[starttranscolor + 1] = (UINT8)144; - for (i = 2; i < 4; i++) - dest_colormap[starttranscolor + i] = (UINT8)(160 + (i-2)); - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)(162 + ((i-4) >> 1)); - for (; i < 14; i++) - dest_colormap[starttranscolor + i] = (UINT8)164; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)165; - break; - - case SKINCOLOR_SUPERPURPLE3: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)(160 + i); - for (; i < 6; i++) - dest_colormap[starttranscolor + i] = (UINT8)(162 + ((i-2) >> 1)); - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)164; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-12) >> 1)); - break; - - case SKINCOLOR_SUPERPURPLE4: - dest_colormap[starttranscolor] = (UINT8)162; - for (i = 1; i < 3; i++) - dest_colormap[starttranscolor + i] = (UINT8)163; - for (; i < 9; i++) - dest_colormap[starttranscolor + i] = (UINT8)164; - for (; i < 13; i++) - dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-9) >> 1)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(167 + (i-13)); - break; - - case SKINCOLOR_SUPERPURPLE5: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)163; - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)164; - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-8) >> 1)); - for (; i < 15; i++) - dest_colormap[starttranscolor + i] = (UINT8)(167 + (i-12)); - dest_colormap[starttranscolor + i] = (UINT8)253; - break; - - // Super rusts. - case SKINCOLOR_SUPERRUST1: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 5; i++) - dest_colormap[starttranscolor + i] = (UINT8)208; - for (; i < 7; i++) - dest_colormap[starttranscolor + i] = (UINT8)48; - for (; i < 10; i++) - dest_colormap[starttranscolor + i] = (UINT8)(49 + (i-7)); - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)(55 + ((i-10)*3)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-11)); - break; - - case SKINCOLOR_SUPERRUST2: - for (i = 0; i < 4; i++) - dest_colormap[starttranscolor + i] = (UINT8)48; - for (; i < 9; i++) - dest_colormap[starttranscolor + i] = (UINT8)(49 + (i-4)); - for (; i < 11; i++) - dest_colormap[starttranscolor + i] = (UINT8)(56 + ((i-9)*2)); - for (; i < 15; i++) - dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-11)); - dest_colormap[starttranscolor + i] = (UINT8)71; - break; - - case SKINCOLOR_SUPERRUST3: - dest_colormap[starttranscolor] = (UINT8)49; - for (i = 1; i < 3; i++) - dest_colormap[starttranscolor + i] = (UINT8)50; - for (; i < 5; i++) - dest_colormap[starttranscolor + i] = (UINT8)(51 + (i-3)); - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)(54 + (i-5)); - dest_colormap[starttranscolor + (i++)] = (UINT8)58; - for (; i < 15; i++) - dest_colormap[starttranscolor + i] = (UINT8)(68 + ((i-7) >> 1)); - dest_colormap[starttranscolor + i] = (UINT8)46; - break; - - case SKINCOLOR_SUPERRUST4: - dest_colormap[starttranscolor] = (UINT8)83; - dest_colormap[starttranscolor + 1] = (UINT8)72; - for (i = 2; i < 6; i++) - dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-2)); - for (; i < 14; i++) - dest_colormap[starttranscolor + i] = (UINT8)(68 + ((i-6) >> 1)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)46; - break; - - case SKINCOLOR_SUPERRUST5: - for (i = 0; i < 3; i++) - dest_colormap[starttranscolor + i] = (UINT8)(64 + i); - for (; i < 7; i++) - dest_colormap[starttranscolor + i] = (UINT8)(67 + ((i-3) >> 1)); - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)(233 + (i-7)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(238 + ((i-12) >> 1)); - break; - - // Super tans. - case SKINCOLOR_SUPERTAN1: - for (i = 0; i < 10; i++) - dest_colormap[starttranscolor + i] = (UINT8)0; - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-10) >> 1)); - break; - - case SKINCOLOR_SUPERTAN2: - dest_colormap[starttranscolor] = (UINT8)0; - for (i = 1; i < 7; i++) - dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-1) >> 1)); - dest_colormap[starttranscolor + (i++)] = (UINT8)82; - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)84; - for (; i < 15; i++) - dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-12)); - dest_colormap[starttranscolor + i] = (UINT8)245; - break; - - case SKINCOLOR_SUPERTAN3: - dest_colormap[starttranscolor] = (UINT8)80; - for (i = 1; i < 5; i++) - dest_colormap[starttranscolor + i] = (UINT8)(81 + ((i-1) >> 1)); - dest_colormap[starttranscolor + (i++)] = (UINT8)82; - for (; i < 10; i++) - dest_colormap[starttranscolor + i] = (UINT8)84; - for (; i < 13; i++) - dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-10)); - for (; i < 16; i++) - dest_colormap[starttranscolor + i] = (UINT8)(245 + ((i-13)*2)); - break; - - case SKINCOLOR_SUPERTAN4: - dest_colormap[starttranscolor] = (UINT8)81; - for (i = 1; i < 5; i++) - dest_colormap[starttranscolor + i] = (UINT8)82; - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)84; - for (; i < 11; i++) - dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-8)); - for (; i < 15; i++) - dest_colormap[starttranscolor + i] = (UINT8)(245 + ((i-11)*2)); - dest_colormap[starttranscolor + i] = (UINT8)237; - break; - - case SKINCOLOR_SUPERTAN5: - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + i] = (UINT8)82; - for (; i < 5; i++) - dest_colormap[starttranscolor + i] = (UINT8)84; - for (; i < 8; i++) - dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-5)); - for (; i < 12; i++) - dest_colormap[starttranscolor + i] = (UINT8)(245 + (i-8)); - for (; i < 15; i++) - dest_colormap[starttranscolor + i] = (UINT8)(237 + (i-12)); - dest_colormap[starttranscolor + i] = (UINT8)239; - break; - - default: - I_Error("Invalid skin color #%hu.", (UINT16)color); - break; - } + for (i = 0; i < skinramplength; i++) + dest_colormap[starttranscolor + i] = (UINT8)Color_Index[color-1][i]; } From 634c560e992fef42c3bb3ff3d03376189a62fc50 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 23 Jul 2017 17:49:19 +0100 Subject: [PATCH 53/61] * Who wore it better? https://cdn.discordapp.com/attachments/293238104096112641/338696939774279680/srb20037.png * Now that Cyan is back, swap out the substitute Teal in the emblems for it. * P_GetMobjSprite2 is now P_GetSkinSprite2. * Correct "Siler". --- src/lua_mobjlib.c | 2 +- src/m_cond.c | 20 ++--- src/m_menu.c | 214 ++++++++++++++++++++++++++++++++-------------- src/p_local.h | 1 - src/p_mobj.c | 205 +++----------------------------------------- src/r_draw.c | 2 +- src/r_things.c | 189 +++++++++++++++++++++++++++++++++++++++- src/r_things.h | 2 + 8 files changed, 360 insertions(+), 275 deletions(-) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 2fcccab66..d384b75d1 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -417,7 +417,7 @@ static int mobj_set(lua_State *L) mo->frame = (UINT32)luaL_checkinteger(L, 3); break; case mobj_sprite2: - mo->sprite2 = P_GetMobjSprite2(mo, (UINT8)luaL_checkinteger(L, 3)); + mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), (UINT8)luaL_checkinteger(L, 3), mo->player); break; case mobj_anim_duration: mo->anim_duration = (UINT16)luaL_checkinteger(L, 3); diff --git a/src/m_cond.c b/src/m_cond.c index b7735d4ce..9339c4989 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -499,63 +499,63 @@ emblem_t emblemlocations[MAXEMBLEMS] = // FLORAL FIELD // --- {0, 5394, -996, 160, 50, 'N', SKINCOLOR_RUST, 0, "", 0}, - {ET_NGRADE, 0,0,0, 50, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, + {ET_NGRADE, 0,0,0, 50, 'Q', SKINCOLOR_CYAN, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 50, 'T', SKINCOLOR_GREY, 40*TICRATE, "", 0}, // TOXIC PLATEAU // --- {0, 780, -1664, 32, 51, 'N', SKINCOLOR_RUST, 0, "", 0}, - {ET_NGRADE, 0,0,0, 51, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, + {ET_NGRADE, 0,0,0, 51, 'Q', SKINCOLOR_CYAN, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 51, 'T', SKINCOLOR_GREY, 50*TICRATE, "", 0}, // FLOODED COVE // --- {0, 1824, -1888, 2448, 52, 'N', SKINCOLOR_RUST, 0, "", 0}, - {ET_NGRADE, 0,0,0, 52, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, + {ET_NGRADE, 0,0,0, 52, 'Q', SKINCOLOR_CYAN, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 52, 'T', SKINCOLOR_GREY, 90*TICRATE, "", 0}, // CAVERN FORTRESS // --- {0, -3089, -431, 1328, 53, 'N', SKINCOLOR_RUST, 0, "", 0}, - {ET_NGRADE, 0,0,0, 53, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, + {ET_NGRADE, 0,0,0, 53, 'Q', SKINCOLOR_CYAN, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 53, 'T', SKINCOLOR_GREY, 75*TICRATE, "", 0}, // DUSTY WASTELAND // --- {0, 957, 924, 2956, 54, 'N', SKINCOLOR_RUST, 0, "", 0}, - {ET_NGRADE, 0,0,0, 54, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, + {ET_NGRADE, 0,0,0, 54, 'Q', SKINCOLOR_CYAN, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 54, 'T', SKINCOLOR_GREY, 65*TICRATE, "", 0}, // MAGMA CAVES // --- {0, -2752, 3104, 1800, 55, 'N', SKINCOLOR_RUST, 0, "", 0}, - {ET_NGRADE, 0,0,0, 55, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, + {ET_NGRADE, 0,0,0, 55, 'Q', SKINCOLOR_CYAN, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 55, 'T', SKINCOLOR_GREY, 80*TICRATE, "", 0}, // EGG SATELLITE // --- {0, 5334, -609, 3426, 56, 'N', SKINCOLOR_RUST, 0, "", 0}, - {ET_NGRADE, 0,0,0, 56, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, + {ET_NGRADE, 0,0,0, 56, 'Q', SKINCOLOR_CYAN, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 56, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // BLACK HOLE // --- {0, 2108, 3776, 32, 57, 'N', SKINCOLOR_RUST, 0, "", 0}, - {ET_NGRADE, 0,0,0, 57, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, + {ET_NGRADE, 0,0,0, 57, 'Q', SKINCOLOR_CYAN, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 57, 'T', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // SPRING HILL // --- {0, -1840, -1024, 1644, 58, 'N', SKINCOLOR_RUST, 0, "", 0}, - {ET_NGRADE, 0,0,0, 58, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, + {ET_NGRADE, 0,0,0, 58, 'Q', SKINCOLOR_CYAN, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 58, 'T', SKINCOLOR_GREY, 60*TICRATE, "", 0}, }; @@ -566,7 +566,7 @@ extraemblem_t extraemblems[MAXEXTRAEMBLEMS] = {"All Emeralds", "Complete 1P Mode with all Emeralds", 11, 'V', SKINCOLOR_GREY, 0}, {"Perfect Bonus", "Perfect Bonus on a non-secret stage", 30, 'P', SKINCOLOR_GOLD, 0}, {"PLACEHOLDER", "PLACEHOLDER", 0, 'O', SKINCOLOR_RUST, 0}, - {"NiGHTS Mastery", "Show your mastery of NiGHTS!", 22, 'W', SKINCOLOR_TEAL, 0}, + {"NiGHTS Mastery", "Show your mastery of NiGHTS!", 22, 'W', SKINCOLOR_CYAN, 0}, }; // Default Unlockables diff --git a/src/m_menu.c b/src/m_menu.c index fc59325a7..ed6bbd32b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1012,8 +1012,8 @@ static menuitem_t MP_ConnectIPMenu[] = static menuitem_t MP_PlayerSetupMenu[] = { {IT_KEYHANDLER | IT_STRING, NULL, "Your name", M_HandleSetupMultiPlayer, 0}, - {IT_KEYHANDLER | IT_STRING, NULL, "Your color", M_HandleSetupMultiPlayer, 16}, - {IT_KEYHANDLER | IT_STRING, NULL, "Your player", M_HandleSetupMultiPlayer, 96}, // Tails 01-18-2001 + {IT_KEYHANDLER | IT_STRING, NULL, "Your player", M_HandleSetupMultiPlayer, 0}, // Tails 01-18-2001 + {IT_KEYHANDLER | IT_STRING, NULL, "Your color", M_HandleSetupMultiPlayer, 0}, }; // ------------------------------------ @@ -1738,7 +1738,7 @@ menu_t MP_PlayerSetupDef = &MP_MainDef, MP_PlayerSetupMenu, M_DrawSetupMultiPlayerMenu, - 27, 40, + 19, 26, 0, M_QuitMultiPlayerMenu }; @@ -5268,7 +5268,7 @@ static void M_DrawSkyRoom(void) '\x1C' | V_YELLOWMAP, false); V_DrawCharacter(BASEVIDWIDTH - currentMenu->x + 2 + (skullAnimCounter/5), currentMenu->y + y, '\x1D' | V_YELLOWMAP, false); - } + } if (cv_soundtest.value) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + y + 8, V_YELLOWMAP, S_sfx[cv_soundtest.value].name); } @@ -7681,11 +7681,9 @@ static void M_HandleConnectIP(INT32 choice) // ======================== // Tails 03-02-2002 -#define PLBOXW 8 -#define PLBOXH 9 - static UINT8 multi_tics; static UINT8 multi_frame; +static UINT8 multi_spr2; // this is set before entering the MultiPlayer setup menu, // for either player 1 or 2 @@ -7699,33 +7697,54 @@ static INT32 setupm_fakecolor; static void M_DrawSetupMultiPlayerMenu(void) { - INT32 mx, my, flags = 0; + INT32 x, y, cursory = 0, flags = 0; spritedef_t *sprdef; spriteframe_t *sprframe; patch_t *patch; + UINT8 *colormap; - mx = MP_PlayerSetupDef.x; - my = MP_PlayerSetupDef.y; + x = MP_PlayerSetupDef.x; + y = MP_PlayerSetupDef.y; // use generic drawer for cursor, items and title - M_DrawGenericMenu(); + //M_DrawGenericMenu(); + + // draw title (or big pic) + M_DrawMenuTitle(); + + M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Name", true); + if (itemOn == 0) + cursory = y; + y += 11; // draw name string - M_DrawTextBox(mx + 90, my - 8, MAXPLAYERNAME, 1); - V_DrawString(mx + 98, my, V_ALLOWLOWERCASE, setupm_name); + V_DrawFill(x, y, 282/*(MAXPLAYERNAME+1)*8+6*/, 14, 159); + V_DrawString(x + 8, y + 3, V_ALLOWLOWERCASE, setupm_name); + if (skullAnimCounter < 4 && itemOn == 0) + V_DrawCharacter(x + 8 + V_StringWidth(setupm_name, V_ALLOWLOWERCASE), y + 3, + '_' | 0x80, false); + + y += 20; + + M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Character", true); + if (itemOn == 1) + cursory = y; // draw skin string - V_DrawString(mx + 90, my + 96, - ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|V_YELLOWMAP|V_ALLOWLOWERCASE, + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, + ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|(itemOn == 1 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, skins[setupm_fakeskin].realname); - // draw the name of the color you have chosen - // Just so people don't go thinking that "Default" is Green. - V_DrawString(208, 72, V_YELLOWMAP|V_ALLOWLOWERCASE, Color_Names[setupm_fakecolor]); + if (itemOn == 1 && (MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(skins[setupm_fakeskin].realname, V_ALLOWLOWERCASE) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } - // draw text cursor for name - if (!itemOn && skullAnimCounter < 4) // blink cursor - V_DrawCharacter(mx + 98 + V_StringWidth(setupm_name, 0), my, '_',false); + x = BASEVIDWIDTH/2; + y += 11; // anim the player in the box if (--multi_tics <= 0) @@ -7734,14 +7753,18 @@ static void M_DrawSetupMultiPlayerMenu(void) multi_tics = 4; } - // skin 0 is default player sprite - if (R_SkinAvailable(skins[setupm_fakeskin].name) != -1) - sprdef = &skins[R_SkinAvailable(skins[setupm_fakeskin].name)].sprites[SPR2_WALK]; - else - sprdef = &skins[0].sprites[SPR2_WALK]; +#define charw 74 - if (!sprdef->numframes) // No frames ?? - return; // Can't render! + // draw box around character + V_DrawFill(x-(charw/2), y, charw, 84, 159); + + sprdef = &skins[setupm_fakeskin].sprites[multi_spr2]; + + if (!setupm_fakecolor || !sprdef->numframes) // should never happen but hey, who knows + goto faildraw; + + // ok, draw player sprite for sure now + colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor, 0); if (multi_frame >= sprdef->numframes) multi_frame = 0; @@ -7751,38 +7774,82 @@ static void M_DrawSetupMultiPlayerMenu(void) if (sprframe->flip & 1) // Only for first sprite flags |= V_FLIP; // This sprite is left/right flipped! - // draw box around guy - M_DrawTextBox(mx + 90, my + 8, PLBOXW, PLBOXH); +#define chary (y+64) - // draw player sprite - if (!setupm_fakecolor) // should never happen but hey, who knows + V_DrawFixedPatch( + x<numframes) // No frames ?? + return; // Can't render! + + sprframe = &sprdef->spriteframes[0]; + patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + if (sprframe->flip & 1) // Only for first sprite + flags |= V_FLIP; // This sprite is left/right flipped! + + V_DrawScaledPatch(x, chary, flags, patch); + +#undef chary + +colordraw: + x = MP_PlayerSetupDef.x; + y += 75; + + M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Color", true); + if (itemOn == 2) + cursory = y; + + // draw color string + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, + (itemOn == 2 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, + Color_Names[setupm_fakecolor]); + + if (itemOn == 2 && (MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE) { - if (skins[setupm_fakeskin].flags & SF_HIRES) - { - V_DrawSciencePatch((mx+98+(PLBOXW*8/2))<= MAXSKINCOLORS) + col -= MAXSKINCOLORS-1; + x += w; } - else - V_DrawMappedPatch(mx + 98 + (PLBOXW*8/2), my + 16 + (PLBOXH*8) - 12, flags, patch, colormap); - - Z_Free(colormap); } +#undef charw +#undef indexwidth + + V_DrawScaledPatch(currentMenu->x - 17, cursory, 0, + W_CachePatchName("M_CURSOR", PU_CACHE)); } // Handle 1P/2P MP Setup @@ -7805,7 +7872,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice) break; case KEY_LEFTARROW: - if (itemOn == 2) //player skin + if (itemOn == 1) //player skin { S_StartSound(NULL,sfx_menu1); // Tails prev_setupm_fakeskin = setupm_fakeskin; @@ -7816,16 +7883,18 @@ static void M_HandleSetupMultiPlayer(INT32 choice) setupm_fakeskin = numskins-1; } while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUsable(-1, setupm_fakeskin))); + multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL); } - else if (itemOn == 1) // player color + else if (itemOn == 2) // player color { S_StartSound(NULL,sfx_menu1); // Tails setupm_fakecolor--; } break; + case KEY_ENTER: case KEY_RIGHTARROW: - if (itemOn == 2) //player skin + if (itemOn == 1) //player skin { S_StartSound(NULL,sfx_menu1); // Tails prev_setupm_fakeskin = setupm_fakeskin; @@ -7836,8 +7905,9 @@ static void M_HandleSetupMultiPlayer(INT32 choice) setupm_fakeskin = 0; } while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUsable(-1, setupm_fakeskin))); + multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL); } - else if (itemOn == 1) // player color + else if (itemOn == 2) // player color { S_StartSound(NULL,sfx_menu1); // Tails setupm_fakecolor++; @@ -7849,22 +7919,30 @@ static void M_HandleSetupMultiPlayer(INT32 choice) break; case KEY_BACKSPACE: - if ((l = strlen(setupm_name))!=0 && itemOn == 0) + if (itemOn == 0 && (l = strlen(setupm_name))!=0) { S_StartSound(NULL,sfx_menu1); // Tails - setupm_name[l-1] =0; + setupm_name[l-1] = 0; + } + break; + + case KEY_DEL: + if (itemOn == 0 && (l = strlen(setupm_name))!=0) + { + S_StartSound(NULL,sfx_menu1); // Tails + setupm_name[0] = 0; } break; default: - if (choice < 32 || choice > 127 || itemOn != 0) + if (itemOn != 0 || choice < 32 || choice > 127) break; + S_StartSound(NULL,sfx_menu1); // Tails l = strlen(setupm_name); if (l < MAXPLAYERNAME-1) { - S_StartSound(NULL,sfx_menu1); // Tails - setupm_name[l] =(char)choice; - setupm_name[l+1] =0; + setupm_name[l] = (char)choice; + setupm_name[l+1] = 0; } break; } @@ -7907,9 +7985,11 @@ static void M_SetupMultiPlayer(INT32 choice) // disable skin changes if we can't actually change skins if (!CanChangeSkin(consoleplayer)) - MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT); + MP_PlayerSetupMenu[1].status = (IT_GRAYEDOUT); else - MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING); + MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER|IT_STRING); + + multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL); MP_PlayerSetupDef.prevMenu = currentMenu; M_SetupNextMenu(&MP_PlayerSetupDef); @@ -7938,9 +8018,11 @@ static void M_SetupMultiPlayer2(INT32 choice) // disable skin changes if we can't actually change skins if (splitscreen && !CanChangeSkin(secondarydisplayplayer)) - MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT); + MP_PlayerSetupMenu[1].status = (IT_GRAYEDOUT); else - MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER | IT_STRING); + MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER | IT_STRING); + + multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL); MP_PlayerSetupDef.prevMenu = currentMenu; M_SetupNextMenu(&MP_PlayerSetupDef); diff --git a/src/p_local.h b/src/p_local.h index a579eaeff..b1bfc6456 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -228,7 +228,6 @@ void P_PrecipitationEffects(void); void P_RemoveMobj(mobj_t *th); boolean P_MobjWasRemoved(mobj_t *th); void P_RemoveSavegameMobj(mobj_t *th); -UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2); boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state); void P_RunShields(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index 69c1e6e22..ccf5e3668 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -185,195 +185,6 @@ static void P_CyclePlayerMobjState(mobj_t *mobj) } } -// -// P_GetMobjSprite2 -// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing. -// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version. -// - -UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2) -{ - player_t *player = mobj->player; - skin_t *skin = ((skin_t *)mobj->skin); - UINT8 super = (spr2 & FF_SPR2SUPER); - - if (!skin) - return 0; - - while (!(skin->sprites[spr2].numframes) - && spr2 != SPR2_STND) - { - if (spr2 & FF_SPR2SUPER) - { - spr2 &= ~FF_SPR2SUPER; - continue; - } - - switch(spr2) - { - case SPR2_RUN: - spr2 = SPR2_WALK; - break; - case SPR2_STUN: - spr2 = SPR2_PAIN; - break; - case SPR2_DRWN: - spr2 = SPR2_DEAD; - break; - case SPR2_SPIN: - spr2 = SPR2_ROLL; - break; - case SPR2_GASP: - spr2 = SPR2_SPNG; - break; - case SPR2_JUMP: - spr2 = ((player - ? player->charflags - : skin->flags) - & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL; - break; - case SPR2_SPNG: // spring - spr2 = SPR2_FALL; - break; - case SPR2_FALL: - spr2 = SPR2_WALK; - break; - case SPR2_RIDE: - spr2 = SPR2_FALL; - break; - - case SPR2_FLY : - spr2 = SPR2_SPNG; - break; - case SPR2_SWIM: - spr2 = SPR2_FLY ; - break; - case SPR2_TIRE: - spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; - break; - - case SPR2_GLID: - spr2 = SPR2_FLY; - break; - case SPR2_CLMB: - spr2 = SPR2_ROLL; - break; - case SPR2_CLNG: - spr2 = SPR2_CLMB; - break; - - case SPR2_FLT : - spr2 = SPR2_WALK; - break; - case SPR2_FRUN: - spr2 = SPR2_RUN ; - break; - - case SPR2_DASH: - spr2 = SPR2_FRUN; - break; - - case SPR2_BNCE: - spr2 = SPR2_FALL; - break; - case SPR2_BLND: - spr2 = SPR2_ROLL; - break; - - case SPR2_TWIN: - spr2 = SPR2_ROLL; - break; - - case SPR2_MLEE: - spr2 = SPR2_TWIN; - break; - - // NiGHTS sprites. - case SPR2_NSTD: - spr2 = SPR2_STND; - super = FF_SPR2SUPER; - break; - case SPR2_NFLT: - spr2 = SPR2_FLT ; - super = FF_SPR2SUPER; - break; - case SPR2_NSTN: - spr2 = SPR2_STUN; - break; - case SPR2_NPUL: - spr2 = SPR2_NSTN; - break; - case SPR2_NATK: - spr2 = SPR2_ROLL; - super = FF_SPR2SUPER; - break; - /*case SPR2_NGT0: - spr2 = SPR2_NFLT; - break;*/ - case SPR2_NGT1: - case SPR2_NGT7: - case SPR2_DRL0: - spr2 = SPR2_NGT0; - break; - case SPR2_NGT2: - case SPR2_DRL1: - spr2 = SPR2_NGT1; - break; - case SPR2_NGT3: - case SPR2_DRL2: - spr2 = SPR2_NGT2; - break; - case SPR2_NGT4: - case SPR2_DRL3: - spr2 = SPR2_NGT3; - break; - case SPR2_NGT5: - case SPR2_DRL4: - spr2 = SPR2_NGT4; - break; - case SPR2_NGT6: - case SPR2_DRL5: - spr2 = SPR2_NGT5; - break; - case SPR2_DRL6: - spr2 = SPR2_NGT6; - break; - case SPR2_NGT8: - case SPR2_DRL7: - spr2 = SPR2_NGT7; - break; - case SPR2_NGT9: - case SPR2_DRL8: - spr2 = SPR2_NGT8; - break; - case SPR2_NGTA: - case SPR2_DRL9: - spr2 = SPR2_NGT9; - break; - case SPR2_NGTB: - case SPR2_DRLA: - spr2 = SPR2_NGTA; - break; - case SPR2_NGTC: - case SPR2_DRLB: - spr2 = SPR2_NGTB; - break; - case SPR2_DRLC: - spr2 = SPR2_NGTC; - break; - - // Dunno? Just go to standing then. - default: - spr2 = SPR2_STND; - break; - } - - spr2 |= super; - } - - return spr2; -} - // // P_SetPlayerMobjState // Returns true if the mobj is still present. @@ -574,14 +385,16 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) { skin_t *skin = ((skin_t *)mobj->skin); UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; - UINT8 numframes; - - UINT8 spr2 = P_GetMobjSprite2(mobj, (((player->powers[pw_super]) ? FF_SPR2SUPER : 0)|st->frame) & FF_FRAMEMASK); + UINT8 numframes, spr2; if (skin) + { + spr2 = P_GetSkinSprite2(skin, (((player->powers[pw_super]) ? FF_SPR2SUPER : 0)|st->frame) & FF_FRAMEMASK, mobj->player); numframes = skin->sprites[spr2].numframes; + } else { + spr2 = 0; frame = 0; numframes = 0; } @@ -700,14 +513,16 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) { skin_t *skin = ((skin_t *)mobj->skin); UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; - UINT8 numframes; - - UINT8 spr2 = P_GetMobjSprite2(mobj, st->frame & FF_FRAMEMASK); + UINT8 numframes, spr2; if (skin) + { + spr2 = P_GetSkinSprite2(skin, st->frame & FF_FRAMEMASK, mobj->player); numframes = skin->sprites[spr2].numframes; + } else { + spr2 = 0; frame = 0; numframes = 0; } diff --git a/src/r_draw.c b/src/r_draw.c index a884cdf1f..471fa1ed0 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -269,7 +269,7 @@ const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] = // Greyscale ranges "White", // SKINCOLOR_WHITE, "Bone", // SKINCOLOR_BONE, - "Siler", // SKINCOLOR_SILVER, + "Silver", // SKINCOLOR_SILVER, "Grey", // SKINCOLOR_GREY, "Cloudy", // SKINCOLOR_CLOUDY, "Carbon", // SKINCOLOR_CARBON, diff --git a/src/r_things.c b/src/r_things.c index 3b50eb106..36a7eb555 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2477,6 +2477,193 @@ skin_t skins[MAXSKINS+1]; CV_PossibleValue_t skin_cons_t[MAXSKINS+1]; #endif +// +// P_GetSkinSprite2 +// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing. +// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version. +// + +UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player) +{ + UINT8 super = (spr2 & FF_SPR2SUPER); + + if (!skin) + return 0; + + while (!(skin->sprites[spr2].numframes) + && spr2 != SPR2_STND) + { + if (spr2 & FF_SPR2SUPER) + { + spr2 &= ~FF_SPR2SUPER; + continue; + } + + switch(spr2) + { + case SPR2_RUN: + spr2 = SPR2_WALK; + break; + case SPR2_STUN: + spr2 = SPR2_PAIN; + break; + case SPR2_DRWN: + spr2 = SPR2_DEAD; + break; + case SPR2_SPIN: + spr2 = SPR2_ROLL; + break; + case SPR2_GASP: + spr2 = SPR2_SPNG; + break; + case SPR2_JUMP: + spr2 = ((player + ? player->charflags + : skin->flags) + & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL; + break; + case SPR2_SPNG: // spring + spr2 = SPR2_FALL; + break; + case SPR2_FALL: + spr2 = SPR2_WALK; + break; + case SPR2_RIDE: + spr2 = SPR2_FALL; + break; + + case SPR2_FLY : + spr2 = SPR2_SPNG; + break; + case SPR2_SWIM: + spr2 = SPR2_FLY ; + break; + case SPR2_TIRE: + spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; + break; + + case SPR2_GLID: + spr2 = SPR2_FLY; + break; + case SPR2_CLMB: + spr2 = SPR2_ROLL; + break; + case SPR2_CLNG: + spr2 = SPR2_CLMB; + break; + + case SPR2_FLT : + spr2 = SPR2_WALK; + break; + case SPR2_FRUN: + spr2 = SPR2_RUN ; + break; + + case SPR2_DASH: + spr2 = SPR2_FRUN; + break; + + case SPR2_BNCE: + spr2 = SPR2_FALL; + break; + case SPR2_BLND: + spr2 = SPR2_ROLL; + break; + + case SPR2_TWIN: + spr2 = SPR2_ROLL; + break; + + case SPR2_MLEE: + spr2 = SPR2_TWIN; + break; + + // NiGHTS sprites. + case SPR2_NSTD: + spr2 = SPR2_STND; + super = FF_SPR2SUPER; + break; + case SPR2_NFLT: + spr2 = SPR2_FLT ; + super = FF_SPR2SUPER; + break; + case SPR2_NSTN: + spr2 = SPR2_STUN; + break; + case SPR2_NPUL: + spr2 = SPR2_NSTN; + break; + case SPR2_NATK: + spr2 = SPR2_ROLL; + super = FF_SPR2SUPER; + break; + /*case SPR2_NGT0: + spr2 = SPR2_NFLT; + break;*/ + case SPR2_NGT1: + case SPR2_NGT7: + case SPR2_DRL0: + spr2 = SPR2_NGT0; + break; + case SPR2_NGT2: + case SPR2_DRL1: + spr2 = SPR2_NGT1; + break; + case SPR2_NGT3: + case SPR2_DRL2: + spr2 = SPR2_NGT2; + break; + case SPR2_NGT4: + case SPR2_DRL3: + spr2 = SPR2_NGT3; + break; + case SPR2_NGT5: + case SPR2_DRL4: + spr2 = SPR2_NGT4; + break; + case SPR2_NGT6: + case SPR2_DRL5: + spr2 = SPR2_NGT5; + break; + case SPR2_DRL6: + spr2 = SPR2_NGT6; + break; + case SPR2_NGT8: + case SPR2_DRL7: + spr2 = SPR2_NGT7; + break; + case SPR2_NGT9: + case SPR2_DRL8: + spr2 = SPR2_NGT8; + break; + case SPR2_NGTA: + case SPR2_DRL9: + spr2 = SPR2_NGT9; + break; + case SPR2_NGTB: + case SPR2_DRLA: + spr2 = SPR2_NGTA; + break; + case SPR2_NGTC: + case SPR2_DRLB: + spr2 = SPR2_NGTB; + break; + case SPR2_DRLC: + spr2 = SPR2_NGTC; + break; + + // Dunno? Just go to standing then. + default: + spr2 = SPR2_STND; + break; + } + + spr2 |= super; + } + + return spr2; +} + static void Sk_SetDefaultValue(skin_t *skin) { INT32 i; @@ -2530,7 +2717,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->spinitem = -1; skin->revitem = -1; - skin->highresscale = FRACUNIT>>1; + skin->highresscale = FRACUNIT; skin->availability = 0; diff --git a/src/r_things.h b/src/r_things.h index 3907fd2ae..efa5eae82 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -208,6 +208,8 @@ UINT32 R_GetSkinAvailabilities(void); INT32 R_SkinAvailable(const char *name); void R_AddSkins(UINT16 wadnum); +UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player); + #ifdef DELFILE void R_DelSkins(UINT16 wadnum); #endif From 3186d6a4e44a8b8259f974c435dd0c01fc645f44 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 25 Jul 2017 18:34:13 +0100 Subject: [PATCH 54/61] * An improved Multiplayer menu. * If NONET, the Multiplayer option on the main menu leads directly to the Splitscreen menu, which also includes player 1/2 setup under this circumstance. * A mechanism to save player name, skin and colour as defaults to config.cfg. --- src/d_main.c | 8 ++ src/d_netcmd.c | 21 +++- src/d_netcmd.h | 7 ++ src/m_menu.c | 305 ++++++++++++++++++++++++++++++------------------- 4 files changed, 221 insertions(+), 120 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 1a58ee89a..a3a9e8348 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -717,6 +717,14 @@ void D_StartTitle(void) // empty maptol so mario/etc sounds don't play in sound test when they shouldn't maptol = 0; + // reset to default player stuff + COM_BufAddText (va("%s \"%s\"\n",cv_playername.name,cv_defaultplayername.string)); + COM_BufAddText (va("%s \"%s\"\n",cv_skin.name,cv_defaultskin.string)); + COM_BufAddText (va("%s \"%s\"\n",cv_playercolor.name,cv_defaultplayercolor.string)); + COM_BufAddText (va("%s \"%s\"\n",cv_playername2.name,cv_defaultplayername2.string)); + COM_BufAddText (va("%s \"%s\"\n",cv_skin2.name,cv_defaultskin2.string)); + COM_BufAddText (va("%s \"%s\"\n",cv_playercolor2.name,cv_defaultplayercolor2.string)); + gameaction = ga_nothing; displayplayer = consoleplayer = 0; gametype = GT_COOP; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 185fb4127..240438fec 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -224,9 +224,9 @@ consvar_t cv_seenames = {"seenames", "Ally/Foe", CV_SAVE, seenames_cons_t, 0, 0, consvar_t cv_allowseenames = {"allowseenames", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif -// these are just meant to be saved to the config -consvar_t cv_playername = {"name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_playername2 = {"name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +// names +consvar_t cv_playername = {"name", "Sonic", CV_CALL|CV_NOINIT, NULL, Name_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playername2 = {"name2", "Tails", CV_CALL|CV_NOINIT, NULL, Name2_OnChange, 0, NULL, NULL, 0, 0, NULL}; // player colors consvar_t cv_playercolor = {"color", "Blue", CV_CALL|CV_NOINIT, Color_cons_t, Color_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_playercolor2 = {"color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -234,6 +234,14 @@ consvar_t cv_playercolor2 = {"color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t consvar_t cv_skin = {"skin", DEFAULTSKIN, CV_CALL|CV_NOINIT, NULL, Skin_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_skin2 = {"skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT, NULL, Skin2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +// saved versions of the above six +consvar_t cv_defaultplayername = {"defaultname", "Sonic", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_defaultplayername2 = {"defaultname2", "Tails", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_defaultplayercolor = {"defaultcolor", "Blue", CV_SAVE, Color_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_defaultplayercolor2 = {"defaultcolor2", "Orange", CV_SAVE, Color_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_defaultskin = {"defaultskin", DEFAULTSKIN, CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_defaultskin2 = {"defaultskin2", DEFAULTSKIN2, CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_skipmapcheck = {"skipmapcheck", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; INT32 cv_debug; @@ -654,6 +662,13 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_playername2); CV_RegisterVar(&cv_playercolor2); CV_RegisterVar(&cv_skin2); + // saved versions of the above six + CV_RegisterVar(&cv_defaultplayername); + CV_RegisterVar(&cv_defaultplayercolor); + CV_RegisterVar(&cv_defaultskin); + CV_RegisterVar(&cv_defaultplayername2); + CV_RegisterVar(&cv_defaultplayercolor2); + CV_RegisterVar(&cv_defaultskin2); #ifdef SEENAMES CV_RegisterVar(&cv_seenames); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 9ab59f6ee..f71764525 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -25,6 +25,13 @@ extern consvar_t cv_skin; extern consvar_t cv_playername2; extern consvar_t cv_playercolor2; extern consvar_t cv_skin2; +// saved versions of the above six +extern consvar_t cv_defaultplayername; +extern consvar_t cv_defaultplayercolor; +extern consvar_t cv_defaultskin; +extern consvar_t cv_defaultplayername2; +extern consvar_t cv_defaultplayercolor2; +extern consvar_t cv_defaultskin2; #ifdef SEENAMES extern consvar_t cv_seenames, cv_allowseenames; diff --git a/src/m_menu.c b/src/m_menu.c index ed6bbd32b..407626e22 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -262,7 +262,7 @@ static void M_ConfirmTeamChange(INT32 choice); static void M_SecretsMenu(INT32 choice); static void M_SetupChoosePlayer(INT32 choice); static void M_QuitSRB2(INT32 choice); -menu_t SP_MainDef, MP_MainDef, OP_MainDef; +menu_t SP_MainDef, OP_MainDef; menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef; // Single Player @@ -285,21 +285,19 @@ static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; static menu_t SP_NightsAttackDef, SP_NightsReplayDef, SP_NightsGuestReplayDef, SP_NightsGhostDef; // Multiplayer -#ifndef NONET -static void M_StartServerMenu(INT32 choice); -static void M_ConnectMenu(INT32 choice); -static void M_ConnectIPMenu(INT32 choice); -#endif +static void M_SetupMultiPlayer(INT32 choice); +static void M_SetupMultiPlayer2(INT32 choice); static void M_StartSplitServerMenu(INT32 choice); static void M_StartServer(INT32 choice); static void M_ServerOptions(INT32 choice); #ifndef NONET +static void M_StartServerMenu(INT32 choice); +static void M_ConnectMenu(INT32 choice); static void M_Refresh(INT32 choice); static void M_Connect(INT32 choice); static void M_ChooseRoom(INT32 choice); +menu_t MP_MainDef; #endif -static void M_SetupMultiPlayer(INT32 choice); -static void M_SetupMultiPlayer2(INT32 choice); // Options // Split into multiple parts due to size @@ -367,16 +365,13 @@ static void M_OGL_DrawColorMenu(void); #ifndef NONET static void M_DrawScreenshotMenu(void); static void M_DrawConnectMenu(void); -static void M_DrawConnectIPMenu(void); +static void M_DrawMPMainMenu(void); static void M_DrawRoomMenu(void); #endif static void M_DrawJoystick(void); static void M_DrawSetupMultiPlayerMenu(void); // Handling functions -#ifndef NONET -static boolean M_CancelConnect(void); -#endif static boolean M_ExitPandorasBox(void); static boolean M_QuitMultiPlayerMenu(void); static void M_HandleLevelPlatter(INT32 choice); @@ -385,6 +380,7 @@ static void M_HandleImageDef(INT32 choice); static void M_HandleLoadSave(INT32 choice); static void M_HandleLevelStats(INT32 choice); #ifndef NONET +static boolean M_CancelConnect(void); static void M_HandleConnectIP(INT32 choice); #endif static void M_HandleSetupMultiPlayer(INT32 choice); @@ -487,11 +483,15 @@ static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dum // --------- static menuitem_t MainMenu[] = { - {IT_CALL |IT_STRING, NULL, "Secrets", M_SecretsMenu, 84}, - {IT_CALL |IT_STRING, NULL, "1 player", M_SinglePlayerMenu, 92}, - {IT_SUBMENU|IT_STRING, NULL, "multiplayer", &MP_MainDef, 100}, - {IT_CALL |IT_STRING, NULL, "options", M_Options, 108}, - {IT_CALL |IT_STRING, NULL, "quit game", M_QuitSRB2, 116}, + {IT_STRING|IT_CALL, NULL, "Secrets", M_SecretsMenu, 84}, + {IT_STRING|IT_CALL, NULL, "1 player", M_SinglePlayerMenu, 92}, +#ifndef NONET + {IT_STRING|IT_SUBMENU, NULL, "multiplayer", &MP_MainDef, 100}, +#else + {IT_STRING|IT_CALL, NULL, "multiplayer", M_StartSplitServerMenu, 100}, +#endif + {IT_STRING|IT_CALL, NULL, "options", M_Options, 108}, + {IT_STRING|IT_CALL, NULL, "quit game", M_QuitSRB2, 116}, }; typedef enum @@ -902,56 +902,56 @@ static menuitem_t SP_PlayerMenu[] = // Multiplayer and all of its submenus // ----------------------------------- // Prefix: MP_ + +// Separated splitscreen and normal servers. +static menuitem_t MP_SplitServerMenu[] = +{ + {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_GameTypeChange, 100}, +#ifdef NONET // In order to keep player setup accessible. + {IT_STRING|IT_CALL, NULL, "Player 1 setup...", M_SetupMultiPlayer, 110}, + {IT_STRING|IT_CALL, NULL, "Player 2 setup...", M_SetupMultiPlayer2, 120}, +#endif + {IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130}, + {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140}, +}; + +#ifndef NONET + static menuitem_t MP_MainMenu[] = { -#ifndef NONET - {IT_CALL | IT_STRING, NULL, "HOST GAME", M_StartServerMenu, 10}, - {IT_CALL | IT_STRING, NULL, "JOIN GAME (Search)", M_ConnectMenu, 30}, - {IT_CALL | IT_STRING, NULL, "JOIN GAME (Specify IP)", M_ConnectIPMenu, 40}, -#endif - {IT_CALL | IT_STRING, NULL, "TWO PLAYER GAME", M_StartSplitServerMenu, 60}, - - {IT_CALL | IT_STRING, NULL, "PLAYER 1 SETUP", M_SetupMultiPlayer, 80}, - {IT_CALL | IT_STRING, NULL, "PLAYER 2 SETUP", M_SetupMultiPlayer2, 90}, + {IT_HEADER, NULL, "Host a game", NULL, 0}, + {IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 12}, + {IT_STRING|IT_CALL, NULL, "Splitscreen...", M_StartSplitServerMenu, 22}, + {IT_HEADER, NULL, "Join a game", NULL, 40}, + {IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenu, 52}, + {IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 62}, + {IT_HEADER, NULL, "Player setup", NULL, 94}, + {IT_STRING|IT_CALL, NULL, "Player 1...", M_SetupMultiPlayer, 106}, + {IT_STRING|IT_CALL, NULL, "Player 2... ", M_SetupMultiPlayer2, 116}, }; static menuitem_t MP_ServerMenu[] = { - {IT_DISABLED|IT_NOTHING, NULL, "", NULL, 0}, -#ifndef NONET - {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 10}, - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 20}, - {IT_STRING|IT_CVAR, NULL, "Max Players", &cv_maxplayers, 46}, - {IT_STRING|IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 56}, -#endif - {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_GameTypeChange, 100}, - {IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130}, - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140}, + {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 10}, + {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 20}, + {IT_STRING|IT_CVAR, NULL, "Max Players", &cv_maxplayers, 46}, + {IT_STRING|IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 56}, + {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_GameTypeChange, 100}, + {IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130}, + {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140}, }; enum { - mp_server_dummy = 0, // exists solely so zero-indexed in both NONET and not NONET -#ifndef NONET - mp_server_room, + mp_server_room = 0, mp_server_name, mp_server_maxpl, mp_server_waddl, -#endif mp_server_levelgt, mp_server_options, mp_server_start }; -// Separated splitscreen and normal servers. -static menuitem_t MP_SplitServerMenu[] = -{ - {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_GameTypeChange, 100}, - {IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130}, - {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140}, -}; - -#ifndef NONET static menuitem_t MP_ConnectMenu[] = { {IT_STRING | IT_CALL, NULL, "Room...", M_RoomMenu, 4}, @@ -1003,17 +1003,14 @@ static menuitem_t MP_RoomMenu[] = {IT_DISABLED, NULL, "", M_ChooseRoom, 162}, }; -static menuitem_t MP_ConnectIPMenu[] = -{ - {IT_KEYHANDLER | IT_STRING, NULL, " IP Address:", M_HandleConnectIP, 0}, -}; #endif static menuitem_t MP_PlayerSetupMenu[] = { - {IT_KEYHANDLER | IT_STRING, NULL, "Your name", M_HandleSetupMultiPlayer, 0}, - {IT_KEYHANDLER | IT_STRING, NULL, "Your player", M_HandleSetupMultiPlayer, 0}, // Tails 01-18-2001 - {IT_KEYHANDLER | IT_STRING, NULL, "Your color", M_HandleSetupMultiPlayer, 0}, + {IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // name + {IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // skin + {IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // colour + {IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // default }; // ------------------------------------ @@ -1665,29 +1662,16 @@ menu_t SP_PlayerDef = }; // Multiplayer -menu_t MP_MainDef = DEFAULTMENUSTYLE("M_MULTI", MP_MainMenu, &MainDef, 60, 40); - -menu_t MP_ServerDef = -{ - "M_MULTI", - sizeof (MP_ServerMenu)/sizeof (menuitem_t), - &MP_MainDef, - MP_ServerMenu, - M_DrawServerMenu, - 27, 30 -#ifdef NONET - - 50 -#endif - , - 0, - NULL -}; menu_t MP_SplitServerDef = { "M_MULTI", sizeof (MP_SplitServerMenu)/sizeof (menuitem_t), +#ifndef NONET &MP_MainDef, +#else + &MainDef, +#endif MP_SplitServerMenu, M_DrawServerMenu, 27, 30 - 50, @@ -1696,6 +1680,31 @@ menu_t MP_SplitServerDef = }; #ifndef NONET + +menu_t MP_MainDef = +{ + "M_MULTI", + sizeof (MP_MainMenu)/sizeof (menuitem_t), + &MainDef, + MP_MainMenu, + M_DrawMPMainMenu, + 27, 40, + 0, + M_CancelConnect +}; + +menu_t MP_ServerDef = +{ + "M_MULTI", + sizeof (MP_ServerMenu)/sizeof (menuitem_t), + &MP_MainDef, + MP_ServerMenu, + M_DrawServerMenu, + 27, 30, + 0, + NULL +}; + menu_t MP_ConnectDef = { "M_MULTI", @@ -1707,17 +1716,7 @@ menu_t MP_ConnectDef = 0, M_CancelConnect }; -menu_t MP_ConnectIPDef = -{ - "M_MULTI", - sizeof (MP_ConnectIPMenu)/sizeof (menuitem_t), - &MP_MainDef, - MP_ConnectIPMenu, - M_DrawConnectIPMenu, - 27,40, - 0, - M_CancelConnect -}; + menu_t MP_RoomDef = { "M_MULTI", @@ -1735,23 +1734,23 @@ menu_t MP_PlayerSetupDef = { "M_SPLAYR", sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t), - &MP_MainDef, + &MainDef, // doesn't matter MP_PlayerSetupMenu, M_DrawSetupMultiPlayerMenu, - 19, 26, + 19, 22, 0, M_QuitMultiPlayerMenu }; // Options -menu_t OP_MainDef = DEFAULTMENUSTYLE("M_OPTTTL", OP_MainMenu, &MainDef, 60, 30); +menu_t OP_MainDef = DEFAULTMENUSTYLE("M_OPTTTL", OP_MainMenu, &MainDef, 50, 30); menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE(OP_ChangeControlsMenu, &OP_MainDef); menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P1ControlsMenu, &OP_MainDef, 50, 30); menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_P2ControlsMenu, &OP_MainDef, 50, 30); menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30); menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE("M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 35, 30); -menu_t OP_Joystick1Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 60, 30); -menu_t OP_Joystick2Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 60, 30); +menu_t OP_Joystick1Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 50, 30); +menu_t OP_Joystick2Def = DEFAULTMENUSTYLE("M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30); menu_t OP_JoystickSetDef = { "M_CONTRO", @@ -7460,13 +7459,18 @@ static void M_DrawServerMenu(void) if (cv_nextmap.value) { +#ifndef NONET +#define imgheight MP_ServerMenu[mp_server_levelgt].alphaKey +#else +#define imgheight 100 +#endif patch_t *PictureOfLevel; lumpnum_t lumpnum; char headerstr[40]; sprintf(headerstr, "%s - %s", cv_newgametype.string, cv_nextmap.string); - M_DrawLevelPlatterHeader(currentMenu->y + MP_ServerMenu[mp_server_levelgt].alphaKey - 10 - lsheadingheight/2, (const char *)headerstr, true); + M_DrawLevelPlatterHeader(currentMenu->y + imgheight - 10 - lsheadingheight/2, (const char *)headerstr, true); // A 160x100 image of the level as entry MAPxxP lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); @@ -7476,7 +7480,7 @@ static void M_DrawServerMenu(void) else PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); - V_DrawSmallScaledPatch(319 - (currentMenu->x + (SHORT(PictureOfLevel->width)/2)), currentMenu->y + MP_ServerMenu[mp_server_levelgt].alphaKey, 0, PictureOfLevel); + V_DrawSmallScaledPatch(319 - (currentMenu->x + (SHORT(PictureOfLevel->width)/2)), currentMenu->y + imgheight, 0, PictureOfLevel); } } @@ -7580,30 +7584,40 @@ static void M_StartServerMenu(INT32 choice) static char setupm_ip[16]; -// Connect using IP address Tails 11-19-2002 -static void M_ConnectIPMenu(INT32 choice) -{ - (void)choice; - // modified game check: no longer handled - // we don't request a restart unless the filelist differs - - M_SetupNextMenu(&MP_ConnectIPDef); -} - // Draw the funky Connect IP menu. Tails 11-19-2002 // So much work for such a little thing! -static void M_DrawConnectIPMenu(void) +static void M_DrawMPMainMenu(void) { + INT32 x = currentMenu->x; + INT32 y = currentMenu->y; + // use generic drawer for cursor, items and title M_DrawGenericMenu(); +#if MAXPLAYERS == 32 + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+12, + ((itemOn == 1) ? V_YELLOWMAP : 0), "(2-32 players)"); +#else +Update the maxplayers label... +#endif + + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+22, + ((itemOn == 2) ? V_YELLOWMAP : 0), "(2 players)"); + + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+116, + ((itemOn == 8) ? V_YELLOWMAP : 0), "(splitscreen)"); + + y += 62; + + V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 159); + // draw name string - V_DrawString(128,40, V_MONOSPACE, setupm_ip); + V_DrawString(x+8,y+12, V_MONOSPACE, setupm_ip); // draw text cursor for name - if (itemOn == 0 && - skullAnimCounter < 4) //blink cursor - V_DrawCharacter(128+V_StringWidth(setupm_ip, V_MONOSPACE),40,'_',false); + if (itemOn == 5 //0 + && skullAnimCounter < 4) //blink cursor + V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_MONOSPACE),y+12,'_',false); } // Tails 11-19-2002 @@ -7624,11 +7638,21 @@ static void M_ConnectIP(INT32 choice) // Tails 11-19-2002 static void M_HandleConnectIP(INT32 choice) { - size_t l; - boolean exitmenu = false; // exit to previous menu and send name change + size_t l; + boolean exitmenu = false; // exit to previous menu and send name change switch (choice) { + case KEY_DOWNARROW: + M_NextOpt(); + S_StartSound(NULL,sfx_menu1); // Tails + break; + + case KEY_UPARROW: + M_PrevOpt(); + S_StartSound(NULL,sfx_menu1); // Tails + break; + case KEY_ENTER: S_StartSound(NULL,sfx_menu1); // Tails M_ClearMenus(true); @@ -7640,29 +7664,41 @@ static void M_HandleConnectIP(INT32 choice) break; case KEY_BACKSPACE: - if ((l = strlen(setupm_ip))!=0 && itemOn == 0) + if ((l = strlen(setupm_ip)) != 0) { S_StartSound(NULL,sfx_menu1); // Tails - setupm_ip[l-1] =0; + setupm_ip[l-1] = 0; + } + break; + + case KEY_DEL: + if (setupm_ip[0]) + { + S_StartSound(NULL,sfx_menu1); // Tails + setupm_ip[0] = 0; } break; default: l = strlen(setupm_ip); - if (l < 16-1 && (choice == 46 || (choice >= 48 && choice <= 57))) // Rudimentary number and period enforcing + if (l >= 16-1) + break; + + if (choice == 46 || (choice >= 48 && choice <= 57)) // Rudimentary number and period enforcing { S_StartSound(NULL,sfx_menu1); // Tails - setupm_ip[l] =(char)choice; - setupm_ip[l+1] =0; + setupm_ip[l] = (char)choice; + setupm_ip[l+1] = 0; } - else if (l < 16-1 && choice >= 199 && choice <= 211 && choice != 202 && choice != 206) //numpad too! + else if (choice >= 199 && choice <= 211 && choice != 202 && choice != 206) //numpad too! { XBOXSTATIC char keypad_translation[] = {'7','8','9','-','4','5','6','+','1','2','3','0','.'}; choice = keypad_translation[choice - 199]; S_StartSound(NULL,sfx_menu1); // Tails - setupm_ip[l] =(char)choice; - setupm_ip[l+1] =0; + setupm_ip[l] = (char)choice; + setupm_ip[l+1] = 0; } + break; } @@ -7692,6 +7728,9 @@ static player_t *setupm_player; static consvar_t *setupm_cvskin; static consvar_t *setupm_cvcolor; static consvar_t *setupm_cvname; +static consvar_t *setupm_cvdefaultskin; +static consvar_t *setupm_cvdefaultcolor; +static consvar_t *setupm_cvdefaultname; static INT32 setupm_fakeskin; static INT32 setupm_fakecolor; @@ -7848,7 +7887,21 @@ colordraw: #undef charw #undef indexwidth - V_DrawScaledPatch(currentMenu->x - 17, cursory, 0, + x = MP_PlayerSetupDef.x; + y += 20; + + V_DrawString(x, y, + ((R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin + || setupm_cvdefaultcolor->value != setupm_fakecolor + || strcmp(setupm_name, setupm_cvdefaultname->string)) + ? 0 + : V_TRANSLUCENT) + | ((itemOn == 3) ? V_YELLOWMAP : 0), + "Save as default"); + if (itemOn == 3) + cursory = y; + + V_DrawScaledPatch(x - 17, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); } @@ -7893,6 +7946,18 @@ static void M_HandleSetupMultiPlayer(INT32 choice) break; case KEY_ENTER: + if (itemOn == 3 + && (R_SkinAvailable(setupm_cvdefaultskin->string) != setupm_fakeskin + || setupm_cvdefaultcolor->value != setupm_fakecolor + || strcmp(setupm_name, setupm_cvdefaultname->string))) + { + S_StartSound(NULL,sfx_strpst); + // you know what? always putting these in the buffer won't hurt anything. + COM_BufAddText (va("%s \"%s\"\n",setupm_cvdefaultskin->name,skins[setupm_fakeskin].name)); + COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor)); + COM_BufAddText (va("%s %s\n",setupm_cvdefaultname->name,setupm_name)); + break; + } case KEY_RIGHTARROW: if (itemOn == 1) //player skin { @@ -7976,6 +8041,9 @@ static void M_SetupMultiPlayer(INT32 choice) setupm_cvskin = &cv_skin; setupm_cvcolor = &cv_playercolor; setupm_cvname = &cv_playername; + setupm_cvdefaultskin = &cv_defaultskin; + setupm_cvdefaultcolor = &cv_defaultplayercolor; + setupm_cvdefaultname = &cv_defaultplayername; // For whatever reason this doesn't work right if you just use ->value setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); @@ -8009,6 +8077,9 @@ static void M_SetupMultiPlayer2(INT32 choice) setupm_cvskin = &cv_skin2; setupm_cvcolor = &cv_playercolor2; setupm_cvname = &cv_playername2; + setupm_cvdefaultskin = &cv_defaultskin2; + setupm_cvdefaultcolor = &cv_defaultplayercolor2; + setupm_cvdefaultname = &cv_defaultplayername2; // For whatever reason this doesn't work right if you just use ->value setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string); From 2bdf432703fbb4b48c3dec04acb4d08b2fa9ba0e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 26 Jul 2017 13:50:49 +0100 Subject: [PATCH 55/61] Allow for the previous defaulting system to continue working. --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 240438fec..50a25f475 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -654,7 +654,7 @@ void D_RegisterClientCommands(void) // register these so it is saved to config if ((username = I_GetUserName())) - cv_playername.defaultvalue = username; + cv_playername.defaultvalue = cv_defaultplayername.defaultvalue = username; CV_RegisterVar(&cv_playername); CV_RegisterVar(&cv_playercolor); CV_RegisterVar(&cv_skin); // r_things.c (skin NAME) From 672bcc349c0ee07b0edf7844e53cfdf00e3fcb22 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 26 Jul 2017 16:10:08 +0100 Subject: [PATCH 56/61] * Hide the number of lives you can steal if game-overed. It's not directly relevant unless you're game overed. * Fix an issue where everyone being game overed except for one person, and then kicking that one person, meant the game over trigger was never met. * Fix an issue where the spectator text could be overridden with a count of the number of remaining players to complete the level. * Fixed a few glitches with spinning. (Unrelated to the branch, but exposed through new_coop testing.) --- src/p_mobj.c | 20 ++++++++++---------- src/p_user.c | 41 ++++++++++++++++++----------------------- src/st_stuff.c | 4 +++- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index ccf5e3668..122d3bfd5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3041,6 +3041,15 @@ static void P_PlayerZMovement(mobj_t *mo) if (mo->health && !mo->player->spectator && !P_CheckDeathPitCollide(mo)) { + if ((mo->player->charability2 == CA2_SPINDASH) && !(mo->player->pflags & PF_THOKKED) && (mo->player->cmd.buttons & BT_USE) && (FixedHypot(mo->momx, mo->momy) > (5*mo->scale))) + { + mo->player->pflags |= PF_SPINNING; + P_SetPlayerMobjState(mo, S_PLAY_ROLL); + S_StartSound(mo, sfx_spin); + } + else + mo->player->pflags &= ~PF_SPINNING; + if (mo->player->pflags & PF_GLIDING) // ground gliding { mo->player->skidtime = TICRATE; @@ -3053,7 +3062,7 @@ static void P_PlayerZMovement(mobj_t *mo) S_StartSound(mo, sfx_s3k8b); mo->player->pflags |= PF_FULLSTASIS; } - else if (mo->player->pflags & PF_JUMPED || (mo->player->pflags & (PF_SPINNING|PF_USEDOWN)) != (PF_SPINNING|PF_USEDOWN) + else if (mo->player->pflags & PF_JUMPED || !(mo->player->pflags & PF_SPINNING) || mo->player->powers[pw_tailsfly] || mo->state-states == S_PLAY_FLY_TIRED) { if (mo->player->cmomx || mo->player->cmomy) @@ -3084,15 +3093,6 @@ static void P_PlayerZMovement(mobj_t *mo) } } - if ((mo->player->charability2 == CA2_SPINDASH) && !(mo->player->pflags & PF_THOKKED) && (mo->player->cmd.buttons & BT_USE) && (FixedHypot(mo->momx, mo->momy) > (5*mo->scale))) - { - mo->player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(mo, S_PLAY_ROLL); - S_StartSound(mo, sfx_spin); - } - else - mo->player->pflags &= ~PF_SPINNING; - if (!(mo->player->pflags & PF_GLIDING)) mo->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); diff --git a/src/p_user.c b/src/p_user.c index adaa78ed4..28646d0ca 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4837,7 +4837,7 @@ static void P_3dMovement(player_t *player) angle_t dangle; // replaces old quadrants bits fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); boolean analogmove = false; - boolean spin = (player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH)); + boolean spin = ((onground = P_IsObjectOnGround(player->mo)) && player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH)); fixed_t oldMagnitude, newMagnitude; #ifdef ESLOPE vector3_t totalthrust; @@ -4927,9 +4927,6 @@ static void P_3dMovement(player_t *player) if (player->pflags & PF_SLIDING) cmd->forwardmove = 0; - // Do not let the player control movement if not onground. - onground = P_IsObjectOnGround(player->mo); - player->aiming = cmd->aiming<>= 2; // proper air movement - // Allow a bit of movement while spinning - if (player->pflags & PF_SPINNING) + else if (player->pflags & PF_SPINNING) { if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0) || (player->pflags & PF_STARTDASH)) movepushforward = 0; else - movepushforward = FixedDiv(movepushforward, 16*FRACUNIT); + movepushforward >>= 4; } movepushforward = FixedMul(movepushforward, player->mo->scale); @@ -5077,17 +5070,14 @@ static void P_3dMovement(player_t *player) // allow very small movement while in air for gameplay if (!onground) movepushforward >>= 2; // proper air movement - // Allow a bit of movement while spinning - if (player->pflags & PF_SPINNING) + else if (player->pflags & PF_SPINNING) { - // Stupid little movement prohibitor hack - // that REALLY shouldn't belong in analog code. if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0) || (player->pflags & PF_STARTDASH)) movepushforward = 0; else - movepushforward = FixedDiv(movepushforward, 16*FRACUNIT); + movepushforward >>= 4; } movepushsideangle = controldirection; @@ -8198,6 +8188,10 @@ boolean P_GetLives(player_t *player) static void P_ConsiderAllGone(void) { INT32 i, lastdeadplayer = -1, deadtimercheck = INT32_MAX; + + if (countdown2) + return; + for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) @@ -8206,15 +8200,16 @@ static void P_ConsiderAllGone(void) if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) break; - if (players[i].lives > 0) + if (players[i].spectator) + { + if (lastdeadplayer == -1) + lastdeadplayer = i; + } + else if (players[i].lives > 0) { - if (players[i].spectator && lastdeadplayer == -1) - ; - else if (players[i].deadtimer < deadtimercheck) - deadtimercheck = players[i].deadtimer; - else - continue; lastdeadplayer = i; + if (players[i].deadtimer < deadtimercheck) + deadtimercheck = players[i].deadtimer; } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 06877bbb3..c85e5d28e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -761,6 +761,7 @@ static void ST_drawLives(void) va("%d",sum)); return; } +#if 0 // render the number of lives you COULD steal case 2: { INT32 i, sum = 0; @@ -781,6 +782,7 @@ static void ST_drawLives(void) V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF|v_splitflag, va("/%d",sum)); } // intentional fallthrough +#endif default: // don't return so the SP one can be drawn below break; @@ -1997,7 +1999,7 @@ static void ST_overlayDrawer(void) if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer) { - if (stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP) + if (!stplyr->spectator && stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP) { INT32 i, total = 0, exiting = 0; From be5184a8cc19b7ca0fb129e32e73ece6837ae421 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 26 Jul 2017 16:34:33 +0100 Subject: [PATCH 57/61] ...fixed some weirdness with spinning I accidentially introduced in an attempt to fix it. --- src/p_user.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 28646d0ca..002a6fda0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5028,18 +5028,20 @@ static void P_3dMovement(player_t *player) { movepushforward = cmd->forwardmove * (thrustfactor * acceleration); - // allow very small movement while in air for gameplay - if (!onground) - movepushforward >>= 2; // proper air movement // Allow a bit of movement while spinning - else if (player->pflags & PF_SPINNING) + if (player->pflags & PF_SPINNING) { if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0) || (player->pflags & PF_STARTDASH)) movepushforward = 0; - else + else if (onground) movepushforward >>= 4; + else + movepushforward >>= 3; } + // allow very small movement while in air for gameplay + else if (!onground) + movepushforward >>= 2; // proper air movement movepushforward = FixedMul(movepushforward, player->mo->scale); @@ -5067,18 +5069,20 @@ static void P_3dMovement(player_t *player) movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration); - // allow very small movement while in air for gameplay - if (!onground) - movepushforward >>= 2; // proper air movement // Allow a bit of movement while spinning - else if (player->pflags & PF_SPINNING) + if (player->pflags & PF_SPINNING) { if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0) || (player->pflags & PF_STARTDASH)) movepushforward = 0; - else + else if (onground) movepushforward >>= 4; + else + movepushforward >>= 3; } + // allow very small movement while in air for gameplay + else if (!onground) + movepushforward >>= 2; // proper air movement movepushsideangle = controldirection; @@ -5096,25 +5100,26 @@ static void P_3dMovement(player_t *player) { movepushside = cmd->sidemove * (thrustfactor * acceleration); + // allow very small movement while in air for gameplay if (!onground) { - movepushside >>= 2; - + movepushside >>= 2; // proper air movement // Reduce movepushslide even more if over "max" flight speed - if (player->powers[pw_tailsfly] && player->speed > topspeed) + if ((player->pflags & PF_SPINNING) || (player->powers[pw_tailsfly] && player->speed > topspeed)) movepushside >>= 2; } - // Allow a bit of movement while spinning - if (player->pflags & PF_SPINNING) + else if (player->pflags & PF_SPINNING) { - if ((player->pflags & PF_STARTDASH)) + if (player->pflags & PF_STARTDASH) movepushside = 0; + else if (onground) + movepushside >>= 4; else - movepushside = FixedDiv(movepushside,16*FRACUNIT); + movepushside >>= 3; } - // Finally move the player now that his speed/direction has been decided. + // Finally move the player now that their speed/direction has been decided. movepushside = FixedMul(movepushside, player->mo->scale); #ifdef ESLOPE From cca779e4a09d1ecdf449f20332c879aa7a32f193 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 2 Aug 2017 13:11:21 +0100 Subject: [PATCH 58/61] * Updated Supercyan constants/names to Supersky, considering the base skincolour Cyan was renamed Sky (and a new Cyan was made independently of that). * Swapped the names of Cloudy and Silver so that Silver meant the shinier option. --- src/dehacked.c | 14 +++++++------- src/doomdef.h | 14 +++++++------- src/r_draw.c | 44 ++++++++++++++++++++++---------------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 809cdfac0..0d88359ea 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6775,9 +6775,9 @@ static const char *COLOR_ENUMS[] = { // Greyscale ranges "WHITE", // SKINCOLOR_WHITE, "BONE", // SKINCOLOR_BONE, - "SILVER", // SKINCOLOR_SILVER, - "GREY", // SKINCOLOR_GREY, "CLOUDY", // SKINCOLOR_CLOUDY, + "GREY", // SKINCOLOR_GREY, + "SILVER", // SKINCOLOR_SILVER, "CARBON", // SKINCOLOR_CARBON, "JET", // SKINCOLOR_JET, "BLACK", // SKINCOLOR_BLACK, @@ -6871,11 +6871,11 @@ static const char *COLOR_ENUMS[] = { "SUPERPERIDOT4", // SKINCOLOR_SUPERPERIDOT4, "SUPERPERIDOT5", // SKINCOLOR_SUPERPERIDOT5, - "SUPERCYAN1", // SKINCOLOR_SUPERCYAN1 - "SUPERCYAN2", // SKINCOLOR_SUPERCYAN2, - "SUPERCYAN3", // SKINCOLOR_SUPERCYAN3, - "SUPERCYAN4", // SKINCOLOR_SUPERCYAN4, - "SUPERCYAN5", // SKINCOLOR_SUPERCYAN5, + "SUPERSKY1", // SKINCOLOR_SUPERSKY1 + "SUPERSKY2", // SKINCOLOR_SUPERSKY2, + "SUPERSKY3", // SKINCOLOR_SUPERSKY3, + "SUPERSKY4", // SKINCOLOR_SUPERSKY4, + "SUPERSKY5", // SKINCOLOR_SUPERSKY5, "SUPERPURPLE1", // SKINCOLOR_SUPERPURPLE1, "SUPERPURPLE2", // SKINCOLOR_SUPERPURPLE2, diff --git a/src/doomdef.h b/src/doomdef.h index 1d8f99a7a..ec01d50c9 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -233,9 +233,9 @@ typedef enum // Greyscale ranges SKINCOLOR_WHITE, SKINCOLOR_BONE, - SKINCOLOR_SILVER, - SKINCOLOR_GREY, SKINCOLOR_CLOUDY, + SKINCOLOR_GREY, + SKINCOLOR_SILVER, SKINCOLOR_CARBON, SKINCOLOR_JET, SKINCOLOR_BLACK, @@ -333,11 +333,11 @@ typedef enum SKINCOLOR_SUPERPERIDOT4, SKINCOLOR_SUPERPERIDOT5, - SKINCOLOR_SUPERCYAN1, - SKINCOLOR_SUPERCYAN2, - SKINCOLOR_SUPERCYAN3, - SKINCOLOR_SUPERCYAN4, - SKINCOLOR_SUPERCYAN5, + SKINCOLOR_SUPERSKY1, + SKINCOLOR_SUPERSKY2, + SKINCOLOR_SUPERSKY3, + SKINCOLOR_SUPERSKY4, + SKINCOLOR_SUPERSKY5, SKINCOLOR_SUPERPURPLE1, SKINCOLOR_SUPERPURPLE2, diff --git a/src/r_draw.c b/src/r_draw.c index 471fa1ed0..dadc494dc 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -137,9 +137,9 @@ const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = { // Greyscale ranges {0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11}, // SKINCOLOR_WHITE {0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x11, 0x12}, // SKINCOLOR_BONE - {0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}, // SKINCOLOR_SILVER + {0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}, // SKINCOLOR_CLOUDY {0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}, // SKINCOLOR_GREY - {0x02, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f}, // SKINCOLOR_CLOUDY + {0x02, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f}, // SKINCOLOR_SILVER {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x17, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1c, 0x1d}, // SKINCOLOR_CARBON {0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f}, // SKINCOLOR_JET {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, // SKINCOLOR_BLACK @@ -235,11 +235,11 @@ const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = { {0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f}, // SKINCOLOR_SUPERPERIDOT4 {0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0x5e, 0x5e, 0x5f, 0x77}, // SKINCOLOR_SUPERPERIDOT5 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84}, // SKINCOLOR_SUPERCYAN1 - {0x00, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86}, // SKINCOLOR_SUPERCYAN2 - {0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87}, // SKINCOLOR_SUPERCYAN3 - {0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a}, // SKINCOLOR_SUPERCYAN4 - {0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8b}, // SKINCOLOR_SUPERCYAN5 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84}, // SKINCOLOR_SUPERSKY1 + {0x00, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86}, // SKINCOLOR_SUPERSKY2 + {0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87}, // SKINCOLOR_SUPERSKY3 + {0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a}, // SKINCOLOR_SUPERSKY4 + {0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8b}, // SKINCOLOR_SUPERSKY5 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa2}, // SKINCOLOR_SUPERPURPLE1 {0x00, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5}, // SKINCOLOR_SUPERPURPLE2 @@ -269,9 +269,9 @@ const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] = // Greyscale ranges "White", // SKINCOLOR_WHITE, "Bone", // SKINCOLOR_BONE, - "Silver", // SKINCOLOR_SILVER, - "Grey", // SKINCOLOR_GREY, "Cloudy", // SKINCOLOR_CLOUDY, + "Grey", // SKINCOLOR_GREY, + "Silver", // SKINCOLOR_SILVER, "Carbon", // SKINCOLOR_CARBON, "Jet", // SKINCOLOR_JET, "Black", // SKINCOLOR_BLACK, @@ -335,15 +335,15 @@ const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] = "Rosy", // SKINCOLOR_ROSY, // Super behaves by different rules (one name per 5 colours), and will be accessed exclusively via R_GetSuperColorByName instead of R_GetColorByName. - "Silver", // SKINCOLOR_SUPERSILVER1 - "Red", // SKINCOLOR_SUPERRED1 - "Orange", // SKINCOLOR_SUPERORANGE1 - "Gold", // SKINCOLOR_SUPERGOLD1 - "Peridot", // SKINCOLOR_SUPERPERIDOT1 - "Cyan", // SKINCOLOR_SUPERCYAN1 - "Purple", // SKINCOLOR_SUPERPURPLE1 - "Rust", // SKINCOLOR_SUPERRUST1 - "Tan" // SKINCOLOR_SUPERTAN1 + "Silver", // SKINCOLOR_SUPERSILVER1, + "Red", // SKINCOLOR_SUPERRED1, + "Orange", // SKINCOLOR_SUPERORANGE1, + "Gold", // SKINCOLOR_SUPERGOLD1, + "Peridot", // SKINCOLOR_SUPERPERIDOT1, + "Sky", // SKINCOLOR_SUPERSKY1, + "Purple", // SKINCOLOR_SUPERPURPLE1, + "Rust", // SKINCOLOR_SUPERRUST1, + "Tan" // SKINCOLOR_SUPERTAN1, }; /* @@ -357,16 +357,16 @@ const UINT8 Color_Opposite[(MAXSKINCOLORS - 1)*2] = // Greyscale ranges SKINCOLOR_BLACK,5, // SKINCOLOR_WHITE, SKINCOLOR_JET,7, // SKINCOLOR_BONE, - SKINCOLOR_CARBON,7, // SKINCOLOR_SILVER, + SKINCOLOR_CARBON,7, // SKINCOLOR_CLOUDY, SKINCOLOR_AETHER,12, // SKINCOLOR_GREY, - SKINCOLOR_SLATE,12, // SKINCOLOR_CLOUDY, - SKINCOLOR_SILVER,7, // SKINCOLOR_CARBON, + SKINCOLOR_SLATE,12, // SKINCOLOR_SILVER, + SKINCOLOR_CLOUDY,7, // SKINCOLOR_CARBON, SKINCOLOR_BONE,7, // SKINCOLOR_JET, SKINCOLOR_WHITE,7, // SKINCOLOR_BLACK, // Desaturated SKINCOLOR_GREY,15, // SKINCOLOR_AETHER, - SKINCOLOR_CLOUDY,12, // SKINCOLOR_SLATE, + SKINCOLOR_SILVER,12, // SKINCOLOR_SLATE, SKINCOLOR_AZURE,9, // SKINCOLOR_PINK, SKINCOLOR_RUST,7, // SKINCOLOR_YOGURT, SKINCOLOR_TAN,2, // SKINCOLOR_BROWN, From e21ae8de7d0941d427d637116d1563c68f975ee5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 3 Aug 2017 00:01:12 +0100 Subject: [PATCH 59/61] * Updated NiGHTS skincolor list on Rob's request. * Unrelated: fixed a bug where FF_ANIMATE stuff tried to access rain's skin. --- src/p_mobj.c | 2 +- src/st_stuff.c | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 122d3bfd5..42003e264 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -86,7 +86,7 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum) // FUNCINLINE static ATTRINLINE void P_SetupStateAnimation(mobj_t *mobj, state_t *st) { - INT32 animlength = (mobj->skin && mobj->sprite == SPR_PLAY) + INT32 animlength = (mobj->sprite == SPR_PLAY && mobj->skin) ? (INT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes) - 1 : st->var1; diff --git a/src/st_stuff.c b/src/st_stuff.c index c85e5d28e..260c1dd62 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -969,15 +969,25 @@ static void ST_drawFirstPersonHUD(void) /*#define NUMLINKCOLORS 14 static skincolors_t linkColor[NUMLINKCOLORS] = {SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, - SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED, - SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/ + SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED, + SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/ -// 2.2+: (unix time 1470866042) Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot -#define NUMLINKCOLORS 13 +// 2.2 indev list: (unix time 1470866042) Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot +/*#define NUMLINKCOLORS 13 static skincolors_t linkColor[NUMLINKCOLORS] = -{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL, - SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, - SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}; +{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL, + SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, + SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT};*/ + +// 2.2+ list: [19:59:52] Ruby > Red > Flame > Sunset > Orange > Gold > Yellow > Lime > Green > Aqua > cyan > Sky > Blue > Pastel > Purple > Bubblegum > Magenta > Rosy > repeat +// [20:00:25] Also Icy for the link freeze text color +// [20:04:03] I would start it on lime +#define NUMLINKCOLORS 18 +static skincolors_t linkColor[NUMLINKCOLORS] = +{SKINCOLOR_LIME, SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_SKY, + SKINCOLOR_SAPPHIRE, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, SKINCOLOR_BUBBLEGUM, SKINCOLOR_MAGENTA, + SKINCOLOR_ROSY, SKINCOLOR_RUBY, SKINCOLOR_RED, SKINCOLOR_FLAME, SKINCOLOR_SUNSET, + SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW}; static void ST_drawNightsRecords(void) { @@ -1078,8 +1088,8 @@ static void ST_drawNiGHTSHUD(void) stplyr->linkcount > minlink) { skincolors_t colornum = linkColor[((stplyr->linkcount-1) / 5) % NUMLINKCOLORS]; - if (stplyr->powers[pw_nights_linkfreeze]) - colornum = SKINCOLOR_WHITE; + if (stplyr->powers[pw_nights_linkfreeze] && (!(stplyr->powers[pw_nights_linkfreeze] & 2) || (stplyr->powers[pw_nights_linkfreeze] > flashingtics))) + colornum = SKINCOLOR_ICY; if (stplyr->linktimer < 2*TICRATE/3) { From 8fcb66b3fa68e35ae57f6bc452765f854b5a2ca7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 5 Aug 2017 12:26:05 +0100 Subject: [PATCH 60/61] Allow for new coop leveltime reloading --- src/p_setup.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 49ee5e196..2027ffb85 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2845,6 +2845,18 @@ boolean P_SetupLevel(boolean skipprecip) } } + if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + { + // is this a hack? maybe + tic_t maxstarposttime = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].starposttime > maxstarposttime) + maxstarposttime = players[i].starposttime; + } + leveltime = maxstarposttime; + } + if (modeattacking == ATTACKING_RECORD && !demoplayback) P_LoadRecordGhosts(); else if (modeattacking == ATTACKING_NIGHTS && !demoplayback) From b51e80ef8824aa77bbd21d955023379a94e7dd67 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 5 Aug 2017 22:13:35 +0100 Subject: [PATCH 61/61] Make timer reset work in LF_NORELOAD as well. --- src/g_game.c | 34 +++++++++++++++++++++++++++------- src/p_setup.c | 1 + 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 6e43aeb8b..600c8c896 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2592,6 +2592,8 @@ void G_DoReborn(INT32 playernum) { for (i = 0; i < MAXPLAYERS; i++) { + if (!playeringame[i]) + continue; players[i].starpostangle = 0; players[i].starposttime = 0; players[i].starpostx = 0; @@ -2602,9 +2604,15 @@ void G_DoReborn(INT32 playernum) } if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD)) { - player->playerstate = PST_REBORN; P_LoadThingsOnly(); - P_ClearStarPost(player->starpostnum); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + players[i].playerstate = PST_REBORN; + P_ClearStarPost(players[i].starpostnum); + } // Do a wipe wipegamestate = -1; @@ -2628,12 +2636,24 @@ void G_DoReborn(INT32 playernum) CON_ClearHUD(); // Starpost support - G_SpawnPlayer(playernum, (player->starposttime)); + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + G_SpawnPlayer(i, (players[i].starposttime)); + } - if (botingame) - { // Bots respawn next to their master. - players[secondarydisplayplayer].playerstate = PST_REBORN; - G_SpawnPlayer(secondarydisplayplayer, false); + // restore time in netgame (see also p_setup.c) + if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + { + // is this a hack? maybe + tic_t maxstarposttime = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].starposttime > maxstarposttime) + maxstarposttime = players[i].starposttime; + } + leveltime = maxstarposttime; } } else diff --git a/src/p_setup.c b/src/p_setup.c index d40f4fc3b..8a91de76b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2860,6 +2860,7 @@ boolean P_SetupLevel(boolean skipprecip) } } + // restore time in netgame (see also g_game.c) if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) { // is this a hack? maybe