Merge branch 'battlesync' into 'master'

BATTLE SYNC

See merge request KartKrew/Kart!564
This commit is contained in:
SteelT 2022-03-24 01:28:28 +00:00
commit 44c95916b6
6 changed files with 183 additions and 63 deletions

View file

@ -439,14 +439,12 @@ void K_RunPaperItemSpawners(void)
if (pcount > 0)
{
#define MAXITEM 64
UINT8 item = 0;
mobj_t *spotList[MAXITEM];
boolean spotUsed[MAXITEM];
UINT8 spotMap[MAXITEM];
UINT8 spotCount = 0, spotBackup = 0;
INT16 starti = 0;
memset(spotUsed, false, sizeof(spotUsed));
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
@ -454,21 +452,23 @@ void K_RunPaperItemSpawners(void)
mo = (mobj_t *)th;
if (mo->type == MT_PAPERITEMSPOT)
{
if (item >= MAXITEM)
continue;
spotList[item] = mo;
item++;
}
else if (mo->type == MT_EMERALD)
if (mo->type == MT_EMERALD)
{
emeraldsSpawned |= mo->extravalue1;
}
if (mo->type != MT_PAPERITEMSPOT)
continue;
if (spotCount >= MAXITEM)
continue;
spotList[spotCount] = mo;
spotMap[spotCount] = spotCount;
spotCount++;
}
if (item <= 0)
if (spotCount <= 0)
{
return;
}
@ -488,24 +488,34 @@ void K_RunPaperItemSpawners(void)
}
}
for (i = starti; i < min(item + starti, pcount); i++)
//CONS_Printf("leveltime = %d ", leveltime);
spotBackup = spotCount;
for (i = starti; i < pcount; i++)
{
UINT8 r = P_RandomKey(item);
UINT8 recursion = 0;
UINT8 r = 0, key = 0;
mobj_t *drop = NULL;
SINT8 flip = 1;
while (spotUsed[r] == true)
if (spotCount == 0)
{
r = P_RandomKey(item);
if ((recursion++) > MAXITEM)
{
// roll with it anyway I guess
break;
}
// all are accessible again
spotCount = spotBackup;
}
if (spotCount == 1)
{
key = 0;
}
else
{
key = P_RandomKey(spotCount);
}
r = spotMap[key];
//CONS_Printf("[%d %d %d] ", i, key, r);
flip = P_MobjFlip(spotList[r]);
// When -1, we're spawning a Chaos Emerald.
@ -537,8 +547,23 @@ void K_RunPaperItemSpawners(void)
}
K_FlipFromObject(drop, spotList[r]);
spotUsed[r] = true;
spotCount--;
if (key != spotCount)
{
// So the core theory of what's going on is that we keep every
// available option at the front of the array, so we don't have
// to skip over any gaps or do recursion to avoid doubles.
// But because spotCount can be reset in the case of a low
// quanitity of item spawnpoints in a map, we still need every
// entry in the array, even outside of the "visible" range.
// A series of swaps allows us to adhere to both constraints.
// -toast 22/03/22 (semipalindromic!)
spotMap[key] = spotMap[spotCount];
spotMap[spotCount] = r; // was set to spotMap[key] previously
}
}
//CONS_Printf("\n");
}
}
}

View file

