Merge branch 'miniladder-16' into 'master'

Miniladder for 1.6

See merge request KartKrew/Kart!754
This commit is contained in:
toaster 2022-11-05 13:16:22 +00:00
commit 3b212a1138
15 changed files with 136 additions and 58 deletions

View file

@ -3927,6 +3927,11 @@ static void HandleConnect(SINT8 node)
// If a server filled out, then it'd overwrite the host and turn everyone into weird husks.....
// It's too much effort to legimately fix right now. Just prevent it from reaching that state.
UINT8 maxplayers = min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxconnections.value);
UINT8 connectedplayers = 0;
for (i = dedicated ? 1 : 0; i < MAXPLAYERS; i++)
if (playernode[i] != UINT8_MAX) // We use this to count players because it is affected by SV_AddWaitingPlayers when more than one client joins on the same tic, unlike playeringame and D_NumPlayers. UINT8_MAX denotes no node for that player
connectedplayers++;
if (bannednode && bannednode[node].banid != SIZE_MAX)
{
@ -3984,7 +3989,7 @@ static void HandleConnect(SINT8 node)
{
SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment."));
}
else if (D_NumPlayers() >= maxplayers)
else if (connectedplayers >= maxplayers)
{
SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), maxplayers));
}
@ -3992,7 +3997,7 @@ static void HandleConnect(SINT8 node)
{
SV_SendRefuse(node, M_GetText("Too many players from\nthis node."));
}
else if (netgame && D_NumPlayers() + netbuffer->u.clientcfg.localplayers > maxplayers)
else if (netgame && connectedplayers + netbuffer->u.clientcfg.localplayers > maxplayers)
{
SV_SendRefuse(node, va(M_GetText("Number of local players\nwould exceed maximum: %d"), maxplayers));
}
@ -5475,14 +5480,6 @@ boolean TryRunTics(tic_t realtics)
if (ticking)
{
if (advancedemo)
{
if (timedemo_quit)
COM_ImmedExecute("quit");
else
D_StartTitle();
}
else
{
// run the count * tics
while (neededtic > gametic)

View file

@ -131,7 +131,6 @@ INT32 postimgparam[MAXSPLITSCREENPLAYERS];
boolean sound_disabled = false;
boolean digital_disabled = false;
boolean advancedemo;
#ifdef DEBUGFILE
INT32 debugload = 0;
#endif
@ -913,15 +912,6 @@ void D_SRB2Loop(void)
}
}
//
// D_AdvanceDemo
// Called after each demo or intro demosequence finishes
//
void D_AdvanceDemo(void)
{
advancedemo = true;
}
// =========================================================================
// D_SRB2Main
// =========================================================================
@ -997,7 +987,6 @@ void D_StartTitle(void)
//demosequence = -1;
G_SetGametype(GT_RACE); // SRB2kart
paused = false;
advancedemo = false;
// clear cmd building stuff
memset(gamekeydown, 0, sizeof (gamekeydown));

View file

@ -18,8 +18,6 @@
#include "d_event.h"
#include "w_wad.h" // for MAX_WADFILES
extern boolean advancedemo;
// make sure not to write back the config until it's been correctly loaded
extern tic_t rendergametic;
@ -52,7 +50,6 @@ const char *D_Home(void);
//
// BASE LEVEL
//
void D_AdvanceDemo(void);
void D_StartTitle(void);
#endif //__D_MAIN__

View file

