mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'battlesync' into 'master'
BATTLE SYNC See merge request KartKrew/Kart!564
This commit is contained in:
commit
44c95916b6
6 changed files with 183 additions and 63 deletions
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
64
src/k_hud.c
64
src/k_hud.c
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
80
src/p_mobj.c
80
src/p_mobj.c
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue