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.
This commit is contained in:
toasterbabe 2017-07-04 13:17:29 +01:00
parent 2fd6a20be0
commit bc066a16a0
9 changed files with 186 additions and 86 deletions

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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");

View File

@ -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++)

View File

@ -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;

View File

@ -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;

View File

@ -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))

View File

@ -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++)