Basic voting rows port

Still crashes and seems to mess with the newgametype
This commit is contained in:
NepDisk 2025-05-28 10:35:32 -04:00
parent 6d071fd23a
commit 8faba2dd35
6 changed files with 192 additions and 45 deletions

View file

@ -570,6 +570,9 @@ consvar_t cv_forceskin = CVAR_INIT ("forceskin", "None", CV_NETVAR|CV_CALL|CV_CH
consvar_t cv_downloading = CVAR_INIT ("downloading", "On", 0, CV_OnOff, NULL);
consvar_t cv_allowexitlevel = CVAR_INIT ("allowexitlevel", "No", CV_NETVAR, CV_YesNo, NULL);
static CV_PossibleValue_t votemaxrows_cons_t[] = {{1, "MIN"}, {3, "MAX"}, {0, NULL}};
consvar_t cv_votemaxrows = CVAR_INIT ("votemaxrows", "2", CV_SAVE|CV_NETVAR, votemaxrows_cons_t, NULL);
consvar_t cv_netstat = CVAR_INIT ("netstat", "Off", 0, CV_OnOff, NULL); // show bandwidth statistics
static CV_PossibleValue_t nettimeout_cons_t[] = {{TICRATE/7, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}};
consvar_t cv_nettimeout = CVAR_INIT ("nettimeout", "210", CV_CALL|CV_SAVE, nettimeout_cons_t, NetTimeout_OnChange);
@ -649,6 +652,9 @@ UINT8 splitscreen = 0;
boolean circuitmap = false;
INT32 adminplayers[MAXPLAYERS];
#define VOTEROWS ((cv_votemaxrows.value*3) + ((cv_votemaxrows.value > 1) ? (cv_votemaxrows.value - 1) : 0))
#define VOTEROWSADDSONE ((cv_votemaxrows.value*3) + 1 + ((cv_votemaxrows.value > 1) ? (cv_votemaxrows.value - 1) : 0))
// Scheduled commands.
scheduleTask_t **schedule = NULL;
size_t schedule_size = 0;
@ -854,6 +860,7 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_playbackspeed);
CV_RegisterVar(&cv_forceskin);
CV_RegisterVar(&cv_downloading);
CV_RegisterVar(&cv_votemaxrows);
K_RegisterKartStuff(); // SRB2kart
@ -2776,7 +2783,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
void D_SetupVote(void)
{
UINT8 buf[5*2]; // four UINT16 maps (at twice the width of a UINT8), and two gametypes
UINT8 buf[13*2]; // twelve UINT16 maps (at twice the width of a UINT8), and two gametypes
UINT8 *p = buf;
INT32 i;
UINT8 gt = (cv_kartgametypepreference.value == -1) ? gametype : cv_kartgametypepreference.value;
@ -2794,16 +2801,17 @@ void D_SetupVote(void)
WRITEUINT8(p, secondgt);
secondgt &= ~VOTEMODIFIER_ENCORE;
for (i = 0; i < 4; i++)
for (i = 0; i < VOTEROWSADDSONE; i++)
{
UINT16 m;
if (i == 2) // sometimes a different gametype
m = G_RandMap(G_TOLFlag(secondgt), prevmap, ((secondgt != gametype) ? 2 : 0), 0, true, votebuffer);
else if (i >= 3) // unknown-random and formerly force-unknown MAP HELL
else if (i >= VOTEROWS) // unknown-random and formerly force-unknown MAP HELL
m = G_RandMap(G_TOLFlag(gt), prevmap, 0, (i-2), (i < 4), votebuffer);
else
m = G_RandMap(G_TOLFlag(gt), prevmap, 0, 0, true, votebuffer);
if (i < 3)
if (i < VOTEROWS)
votebuffer[i] = m;
WRITEUINT16(p, m);
}
@ -5510,7 +5518,7 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
{
INT32 i;
UINT8 gt, secondgt;
INT16 tempvotelevels[4][2];
INT16 tempvotelevels[12][2];
if (playernum != serverplayer) // admin shouldn't be able to set up vote...
{
@ -5520,6 +5528,7 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
return;
}
// Get gametype data.
gt = (UINT8)READUINT8(*cp);
secondgt = (UINT8)READUINT8(*cp);
@ -5530,7 +5539,7 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
gt &= ~VOTEMODIFIER_ENCORE;
}
for (i = 0; i < 4; i++)
for (i = 0; i < VOTEROWSADDSONE; i++)
{
tempvotelevels[i][0] = (UINT16)READUINT16(*cp);
tempvotelevels[i][1] = gt;
@ -7320,3 +7329,6 @@ void Got_DiscordInfo(UINT8 **p, INT32 playernum)
(*p) += 3;
#endif
}
#undef VOTEROWS
#undef VOTEROWSADDSONE

View file

@ -52,6 +52,8 @@ extern consvar_t cv_numlaps;
extern UINT32 timelimitintics, extratimeintics, secretextratime;
extern consvar_t cv_allowexitlevel;
extern consvar_t cv_votemaxrows;
extern consvar_t cv_autobalance;
extern consvar_t cv_teamscramble;
extern consvar_t cv_scrambleonchange;

View file

@ -681,7 +681,7 @@ extern boolean legitimateexit;
extern boolean comebackshowninfo;
extern tic_t curlap, bestlap;
extern INT16 votelevels[4][2];
extern INT16 votelevels[12][2];
extern SINT8 votes[MAXPLAYERS];
extern SINT8 pickedvote;

View file

@ -288,7 +288,7 @@ boolean franticitems; // Frantic items currently enabled?
boolean comeback; // Battle Mode's karma comeback is on/off
// Voting system
INT16 votelevels[4][2]; // Levels that were rolled by the host
INT16 votelevels[12][2]; // Levels that were rolled by the host
SINT8 votes[MAXPLAYERS]; // Each player's vote
SINT8 pickedvote; // What vote the host rolls

View file

@ -5140,7 +5140,7 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
WRITEUINT8(save->p, slipdashactive);
WRITEUINT8(save->p, purpledriftactive);
for (i = 0; i < 4; i++)
for (i = 0; i < 12; i++)
{
WRITEINT16(save->p, votelevels[i][0]);
WRITEINT16(save->p, votelevels[i][1]);
@ -5313,7 +5313,7 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
slipdashactive = READUINT8(save->p);
purpledriftactive = READUINT8(save->p);
for (i = 0; i < 4; i++)
for (i = 0; i < 12; i++)
{
votelevels[i][0] = READINT16(save->p);
votelevels[i][1] = READINT16(save->p);

View file

@ -163,11 +163,14 @@ typedef struct
boolean loaded;
} y_voteclient;
static y_votelvlinfo levelinfo[5];
static y_votelvlinfo levelinfo[13];
static y_voteclient voteclient;
static INT32 votetic;
static INT32 lastvotetic;
static INT32 voteendtic = -1;
static SINT8 votemax = 3;
static INT32 voterowmem = 0;
static boolean rowchange = false;
static boolean votenotyetpicked;
static patch_t *cursor = NULL;
static patch_t *cursor1 = NULL;
@ -1150,12 +1153,50 @@ static inline void Y_DrawAnimatedVoteScreenPatch(boolean widePatch)
//
void Y_VoteDrawer(void)
{
INT32 i, x, y = 0, height = 0;
INT32 rowval, i, lvls, x, picdiff, y = 0, height = 0;
UINT8 selected[4];
fixed_t rubyheight = 0;
fixed_t scale;
patch_t *pic;
INT16 mapnum;
fixed_t picscale = FRACUNIT; // GREENRES
fixed_t picwidth = 160;
// CEP: scale by screen hypotenuse for extra voting rows
INT32 vidx = ((vid.width) / vid.dupx);
INT32 vidy = ((vid.height) / vid.dupy);
fixed_t hypotf = 0;
INT32 hypoti = 0;
// get the hypotenuse
hypoti = (vidx*vidx) + (vidy*vidy);
hypotf = FixedSqrt(hypoti);
// convert the fixed_t back into an integer
hypoti = ((hypotf*10)/FRACUNIT);
if ((voterowmem != cv_votemaxrows.value) && (votemax != cv_votemaxrows.value)) // voting rows were changed(?)
{
CONS_Printf(M_GetText("Max rows will be changed to %d on the next votescreen.\n"), cv_votemaxrows.value); // notify the players
voterowmem = cv_votemaxrows.value;
}
// divisor for rescaling
INT32 hypotdiv = max(10, (40-hypoti));
// readjust the picscale
picscale *= 10;
picscale /= (40-hypoti);
picwidth *= picscale;
// shitty hack to prevent alignment issues
if ( ((hypoti % 5) == 1) || ((hypoti % 5) == 4) || ((hypoti % 5) == 2) )
{
if ((hypoti % 5) == 2) // scale DOWN the image
picscale -= (hypoti*16);
else
picscale += (hypoti*2); // scale UP the image
}
if (rendermode == render_none)
return;
@ -1200,7 +1241,8 @@ void Y_VoteDrawer(void)
}
}
for (i = 0; i < 4; i++) // First, we need to figure out the height of this thing...
rowval = (votemax*3)+((votemax > 1) ? (votemax - 1) : 0);
for (i = 0; i < (rowval+1); i++) // First, we need to figure out the height of this thing...
{
UINT8 j;
selected[i] = 0; // Initialize
@ -1212,21 +1254,39 @@ void Y_VoteDrawer(void)
}
if (selected[i])
height += 50;
height += 25; // 50
else
height += 25;
if (i < 3)
if (i < rowval)
height += 5-splitscreen;
}
height /= votemax;
y = (200-height)/2;
for (i = 0; i < 4; i++)
picdiff = 80*( max(0, (votemax-1) ) ); // let's draw these in reverse order
lvls = -1; // shitty cheat
for (i = 0; i < (rowval+1); i++)
{
const char *str;
UINT8 j, color;
if (i == 3)
// CEP: hack hell
INT32 scaledpicdiff = ((picdiff*10)/hypotdiv);
INT32 fillscale = 800/hypotdiv;
INT32 hypotmod = (hypoti % 5); // hypotenuse mod 5, rescale the bounding box
INT32 hypotadd = ((hypotmod > 1) ? (hypotmod/4) : hypotmod); // how much do we add the bounding box by?
// integer scaling makes me want to DIE
if (hypotmod == 3)
hypotadd += (1);
scaledpicdiff *= 3;
scaledpicdiff /= 2; // 1.5
if (i == rowval)
{
str = "RANDOM";
mapnum = -1;
@ -1288,59 +1348,99 @@ void Y_VoteDrawer(void)
if (votes[p] != -1 || players[p].spectator)
continue;
handy += 6*(3-splitscreen) + (13*j);
V_DrawMappedPatch(BASEVIDWIDTH-124, handy, V_SNAPTORIGHT, thiscurs, colormap);
handy += 3*(3-splitscreen) + (13*j);
V_DrawMappedPatch(BASEVIDWIDTH-(1600/hypotdiv)-scaledpicdiff, handy, V_SNAPTORIGHT, thiscurs, colormap);
if (votetic % 10 < 4)
V_DrawFill(BASEVIDWIDTH-100-sizeadd, y-sizeadd, 80+(sizeadd*2), 50+(sizeadd*2), 0|V_SNAPTORIGHT);
V_DrawFill(BASEVIDWIDTH-(1200/hypotdiv)-sizeadd-scaledpicdiff, y-sizeadd, (fillscale + (sizeadd*2) + hypotadd), ((500/hypotdiv)+(sizeadd*2)) + hypotadd, 0|V_SNAPTORIGHT);
else
V_DrawFill(BASEVIDWIDTH-100-sizeadd, y-sizeadd, 80+(sizeadd*2), 50+(sizeadd*2), color|V_SNAPTORIGHT);
V_DrawFill(BASEVIDWIDTH-(1200/hypotdiv)-sizeadd-scaledpicdiff, y-sizeadd, (fillscale + (sizeadd*2) + hypotadd), ((500/hypotdiv)+(sizeadd*2)) + hypotadd, color|V_SNAPTORIGHT);
sizeadd--;
}
if (!levelinfo[i].encore)
V_DrawFixedPatch((BASEVIDWIDTH-100)<<FRACBITS, y<<FRACBITS, scale, V_SNAPTORIGHT, pic, NULL);
V_DrawFixedPatch((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS, y<<FRACBITS, picscale/2, V_SNAPTORIGHT, pic, 0);
else
{
V_DrawFixedPatch((BASEVIDWIDTH-20)<<FRACBITS, y<<FRACBITS, scale, V_FLIP|V_SNAPTORIGHT, pic, NULL);
V_DrawFixedPatch((BASEVIDWIDTH-60)<<FRACBITS, ((y+25)<<FRACBITS) - (rubyheight<<1), FRACUNIT, V_SNAPTORIGHT, rubyicon, NULL);
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/2), y<<FRACBITS, picscale/2, V_FLIP|V_SNAPTORIGHT, pic, 0);
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/4), (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, picscale, V_SNAPTORIGHT, rubyicon, NULL);
}
V_DrawRightAlignedThinString(BASEVIDWIDTH-21, 40+y, V_SNAPTORIGHT|V_6WIDTHSPACE, str);
V_DrawRightAlignedThinString(BASEVIDWIDTH-(420/hypotdiv)-scaledpicdiff, (400/hypotdiv)+y, V_SNAPTORIGHT|V_6WIDTHSPACE, str);
if (levelinfo[i].gts)
{
INT32 w = V_ThinStringWidth(levelinfo[i].gts, V_SNAPTORIGHT)+1;
V_DrawFill(BASEVIDWIDTH-100, y+10, w+1, 2, V_SNAPTORIGHT|31);
V_DrawFill(BASEVIDWIDTH-100, y, w, 11, V_SNAPTORIGHT|levelinfo[i].gtc);
V_DrawDiag(BASEVIDWIDTH-100+w+1, y, 12, V_SNAPTORIGHT|31);
V_DrawDiag(BASEVIDWIDTH-100+w, y, 11, V_SNAPTORIGHT|levelinfo[i].gtc);
V_DrawThinString(BASEVIDWIDTH-99, y+1, V_SNAPTORIGHT, levelinfo[i].gts);
w *= 10;
w /= (hypotdiv);
if (hypoti >= 16)
{
V_DrawFill(BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff, y+10, w+1, 2, V_SNAPTORIGHT|31);
V_DrawFill(BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff, y, w, 11, V_SNAPTORIGHT|levelinfo[i].gtc);
V_DrawDiag(BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff+w+1, y, 12, V_SNAPTORIGHT|31);
V_DrawDiag(BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff+w, y, 11, V_SNAPTORIGHT|levelinfo[i].gtc);
V_DrawThinString(BASEVIDWIDTH-(1188/hypotdiv)-scaledpicdiff, y+1, V_SNAPTORIGHT, levelinfo[i].gts);
}
else // literally almost entirely covers the map icon, let's just mark it red or something
{
V_DrawDiag(BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff, y, 8, V_SNAPTORIGHT|31);
V_DrawDiag(BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff, y, 6, V_SNAPTORIGHT|levelinfo[i].gtc);
}
}
y += 50;
y += ((25*10) / (hypotdiv/2));
lvls += 1;
// screen height isn't doing us any favors
if (lvls >= 6) // loop over if we have an extra row
{
lvls = -2;
picdiff -= 90; // yes, this will overlap; no, I don't plan to change it
y = (200-height)/2;
y -= 5;
}
}
else
{
scale /= 2;
if (!levelinfo[i].encore)
V_DrawFixedPatch((BASEVIDWIDTH-60)<<FRACBITS, y<<FRACBITS, scale, V_SNAPTORIGHT, pic, NULL);
V_DrawFixedPatch((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS, y<<FRACBITS, picscale/2, V_SNAPTORIGHT, pic, 0);
else
{
V_DrawFixedPatch((BASEVIDWIDTH-20)<<FRACBITS, y<<FRACBITS, scale, V_FLIP|V_SNAPTORIGHT, pic, NULL);
V_DrawFixedPatch((BASEVIDWIDTH-40)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, FRACUNIT/2, V_SNAPTORIGHT, rubyicon, NULL);
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/2), y<<FRACBITS, picscale/2, V_FLIP|V_SNAPTORIGHT, pic, 0);
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/4), (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, picscale, V_SNAPTORIGHT, rubyicon, NULL);
}
if (levelinfo[i].gts)
{
V_DrawDiag(BASEVIDWIDTH-60, y, 8, V_SNAPTORIGHT|31);
V_DrawDiag(BASEVIDWIDTH-60, y, 6, V_SNAPTORIGHT|levelinfo[i].gtc);
V_DrawDiag(BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff, y, 8, V_SNAPTORIGHT|31);
V_DrawDiag(BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff, y, 6, V_SNAPTORIGHT|levelinfo[i].gtc);
}
y += ((25*10) / (hypotdiv/2));
lvls += 1;
if (lvls >= 6)
{
lvls = -2;
picdiff -= 90;
y = (200-height)/2;
y -= 5;
}
y += 25;
}
y += 5-splitscreen;
lvls += 1;
if (lvls >= 6)
{
lvls = -2;
picdiff -= 90;
y = (200-height)/2;
y -= 5;
}
}
x = 20;
@ -1353,7 +1453,7 @@ void Y_VoteDrawer(void)
if ((playeringame[i] && !players[i].spectator) && votes[i] != -1)
{
if (votes[i] >= 3 && (i != pickedvote || voteendtic == -1))
if (votes[i] >= ((votemax*3)+((votemax > 1) ? (votemax - 1) : 0)) && (i != pickedvote || voteendtic == -1))
mapnum = -1; // randomlvl
else
mapnum = votelevels[votes[i]][0];
@ -1442,7 +1542,7 @@ static void Y_VoteStops(SINT8 pick, SINT8 level)
nextmap = votelevels[level][0];
//if (level == 4)
// S_StartSound(NULL, sfx_noooo2); // gasp
//S_StartSound(NULL, sfx_noooo2); // gasp
if (mapheaderinfo[nextmap] && (mapheaderinfo[nextmap]->menuflags & LF2_HIDEINMENU))
S_StartSound(NULL, sfx_noooo1); // this is bad
else if (netgame && P_IsLocalPlayer(&players[pick]))
@ -1490,7 +1590,7 @@ void Y_VoteTicker(void)
if (!playeringame[i] || players[i].spectator)
votes[i] = -1; // Spectators are the lower class, and have effectively no voice in the government. Democracy sucks.
else if (pickedvote != -1 && votes[i] == -1)
votes[i] = 3; // Slow people get random
votes[i] = (votemax*3)+((votemax > 1) ? (votemax - 1) : 0); // Slow people get random
}
if (server && pickedvote != -1 && votes[pickedvote] == -1) // Uh oh! The person who got picked left! Recalculate, quick!
@ -1583,6 +1683,12 @@ void Y_VoteTicker(void)
{
UINT8 p;
boolean pressed = false;
SINT8 votewrap = 0;
if (votemax == 2)
votewrap = 3;
else if (votemax == 3)
votewrap = 7;
switch (i)
{
@ -1619,9 +1725,31 @@ void Y_VoteTicker(void)
pressed = true;
}
if (votemax > 1) // only allow side-movements for multi-row selections
{
// HORRIBLE hack, my GOD
if (G_PlayerInputDown(i, gc_turnright, false) && !pressed) // move right
{
if (voteclient.playerinfo[i].selection <= votewrap)
voteclient.playerinfo[i].selection += 4;
else
voteclient.playerinfo[i].selection -= ((votemax-1)*4);
pressed = true;
}
if (G_PlayerInputDown(i, gc_turnleft, false) && !pressed) // move left
{
if (voteclient.playerinfo[i].selection > 3)
voteclient.playerinfo[i].selection -= 4;
else
voteclient.playerinfo[i].selection += ((votemax-1)*4);
pressed = true;
}
}
if (voteclient.playerinfo[i].selection < 0)
voteclient.playerinfo[i].selection = 3;
if (voteclient.playerinfo[i].selection > 3)
voteclient.playerinfo[i].selection = ((votemax*3)+((votemax > 1) ? (votemax-1) : 0) );
if (voteclient.playerinfo[i].selection > ((votemax*3)+((votemax > 1) ? (votemax-1) : 0)) )
voteclient.playerinfo[i].selection = 0;
if (G_PlayerInputDown(i, gc_accelerate, false) && pressed == false)
@ -1648,7 +1776,7 @@ void Y_VoteTicker(void)
for (i = 0; i < MAXPLAYERS; i++)
{
if ((playeringame[i] && !players[i].spectator) && votes[i] == -1)
votes[i] = 3;
votes[i] = (votemax*3)+((votemax > 1) ? (votemax-1) : 0);
}
}
else
@ -1690,8 +1818,13 @@ void Y_VoteTicker(void)
void Y_StartVote(void)
{
INT32 i = 0;
INT32 rowval = (cv_votemaxrows.value*3)+((cv_votemaxrows.value > 1) ? (cv_votemaxrows.value - 1) : 0);
boolean battlemode = ((votelevels[0][1] & ~VOTEMODIFIER_ENCORE) == GT_BATTLE); // todo gametyperules
votemax = cv_votemaxrows.value; // can we please avoid SIGSEGVs
voterowmem = cv_votemaxrows.value; // this is just for the notif system
rowchange = false;
votetic = -1;
#ifdef PARANOIA
@ -1730,7 +1863,7 @@ void Y_StartVote(void)
for (i = 0; i < MAXPLAYERS; i++)
votes[i] = -1;
for (i = 0; i < 4; i++)
for (i = 0; i < (rowval + 1); i++)
{
// set up the encore
levelinfo[i].encore = (votelevels[i][1] & VOTEMODIFIER_ENCORE);
@ -1836,7 +1969,7 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level)
for (i = 0; i < MAXPLAYERS; i++)
{
if ((playeringame[i] && !players[i].spectator) && votes[i] == -1)
votes[i] = 3;
votes[i] = (votemax*3)+((votemax > 1) ? (votemax - 1) : 0);
if (votes[i] == -1 || endtype > 1) // Don't need to go on
continue;