@ -224,7 +224,10 @@ void readfreeslots(MYFILE *f)
// TODO: Out-of-slots warnings/errors.
// TODO: Name too long (truncated) warnings.
if (fastcmp(type, "SFX"))
{
CONS_Printf("Sound sfx_%s allocated.\n",word);
S_AddSoundFx(word, false, 0, false);
}
else if (fastcmp(type, "SPR"))
{
for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++)
@ -238,39 +241,54 @@ void readfreeslots(MYFILE *f)
// Found a free slot!
strncpy(sprnames[i],word,4);
//sprnames[i][4] = 0;
CONS_Printf("Sprite SPR_%s allocated.\n",word);
used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now.
break;
}
if (i > SPR_LASTFREESLOT)
I_Error("Out of Sprite Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word);
}
else if (fastcmp(type, "S"))
{
for (i = 0; i < NUMSTATEFREESLOTS; i++)
if (!FREE_STATES[i]) {
CONS_Printf("State S_%s allocated.\n",word);
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_STATES[i],word);
freeslotusage[0][0]++;
break;
}
if (i == NUMSTATEFREESLOTS)
I_Error("Out of State Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word);
}
else if (fastcmp(type, "MT"))
{
for (i = 0; i < NUMMOBJFREESLOTS; i++)
if (!FREE_MOBJS[i]) {
CONS_Printf("MobjType MT_%s allocated.\n",word);
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_MOBJS[i],word);
freeslotusage[1][0]++;
break;
}
if (i == NUMMOBJFREESLOTS)
I_Error("Out of Mobj Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word);
}
else if (fastcmp(type, "SKINCOLOR"))
{
for (i = 0; i < NUMCOLORFREESLOTS; i++)
if (!FREE_SKINCOLORS[i]) {
CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word);
FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_SKINCOLORS[i],word);
M_AddMenuColor(numskincolors++);
break;
}
if (i == NUMCOLORFREESLOTS)
I_Error("Out of Skincolor Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word);
}
else if (fastcmp(type, "SPR2"))
{
@ -287,7 +305,7 @@ void readfreeslots(MYFILE *f)
spr2defaults[free_spr2] = 0;
spr2names[free_spr2++][4] = 0;
} else
deh_warning("Ran out of free SPR2 slots!\n");
I_Error("Out of SPR2 Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word);
}
else if (fastcmp(type, "TOL"))
{
@ -302,7 +320,7 @@ void readfreeslots(MYFILE *f)
// We don't, so freeslot it.
if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags.
deh_warning("Ran out of free typeoflevel slots!\n");
I_Error("Out of Typeoflevel Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word);
else
{
G_AddTOL(lastcustomtol, word);
@ -326,7 +344,7 @@ void readfreeslots(MYFILE *f)
precipprops[i].name = Z_StrDup(word);
precip_freeslot++;
} else
deh_warning("Ran out of free PRECIP slots!\n");
I_Error("Out of Precipitation Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word);
}
else
deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word);

View file

@ -2006,7 +2006,7 @@ void G_BeginRecording(void)
if (wadfiles[i]->important)
{
nameonly(( filename = va("%s", wadfiles[i]->filename) ));
WRITESTRINGN(demo_p, filename, 64);
WRITESTRINGL(demo_p, filename, MAX_WADPATH);
WRITEMEM(demo_p, wadfiles[i]->md5sum, 16);
totalfiles++;
@ -3727,7 +3727,11 @@ static void G_StopTimingDemo(void)
if (restorecv_vidwait != cv_vidwait.value)
CV_SetValue(&cv_vidwait, restorecv_vidwait);
D_AdvanceDemo();
if (timedemo_quit)
COM_ImmedExecute("quit");
else
D_StartTitle();
}
// reset engine variable set for the demos
@ -3786,10 +3790,12 @@ boolean G_CheckDemoStatus(void)
{
G_StopDemo();
if (modeattacking)
if (timedemo_quit)
COM_ImmedExecute("quit");
else if (modeattacking)
M_EndModeAttackRun();
else
D_AdvanceDemo();
D_StartTitle();
}
return true;

View file

@ -3898,6 +3898,18 @@ static void M_DrawReplayHutReplayInfo(menudemo_t *demoref)
if (demoref->gametype == GT_RACE)
{
V_DrawThinString(x, y+39, V_SNAPTOTOP|highlightflags, "TIME");
}
else
{
V_DrawThinString(x, y+39, V_SNAPTOTOP|highlightflags, "SCORE");
}
if (demoref->standings[0].timeorscore == (UINT32_MAX-1))
{
V_DrawThinString(x+32, y+39, V_SNAPTOTOP, "NO CONTEST");
}
else if (demoref->gametype == GT_RACE)
{
V_DrawRightAlignedString(x+84, y+40, V_SNAPTOTOP, va("%d'%02d\"%02d",
G_TicsToMinutes(demoref->standings[0].timeorscore, true),
G_TicsToSeconds(demoref->standings[0].timeorscore),
@ -3906,7 +3918,6 @@ static void M_DrawReplayHutReplayInfo(menudemo_t *demoref)
}
else
{
V_DrawThinString(x, y+39, V_SNAPTOTOP|highlightflags, "SCORE");
V_DrawString(x+32, y+40, V_SNAPTOTOP, va("%d", demoref->standings[0].timeorscore));
}
@ -3915,7 +3926,7 @@ static void M_DrawReplayHutReplayInfo(menudemo_t *demoref)
// Lat: 08/06/2020: For some reason missing skins have their value set to 255 (don't even ask me why I didn't write this)
// and for an even STRANGER reason this passes the first check below, so we're going to make sure that the skin here ISN'T 255 before we do anything stupid.
if (demoref->standings[0].skin != 0xFF)
if (demoref->standings[0].skin < numskins)
{
patch = faceprefix[demoref->standings[0].skin][FACE_WANTED];
colormap = R_GetTranslationColormap(
@ -4116,7 +4127,7 @@ void M_DrawReplayStartMenu(void)
// Lat: 08/06/2020: For some reason missing skins have their value set to 255 (don't even ask me why I didn't write this)
// and for an even STRANGER reason this passes the first check below, so we're going to make sure that the skin here ISN'T 255 before we do anything stupid.
if (demoref->standings[i].skin != 0xFF)
if (demoref->standings[i].skin < numskins)
{
patch = faceprefix[demoref->standings[i].skin][FACE_RANK];
colormap = R_GetTranslationColormap(

View file

@ -10769,21 +10769,41 @@ void P_RemovePrecipMobj(precipmobj_t *mobj)
void P_RemoveSavegameMobj(mobj_t *mobj)
{
// unlink from sector and block lists
P_UnsetThingPosition(mobj);
// Remove touching_sectorlist from mobj.
if (sector_list)
if (((thinker_t *)mobj)->function.acp1 == (actionf_p1)P_NullPrecipThinker)
{
P_DelSeclist(sector_list);
sector_list = NULL;
P_UnsetPrecipThingPosition((precipmobj_t *)mobj);
if (precipsector_list)
{
P_DelPrecipSeclist(precipsector_list);
precipsector_list = NULL;
}
}
else
{
// unlink from sector and block lists
P_UnsetThingPosition(mobj);
// Remove touching_sectorlist from mobj.
if (sector_list)
{
P_DelSeclist(sector_list);
sector_list = NULL;
}
}
// stop any playing sound
S_StopSound(mobj);
R_RemoveMobjInterpolator(mobj);
// free block
P_RemoveThinker((thinker_t *)mobj);
R_RemoveMobjInterpolator(mobj);
// Here we use the same code as R_RemoveThinkerDelayed, but without reference counting (we're removing everything so it shouldn't matter) and without touching currentthinker since we aren't in P_RunThinkers
{
thinker_t *thinker = (thinker_t *)mobj;
thinker_t *next = thinker->next;
(next->prev = thinker->prev)->next = next;
Z_Free(thinker);
}
}
static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}};

View file

@ -3341,6 +3341,19 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->player->viewz = mobj->player->mo->z + mobj->player->viewheight;
}
if (mobj->type == MT_SKYBOX)
{
mtag_t tag = mobj->movedir;
if (tag < 0 || tag > 15)
{
CONS_Debug(DBG_GAMELOGIC, "LoadMobjThinker: Skybox ID %d of netloaded object is not between 0 and 15!\n", tag);
}
else if (mobj->flags2 & MF2_AMBUSH)
skyboxcenterpnts[tag] = mobj;
else
skyboxviewpnts[tag] = mobj;
}
if (diff2 & MD2_WAYPOINTCAP)
P_SetTarget(&waypointcap, mobj);
@ -3968,10 +3981,14 @@ static void P_NetUnArchiveThinkers(void)
{
next = currentthinker->next;
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker || currentthinker->function.acp1 == (actionf_p1)P_NullPrecipThinker)
P_RemoveSavegameMobj((mobj_t *)currentthinker); // item isn't saved, don't remove it
else
{
(next->prev = currentthinker->prev)->next = next;
R_DestroyLevelInterpolators(currentthinker);
Z_Free(currentthinker);
}
}
}

View file

@ -2387,6 +2387,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
camera[i].y += y;
camera[i].z += z;
camera[i].subsector = R_PointInSubsector(camera[i].x, camera[i].y);
R_RelativeTeleportViewInterpolation(i, x, y, z, 0);
break;
}
}

