2014-03-15 16:59:03 +00:00
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
2016-07-06 04:09:17 +00:00
// Copyright (C) 2004-2016 by Sonic Team Junior.
2014-03-15 16:59:03 +00:00
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file y_inter.c
2016-07-06 04:09:17 +00:00
/// \brief Tally screens, or "Intermissions" as they were formally called in Doom
2014-03-15 16:59:03 +00:00
# include "doomdef.h"
# include "doomstat.h"
# include "d_main.h"
# include "f_finale.h"
# include "g_game.h"
# include "hu_stuff.h"
# include "i_net.h"
# include "i_video.h"
# include "p_tick.h"
# include "r_defs.h"
# include "r_things.h"
# include "s_sound.h"
# include "st_stuff.h"
# include "v_video.h"
# include "w_wad.h"
# include "y_inter.h"
# include "z_zone.h"
# include "m_menu.h"
# include "m_misc.h"
# include "i_system.h"
# include "p_setup.h"
# include "r_local.h"
# include "p_local.h"
# include "m_cond.h" // condition sets
2018-07-02 12:20:04 +00:00
# include "m_random.h" // M_RandomKey
2018-02-04 04:47:47 +00:00
# include "g_input.h" // PLAYER1INPUTDOWN
2018-06-05 06:11:47 +00:00
# include "k_kart.h" // colortranslations
2018-07-02 12:20:04 +00:00
# include "console.h" // cons_menuhighlight
2018-01-27 06:17:08 +00:00
2014-03-15 16:59:03 +00:00
# ifdef HWRENDER
# include "hardware/hw_main.h"
# endif
# ifdef PC_DOS
# include <stdio.h> // for snprintf
int snprintf ( char * str , size_t n , const char * fmt , . . . ) ;
//int vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
# endif
typedef struct
{
char patch [ 9 ] ;
INT32 points ;
UINT8 display ;
} y_bonus_t ;
typedef union
{
2018-07-18 19:23:46 +00:00
/*struct
2014-03-15 16:59:03 +00:00
{
2017-09-28 20:54:26 +00:00
char passed1 [ 21 ] ; // KNUCKLES GOT / CRAWLA HONCHO
2014-04-14 05:14:58 +00:00
char passed2 [ 16 ] ; // THROUGH THE ACT / PASSED THE ACT
2014-03-15 16:59:03 +00:00
INT32 passedx1 ;
INT32 passedx2 ;
y_bonus_t bonuses [ 4 ] ;
patch_t * bonuspatches [ 4 ] ;
SINT8 gotperfbonus ; // Used for visitation flags.
UINT32 score , total ; // fake score, total
UINT32 tics ; // time
patch_t * ttlnum ; // act number being displayed
patch_t * ptotal ; // TOTAL
UINT8 gotlife ; // Number of extra lives obtained
2018-07-19 12:23:15 +00:00
} coop ; */
2014-03-15 16:59:03 +00:00
struct
{
UINT8 * color [ MAXPLAYERS ] ; // Winner's color #
INT32 * character [ MAXPLAYERS ] ; // Winner's character #
INT32 num [ MAXPLAYERS ] ; // Winner's player #
char * name [ MAXPLAYERS ] ; // Winner's name
INT32 numplayers ; // Number of players being displayed
2018-08-05 15:35:33 +00:00
char levelstring [ 64 ] ; // holds levelnames up to 64 characters
2017-02-07 22:19:04 +00:00
// SRB2kart
2018-07-19 15:28:36 +00:00
UINT8 increase [ MAXPLAYERS ] ; //how much did the score increase by?
2018-07-18 19:23:46 +00:00
UINT32 val [ MAXPLAYERS ] ; //Gametype-specific value
2018-07-18 00:21:36 +00:00
UINT8 pos [ MAXPLAYERS ] ; // player positions. used for ties
2018-07-18 19:23:46 +00:00
boolean rankingsmode ; // rankings mode
2018-07-23 22:50:41 +00:00
boolean encore ; // encore mode
2014-03-15 16:59:03 +00:00
} match ;
} y_data ;
static y_data data ;
// graphics
static patch_t * bgpatch = NULL ; // INTERSCR
static patch_t * widebgpatch = NULL ; // INTERSCW
static patch_t * bgtile = NULL ; // SPECTILE/SRB2BACK
static patch_t * interpic = NULL ; // custom picture defined in map header
static boolean usetile ;
2014-03-21 18:42:55 +00:00
boolean usebuffer = false ;
2014-03-15 16:59:03 +00:00
static boolean useinterpic ;
static INT32 timer ;
static INT32 intertic ;
static INT32 endtic = - 1 ;
2018-07-18 19:23:46 +00:00
static INT32 sorttic = - 1 ;
2014-03-15 16:59:03 +00:00
intertype_t intertype = int_none ;
static void Y_FollowIntermission ( void ) ;
static void Y_UnloadData ( void ) ;
2018-01-27 06:17:08 +00:00
// SRB2Kart: voting stuff
2018-05-31 22:49:19 +00:00
// Level images
2018-01-27 06:17:08 +00:00
typedef struct
{
2018-07-07 21:10:26 +00:00
char str [ 62 ] ;
2018-06-28 14:47:56 +00:00
UINT8 gtc ;
const char * gts ;
2018-01-27 06:17:08 +00:00
patch_t * pic ;
2018-08-11 21:23:40 +00:00
boolean encore ;
2018-02-04 04:47:47 +00:00
} y_votelvlinfo ;
2018-01-27 06:17:08 +00:00
2018-05-31 22:49:19 +00:00
// Clientside & splitscreen player info.
2018-01-27 06:17:08 +00:00
typedef struct
{
2018-02-23 01:04:52 +00:00
SINT8 selection ;
2018-02-04 04:47:47 +00:00
UINT8 delay ;
2018-05-31 22:49:19 +00:00
} y_voteplayer ;
typedef struct
{
y_voteplayer playerinfo [ 4 ] ;
2018-02-11 00:02:15 +00:00
UINT8 ranim ;
UINT8 rtics ;
UINT8 roffset ;
2018-02-11 17:18:25 +00:00
UINT8 rsynctime ;
UINT8 rendoff ;
2018-07-28 01:59:00 +00:00
boolean loaded ;
2018-02-04 04:47:47 +00:00
} y_voteclient ;
2018-01-27 06:17:08 +00:00
2018-07-22 20:02:31 +00:00
static y_votelvlinfo levelinfo [ 5 ] ;
2018-02-04 04:47:47 +00:00
static y_voteclient voteclient ;
2018-01-27 06:17:08 +00:00
static INT32 votetic ;
static INT32 voteendtic = - 1 ;
static patch_t * cursor = NULL ;
2018-06-05 06:11:47 +00:00
static patch_t * cursor1 = NULL ;
static patch_t * cursor2 = NULL ;
static patch_t * cursor3 = NULL ;
static patch_t * cursor4 = NULL ;
2018-01-28 04:52:01 +00:00
static patch_t * randomlvl = NULL ;
2018-08-11 21:23:40 +00:00
static patch_t * rubyicon = NULL ;
2018-01-27 06:17:08 +00:00
static void Y_UnloadVoteData ( void ) ;
2018-07-19 13:29:11 +00:00
//
// SRB2Kart - Y_CalculateMatchData and ancillary functions
//
static void Y_CompareRace ( INT32 i )
{
UINT32 val = ( ( players [ i ] . pflags & PF_TIMEOVER | | players [ i ] . realtime = = UINT32_MAX )
? ( UINT32_MAX - 1 ) : players [ i ] . realtime ) ;
if ( ! ( val < data . match . val [ data . match . numplayers ] ) )
return ;
data . match . val [ data . match . numplayers ] = val ;
data . match . num [ data . match . numplayers ] = i ;
}
static void Y_CompareBattle ( INT32 i )
{
UINT32 val = ( ( players [ i ] . pflags & PF_TIMEOVER )
? ( UINT32_MAX - 1 ) : players [ i ] . marescore ) ;
if ( ! ( data . match . val [ data . match . numplayers ] = = UINT32_MAX
| | ( ! ( players [ i ] . pflags & PF_TIMEOVER ) & & val > data . match . val [ data . match . numplayers ] ) ) )
return ;
data . match . val [ data . match . numplayers ] = val ;
data . match . num [ data . match . numplayers ] = i ;
}
static void Y_CompareRank ( INT32 i )
{
if ( ! ( data . match . val [ data . match . numplayers ] = = UINT32_MAX | | players [ i ] . score > data . match . val [ data . match . numplayers ] ) )
return ;
data . match . val [ data . match . numplayers ] = players [ i ] . score ;
data . match . num [ data . match . numplayers ] = i ;
}
static void Y_CalculateMatchData ( boolean rankingsmode , void ( * comparison ) ( INT32 ) )
{
INT32 i , j ;
boolean completed [ MAXPLAYERS ] ;
INT32 numplayersingame = 0 ;
// Initialize variables
if ( ( data . match . rankingsmode = rankingsmode ) )
sprintf ( data . match . levelstring , " * Total Rankings * " ) ;
2018-08-05 15:35:33 +00:00
else
{
// set up the levelstring
if ( mapheaderinfo [ prevmap ] - > levelflags & LF_NOZONE )
{
if ( mapheaderinfo [ prevmap ] - > actnum [ 0 ] )
snprintf ( data . match . levelstring ,
sizeof data . match . levelstring ,
" * %s %s * " ,
mapheaderinfo [ prevmap ] - > lvlttl , mapheaderinfo [ prevmap ] - > actnum ) ;
else
snprintf ( data . match . levelstring ,
sizeof data . match . levelstring ,
" * %s * " ,
mapheaderinfo [ prevmap ] - > lvlttl ) ;
}
else
{
const char * zonttl = ( mapheaderinfo [ prevmap ] - > zonttl [ 0 ] ? mapheaderinfo [ prevmap ] - > zonttl : " ZONE " ) ;
if ( mapheaderinfo [ prevmap ] - > actnum [ 0 ] )
snprintf ( data . match . levelstring ,
sizeof data . match . levelstring ,
" * %s %s %s * " ,
mapheaderinfo [ prevmap ] - > lvlttl , zonttl , mapheaderinfo [ prevmap ] - > actnum ) ;
else
snprintf ( data . match . levelstring ,
sizeof data . match . levelstring ,
" * %s %s * " ,
mapheaderinfo [ prevmap ] - > lvlttl , zonttl ) ;
}
data . match . levelstring [ sizeof data . match . levelstring - 1 ] = ' \0 ' ;
}
2018-07-19 13:29:11 +00:00
2018-07-23 22:50:41 +00:00
data . match . encore = ( ! rankingsmode & & encoremode ) ;
2018-07-19 13:29:11 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
2018-07-19 15:28:36 +00:00
data . match . val [ i ] = UINT32_MAX ;
if ( ! rankingsmode )
data . match . increase [ i ] = UINT8_MAX ;
2018-07-19 13:29:11 +00:00
if ( ! playeringame [ i ] | | players [ i ] . spectator )
continue ;
numplayersingame + + ;
}
2018-07-19 15:28:36 +00:00
memset ( data . match . color , 0 , sizeof ( data . match . color ) ) ;
memset ( data . match . character , 0 , sizeof ( data . match . character ) ) ;
memset ( completed , 0 , sizeof ( completed ) ) ;
data . match . numplayers = 0 ;
2018-07-19 13:29:11 +00:00
for ( j = 0 ; j < numplayersingame ; j + + )
{
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
if ( ! playeringame [ i ] | | players [ i ] . spectator | | completed [ i ] )
continue ;
comparison ( i ) ;
}
i = data . match . num [ data . match . numplayers ] ;
completed [ i ] = true ;
data . match . color [ data . match . numplayers ] = & players [ i ] . skincolor ;
data . match . character [ data . match . numplayers ] = & players [ i ] . skin ;
data . match . name [ data . match . numplayers ] = player_names [ i ] ;
if ( data . match . numplayers & & ( data . match . val [ data . match . numplayers ] = = data . match . val [ data . match . numplayers - 1 ] ) )
data . match . pos [ data . match . numplayers ] = data . match . pos [ data . match . numplayers - 1 ] ;
else
data . match . pos [ data . match . numplayers ] = data . match . numplayers + 1 ;
2018-07-19 15:28:36 +00:00
if ( ! rankingsmode & & ! ( players [ i ] . pflags & PF_TIMEOVER ) & & ( data . match . pos [ data . match . numplayers ] ! = numplayersingame ) )
2018-07-19 13:29:11 +00:00
{
data . match . increase [ i ] = numplayersingame - data . match . pos [ data . match . numplayers ] ;
players [ i ] . score + = data . match . increase [ i ] ;
}
data . match . numplayers + + ;
}
}
2014-03-15 16:59:03 +00:00
//
// Y_IntermissionDrawer
//
2018-07-19 13:29:11 +00:00
// Called by D_Display. Nothing is modified here; all it does is draw. (SRB2Kart: er, about that...)
2014-03-15 16:59:03 +00:00
// Neat concept, huh?
//
void Y_IntermissionDrawer ( void )
{
2018-07-18 19:23:46 +00:00
INT32 i , whiteplayer = MAXPLAYERS , x = 4 , hilicol = V_YELLOWMAP ; // fallback
2014-03-15 16:59:03 +00:00
if ( intertype = = int_none | | rendermode = = render_none )
return ;
if ( ! usebuffer )
V_DrawFill ( 0 , 0 , BASEVIDWIDTH , BASEVIDHEIGHT , 31 ) ;
if ( useinterpic )
V_DrawScaledPatch ( 0 , 0 , 0 , interpic ) ;
else if ( ! usetile )
{
if ( rendermode = = render_soft & & usebuffer )
VID_BlitLinearScreen ( screens [ 1 ] , screens [ 0 ] , vid . width * vid . bpp , vid . height , vid . width * vid . bpp , vid . rowbytes ) ;
# ifdef HWRENDER
else if ( rendermode ! = render_soft & & usebuffer )
{
HWR_DrawIntermissionBG ( ) ;
}
# endif
else
{
if ( widebgpatch & & rendermode = = render_soft & & vid . width / vid . dupx = = 400 )
V_DrawScaledPatch ( 0 , 0 , V_SNAPTOLEFT , widebgpatch ) ;
else
V_DrawScaledPatch ( 0 , 0 , 0 , bgpatch ) ;
}
}
else
V_DrawPatchFill ( bgtile ) ;
2018-07-19 04:07:13 +00:00
if ( usebuffer ) // Fade everything out
2018-07-29 00:04:43 +00:00
V_DrawFadeScreen ( 0xFF00 , 20 ) ;
2018-07-19 04:07:13 +00:00
2018-07-18 19:23:46 +00:00
if ( ! splitscreen )
whiteplayer = demoplayback ? displayplayer : consoleplayer ;
if ( cons_menuhighlight . value )
hilicol = cons_menuhighlight . value ;
else if ( modeattacking )
hilicol = V_ORANGEMAP ;
else
hilicol = ( ( intertype = = int_race ) ? V_SKYMAP : V_REDMAP ) ;
if ( sorttic ! = - 1 & & intertic > sorttic )
{
INT32 count = ( intertic - sorttic ) ;
if ( count < 8 )
x - = ( ( count * vid . width ) / ( 8 * vid . dupx ) ) ;
2018-07-19 13:29:11 +00:00
else if ( count = = 8 )
goto dotimer ;
else if ( count < 16 )
x + = ( ( ( 16 - count ) * vid . width ) / ( 8 * vid . dupx ) ) ;
2018-07-18 19:23:46 +00:00
}
2017-02-07 22:19:04 +00:00
// SRB2kart 290117 - compeltely replaced this block.
2018-07-18 19:23:46 +00:00
/*if (intertype == int_timeattack)
2014-03-15 16:59:03 +00:00
{
// draw time
2017-10-17 20:23:38 +00:00
ST_DrawPatchFromHud ( HUD_TIME , sbotime ) ;
2017-02-07 22:19:04 +00:00
if ( cv_timetic . value )
2017-10-17 20:23:38 +00:00
ST_DrawNumFromHud ( HUD_SECONDS , data . coop . tics ) ;
2014-03-15 16:59:03 +00:00
else
{
2017-10-17 20:23:38 +00:00
INT32 seconds , minutes , tictrn ;
2014-03-15 16:59:03 +00:00
2017-10-17 20:23:38 +00:00
seconds = G_TicsToSeconds ( data . coop . tics ) ;
minutes = G_TicsToMinutes ( data . coop . tics , true ) ;
tictrn = G_TicsToCentiseconds ( data . coop . tics ) ;
ST_DrawNumFromHud ( HUD_MINUTES , minutes ) ; // Minutes
ST_DrawPatchFromHud ( HUD_TIMECOLON , sbocolon ) ; // Colon
ST_DrawPadNumFromHud ( HUD_SECONDS , seconds , 2 ) ; // Seconds
2018-07-18 19:23:46 +00:00
// SRB2kart - pulled from old coop block, just in case we need it
2017-10-17 20:23:38 +00:00
// we should show centiseconds on the intermission screen too, if the conditions are right.
if ( modeattacking | | cv_timetic . value = = 2 )
{
ST_DrawPatchFromHud ( HUD_TIMETICCOLON , sboperiod ) ; // Period
ST_DrawPadNumFromHud ( HUD_TICS , tictrn , 2 ) ; // Tics
2018-07-18 19:23:46 +00:00
}
2017-10-17 20:23:38 +00:00
ST_DrawPatchFromHud ( HUD_TIMETICCOLON , sboperiod ) ; // Period
ST_DrawPadNumFromHud ( HUD_TICS , tictrn , 2 ) ; // Tics
}
2014-03-15 16:59:03 +00:00
// draw the "got through act" lines and act number
V_DrawLevelTitle ( data . coop . passedx1 , 49 , 0 , data . coop . passed1 ) ;
V_DrawLevelTitle ( data . coop . passedx2 , 49 + V_LevelNameHeight ( data . coop . passed2 ) + 2 , 0 , data . coop . passed2 ) ;
2018-06-05 21:28:46 +00:00
if ( strlen ( mapheaderinfo [ prevmap ] - > actnum ) > 0 )
2014-03-15 16:59:03 +00:00
V_DrawScaledPatch ( 244 , 57 , 0 , data . coop . ttlnum ) ;
2017-02-07 22:19:04 +00:00
//if (gottimebonus && endtic != -1)
// V_DrawCenteredString(BASEVIDWIDTH/2, 172, V_YELLOWMAP, "TIME BONUS UNLOCKED!");
2014-03-15 16:59:03 +00:00
}
2018-07-18 19:23:46 +00:00
else */ if ( intertype = = int_race | | intertype = = int_match )
2014-03-15 16:59:03 +00:00
{
2017-02-07 22:19:04 +00:00
INT32 y = 48 ;
2018-07-22 16:39:09 +00:00
const char * timeheader ;
if ( data . match . rankingsmode )
timeheader = " RANK " ;
else
timeheader = ( intertype = = int_race ? " TIME " : " SCORE " ) ;
2016-07-06 04:09:17 +00:00
2017-02-07 22:19:04 +00:00
// draw the level name
2018-07-18 19:23:46 +00:00
V_DrawCenteredString ( - 4 + x + BASEVIDWIDTH / 2 , 20 , 0 , data . match . levelstring ) ;
V_DrawFill ( x , 42 , 312 , 1 , 0 ) ;
2014-03-15 16:59:03 +00:00
2018-07-23 22:50:41 +00:00
if ( data . match . encore )
V_DrawCenteredString ( - 4 + x + BASEVIDWIDTH / 2 , 20 - 8 , hilicol , " ENCORE MODE " ) ;
2017-02-07 22:19:04 +00:00
if ( data . match . numplayers > 8 )
2014-03-15 16:59:03 +00:00
{
2018-08-24 12:36:03 +00:00
V_DrawFill ( x + 156 , 32 , 1 , 152 , 0 ) ;
2017-02-07 22:19:04 +00:00
2018-07-02 12:20:04 +00:00
V_DrawCenteredString ( x + 6 + ( BASEVIDWIDTH / 2 ) , 32 , hilicol , " # " ) ;
V_DrawString ( x + 36 + ( BASEVIDWIDTH / 2 ) , 32 , hilicol , " NAME " ) ;
2017-02-07 22:19:04 +00:00
2018-07-19 04:07:13 +00:00
V_DrawRightAlignedString ( x + 152 , 32 , hilicol , timeheader ) ;
2016-07-06 04:09:17 +00:00
}
2017-02-07 22:19:04 +00:00
2018-07-02 12:20:04 +00:00
V_DrawCenteredString ( x + 6 , 32 , hilicol , " # " ) ;
V_DrawString ( x + 36 , 32 , hilicol , " NAME " ) ;
2017-02-07 22:19:04 +00:00
2018-07-19 04:07:13 +00:00
V_DrawRightAlignedString ( x + ( BASEVIDWIDTH / 2 ) + 152 , 32 , hilicol , timeheader ) ;
2017-02-07 22:19:04 +00:00
for ( i = 0 ; i < data . match . numplayers ; i + + )
2014-03-15 16:59:03 +00:00
{
2018-07-19 00:27:36 +00:00
if ( data . match . num [ i ] ! = MAXPLAYERS & & playeringame [ data . match . num [ i ] ] & & ! players [ data . match . num [ i ] ] . spectator )
2014-03-15 16:59:03 +00:00
{
2018-08-24 12:36:03 +00:00
char strtime [ MAXPLAYERNAME + 1 ] ;
2018-07-02 12:20:04 +00:00
2018-07-19 00:27:36 +00:00
V_DrawCenteredString ( x + 6 , y , 0 , va ( " %d " , data . match . pos [ i ] ) ) ;
2017-02-07 22:19:04 +00:00
if ( data . match . color [ i ] = = 0 )
V_DrawSmallScaledPatch ( x + 16 , y - 4 , 0 , faceprefix [ * data . match . character [ i ] ] ) ;
else
{
UINT8 * colormap = R_GetTranslationColormap ( * data . match . character [ i ] , * data . match . color [ i ] , GTC_CACHE ) ;
V_DrawSmallMappedPatch ( x + 16 , y - 4 , 0 , faceprefix [ * data . match . character [ i ] ] , colormap ) ;
}
2014-03-15 16:59:03 +00:00
2018-08-24 12:36:03 +00:00
if ( data . match . numplayers > 8 )
strlcpy ( strtime , data . match . name [ i ] , 6 ) ;
2017-02-07 22:19:04 +00:00
else
2018-08-24 12:36:03 +00:00
STRBUFCPY ( strtime , data . match . name [ i ] ) ;
2014-03-15 16:59:03 +00:00
2018-07-18 19:23:46 +00:00
V_DrawString ( x + 36 , y ,
( ( data . match . num [ i ] = = whiteplayer )
? hilicol | V_ALLOWLOWERCASE
: V_ALLOWLOWERCASE ) ,
2018-08-24 12:36:03 +00:00
strtime ) ;
2014-03-15 16:59:03 +00:00
2018-07-19 04:07:13 +00:00
if ( data . match . rankingsmode )
{
2018-07-19 15:28:36 +00:00
if ( data . match . increase [ data . match . num [ i ] ] ! = UINT8_MAX )
{
if ( data . match . increase [ data . match . num [ i ] ] > 9 )
snprintf ( strtime , sizeof strtime , " (+%02d) " , data . match . increase [ data . match . num [ i ] ] ) ;
else
snprintf ( strtime , sizeof strtime , " (+ %d) " , data . match . increase [ data . match . num [ i ] ] ) ;
2017-02-07 22:19:04 +00:00
2018-07-19 15:28:36 +00:00
if ( data . match . numplayers > 8 )
V_DrawRightAlignedString ( x + 120 , y , 0 , strtime ) ;
else
V_DrawRightAlignedString ( x + 120 + BASEVIDWIDTH / 2 , y , 0 , strtime ) ;
2018-07-19 04:07:13 +00:00
2018-07-19 15:28:36 +00:00
snprintf ( strtime , sizeof strtime , " %d " , data . match . val [ i ] - data . match . increase [ data . match . num [ i ] ] ) ;
}
else
snprintf ( strtime , sizeof strtime , " %d " , data . match . val [ i ] ) ;
2017-02-07 22:19:04 +00:00
2018-07-19 04:07:13 +00:00
if ( data . match . numplayers > 8 )
V_DrawRightAlignedString ( x + 152 , y , 0 , strtime ) ;
else
V_DrawRightAlignedString ( x + 152 + BASEVIDWIDTH / 2 , y , 0 , strtime ) ;
}
else
2018-07-18 00:21:36 +00:00
{
2018-07-18 19:23:46 +00:00
if ( data . match . val [ i ] = = ( UINT32_MAX - 1 ) )
2018-07-18 00:21:36 +00:00
{
2018-07-18 19:23:46 +00:00
if ( data . match . numplayers > 8 )
2018-07-19 04:07:13 +00:00
V_DrawRightAlignedThinString ( x + 152 , y - 1 , 0 , " NO CONTEST " ) ;
2018-07-18 00:21:36 +00:00
else
2018-07-19 04:07:13 +00:00
V_DrawRightAlignedThinString ( x + 152 + BASEVIDWIDTH / 2 , y - 1 , 0 , " NO CONTEST " ) ;
2018-07-18 00:21:36 +00:00
}
else
2018-07-18 19:23:46 +00:00
{
if ( intertype = = int_race )
{
snprintf ( strtime , sizeof strtime , " %i:%02i.%02i " , G_TicsToMinutes ( data . match . val [ i ] , true ) ,
G_TicsToSeconds ( data . match . val [ i ] ) , G_TicsToCentiseconds ( data . match . val [ i ] ) ) ;
strtime [ sizeof strtime - 1 ] = ' \0 ' ;
if ( data . match . numplayers > 8 )
2018-07-19 04:07:13 +00:00
V_DrawRightAlignedString ( x + 152 , y , 0 , strtime ) ;
2018-07-18 19:23:46 +00:00
else
2018-07-19 04:07:13 +00:00
V_DrawRightAlignedString ( x + 152 + BASEVIDWIDTH / 2 , y , 0 , strtime ) ;
2018-07-18 19:23:46 +00:00
}
else
{
if ( data . match . numplayers > 8 )
2018-07-19 04:07:13 +00:00
V_DrawRightAlignedString ( x + 152 , y , 0 , va ( " %i " , data . match . val [ i ] ) ) ;
2018-07-18 19:23:46 +00:00
else
2018-07-19 04:07:13 +00:00
V_DrawRightAlignedString ( x + 152 + BASEVIDWIDTH / 2 , y , 0 , va ( " %i " , data . match . val [ i ] ) ) ;
2018-07-18 19:23:46 +00:00
}
2018-07-18 00:21:36 +00:00
}
2018-07-18 19:23:46 +00:00
}
2017-02-07 22:19:04 +00:00
}
2018-07-18 19:23:46 +00:00
else
2018-08-24 12:36:03 +00:00
{
data . match . increase [ data . match . num [ i ] ] = 0 ;
2018-07-19 13:29:11 +00:00
data . match . num [ i ] = MAXPLAYERS ; // this should be the only field setting in this function
2018-08-24 12:36:03 +00:00
}
2017-02-07 22:19:04 +00:00
y + = 16 ;
2018-08-24 12:36:03 +00:00
if ( i = = 7 )
2014-03-15 16:59:03 +00:00
{
2017-02-07 22:19:04 +00:00
y = 48 ;
x + = BASEVIDWIDTH / 2 ;
2014-03-15 16:59:03 +00:00
}
}
}
2018-07-18 19:23:46 +00:00
dotimer :
2014-03-15 16:59:03 +00:00
if ( timer )
2018-07-19 13:29:11 +00:00
{
INT32 tickdown = ( timer + 1 ) / TICRATE ;
2018-07-30 20:53:54 +00:00
V_DrawCenteredString ( BASEVIDWIDTH / 2 , 188 , hilicol ,
2018-08-05 15:35:33 +00:00
va ( " %s starts in %d " , cv_advancemap . string , tickdown ) ) ;
2018-07-19 13:29:11 +00:00
}
2014-03-15 16:59:03 +00:00
// Make it obvious that scrambling is happening next round.
if ( cv_scrambleonchange . value & & cv_teamscramble . value & & ( intertic / TICRATE % 2 = = 0 ) )
2018-07-30 20:53:54 +00:00
V_DrawCenteredString ( BASEVIDWIDTH / 2 , BASEVIDHEIGHT / 2 , hilicol , M_GetText ( " Teams will be scrambled next round! " ) ) ;
2014-03-15 16:59:03 +00:00
}
//
// Y_Ticker
//
// Manages fake score tally for single player end of act, and decides when intermission is over.
//
void Y_Ticker ( void )
{
if ( intertype = = int_none )
return ;
// Check for pause or menu up in single player
2015-01-01 19:50:31 +00:00
if ( paused | | P_AutoPause ( ) )
2014-03-15 16:59:03 +00:00
return ;
intertic + + ;
// Team scramble code for team match and CTF.
// Don't do this if we're going to automatically scramble teams next round.
if ( G_GametypeHasTeams ( ) & & cv_teamscramble . value & & ! cv_scrambleonchange . value & & server )
{
// If we run out of time in intermission, the beauty is that
// the P_Ticker() team scramble code will pick it up.
if ( ( intertic % ( TICRATE / 7 ) ) = = 0 )
P_DoTeamscrambling ( ) ;
}
// multiplayer uses timer (based on cv_inttime)
if ( timer )
{
if ( ! - - timer )
{
Y_EndIntermission ( ) ;
Y_FollowIntermission ( ) ;
return ;
}
}
// single player is hardcoded to go away after awhile
else if ( intertic = = endtic )
{
Y_EndIntermission ( ) ;
Y_FollowIntermission ( ) ;
return ;
}
2018-07-19 13:29:11 +00:00
if ( intertic < TICRATE | | intertic & 1 | | endtic ! = - 1 )
return ;
2014-03-15 16:59:03 +00:00
2018-07-19 13:29:11 +00:00
if ( intertype = = int_race | | intertype = = int_match )
2017-02-07 22:19:04 +00:00
{
2018-07-19 13:59:38 +00:00
if ( netgame | | multiplayer )
2018-07-19 04:07:13 +00:00
{
if ( sorttic = = - 1 )
sorttic = intertic + max ( ( cv_inttime . value / 2 ) - 2 , 2 ) * TICRATE ; // 8 second pause after match results
2018-07-19 13:29:11 +00:00
else
{
if ( ! data . match . rankingsmode & & ( intertic > = sorttic + 8 ) )
Y_CalculateMatchData ( true , Y_CompareRank ) ;
if ( data . match . rankingsmode & & intertic > sorttic + ( 2 * TICRATE ) )
{
INT32 q = 0 , r = 0 ;
boolean kaching = true ;
for ( q = 0 ; q < data . match . numplayers ; q + + )
{
2018-07-19 15:28:36 +00:00
if ( data . match . num [ q ] = = MAXPLAYERS
| | ! data . match . increase [ data . match . num [ q ] ]
| | data . match . increase [ data . match . num [ q ] ] = = UINT8_MAX )
2018-07-19 13:29:11 +00:00
continue ;
2018-07-19 15:28:36 +00:00
data . match . increase [ data . match . num [ q ] ] - - ;
r + + ;
2018-07-19 13:29:11 +00:00
if ( data . match . increase [ data . match . num [ q ] ] )
2018-07-19 15:28:36 +00:00
kaching = false ;
2018-07-19 13:29:11 +00:00
}
if ( r )
S_StartSound ( NULL , ( kaching ? sfx_chchng : sfx_ptally ) ) ;
else
endtic = intertic + 3 * TICRATE ; // 3 second pause after end of tally
}
}
2018-07-18 19:23:46 +00:00
}
2018-07-19 13:59:38 +00:00
else
endtic = intertic + 8 * TICRATE ; // 8 second pause after end of tally
2017-02-07 22:19:04 +00:00
}
2014-03-15 16:59:03 +00:00
}
//
2014-11-12 00:55:07 +00:00
// Y_UpdateRecordReplays
2014-03-15 16:59:03 +00:00
//
2014-11-12 00:55:07 +00:00
// Update replay files/data, etc. for Record Attack
// See G_SetNightsRecords for NiGHTS Attack.
2014-03-15 16:59:03 +00:00
//
2014-11-12 00:55:07 +00:00
static void Y_UpdateRecordReplays ( void )
2014-03-15 16:59:03 +00:00
{
const size_t glen = strlen ( srb2home ) + 1 + strlen ( " replay " ) + 1 + strlen ( timeattackfolder ) + 1 + strlen ( " MAPXX " ) + 1 ;
char * gpath ;
char lastdemo [ 256 ] , bestdemo [ 256 ] ;
UINT8 earnedEmblems ;
// Record new best time
if ( ! mainrecords [ gamemap - 1 ] )
G_AllocMainRecordData ( gamemap - 1 ) ;
if ( ( mainrecords [ gamemap - 1 ] - > time = = 0 ) | | ( players [ consoleplayer ] . realtime < mainrecords [ gamemap - 1 ] - > time ) )
mainrecords [ gamemap - 1 ] - > time = players [ consoleplayer ] . realtime ;
2018-01-22 00:15:26 +00:00
if ( ( mainrecords [ gamemap - 1 ] - > lap = = 0 ) | | ( bestlap < mainrecords [ gamemap - 1 ] - > lap ) )
mainrecords [ gamemap - 1 ] - > lap = bestlap ;
2014-03-15 16:59:03 +00:00
// Save demo!
bestdemo [ 255 ] = ' \0 ' ;
lastdemo [ 255 ] = ' \0 ' ;
2018-01-22 00:15:26 +00:00
G_SetDemoTime ( players [ consoleplayer ] . realtime , bestlap ) ;
2014-03-15 16:59:03 +00:00
G_CheckDemoStatus ( ) ;
I_mkdir ( va ( " %s " PATHSEP " replay " , srb2home ) , 0755 ) ;
I_mkdir ( va ( " %s " PATHSEP " replay " PATHSEP " %s " , srb2home , timeattackfolder ) , 0755 ) ;
if ( ( gpath = malloc ( glen ) ) = = NULL )
I_Error ( " Out of memory for replay filepath \n " ) ;
sprintf ( gpath , " %s " PATHSEP " replay " PATHSEP " %s " PATHSEP " %s " , srb2home , timeattackfolder , G_BuildMapName ( gamemap ) ) ;
snprintf ( lastdemo , 255 , " %s-%s-last.lmp " , gpath , cv_chooseskin . string ) ;
if ( FIL_FileExists ( lastdemo ) )
{
UINT8 * buf ;
size_t len = FIL_ReadFile ( lastdemo , & buf ) ;
snprintf ( bestdemo , 255 , " %s-%s-time-best.lmp " , gpath , cv_chooseskin . string ) ;
if ( ! FIL_FileExists ( bestdemo ) | | G_CmpDemoTime ( bestdemo , lastdemo ) & 1 )
{ // Better time, save this demo.
if ( FIL_FileExists ( bestdemo ) )
remove ( bestdemo ) ;
FIL_WriteFile ( bestdemo , buf , len ) ;
CONS_Printf ( " \x83 %s \x80 %s '%s' \n " , M_GetText ( " NEW RECORD TIME! " ) , M_GetText ( " Saved replay as " ) , bestdemo ) ;
}
2018-01-22 00:15:26 +00:00
snprintf ( bestdemo , 255 , " %s-%s-lap-best.lmp " , gpath , cv_chooseskin . string ) ;
if ( ! FIL_FileExists ( bestdemo ) | | G_CmpDemoTime ( bestdemo , lastdemo ) & ( 1 < < 1 ) )
{ // Better lap time, save this demo.
if ( FIL_FileExists ( bestdemo ) )
remove ( bestdemo ) ;
FIL_WriteFile ( bestdemo , buf , len ) ;
CONS_Printf ( " \x83 %s \x80 %s '%s' \n " , M_GetText ( " NEW RECORD LAP! " ) , M_GetText ( " Saved replay as " ) , bestdemo ) ;
}
2014-03-15 16:59:03 +00:00
//CONS_Printf("%s '%s'\n", M_GetText("Saved replay as"), lastdemo);
Z_Free ( buf ) ;
}
free ( gpath ) ;
// Check emblems when level data is updated
if ( ( earnedEmblems = M_CheckLevelEmblems ( ) ) )
CONS_Printf ( M_GetText ( " \x82 " " Earned %hu emblem%s for Record Attack records. \n " ) , ( UINT16 ) earnedEmblems , earnedEmblems > 1 ? " s " : " " ) ;
// Update timeattack menu's replay availability.
CV_AddValue ( & cv_nextmap , 1 ) ;
CV_AddValue ( & cv_nextmap , - 1 ) ;
}
//
// Y_StartIntermission
//
// Called by G_DoCompleted. Sets up data for intermission drawer/ticker.
//
void Y_StartIntermission ( void )
{
intertic = - 1 ;
# ifdef PARANOIA
if ( endtic ! = - 1 )
I_Error ( " endtic is dirty " ) ;
# endif
if ( ! multiplayer )
{
timer = 0 ;
2017-10-17 00:23:26 +00:00
/* // srb2kart: time attack tally is UGLY rn
2017-02-07 22:19:04 +00:00
if ( modeattacking )
intertype = int_timeattack ;
else
2017-10-17 00:23:26 +00:00
*/
2017-02-07 22:19:04 +00:00
intertype = int_race ;
2014-03-15 16:59:03 +00:00
}
else
{
if ( cv_inttime . value = = 0 & & gametype = = GT_COOP )
timer = 0 ;
else
{
timer = cv_inttime . value * TICRATE ;
if ( ! timer )
timer = 1 ;
}
2018-07-19 12:23:15 +00:00
if ( gametype = = GT_MATCH )
2014-03-15 16:59:03 +00:00
intertype = int_match ;
2018-07-19 12:23:15 +00:00
else //if (gametype == GT_RACE)
2014-03-15 16:59:03 +00:00
intertype = int_race ;
}
// We couldn't display the intermission even if we wanted to.
2017-05-19 15:31:23 +00:00
// But we still need to give the players their score bonuses, dummy.
//if (dedicated) return;
2014-03-15 16:59:03 +00:00
// This should always exist, but just in case...
if ( ! mapheaderinfo [ prevmap ] )
P_AllocMapHeader ( prevmap ) ;
switch ( intertype )
{
case int_match :
{
// Calculate who won
2018-07-19 13:29:11 +00:00
Y_CalculateMatchData ( false , Y_CompareBattle ) ;
2018-08-09 21:59:52 +00:00
if ( cv_inttime . value > 0 )
S_ChangeMusicInternal ( " racent " , true ) ; // loop it
2014-03-15 16:59:03 +00:00
break ;
}
case int_race : // (time-only race)
{
2017-10-17 00:23:26 +00:00
if ( ( ! modifiedgame | | savemoddata ) & & ! multiplayer & & ! demoplayback ) // remove this once we have a proper time attack screen
{
// Update visitation flags
mapvisited [ gamemap - 1 ] | = MV_BEATEN ;
if ( ALL7EMERALDS ( emeralds ) )
mapvisited [ gamemap - 1 ] | = MV_ALLEMERALDS ;
2018-01-22 00:15:26 +00:00
/*if (ultimatemode)
2017-10-17 00:23:26 +00:00
mapvisited [ gamemap - 1 ] | = MV_ULTIMATE ;
if ( data . coop . gotperfbonus )
2018-01-22 00:15:26 +00:00
mapvisited [ gamemap - 1 ] | = MV_PERFECT ; */
2017-10-17 00:23:26 +00:00
if ( modeattacking = = ATTACKING_RECORD )
Y_UpdateRecordReplays ( ) ;
}
2018-02-23 01:04:52 +00:00
2014-03-15 16:59:03 +00:00
// Calculate who won
2018-07-19 13:29:11 +00:00
Y_CalculateMatchData ( false , Y_CompareRace ) ;
2014-03-15 16:59:03 +00:00
break ;
}
case int_none :
default :
break ;
}
2018-07-18 00:21:36 +00:00
2018-08-05 15:35:33 +00:00
//if (intertype == int_race || intertype == int_match)
2018-07-18 00:21:36 +00:00
{
2018-07-19 04:07:13 +00:00
//bgtile = W_CachePatchName("SRB2BACK", PU_STATIC);
usetile = useinterpic = false ;
usebuffer = true ;
2014-03-15 16:59:03 +00:00
}
}
// ======
//
// Y_EndIntermission
//
void Y_EndIntermission ( void )
{
Y_UnloadData ( ) ;
endtic = - 1 ;
2018-07-18 19:23:46 +00:00
sorttic = - 1 ;
2014-03-15 16:59:03 +00:00
intertype = int_none ;
2014-03-21 18:42:55 +00:00
usebuffer = false ;
2014-03-15 16:59:03 +00:00
}
//
// Y_EndGame
//
// Why end the game?
// Because Y_FollowIntermission and F_EndCutscene would
// both do this exact same thing *in different ways* otherwise,
// which made it so that you could only unlock Ultimate mode
// if you had a cutscene after the final level and crap like that.
// This function simplifies it so only one place has to be updated
// when something new is added.
void Y_EndGame ( void )
{
// Only do evaluation and credits in coop games.
if ( gametype = = GT_COOP )
{
if ( nextmap = = 1102 - 1 ) // end game with credits
{
F_StartCredits ( ) ;
return ;
}
if ( nextmap = = 1101 - 1 ) // end game with evaluation
{
F_StartGameEvaluation ( ) ;
return ;
}
}
// 1100 or competitive multiplayer, so go back to title screen.
D_StartTitle ( ) ;
}
//
// Y_FollowIntermission
//
static void Y_FollowIntermission ( void )
{
if ( modeattacking )
{
M_EndModeAttackRun ( ) ;
return ;
}
if ( nextmap < 1100 - 1 )
{
// normal level
G_AfterIntermission ( ) ;
return ;
}
// Start a custom cutscene if there is one.
if ( mapheaderinfo [ gamemap - 1 ] - > cutscenenum & & ! modeattacking )
{
F_StartCustomCutscene ( mapheaderinfo [ gamemap - 1 ] - > cutscenenum - 1 , false , false ) ;
return ;
}
Y_EndGame ( ) ;
}
# define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL
//
// Y_UnloadData
//
static void Y_UnloadData ( void )
{
// In hardware mode, don't Z_ChangeTag a pointer returned by W_CachePatchName().
// It doesn't work and is unnecessary.
if ( rendermode ! = render_soft )
return ;
// unload the background patches
UNLOAD ( bgpatch ) ;
UNLOAD ( widebgpatch ) ;
UNLOAD ( bgtile ) ;
UNLOAD ( interpic ) ;
2018-07-18 19:23:46 +00:00
/*switch (intertype)
2014-03-15 16:59:03 +00:00
{
case int_coop :
// unload the coop and single player patches
UNLOAD ( data . coop . ttlnum ) ;
UNLOAD ( data . coop . bonuspatches [ 3 ] ) ;
UNLOAD ( data . coop . bonuspatches [ 2 ] ) ;
UNLOAD ( data . coop . bonuspatches [ 1 ] ) ;
UNLOAD ( data . coop . bonuspatches [ 0 ] ) ;
UNLOAD ( data . coop . ptotal ) ;
break ;
case int_spec :
// unload the special stage patches
//UNLOAD(data.spec.cemerald);
//UNLOAD(data.spec.nowsuper);
UNLOAD ( data . spec . bonuspatch ) ;
UNLOAD ( data . spec . pscore ) ;
UNLOAD ( data . spec . pcontinues ) ;
break ;
case int_match :
case int_race :
default :
//without this default,
//int_none, int_tag, int_chaos, and int_classicrace
//are not handled
break ;
2018-07-18 19:23:46 +00:00
} */
2014-03-15 16:59:03 +00:00
}
2018-01-27 06:17:08 +00:00
// SRB2Kart: Voting!
//
2018-01-28 01:59:29 +00:00
// Y_VoteDrawer
2018-01-27 06:17:08 +00:00
//
2018-01-28 01:59:29 +00:00
// Draws the voting screen!
2018-01-27 06:17:08 +00:00
//
2018-01-28 01:59:29 +00:00
void Y_VoteDrawer ( void )
2018-01-27 06:17:08 +00:00
{
2018-05-31 22:49:19 +00:00
INT32 i , x , y = 0 , height = 0 ;
UINT8 selected [ 4 ] ;
2018-08-11 21:23:40 +00:00
fixed_t rubyheight = 0 ;
2018-01-27 06:17:08 +00:00
2018-01-28 01:59:29 +00:00
if ( rendermode = = render_none )
return ;
2018-01-27 06:17:08 +00:00
2018-01-28 01:59:29 +00:00
if ( votetic > = voteendtic & & voteendtic ! = - 1 )
return ;
2018-01-27 06:17:08 +00:00
2018-07-28 01:59:00 +00:00
if ( ! voteclient . loaded )
return ;
2018-08-11 21:23:40 +00:00
{
angle_t rubyfloattime = ( ANGLE_MAX / NEWTICRATE ) * ( votetic % NEWTICRATE ) ;
rubyheight = FINESINE ( rubyfloattime > > ANGLETOFINESHIFT ) ;
}
2018-01-28 01:59:29 +00:00
V_DrawFill ( 0 , 0 , BASEVIDWIDTH , BASEVIDHEIGHT , 31 ) ;
2018-01-27 06:17:08 +00:00
2018-01-28 04:52:01 +00:00
if ( widebgpatch & & rendermode = = render_soft & & vid . width / vid . dupx > 320 )
V_DrawScaledPatch ( ( ( vid . width / 2 ) / vid . dupx ) - ( SHORT ( widebgpatch - > width ) / 2 ) ,
( vid . height / vid . dupy ) - SHORT ( widebgpatch - > height ) ,
V_SNAPTOTOP | V_SNAPTOLEFT , widebgpatch ) ;
else
V_DrawScaledPatch ( ( ( vid . width / 2 ) / vid . dupx ) - ( SHORT ( bgpatch - > width ) / 2 ) , // Keep the width/height adjustments, for screens that are less wide than 320(?)
( vid . height / vid . dupy ) - SHORT ( bgpatch - > height ) ,
V_SNAPTOTOP | V_SNAPTOLEFT , bgpatch ) ;
2018-01-27 06:17:08 +00:00
2018-05-31 22:49:19 +00:00
for ( i = 0 ; i < 4 ; i + + ) // First, we need to figure out the height of this thing...
{
UINT8 j ;
selected [ i ] = 0 ; // Initialize
for ( j = 0 ; j < = splitscreen ; j + + )
{
if ( voteclient . playerinfo [ j ] . selection = = i )
selected [ i ] + + ;
}
if ( selected [ i ] )
height + = 50 ;
else
height + = 25 ;
if ( i < 3 )
height + = 5 - splitscreen ;
}
y = ( 200 - height ) / 2 ;
2018-01-27 06:17:08 +00:00
for ( i = 0 ; i < 4 ; i + + )
{
2018-08-11 21:23:40 +00:00
const char * str ;
2018-01-28 04:52:01 +00:00
patch_t * pic ;
2018-07-22 20:02:31 +00:00
UINT8 j , color ;
2018-01-27 06:17:08 +00:00
2018-01-28 04:52:01 +00:00
if ( i = = 3 )
{
2018-08-11 21:23:40 +00:00
str = " RANDOM " ;
2018-01-28 04:52:01 +00:00
pic = randomlvl ;
}
else
{
2018-08-11 21:23:40 +00:00
str = levelinfo [ i ] . str ;
2018-02-04 04:47:47 +00:00
pic = levelinfo [ i ] . pic ;
2018-01-28 04:52:01 +00:00
}
2018-01-27 06:17:08 +00:00
2018-05-31 22:49:19 +00:00
if ( selected [ i ] )
2018-01-28 04:52:01 +00:00
{
2018-07-22 20:02:31 +00:00
UINT8 sizeadd = selected [ i ] ;
2018-05-31 22:49:19 +00:00
for ( j = 0 ; j < = splitscreen ; j + + ) // another loop for drawing the selection backgrounds in the right order, grumble grumble..
2018-01-28 04:52:01 +00:00
{
2018-05-31 22:49:19 +00:00
INT32 handy = y ;
2018-06-12 23:05:11 +00:00
UINT8 p ;
2018-06-05 06:11:47 +00:00
UINT8 * colormap ;
patch_t * thiscurs ;
2018-05-31 22:49:19 +00:00
if ( voteclient . playerinfo [ j ] . selection ! = i )
continue ;
2018-07-02 12:20:04 +00:00
if ( ! splitscreen )
2018-05-31 22:49:19 +00:00
{
2018-06-05 06:11:47 +00:00
thiscurs = cursor ;
2018-06-12 23:05:11 +00:00
p = consoleplayer ;
2018-07-02 12:20:04 +00:00
color = levelinfo [ i ] . gtc ;
2018-06-05 06:11:47 +00:00
colormap = NULL ;
}
2018-01-28 04:52:01 +00:00
else
2018-06-05 06:11:47 +00:00
{
switch ( j )
{
case 1 :
thiscurs = cursor2 ;
2018-06-12 23:05:11 +00:00
p = secondarydisplayplayer ;
2018-06-05 06:11:47 +00:00
break ;
case 2 :
thiscurs = cursor3 ;
2018-06-12 23:05:11 +00:00
p = thirddisplayplayer ;
2018-06-05 06:11:47 +00:00
break ;
case 3 :
thiscurs = cursor4 ;
2018-06-12 23:05:11 +00:00
p = fourthdisplayplayer ;
2018-06-05 06:11:47 +00:00
break ;
default :
thiscurs = cursor1 ;
2018-06-12 23:05:11 +00:00
p = displayplayer ;
2018-06-05 06:11:47 +00:00
break ;
}
2018-06-12 23:05:11 +00:00
color = colortranslations [ players [ p ] . skincolor ] [ 7 ] ;
colormap = R_GetTranslationColormap ( TC_DEFAULT , players [ p ] . skincolor , GTC_CACHE ) ;
2018-05-31 22:49:19 +00:00
}
2018-06-12 23:05:11 +00:00
if ( votes [ p ] ! = - 1 | | players [ p ] . spectator )
continue ;
2018-05-31 22:49:19 +00:00
handy + = 6 * ( 3 - splitscreen ) + ( 13 * j ) ;
2018-06-05 06:11:47 +00:00
V_DrawMappedPatch ( BASEVIDWIDTH - 124 , handy , V_SNAPTORIGHT , thiscurs , colormap ) ;
2018-05-31 22:49:19 +00:00
2018-07-02 12:20:04 +00:00
if ( votetic % 10 < 4 )
2018-05-31 22:49:19 +00:00
V_DrawFill ( BASEVIDWIDTH - 100 - sizeadd , y - sizeadd , 80 + ( sizeadd * 2 ) , 50 + ( sizeadd * 2 ) , 120 | V_SNAPTORIGHT ) ;
2018-01-28 04:52:01 +00:00
else
2018-05-31 22:49:19 +00:00
V_DrawFill ( BASEVIDWIDTH - 100 - sizeadd , y - sizeadd , 80 + ( sizeadd * 2 ) , 50 + ( sizeadd * 2 ) , color | V_SNAPTORIGHT ) ;
2018-06-05 06:11:47 +00:00
2018-05-31 22:49:19 +00:00
sizeadd - - ;
2018-01-28 04:52:01 +00:00
}
2018-05-31 22:49:19 +00:00
2018-08-11 21:23:40 +00:00
if ( ! levelinfo [ i ] . encore )
V_DrawSmallScaledPatch ( BASEVIDWIDTH - 100 , y , V_SNAPTORIGHT , pic ) ;
else
{
2018-08-14 14:32:17 +00:00
V_DrawFixedPatch ( ( BASEVIDWIDTH - 20 ) < < FRACBITS , ( y ) < < FRACBITS , FRACUNIT / 2 , V_FLIP | V_SNAPTORIGHT , pic , 0 ) ;
V_DrawFixedPatch ( ( BASEVIDWIDTH - 60 ) < < FRACBITS , ( ( y + 25 ) < < FRACBITS ) - ( rubyheight < < 1 ) , FRACUNIT , V_SNAPTORIGHT , rubyicon , NULL ) ;
2018-08-11 21:23:40 +00:00
}
2018-01-30 00:22:08 +00:00
V_DrawRightAlignedThinString ( BASEVIDWIDTH - 20 , 40 + y , V_SNAPTORIGHT , str ) ;
2018-06-28 18:07:04 +00:00
if ( levelinfo [ i ] . gts )
2018-06-28 14:47:56 +00:00
{
2018-06-28 18:07:04 +00:00
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 ) ;
2018-06-28 14:47:56 +00:00
}
2018-05-31 22:49:19 +00:00
y + = 50 ;
2018-01-28 01:59:29 +00:00
}
else
2018-01-27 06:17:08 +00:00
{
2018-08-11 21:23:40 +00:00
if ( ! levelinfo [ i ] . encore )
V_DrawTinyScaledPatch ( BASEVIDWIDTH - 60 , y , V_SNAPTORIGHT , pic ) ;
else
{
2018-08-14 14:32:17 +00:00
V_DrawFixedPatch ( ( BASEVIDWIDTH - 20 ) < < FRACBITS , y < < FRACBITS , FRACUNIT / 4 , V_FLIP | V_SNAPTORIGHT , pic , 0 ) ;
V_DrawFixedPatch ( ( BASEVIDWIDTH - 40 ) < < FRACBITS , ( y < < FRACBITS ) + ( 25 < < ( FRACBITS - 1 ) ) - rubyheight , FRACUNIT / 2 , V_SNAPTORIGHT , rubyicon , NULL ) ;
2018-08-11 21:23:40 +00:00
}
2018-06-28 18:07:04 +00:00
if ( levelinfo [ i ] . gts )
{
V_DrawDiag ( BASEVIDWIDTH - 60 , y , 8 , V_SNAPTORIGHT | 31 ) ;
V_DrawDiag ( BASEVIDWIDTH - 60 , y , 6 , V_SNAPTORIGHT | levelinfo [ i ] . gtc ) ;
}
2018-05-31 22:49:19 +00:00
y + = 25 ;
2018-01-27 06:17:08 +00:00
}
2018-05-31 22:49:19 +00:00
y + = 5 - splitscreen ;
2018-01-28 01:59:29 +00:00
}
2018-01-27 06:17:08 +00:00
2018-01-28 01:59:29 +00:00
x = 20 ;
2018-02-28 02:17:34 +00:00
y = 10 ;
2018-01-27 06:17:08 +00:00
2018-02-04 04:47:47 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
2018-01-28 01:59:29 +00:00
{
2018-03-06 00:55:39 +00:00
if ( dedicated & & i = = 0 ) // While leaving blank spots for non-existent players is largely intentional, the first spot *always* being blank looks a tad silly :V
continue ;
2018-02-17 06:53:44 +00:00
if ( ( playeringame [ i ] & & ! players [ i ] . spectator ) & & votes [ i ] ! = - 1 )
2018-01-27 06:17:08 +00:00
{
2018-01-28 04:52:01 +00:00
patch_t * pic ;
2018-07-22 20:02:31 +00:00
if ( votes [ i ] > = 3 & & ( i ! = pickedvote | | voteendtic = = - 1 ) )
2018-01-28 04:52:01 +00:00
pic = randomlvl ;
else
2018-02-04 04:47:47 +00:00
pic = levelinfo [ votes [ i ] ] . pic ;
2018-01-28 04:52:01 +00:00
2018-02-11 00:02:15 +00:00
if ( ! timer & & i = = voteclient . ranim )
2018-01-28 04:52:01 +00:00
{
V_DrawScaledPatch ( x - 18 , y + 9 , V_SNAPTOLEFT , cursor ) ;
2018-07-04 21:57:50 +00:00
if ( voteendtic ! = - 1 & & ! ( votetic % 4 ) )
2018-01-28 04:52:01 +00:00
V_DrawFill ( x - 1 , y - 1 , 42 , 27 , 120 | V_SNAPTOLEFT ) ;
else
2018-07-02 12:20:04 +00:00
V_DrawFill ( x - 1 , y - 1 , 42 , 27 , levelinfo [ votes [ i ] ] . gtc | V_SNAPTOLEFT ) ;
2018-01-28 04:52:01 +00:00
}
2018-08-11 21:23:40 +00:00
if ( ! levelinfo [ votes [ i ] ] . encore )
V_DrawTinyScaledPatch ( x , y , V_SNAPTOLEFT , pic ) ;
else
{
2018-08-14 14:32:17 +00:00
V_DrawFixedPatch ( ( x + 40 ) < < FRACBITS , ( y ) < < FRACBITS , FRACUNIT / 4 , V_SNAPTOLEFT | V_FLIP , pic , 0 ) ;
V_DrawFixedPatch ( ( x + 20 ) < < FRACBITS , ( y < < FRACBITS ) + ( 25 < < ( FRACBITS - 1 ) ) - rubyheight , FRACUNIT / 2 , V_SNAPTORIGHT , rubyicon , NULL ) ;
2018-08-11 21:23:40 +00:00
}
2018-06-28 18:07:04 +00:00
if ( levelinfo [ votes [ i ] ] . gts )
{
V_DrawDiag ( x , y , 8 , V_SNAPTOLEFT | 31 ) ;
V_DrawDiag ( x , y , 6 , V_SNAPTOLEFT | levelinfo [ votes [ i ] ] . gtc ) ;
}
2018-01-28 01:59:29 +00:00
2018-02-04 04:47:47 +00:00
if ( players [ i ] . skincolor = = 0 )
V_DrawSmallScaledPatch ( x + 24 , y + 9 , V_SNAPTOLEFT , faceprefix [ players [ i ] . skin ] ) ;
2018-01-27 06:17:08 +00:00
else
{
2018-02-04 04:47:47 +00:00
UINT8 * colormap = R_GetTranslationColormap ( players [ i ] . skin , players [ i ] . skincolor , GTC_CACHE ) ;
V_DrawSmallMappedPatch ( x + 24 , y + 9 , V_SNAPTOLEFT , faceprefix [ players [ i ] . skin ] , colormap ) ;
2018-01-27 06:17:08 +00:00
}
2018-02-04 04:47:47 +00:00
}
2018-01-27 06:17:08 +00:00
2018-02-04 04:47:47 +00:00
y + = 30 ;
2018-02-28 02:17:34 +00:00
if ( y > BASEVIDHEIGHT - 40 )
2018-02-04 04:47:47 +00:00
{
2018-02-28 02:17:34 +00:00
x + = 60 ;
y = 10 ;
2018-01-27 06:17:08 +00:00
}
}
2018-01-28 01:59:29 +00:00
2018-02-04 04:47:47 +00:00
if ( timer )
2018-07-02 22:17:30 +00:00
{
2018-07-19 13:29:11 +00:00
INT32 hilicol , tickdown = ( timer + 1 ) / TICRATE ;
2018-07-02 22:17:30 +00:00
if ( cons_menuhighlight . value )
hilicol = cons_menuhighlight . value ;
else if ( gametype = = GT_RACE )
hilicol = V_SKYMAP ;
else //if (gametype == GT_MATCH)
hilicol = V_REDMAP ;
2018-07-30 20:53:54 +00:00
V_DrawCenteredString ( BASEVIDWIDTH / 2 , 188 , hilicol ,
2018-07-30 22:17:01 +00:00
va ( " Vote ends in %d " , tickdown ) ) ;
2018-07-02 22:17:30 +00:00
}
}
//
// Y_VoteStop
//
// Vote screen's selection stops moving
//
SINT8 deferredlevel = 0 ;
static void Y_VoteStops ( SINT8 pick , SINT8 level )
{
2018-07-22 20:02:31 +00:00
nextmap = votelevels [ level ] [ 0 ] ;
if ( level = = 4 )
S_StartSound ( NULL , sfx_noooo2 ) ; // gasp
else if ( mapheaderinfo [ nextmap ] & & ( mapheaderinfo [ nextmap ] - > menuflags & LF2_HIDEINMENU ) )
S_StartSound ( NULL , sfx_noooo1 ) ; // this is bad
else if ( ! splitscreen & & pick = = consoleplayer )
S_StartSound ( NULL , sfx_yeeeah ) ; // yeeeah!
2018-07-02 22:17:30 +00:00
else
2018-07-22 20:02:31 +00:00
S_StartSound ( NULL , sfx_kc48 ) ; // just a cool sound
2018-07-02 22:17:30 +00:00
if ( gametype ! = votelevels [ level ] [ 1 ] )
{
INT16 lastgametype = gametype ;
gametype = votelevels [ level ] [ 1 ] ;
D_GameTypeChanged ( lastgametype ) ;
forceresetplayers = true ;
}
2018-08-11 21:23:40 +00:00
deferencoremode = ( levelinfo [ level ] . encore ) ;
2018-01-27 06:17:08 +00:00
}
//
// Y_VoteTicker
//
// Vote screen thinking :eggthinking:
//
void Y_VoteTicker ( void )
{
INT32 i ;
2018-08-09 21:59:52 +00:00
if ( paused | | P_AutoPause ( ) | | ! voteclient . loaded )
2018-01-27 06:17:08 +00:00
return ;
votetic + + ;
2018-01-28 04:52:01 +00:00
if ( votetic = = voteendtic )
2018-01-27 06:17:08 +00:00
{
2018-08-09 21:59:52 +00:00
Y_EndVote ( ) ;
Y_FollowIntermission ( ) ;
2018-01-27 06:17:08 +00:00
return ;
}
2018-02-04 04:47:47 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + ) // Correct votes as early as possible, before they're processed by the game at all
{
if ( ! playeringame [ i ] | | players [ i ] . spectator )
2018-02-17 06:53:44 +00:00
votes [ i ] = - 1 ; // Spectators are the lower class, and have effectively no voice in the government. Democracy sucks.
2018-05-31 22:49:19 +00:00
else if ( pickedvote ! = - 1 & & votes [ i ] = = - 1 )
2018-02-04 04:47:47 +00:00
votes [ i ] = 3 ; // Slow people get random
}
2018-02-17 06:53:44 +00:00
if ( server & & pickedvote ! = - 1 & & votes [ pickedvote ] = = - 1 ) // Uh oh! The person who got picked left! Recalculate, quick!
2018-02-04 04:47:47 +00:00
D_PickVote ( ) ;
2018-01-28 01:59:29 +00:00
if ( ! votetic )
2018-02-11 17:18:25 +00:00
S_ChangeMusicInternal ( " vote " , true ) ;
2018-01-28 01:59:29 +00:00
2018-02-04 04:47:47 +00:00
if ( timer )
timer - - ;
2018-01-27 06:17:08 +00:00
2018-02-04 04:47:47 +00:00
if ( pickedvote ! = - 1 )
2018-01-27 06:17:08 +00:00
{
2018-02-04 04:47:47 +00:00
timer = 0 ;
2018-02-11 17:18:25 +00:00
voteclient . rsynctime + + ;
2018-01-27 06:17:08 +00:00
2018-02-04 04:47:47 +00:00
if ( voteendtic = = - 1 )
{
UINT8 tempvotes [ MAXPLAYERS ] ;
UINT8 numvotes = 0 ;
2018-01-27 06:17:08 +00:00
2018-02-04 04:47:47 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
if ( votes [ i ] = = - 1 )
continue ;
tempvotes [ numvotes ] = i ;
numvotes + + ;
}
2018-01-28 01:59:29 +00:00
2018-03-06 00:55:39 +00:00
if ( numvotes < 1 ) // Whoops! Get outta here.
{
2018-08-09 21:59:52 +00:00
Y_EndVote ( ) ;
Y_FollowIntermission ( ) ;
2018-03-06 00:55:39 +00:00
return ;
}
2018-02-11 00:02:15 +00:00
voteclient . rtics - - ;
2018-08-09 21:59:52 +00:00
if ( voteclient . rtics < = 0 )
2018-02-11 00:02:15 +00:00
{
voteclient . roffset + + ;
2018-02-17 06:53:44 +00:00
voteclient . rtics = min ( 20 , ( 3 * voteclient . roffset / 4 ) + 5 ) ;
2018-02-11 17:18:25 +00:00
S_StartSound ( NULL , sfx_kc39 ) ;
2018-02-11 00:02:15 +00:00
}
2018-02-11 17:18:25 +00:00
if ( voteclient . rendoff = = 0 | | voteclient . roffset < voteclient . rendoff )
voteclient . ranim = tempvotes [ ( ( pickedvote + voteclient . roffset ) % numvotes ) ] ;
2018-02-11 00:02:15 +00:00
2018-02-17 06:53:44 +00:00
if ( voteclient . roffset > = 20 )
2018-02-11 00:02:15 +00:00
{
2018-02-11 17:18:25 +00:00
if ( voteclient . rendoff = = 0 )
{
2018-06-14 01:47:27 +00:00
if ( voteclient . rsynctime % 51 = = 0 ) // Song is 1.45 seconds long (sorry @ whoever wants to replace it in a music wad :V)
2018-02-11 17:18:25 +00:00
{
2018-06-14 01:47:27 +00:00
for ( i = 5 ; i > = 3 ; i - - ) // Find a suitable place to stop
{
if ( tempvotes [ ( ( pickedvote + voteclient . roffset + i ) % numvotes ) ] = = pickedvote )
{
voteclient . rendoff = voteclient . roffset + i ;
2018-07-28 01:59:00 +00:00
if ( M_RandomChance ( FRACUNIT / 32 ) ) // Let it cheat occasionally~
2018-06-14 01:58:21 +00:00
voteclient . rendoff + + ;
2018-06-14 01:47:27 +00:00
S_ChangeMusicInternal ( " voteeb " , false ) ;
break ;
}
}
2018-02-11 17:18:25 +00:00
}
}
else if ( voteclient . roffset > = voteclient . rendoff )
{
voteendtic = votetic + ( 3 * TICRATE ) ;
2018-07-02 22:17:30 +00:00
Y_VoteStops ( pickedvote , deferredlevel ) ;
2018-02-11 17:18:25 +00:00
}
2018-02-11 00:02:15 +00:00
}
2018-01-27 06:17:08 +00:00
}
2018-02-11 00:02:15 +00:00
else
voteclient . ranim = pickedvote ;
2018-02-04 04:47:47 +00:00
}
else
{
if ( votetic < 3 * ( NEWTICRATE / 7 ) ) // give it some time before letting you control it :V
return ;
2018-01-27 06:17:08 +00:00
2018-05-31 22:49:19 +00:00
for ( i = 0 ; i < = splitscreen ; i + + )
2018-01-27 06:17:08 +00:00
{
2018-05-31 22:49:19 +00:00
UINT8 p ;
boolean pressed = false ;
switch ( i )
2018-02-04 04:47:47 +00:00
{
2018-05-31 22:49:19 +00:00
case 1 :
p = secondarydisplayplayer ;
break ;
case 2 :
p = thirddisplayplayer ;
break ;
case 3 :
p = fourthdisplayplayer ;
break ;
default :
p = consoleplayer ;
break ;
2018-02-04 04:47:47 +00:00
}
2018-05-31 22:49:19 +00:00
if ( voteclient . playerinfo [ i ] . delay )
voteclient . playerinfo [ i ] . delay - - ;
if ( ( playeringame [ p ] & & ! players [ p ] . spectator )
& & ! voteclient . playerinfo [ i ] . delay
& & pickedvote = = - 1 & & votes [ p ] = = - 1 )
2018-02-04 04:47:47 +00:00
{
2018-05-31 22:49:19 +00:00
if ( InputDown ( gc_aimforward , i + 1 ) | | JoyAxis ( AXISAIM , i + 1 ) < 0 )
{
voteclient . playerinfo [ i ] . selection - - ;
pressed = true ;
}
if ( ( InputDown ( gc_aimbackward , i + 1 ) | | JoyAxis ( AXISAIM , i + 1 ) > 0 ) & & ! pressed )
{
voteclient . playerinfo [ i ] . selection + + ;
pressed = true ;
}
if ( voteclient . playerinfo [ i ] . selection < 0 )
voteclient . playerinfo [ i ] . selection = 3 ;
if ( voteclient . playerinfo [ i ] . selection > 3 )
voteclient . playerinfo [ i ] . selection = 0 ;
if ( ( InputDown ( gc_accelerate , i + 1 ) | | JoyAxis ( AXISMOVE , i + 1 ) > 0 ) & & ! pressed )
{
D_ModifyClientVote ( voteclient . playerinfo [ i ] . selection , i ) ;
pressed = true ;
}
2018-02-04 04:47:47 +00:00
}
2018-05-31 22:49:19 +00:00
if ( pressed )
2018-02-04 04:47:47 +00:00
{
2018-05-31 22:49:19 +00:00
S_StartSound ( NULL , sfx_kc4a ) ;
voteclient . playerinfo [ i ] . delay = NEWTICRATE / 7 ;
2018-02-04 04:47:47 +00:00
}
2018-01-27 06:17:08 +00:00
}
2018-02-04 04:47:47 +00:00
if ( server )
2018-01-27 06:17:08 +00:00
{
2018-02-28 01:46:01 +00:00
if ( timer = = 0 )
2018-02-04 04:47:47 +00:00
{
2018-02-28 01:46:01 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
2018-05-31 22:49:19 +00:00
if ( ( playeringame [ i ] & & ! players [ i ] . spectator ) & & votes [ i ] = = - 1 )
2018-02-28 01:46:01 +00:00
votes [ i ] = 3 ;
}
2018-02-04 04:47:47 +00:00
}
else
{
2018-05-31 22:49:19 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
2018-02-04 04:47:47 +00:00
{
2018-05-31 22:49:19 +00:00
if ( ( playeringame [ i ] & & ! players [ i ] . spectator ) & & votes [ i ] = = - 1 )
2018-02-17 06:53:44 +00:00
return ;
2018-02-04 04:47:47 +00:00
}
}
2018-01-28 04:55:43 +00:00
2018-02-17 06:53:44 +00:00
timer = 0 ;
if ( voteendtic = = - 1 )
2018-02-04 04:47:47 +00:00
D_PickVote ( ) ;
}
2018-01-28 01:59:29 +00:00
}
2018-01-27 06:17:08 +00:00
}
//
2018-01-28 01:59:29 +00:00
// Y_StartVote
2018-01-27 06:17:08 +00:00
//
2018-01-28 01:59:29 +00:00
// MK online style voting screen, appears after intermission
2018-01-27 06:17:08 +00:00
//
2018-01-28 01:59:29 +00:00
void Y_StartVote ( void )
2018-01-27 06:17:08 +00:00
{
2018-01-28 01:59:29 +00:00
INT32 i = 0 ;
2018-01-27 06:17:08 +00:00
2018-01-28 01:59:29 +00:00
votetic = - 1 ;
2018-01-27 06:17:08 +00:00
2018-01-28 01:59:29 +00:00
# ifdef PARANOIA
if ( voteendtic ! = - 1 )
I_Error ( " voteendtic is dirty " ) ;
# endif
2018-01-27 06:17:08 +00:00
2018-06-28 18:07:04 +00:00
widebgpatch = W_CachePatchName ( ( ( gametype = = GT_MATCH ) ? " BATTLSCW " : " INTERSCW " ) , PU_STATIC ) ;
bgpatch = W_CachePatchName ( ( ( gametype = = GT_MATCH ) ? " BATTLSCR " : " INTERSCR " ) , PU_STATIC ) ;
2018-01-28 01:59:29 +00:00
cursor = W_CachePatchName ( " M_CURSOR " , PU_STATIC ) ;
2018-06-05 06:11:47 +00:00
cursor1 = W_CachePatchName ( " P1CURSOR " , PU_STATIC ) ;
cursor2 = W_CachePatchName ( " P2CURSOR " , PU_STATIC ) ;
cursor3 = W_CachePatchName ( " P3CURSOR " , PU_STATIC ) ;
cursor4 = W_CachePatchName ( " P4CURSOR " , PU_STATIC ) ;
2018-01-28 04:52:01 +00:00
randomlvl = W_CachePatchName ( " RANDOMLV " , PU_STATIC ) ;
2018-08-11 21:23:40 +00:00
rubyicon = W_CachePatchName ( " RUBYICON " , PU_STATIC ) ;
2018-01-27 06:17:08 +00:00
2018-02-04 04:47:47 +00:00
timer = cv_votetime . value * TICRATE ;
pickedvote = - 1 ;
2018-05-31 22:49:19 +00:00
for ( i = 0 ; i < 3 ; i + + )
{
voteclient . playerinfo [ i ] . selection = 0 ;
voteclient . playerinfo [ i ] . delay = 0 ;
}
2018-02-11 00:02:15 +00:00
voteclient . ranim = 0 ;
voteclient . rtics = 1 ;
voteclient . roffset = 0 ;
2018-02-11 17:18:25 +00:00
voteclient . rsynctime = 0 ;
voteclient . rendoff = 0 ;
2018-01-28 01:59:29 +00:00
for ( i = 0 ; i < MAXPLAYERS ; i + + )
2018-02-04 04:47:47 +00:00
votes [ i ] = - 1 ;
2018-01-27 06:17:08 +00:00
2018-07-22 20:02:31 +00:00
for ( i = 0 ; i < 5 ; i + + )
2018-01-27 06:17:08 +00:00
{
2018-01-28 04:52:01 +00:00
lumpnum_t lumpnum ;
2018-01-27 06:17:08 +00:00
2018-08-11 21:23:40 +00:00
// set up the encore
levelinfo [ i ] . encore = ( votelevels [ i ] [ 1 ] & 0x80 ) ;
votelevels [ i ] [ 1 ] & = ~ 0x80 ;
2018-01-28 04:52:01 +00:00
// set up the str
2018-07-22 20:02:31 +00:00
if ( i = = 4 )
levelinfo [ i ] . str [ 0 ] = ' \0 ' ;
2018-01-28 01:59:29 +00:00
else
2018-01-27 06:17:08 +00:00
{
2018-08-11 21:23:40 +00:00
// set up the levelstring
if ( mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > levelflags & LF_NOZONE | | ! mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > zonttl [ 0 ] )
2018-07-22 20:02:31 +00:00
{
2018-08-11 21:23:40 +00:00
if ( mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > actnum [ 0 ] )
2018-07-22 20:02:31 +00:00
snprintf ( levelinfo [ i ] . str ,
sizeof levelinfo [ i ] . str ,
2018-08-11 21:23:40 +00:00
" %s %s " ,
2018-08-12 14:10:47 +00:00
mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > lvlttl , mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > actnum ) ;
2018-07-22 20:02:31 +00:00
else
snprintf ( levelinfo [ i ] . str ,
sizeof levelinfo [ i ] . str ,
2018-08-11 21:23:40 +00:00
" %s " ,
mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > lvlttl ) ;
2018-07-22 20:02:31 +00:00
}
2018-01-28 01:59:29 +00:00
else
2018-07-22 20:02:31 +00:00
{
2018-08-11 21:23:40 +00:00
if ( mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > actnum [ 0 ] )
2018-07-22 20:02:31 +00:00
snprintf ( levelinfo [ i ] . str ,
sizeof levelinfo [ i ] . str ,
2018-08-11 21:23:40 +00:00
" %s %s %s " ,
mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > lvlttl , mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > zonttl , mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > actnum ) ;
2018-07-22 20:02:31 +00:00
else
snprintf ( levelinfo [ i ] . str ,
sizeof levelinfo [ i ] . str ,
2018-08-11 21:23:40 +00:00
" %s %s " ,
mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > lvlttl , mapheaderinfo [ votelevels [ i ] [ 0 ] ] - > zonttl ) ;
2018-07-22 20:02:31 +00:00
}
2018-01-28 01:59:29 +00:00
2018-07-22 20:02:31 +00:00
levelinfo [ i ] . str [ sizeof levelinfo [ i ] . str - 1 ] = ' \0 ' ;
}
2018-01-28 01:59:29 +00:00
2018-06-28 14:47:56 +00:00
// set up the gtc and gts
2018-07-02 12:20:04 +00:00
levelinfo [ i ] . gtc = G_GetGametypeColor ( votelevels [ i ] [ 1 ] ) ;
2018-06-28 18:07:04 +00:00
if ( i = = 2 & & votelevels [ i ] [ 1 ] ! = votelevels [ 0 ] [ 1 ] )
2018-06-29 13:14:24 +00:00
levelinfo [ i ] . gts = gametype_cons_t [ votelevels [ i ] [ 1 ] ] . strvalue ;
else
2018-07-02 12:20:04 +00:00
levelinfo [ i ] . gts = NULL ;
2018-06-28 14:47:56 +00:00
// set up the pic
lumpnum = W_CheckNumForName ( va ( " %sP " , G_BuildMapName ( votelevels [ i ] [ 0 ] + 1 ) ) ) ;
2018-01-28 04:52:01 +00:00
if ( lumpnum ! = LUMPERROR )
2018-06-28 14:47:56 +00:00
levelinfo [ i ] . pic = W_CachePatchName ( va ( " %sP " , G_BuildMapName ( votelevels [ i ] [ 0 ] + 1 ) ) , PU_STATIC ) ;
2018-01-28 04:52:01 +00:00
else
2018-02-04 04:47:47 +00:00
levelinfo [ i ] . pic = W_CachePatchName ( " BLANKLVL " , PU_STATIC ) ;
2018-01-27 06:17:08 +00:00
}
2018-07-28 01:59:00 +00:00
voteclient . loaded = true ;
2018-01-27 06:17:08 +00:00
}
//
// Y_EndVote
//
void Y_EndVote ( void )
{
Y_UnloadVoteData ( ) ;
voteendtic = - 1 ;
}
//
// Y_UnloadVoteData
//
static void Y_UnloadVoteData ( void )
{
if ( rendermode ! = render_soft )
return ;
2018-07-28 01:59:00 +00:00
voteclient . loaded = false ;
2018-01-27 06:17:08 +00:00
UNLOAD ( widebgpatch ) ;
2018-01-28 01:59:29 +00:00
UNLOAD ( bgpatch ) ;
2018-01-27 06:17:08 +00:00
UNLOAD ( cursor ) ;
2018-06-05 06:11:47 +00:00
UNLOAD ( cursor1 ) ;
UNLOAD ( cursor2 ) ;
UNLOAD ( cursor3 ) ;
UNLOAD ( cursor4 ) ;
2018-01-28 04:52:01 +00:00
UNLOAD ( randomlvl ) ;
2018-08-11 21:23:40 +00:00
UNLOAD ( rubyicon ) ;
2018-01-27 06:17:08 +00:00
2018-07-22 20:02:31 +00:00
UNLOAD ( levelinfo [ 4 ] . pic ) ;
2018-02-04 04:47:47 +00:00
UNLOAD ( levelinfo [ 3 ] . pic ) ;
UNLOAD ( levelinfo [ 2 ] . pic ) ;
UNLOAD ( levelinfo [ 1 ] . pic ) ;
UNLOAD ( levelinfo [ 0 ] . pic ) ;
2018-01-27 06:17:08 +00:00
}
2018-02-04 04:47:47 +00:00
//
// Y_SetupVoteFinish
//
2018-02-23 01:04:52 +00:00
void Y_SetupVoteFinish ( SINT8 pick , SINT8 level )
2018-02-04 04:47:47 +00:00
{
2018-03-01 22:05:36 +00:00
if ( pick = = - 1 ) // No other votes? We gotta get out of here, then!
{
2018-07-28 01:59:00 +00:00
if ( voteclient . loaded )
{
Y_EndVote ( ) ;
Y_FollowIntermission ( ) ;
}
2018-03-01 22:05:36 +00:00
return ;
}
2018-02-17 06:53:44 +00:00
if ( pickedvote = = - 1 )
{
INT32 i ;
SINT8 votecompare = - 1 ;
2018-03-01 22:05:36 +00:00
INT32 endtype = 0 ;
2018-02-17 06:53:44 +00:00
voteclient . rsynctime = 0 ;
for ( i = 0 ; i < MAXPLAYERS ; i + + )
{
2018-05-31 22:49:19 +00:00
if ( ( playeringame [ i ] & & ! players [ i ] . spectator ) & & votes [ i ] = = - 1 )
2018-02-17 06:53:44 +00:00
votes [ i ] = 3 ;
2018-03-01 22:05:36 +00:00
if ( votes [ i ] = = - 1 | | endtype > 1 ) // Don't need to go on
2018-02-17 06:53:44 +00:00
continue ;
2018-07-22 20:02:31 +00:00
if ( level = = 4 )
{
votes [ i ] = 4 ;
continue ;
}
if ( endtype = = 2 )
continue ;
2018-02-17 06:53:44 +00:00
if ( votecompare = = - 1 )
2018-03-01 22:05:36 +00:00
{
2018-02-17 06:53:44 +00:00
votecompare = votes [ i ] ;
2018-03-01 22:05:36 +00:00
endtype = 1 ;
}
2018-02-17 06:53:44 +00:00
else if ( votes [ i ] ! = votecompare )
2018-03-01 22:05:36 +00:00
endtype = 2 ;
2018-02-17 06:53:44 +00:00
}
2018-07-22 20:02:31 +00:00
if ( level = = 4 | | endtype = = 1 ) // Only one unique vote, so just end it immediately.
{
voteendtic = votetic + ( 5 * TICRATE ) ;
S_ChangeMusicInternal ( " voteeb " , false ) ;
Y_VoteStops ( pick , level ) ;
}
else if ( endtype = = 0 ) // Might as well put this here, too.
2018-03-01 22:05:36 +00:00
{
2018-07-28 01:59:00 +00:00
if ( voteclient . loaded )
{
Y_EndVote ( ) ;
Y_FollowIntermission ( ) ;
}
2018-03-01 22:05:36 +00:00
return ;
}
2018-02-17 06:53:44 +00:00
else
S_ChangeMusicInternal ( " voteea " , true ) ;
}
2018-07-02 22:17:30 +00:00
deferredlevel = level ;
2018-02-04 04:47:47 +00:00
pickedvote = pick ;
timer = 0 ;
2018-06-07 23:39:45 +00:00
}