@ -1088,6 +1088,7 @@ static void K_initKartHUD(void)
}
}
// see also MT_PLAYERARROW mobjthinker in p_mobj.c
static void K_drawKartItem(void)
{
// ITEM_X = BASEVIDWIDTH-50; // 270
@ -1181,15 +1182,15 @@ static void K_drawKartItem(void)
localpatch = kp_landmine[offset];
//localcolor = SKINCOLOR_JET;
break;
case 16: // Land Mine
case 16: // Drop Target
localpatch = kp_droptarget[offset];
//localcolor = SKINCOLOR_LIME;
break;
/*case 15: // Pogo Spring
/*case 17: // Pogo Spring
localpatch = kp_pogospring[offset];
localcolor = SKINCOLOR_TANGERINE;
break;
case 16: // Kitchen Sink
case 18: // Kitchen Sink
localpatch = kp_kitchensink[offset];
localcolor = SKINCOLOR_STEEL;
break;*/
@ -1782,7 +1783,7 @@ static boolean K_drawKartPositionFaces(void)
// FACE_X = 15; // 15
// FACE_Y = 72; // 72
INT32 Y = FACE_Y+9; // +9 to offset where it's being drawn if there are more than one
INT32 Y = FACE_Y-9; // -9 to offset where it's being drawn if there are more than one
INT32 i, j, ranklines, strank = -1;
boolean completed[MAXPLAYERS];
INT32 rankplayer[MAXPLAYERS];
@ -1838,29 +1839,32 @@ static boolean K_drawKartPositionFaces(void)
}
if (ranklines < 5)
Y -= (9*ranklines);
Y += (9*ranklines);
else
Y -= (9*5);
Y += (9*5);
ranklines--;
i = ranklines;
if (gametype == GT_BATTLE || strank <= 2) // too close to the top, or playing battle, or a spectator? would have had (strank == -1) called out, but already caught by (strank <= 2)
{
i = 0;
if (ranklines > 5) // could be both...
ranklines = 5;
if (i > 4) // could be both...
i = 4;
ranklines = 0;
}
else if (strank+3 > ranklines) // too close to the bottom?
else if (strank+2 >= ranklines) // too close to the bottom?
{
i = ranklines - 5;
if (i < 0)
i = 0;
ranklines -= 4;
if (ranklines < 0)
ranklines = 0;
}
else
{
i = strank-2;
ranklines = strank+3;
i = strank+2;
ranklines = strank-2;
}
for (; i < ranklines; i++)
for (; i >= ranklines; i--)
{
if (!playeringame[rankplayer[i]]) continue;
if (players[rankplayer[i]].spectator) continue;
@ -1920,7 +1924,7 @@ static boolean K_drawKartPositionFaces(void)
V_DrawScaledPatch(FACE_X-5, Y+10, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_facenum[pos]);
}
Y += 18;
Y -= 18;
}
return false;
@ -2143,20 +2147,28 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
INT32 i, rightoffset = 240;
const UINT8 *colormap;
INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2;
int y2;
int basey = y, basex = x, y2;
//this function is designed for 9 or less score lines only
//I_Assert(scorelines <= 9); -- not today bitch, kart fixed it up
V_DrawFill(1-duptweak, 26, dupadjust-2, 1, 0); // Draw a horizontal line because it looks nice!
if (scorelines > 8)
scorelines--;
if (scorelines >= 8)
{
V_DrawFill(160, 26, 1, 147, 0); // Draw a vertical line to separate the two sides.
V_DrawFill(1-duptweak, 173, dupadjust-2, 1, 0); // And a horizontal line near the bottom.
rightoffset = (BASEVIDWIDTH/2) - 4 - x;
x = (BASEVIDWIDTH/2) + 4;
y += 18*(scorelines-8);
}
else
{
y += 18*scorelines;
}
for (i = 0; i < scorelines; i++)
for (i = scorelines; i >= 0; i--)
{
char strtime[MAXPLAYERNAME+1];
@ -2201,7 +2213,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
y2 += SHORT (kp_alagles[0]->height) + 1;
}
if (scorelines > 8)
if (scorelines >= 8)
V_DrawThinString(x + 20, y2, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
else
V_DrawString(x + 20, y2, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime);
@ -2244,7 +2256,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
if (gametype == GT_RACE)
{
#define timestring(time) va("%i'%02i\"%02i", G_TicsToMinutes(time, true), G_TicsToSeconds(time), G_TicsToCentiseconds(time))
if (scorelines > 8)
if (scorelines >= 8)
{
if (players[tab[i].num].exiting)
V_DrawRightAlignedThinString(x+rightoffset, y-1, hilicol|V_6WIDTHSPACE, timestring(players[tab[i].num].realtime));
@ -2267,11 +2279,11 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
else
V_DrawRightAlignedString(x+rightoffset, y, 0, va("%u", tab[i].count));
y += 18;
if (i == 7)
y -= 18;
if (i == 8)
{
y = 33;
x = (BASEVIDWIDTH/2) + 4;
y = basey + 7*18;
x = basex;
}
}
}

View file

@ -613,7 +613,7 @@ INT32 K_KartGetItemOdds(
if (gametype == GT_BATTLE)
{
I_Assert(pos < 6); // DO NOT allow positions past the bounds of the table
I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table
newodds = K_KartItemOddsBattle[item-1][pos];
}
else

View file

@ -112,10 +112,12 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
if (player->exiting || mapreset || (player->pflags & PF_ELIMINATED))
return false;
if ((gametyperules & GTR_BUMPERS) // No bumpers in Match
#ifndef OTHERKARMAMODES
if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) // No bumpers in Match
return false;
&& !weapon
#endif
&& player->bumpers <= 0)
return false;
if (weapon)
{
@ -274,9 +276,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_KillMobj(special, toucher, toucher, DMG_NORMAL);
break;
case MT_SPHEREBOX:
if (player->bumpers <= 0)
if (!P_CanPickupItem(player, 0))
return;
special->momx = special->momy = special->momz = 0;
P_SetTarget(&special->target, toucher);
P_KillMobj(special, toucher, toucher, DMG_NORMAL);
break;

View file

@ -5778,6 +5778,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
}
break;
// see also K_drawKartItem in k_hud.c
case MT_PLAYERARROW:
if (mobj->target && mobj->target->health
&& mobj->target->player && !mobj->target->player->spectator
@ -5799,7 +5800,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
mobj->x = mobj->target->x;
mobj->y = mobj->target->y;
mobj->angle = R_PointToAngle(mobj->x, mobj->y) + ANGLE_90; // literally only happened because i wanted to ^L^R the SPR_ITEM's
P_InitAngle (mobj, R_PointToAngle(mobj->x, mobj->y) + ANGLE_90); // literally only happened because i wanted to ^L^R the SPR_ITEM's
if (!r_splitscreen && players[displayplayers[0]].mo)
{
@ -5852,7 +5853,79 @@ static void P_MobjSceneryThink(mobj_t *mobj)
{
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
mobj->tracer->sprite = SPR_ITEM;
mobj->tracer->frame = FF_FULLBRIGHT|(((mobj->target->player->itemroulette % (13*3)) / 3) + 1);
switch((mobj->target->player->itemroulette % (16*3)) / 3)
{
// Each case is handled in threes, to give three frames of in-game time to see the item on the roulette
case 0: // Sneaker
mobj->tracer->frame = KITEM_SNEAKER;
//localcolor = SKINCOLOR_RASPBERRY;
break;
case 1: // Banana
mobj->tracer->frame = KITEM_BANANA;
//localcolor = SKINCOLOR_YELLOW;
break;
case 2: // Orbinaut
mobj->tracer->frame = KITEM_ORBINAUT;
//localcolor = SKINCOLOR_STEEL;
break;
case 3: // Mine
mobj->tracer->frame = KITEM_MINE;
//localcolor = SKINCOLOR_JET;
break;
case 4: // Grow
mobj->tracer->frame = KITEM_GROW;
//localcolor = SKINCOLOR_TEAL;
break;
case 5: // Hyudoro
mobj->tracer->frame = KITEM_HYUDORO;
//localcolor = SKINCOLOR_STEEL;
break;
case 6: // Rocket Sneaker
mobj->tracer->frame = KITEM_ROCKETSNEAKER;
//localcolor = SKINCOLOR_TANGERINE;
break;
case 7: // Jawz
mobj->tracer->frame = KITEM_JAWZ;
//localcolor = SKINCOLOR_JAWZ;
break;
case 8: // Self-Propelled Bomb
mobj->tracer->frame = KITEM_SPB;
//localcolor = SKINCOLOR_JET;
break;
case 9: // Shrink
mobj->tracer->frame = KITEM_SHRINK;
//localcolor = SKINCOLOR_ORANGE;
break;
case 10: // Invincibility
mobj->tracer->frame = KITEM_INVINCIBILITY;
//localcolor = SKINCOLOR_GREY;
break;
case 11: // Eggman Monitor
mobj->tracer->frame = KITEM_EGGMAN;
//localcolor = SKINCOLOR_ROSE;
break;
case 12: // Ballhog
mobj->tracer->frame = KITEM_BALLHOG;
//localcolor = SKINCOLOR_LILAC;
break;
case 13: // Thunder Shield
mobj->tracer->frame = KITEM_THUNDERSHIELD;
//localcolor = SKINCOLOR_CYAN;
break;
case 14: // Super Ring
mobj->tracer->frame = KITEM_SUPERRING;
//localcolor = SKINCOLOR_GOLD;
break;
case 15: // Land Mine
mobj->tracer->frame = KITEM_LANDMINE;
//localcolor = SKINCOLOR_JET;
break;
case 16: // Drop Target
mobj->tracer->frame = KITEM_DROPTARGET;
//localcolor = SKINCOLOR_LIME;
break;
}
mobj->tracer->frame |= FF_FULLBRIGHT;
mobj->tracer->renderflags &= ~RF_DONTDRAW;
}
else if (mobj->target->player->stealingtimer < 0)
@ -10361,6 +10434,7 @@ void P_RemoveMobj(mobj_t *mobj)
|| mobj->type == MT_BLUESPHERE)
&& !(mobj->flags2 & MF2_DONTRESPAWN))
{
//CONS_Printf("added to queue at tic %d\n", leveltime);
itemrespawnque[iquehead] = mobj->spawnpoint;
itemrespawntime[iquehead] = leveltime;
iquehead = (iquehead+1)&(ITEMQUESIZE-1);
@ -10848,6 +10922,8 @@ void P_RespawnSpecials(void)
if (mthing)
P_SpawnMapThing(mthing);
//CONS_Printf("respawn happened on tic %d, irt %d, t %d\n", leveltime, itemrespawntime[iquetail], time);
// pull it from the que
iquetail = (iquetail+1)&(ITEMQUESIZE-1);
}

View file

@ -332,7 +332,7 @@ static void P_NetArchivePlayers(void)
WRITEINT16(save_p, players[i].karmadelay);
WRITEUINT32(save_p, players[i].overtimekarma);
WRITEINT16(save_p, players[i].spheres);
WRITEINT16(save_p, players[i].spheredigestion);
WRITEUINT32(save_p, players[i].spheredigestion);
WRITESINT8(save_p, players[i].glanceDir);
WRITEUINT8(save_p, players[i].tripWireState);
@ -598,7 +598,7 @@ static void P_NetUnArchivePlayers(void)
players[i].karmadelay = READINT16(save_p);
players[i].overtimekarma = READUINT32(save_p);
players[i].spheres = READINT16(save_p);
players[i].spheredigestion = READINT16(save_p);
players[i].spheredigestion = READUINT32(save_p);
players[i].glanceDir = READSINT8(save_p);
players[i].tripWireState = READUINT8(save_p);
@ -1662,7 +1662,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
if (mobj->type == MT_HOOPCENTER && mobj->threshold == 4242)
return;
if (mobj->spawnpoint && mobj->info->doomednum != -1)
if (mobj->spawnpoint)
{
// spawnpoint is not modified but we must save it since it is an identifier
diff = MD_SPAWNPOINT;
@ -1847,8 +1847,12 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
size_t z;
for (z = 0; z < nummapthings; z++)
if (&mapthings[z] == mobj->spawnpoint)
WRITEUINT16(save_p, z);
{
if (&mapthings[z] != mobj->spawnpoint)
continue;
WRITEUINT16(save_p, z);
break;
}
if (mobj->type == MT_HOOPCENTER)
return;
}