View file

@ -17,6 +17,7 @@
#include "r_state.h"
#include "s_sound.h"
#include "r_main.h"
#include "r_fps.h"
/** \brief The P_MixUp function
@ -73,8 +74,12 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
// move chasecam at new player location
for (i = 0; i <= r_splitscreen; i++)
{
if (thing->player == &players[displayplayers[i]] && camera[i].chase)
if (thing->player != &players[displayplayers[i]])
continue;
if (camera[i].chase)
P_ResetCamera(thing->player, &camera[i]);
R_ResetViewInterpolation(i + 1);
break;
}
// don't run in place after a teleport

View file

@ -24,6 +24,7 @@
#include "lua_hook.h"
#include "m_perfstats.h"
#include "i_system.h" // I_GetPreciseTime
#include "i_video.h" // rendermode
#include "r_main.h"
#include "r_fps.h"
@ -787,15 +788,20 @@ void P_Ticker(boolean run)
// Hack: ensure newview is assigned every tic.
// Ensures view interpolation is T-1 to T in poor network conditions
// We need a better way to assign view state decoupled from game logic
for (i = 0; i <= r_splitscreen; i++)
if (rendermode != render_none)
{
player_t *player = &players[displayplayers[i]];
const boolean skybox = (player->skybox.viewpoint && cv_skybox.value); // True if there's a skybox object and skyboxes are on
if (skybox)
for (i = 0; i <= r_splitscreen; i++)
{
R_SkyboxFrame(i);
player_t *player = &players[displayplayers[i]];
if (!player->mo)
continue;
const boolean skybox = (player->skybox.viewpoint && cv_skybox.value); // True if there's a skybox object and skyboxes are on
if (skybox)
{
R_SkyboxFrame(i);
}
R_SetupFrame(i);
}
R_SetupFrame(i);
}
}

View file

@ -216,6 +216,14 @@ void R_ResetViewInterpolation(UINT8 p)
}
}
void R_RelativeTeleportViewInterpolation(UINT8 p, fixed_t xdiff, fixed_t ydiff, fixed_t zdiff, angle_t angdiff)
{
pview_old[p].x += xdiff;
pview_old[p].y += ydiff;
pview_old[p].z += zdiff;
pview_old[p].angle += angdiff;
}
void R_SetViewContext(enum viewcontext_e _viewcontext)
{
UINT8 i = 0;

View file

@ -126,6 +126,8 @@ void R_InterpolateViewRollAngle(fixed_t frac);
void R_UpdateViewInterpolation(void);
// Reset the view states (e.g. after level load) so R_InterpolateView doesn't interpolate invalid data
void R_ResetViewInterpolation(UINT8 p);
// Update old view for seamless relative teleport
void R_RelativeTeleportViewInterpolation(UINT8 p, fixed_t xdiff, fixed_t ydiff, fixed_t zdiff, angle_t angdiff);
// Set the current view context (the viewvars pointed to by newview)
void R_SetViewContext(enum viewcontext_e _viewcontext);

View file

@ -1089,10 +1089,10 @@ sfxinfo_t S_sfx[NUMSFX] =
{"bhurry", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // v1.0.2 Battle overtime
{"bsnipe", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Banana sniping
{"sploss", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Down to yellow sparks
{"join", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Player joined server
{"leave", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Player left server
{"requst", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Got a Discord join request
{"syfail", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Funny sync failure
{"join", true, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Player joined server
{"leave", true, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Player left server
{"requst", true, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Got a Discord join request
{"syfail", true, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Funny sync failure
{"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // :shitsfree:
{"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Debug notification
{"cock", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Hammer cocks, bang bang
@ -1353,7 +1353,7 @@ sfxenum_t S_AddSoundFx(const char *name, boolean singular, INT32 flags, boolean
return i;
}
CONS_Alert(CONS_WARNING, M_GetText("No more free sound slots\n"));
I_Error("Out of Sound Freeslots while allocating \"%s\"\nLoad less addons to fix this.", name);
return 0;
}

View file

@ -99,9 +99,10 @@ void* vres_GetPatch(virtlump_t *vlump, INT32 tag);
// =========================================================================
#define MAX_WADPATH 512
#define MAX_WADFILES 127 // maximum of wad files used at the same time
// Replay code relies on it being an UINT8 and, just to be safe, in case some wad counter somewhere is a SINT8, you should NOT go above 127 here if you're lazy like me.
// Besides, are there truly 127 wads worth your interrest?
#define MAX_WADFILES 255 // maximum of wad files used at the same time
// Replay code relies on it being an UINT8. There are no SINT8s handling WAD indices, though.
// Can be set all the way up to 255 but not 256,
// because an UINT8 will never be >= 256, probably breaking some conditionals.
#define lumpcache_t void *