Add blue spheres

Doesn't have animations, and doesn't have stat-specific buffs. But it's already a massive improvement
This commit is contained in:
Sally Coolatta 2020-10-22 02:52:33 -04:00
parent 08dc784c17
commit 7ce53ac104
13 changed files with 111 additions and 69 deletions

View file

@ -545,6 +545,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
// Score is resynched in the rspfirm resync packet // Score is resynched in the rspfirm resync packet
rsp->rings = SHORT(players[i].rings); rsp->rings = SHORT(players[i].rings);
rsp->spheres = SHORT(players[i].spheres);
rsp->lives = players[i].lives; rsp->lives = players[i].lives;
rsp->lostlife = players[i].lostlife; rsp->lostlife = players[i].lostlife;
rsp->continues = players[i].continues; rsp->continues = players[i].continues;
@ -689,6 +690,7 @@ static void resynch_read_player(resynch_pak *rsp)
// Score is resynched in the rspfirm resync packet // Score is resynched in the rspfirm resync packet
players[i].rings = SHORT(rsp->rings); players[i].rings = SHORT(rsp->rings);
players[i].spheres = SHORT(rsp->spheres);
players[i].lives = rsp->lives; players[i].lives = rsp->lives;
players[i].lostlife = rsp->lostlife; players[i].lostlife = rsp->lostlife;
players[i].continues = rsp->continues; players[i].continues = rsp->continues;

View file

@ -214,6 +214,7 @@ typedef struct
// Score is resynched in the confirm resync packet // Score is resynched in the confirm resync packet
INT16 rings; INT16 rings;
INT16 spheres;
SINT8 lives; SINT8 lives;
boolean lostlife; boolean lostlife;
SINT8 continues; SINT8 continues;

View file

@ -497,6 +497,7 @@ typedef struct player_s
// player's ring count // player's ring count
INT16 rings; INT16 rings;
INT16 spheres;
// Power ups. invinc and invis are tic counters. // Power ups. invinc and invis are tic counters.
UINT16 powers[NUMPOWERS]; UINT16 powers[NUMPOWERS];

View file

@ -461,30 +461,30 @@ enum GameTypeRules
{ {
// Race rules // Race rules
GTR_CIRCUIT = 1, // Enables the finish line, laps, and the waypoint system. GTR_CIRCUIT = 1, // Enables the finish line, laps, and the waypoint system.
GTR_RINGS = 1<<1, // Rings will be spawned in this mode. (Don't get too cheeky, ring sting is still enabled :])
GTR_BOTS = 1<<2, // Allows bots in this gametype. Combine with BotTiccmd hooks to make bots support your gametype. GTR_BOTS = 1<<2, // Allows bots in this gametype. Combine with BotTiccmd hooks to make bots support your gametype.
// Battle gametype rules // Battle gametype rules
GTR_BUMPERS = 1<<3, // Enables the bumper health system GTR_SPHERES = 1<<3, // Replaces rings with blue spheres
GTR_WANTED = 1<<4, // Enables the wanted anti-camping system GTR_BUMPERS = 1<<4, // Enables the bumper health system
GTR_KARMA = 1<<5, // Enables the Karma system if you're out of bumpers GTR_WANTED = 1<<5, // Enables the wanted anti-camping system
GTR_ITEMARROWS = 1<<6, // Show item box arrows above players GTR_KARMA = 1<<6, // Enables the Karma system if you're out of bumpers
GTR_CAPSULES = 1<<7, // Enables the wanted anti-camping system GTR_ITEMARROWS = 1<<7, // Show item box arrows above players
GTR_BATTLESTARTS = 1<<8, // Use Battle Mode start positions. GTR_CAPSULES = 1<<8, // Enables the wanted anti-camping system
GTR_BATTLESTARTS = 1<<9, // Use Battle Mode start positions.
GTR_POINTLIMIT = 1<<9, // Reaching point limit ends the round GTR_POINTLIMIT = 1<<10, // Reaching point limit ends the round
GTR_TIMELIMIT = 1<<10, // Reaching time limit ends the round GTR_TIMELIMIT = 1<<11, // Reaching time limit ends the round
GTR_OVERTIME = 1<<11, // Allow overtime behavior GTR_OVERTIME = 1<<12, // Allow overtime behavior
// Custom gametype rules // Custom gametype rules
GTR_TEAMS = 1<<12, // Teams are forced on GTR_TEAMS = 1<<13, // Teams are forced on
GTR_NOTEAMS = 1<<13, // Teams are forced off GTR_NOTEAMS = 1<<14, // Teams are forced off
GTR_TEAMSTARTS = 1<<14, // Use team-based start positions GTR_TEAMSTARTS = 1<<15, // Use team-based start positions
// Grand Prix rules // Grand Prix rules
GTR_CAMPAIGN = 1<<15, // Handles cup-based progression GTR_CAMPAIGN = 1<<16, // Handles cup-based progression
GTR_LIVES = 1<<16, // Lives system, players are forced to spectate during Game Over. GTR_LIVES = 1<<17, // Lives system, players are forced to spectate during Game Over.
GTR_SPECIALBOTS = 1<<17, // Bot difficulty gets stronger between rounds, and the rival system is enabled. GTR_SPECIALBOTS = 1<<18, // Bot difficulty gets stronger between rounds, and the rival system is enabled.
// free: to and including 1<<31 // free: to and including 1<<31
}; };

View file

@ -2056,6 +2056,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
UINT8 botdifficulty; UINT8 botdifficulty;
INT16 rings; INT16 rings;
INT16 spheres;
angle_t playerangleturn; angle_t playerangleturn;
UINT8 botdiffincrease; UINT8 botdiffincrease;
@ -2140,7 +2141,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
itemamount = 0; itemamount = 0;
growshrinktimer = 0; growshrinktimer = 0;
bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0); bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0);
rings = ((gametyperules & GTR_RINGS) ? 5 : 0); rings = ((gametyperules & GTR_SPHERES) ? 0 : 5);
spheres = 0;
comebackpoints = 0; comebackpoints = 0;
wanted = 0; wanted = 0;
} }
@ -2168,6 +2170,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
bumper = players[player].kartstuff[k_bumper]; bumper = players[player].kartstuff[k_bumper];
rings = players[player].rings; rings = players[player].rings;
spheres = players[player].spheres;
comebackpoints = players[player].kartstuff[k_comebackpoints]; comebackpoints = players[player].kartstuff[k_comebackpoints];
wanted = players[player].kartstuff[k_wanted]; wanted = players[player].kartstuff[k_wanted];
} }
@ -2216,6 +2219,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->bot = bot; p->bot = bot;
p->botvars.difficulty = botdifficulty; p->botvars.difficulty = botdifficulty;
p->rings = rings; p->rings = rings;
p->spheres = spheres;
p->botvars.diffincrease = botdiffincrease; p->botvars.diffincrease = botdiffincrease;
p->botvars.rival = botrival; p->botvars.rival = botrival;
p->xtralife = xtralife; p->xtralife = xtralife;
@ -2788,9 +2792,9 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] =
UINT32 gametypedefaultrules[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] =
{ {
// Race // Race
GTR_CIRCUIT|GTR_RINGS|GTR_BOTS, GTR_CIRCUIT|GTR_BOTS,
// Battle // Battle
GTR_BUMPERS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME GTR_SPHERES|GTR_BUMPERS|GTR_WANTED|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME
}; };
// //

View file

@ -135,7 +135,7 @@ char sprnames[NUMSPRITES + 1][5] =
"TOKE", // Special Stage Token "TOKE", // Special Stage Token
"RFLG", // Red CTF Flag "RFLG", // Red CTF Flag
"BFLG", // Blue CTF Flag "BFLG", // Blue CTF Flag
//"SPHR", // Sphere "BSPH", // Sphere
"NCHP", // NiGHTS chip "NCHP", // NiGHTS chip
"NSTR", // NiGHTS star "NSTR", // NiGHTS star
"EMBM", // Emblem "EMBM", // Emblem
@ -1800,19 +1800,19 @@ state_t states[NUMSTATES] =
{SPR_RING, 22, 1, {NULL}, 0, 0, S_FASTRING1}, // S_FASTRING12 {SPR_RING, 22, 1, {NULL}, 0, 0, S_FASTRING1}, // S_FASTRING12
// Blue Sphere for special stages // Blue Sphere for special stages
{SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE {SPR_BSPH, FF_SEMIBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE
{SPR_SPHR, FF_FULLBRIGHT {SPR_BSPH, FF_FULLBRIGHT
#ifdef MANIASPHERES #ifdef MANIASPHERES
|FF_ANIMATE|FF_RANDOMANIM |FF_ANIMATE|FF_RANDOMANIM
#endif #endif
, -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS , -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS
{SPR_SPHR, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK {SPR_BSPH, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK
// Bomb Sphere // Bomb Sphere
{SPR_SPHR, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1 {SPR_BSPH, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2}, // S_BOMBSPHERE1
{SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3}, // S_BOMBSPHERE2 {SPR_BSPH, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3}, // S_BOMBSPHERE2
{SPR_SPHR, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4}, // S_BOMBSPHERE3 {SPR_BSPH, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4}, // S_BOMBSPHERE3
{SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1}, // S_BOMBSPHERE4 {SPR_BSPH, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1}, // S_BOMBSPHERE4
// NiGHTS Chip // NiGHTS Chip
{SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 15, 2, S_NULL}, // S_NIGHTSCHIP {SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 15, 2, S_NULL}, // S_NIGHTSCHIP
@ -7923,29 +7923,29 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
}, },
{ // MT_BLUESPHERE { // MT_BLUESPHERE
1706, // doomednum -1, // doomednum
S_BLUESPHERE, // spawnstate S_BLUESPHERE, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
MT_FLINGBLUESPHERE, // reactiontime MT_FLINGBLUESPHERE, // reactiontime
sfx_None, // attacksound sfx_None, // attacksound
S_NULL, // painstate S_NULL, // painstate
0, // painchance 0, // painchance
sfx_None, // painsound sfx_None, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_BLUESPHERESPARK, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_s3k65, // deathsound sfx_s3k65, // deathsound
38*FRACUNIT, // speed 38*FRACUNIT, // speed
16*FRACUNIT, // radius 48*FRACUNIT, // radius
24*FRACUNIT, // height 48*FRACUNIT, // height
0, // display offset 0, // display offset
100, // mass 100, // mass
0, // damage 0, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
S_BLUESPHEREBONUS // raisestate S_BLUESPHEREBONUS // raisestate
}, },
@ -7962,7 +7962,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // painsound sfx_None, // painsound
S_NULL, // meleestate S_NULL, // meleestate
S_NULL, // missilestate S_NULL, // missilestate
S_BLUESPHERESPARK, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_s3k65, // deathsound sfx_s3k65, // deathsound
38*FRACUNIT, // speed 38*FRACUNIT, // speed

View file

@ -406,7 +406,7 @@ typedef enum sprite
SPR_TOKE, // Special Stage Token SPR_TOKE, // Special Stage Token
SPR_RFLG, // Red CTF Flag SPR_RFLG, // Red CTF Flag
SPR_BFLG, // Blue CTF Flag SPR_BFLG, // Blue CTF Flag
//SPR_SPHR, // Sphere SPR_BSPH, // Sphere
SPR_NCHP, // NiGHTS chip SPR_NCHP, // NiGHTS chip
SPR_NSTR, // NiGHTS star SPR_NSTR, // NiGHTS star
SPR_EMBM, // Emblem SPR_EMBM, // Emblem

View file

@ -897,7 +897,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
// SPECIAL CASE No. 4: // SPECIAL CASE No. 4:
// Being in ring debt occasionally forces Super Ring on you if you mashed // Being in ring debt occasionally forces Super Ring on you if you mashed
if ((gametyperules & GTR_RINGS) && mashed && player->rings < 0 && cv_superring.value) if (!(gametyperules & GTR_SPHERES) && mashed && player->rings < 0 && cv_superring.value)
{ {
INT32 debtamount = min(20, abs(player->rings)); INT32 debtamount = min(20, abs(player->rings));
if (P_RandomChance((debtamount*FRACUNIT)/20)) if (P_RandomChance((debtamount*FRACUNIT)/20))
@ -2221,6 +2221,12 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
finalspeed = K_GetKartSpeedFromStat(kartspeed); finalspeed = K_GetKartSpeedFromStat(kartspeed);
if (player->spheres > 0)
{
fixed_t sphereAdd = (FRACUNIT/80); // 50% at max
finalspeed = FixedMul(finalspeed, FRACUNIT + (sphereAdd * player->spheres));
}
if (K_PlayerUsesBotMovement(player)) if (K_PlayerUsesBotMovement(player))
{ {
// Give top speed a buff for bots, since it's a fairly weak stat without drifting // Give top speed a buff for bots, since it's a fairly weak stat without drifting
@ -2261,6 +2267,11 @@ fixed_t K_GetKartAccel(player_t *player)
//k_accel += 3 * (9 - kartspeed); // 36 - 60 //k_accel += 3 * (9 - kartspeed); // 36 - 60
k_accel += 4 * (9 - kartspeed); // 32 - 64 k_accel += 4 * (9 - kartspeed); // 32 - 64
if (player->spheres > 0)
{
fixed_t sphereAdd = (FRACUNIT/10); // 500% at max
k_accel = FixedMul(k_accel, FRACUNIT + (sphereAdd * player->spheres));
}
if (K_PlayerUsesBotMovement(player)) if (K_PlayerUsesBotMovement(player))
{ {
@ -5614,6 +5625,14 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
else if (player->rings < -20) else if (player->rings < -20)
player->rings = -20; player->rings = -20;
if ((leveltime % TICRATE) == 0)
player->spheres--;
if (player->spheres > 40)
player->spheres = 40;
else if (player->spheres < 0)
player->spheres = 0;
if (player->kartstuff[k_ringdelay]) if (player->kartstuff[k_ringdelay])
player->kartstuff[k_ringdelay]--; player->kartstuff[k_ringdelay]--;

View file

@ -209,6 +209,8 @@ static int player_get(lua_State *L)
lua_pushangle(L, plr->drawangle); lua_pushangle(L, plr->drawangle);
else if (fastcmp(field,"rings")) else if (fastcmp(field,"rings"))
lua_pushinteger(L, plr->rings); lua_pushinteger(L, plr->rings);
else if (fastcmp(field,"spheres"))
lua_pushinteger(L, plr->spheres);
else if (fastcmp(field,"powers")) else if (fastcmp(field,"powers"))
LUA_PushUserdata(L, plr->powers, META_POWERS); LUA_PushUserdata(L, plr->powers, META_POWERS);
else if (fastcmp(field,"kartstuff")) else if (fastcmp(field,"kartstuff"))
@ -476,6 +478,8 @@ static int player_set(lua_State *L)
plr->drawangle = luaL_checkangle(L, 3); plr->drawangle = luaL_checkangle(L, 3);
else if (fastcmp(field,"rings")) else if (fastcmp(field,"rings"))
plr->rings = (INT32)luaL_checkinteger(L, 3); plr->rings = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"spheres"))
plr->spheres = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"powers")) else if (fastcmp(field,"powers"))
return NOSET; return NOSET;
else if (fastcmp(field,"pflags")) else if (fastcmp(field,"pflags"))

View file

@ -2371,7 +2371,7 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
P_SetThingPosition(thing); P_SetThingPosition(thing);
if (thing->flags & MF_SHOOTABLE) if (thing->flags & MF_SHOOTABLE)
P_DamageMobj(thing, puncher, puncher, 1, DMG_NORMAL); P_DamageMobj(thing, puncher, puncher, 1, DMG_NORMAL);
else if (thing->type == MT_RING || thing->type == MT_COIN || thing->type == MT_RANDOMITEM) else if (thing->type == MT_RING || thing->type == MT_RANDOMITEM)
{ {
thing->momz = FixedMul(3*FRACUNIT, thing->scale); thing->momz = FixedMul(3*FRACUNIT, thing->scale);
P_TouchSpecialThing(thing, puncher, false); P_TouchSpecialThing(thing, puncher, false);

View file

@ -553,6 +553,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return; return;
case MT_BLUESPHERE:
if (!(P_CanPickupItem(player, 0)))
return;
// Reached the cap, don't waste 'em!
if (player->spheres >= 40)
return;
special->momx = special->momy = special->momz = 0;
player->spheres++;
break;
// Secret emblem thingy // Secret emblem thingy
case MT_EMBLEM: case MT_EMBLEM:
{ {
@ -2000,7 +2012,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
fixed_t momxy = 5<<FRACBITS, momz = 12<<FRACBITS; // base horizonal/vertical thrusts fixed_t momxy = 5<<FRACBITS, momz = 12<<FRACBITS; // base horizonal/vertical thrusts
// Rings shouldn't be in Battle! // Rings shouldn't be in Battle!
if (!(gametyperules & GTR_RINGS)) if (gametyperules & GTR_SPHERES)
return; return;
// Better safe than sorry. // Better safe than sorry.

View file

@ -2111,18 +2111,8 @@ boolean P_ZMovement(mobj_t *mo)
break; break;
case MT_RING: // Ignore still rings case MT_RING: // Ignore still rings
case MT_COIN:
case MT_BLUESPHERE: case MT_BLUESPHERE:
case MT_BOMBSPHERE:
case MT_NIGHTSCHIP:
case MT_NIGHTSSTAR:
case MT_REDTEAMRING:
case MT_BLUETEAMRING:
case MT_FLINGRING: case MT_FLINGRING:
case MT_FLINGCOIN:
case MT_FLINGBLUESPHERE:
case MT_FLINGNIGHTSCHIP:
case MT_FLINGEMERALD:
// Remove flinged stuff from death pits. // Remove flinged stuff from death pits.
if (P_CheckDeathPitCollide(mo)) if (P_CheckDeathPitCollide(mo))
{ {
@ -8916,6 +8906,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
break; break;
case MT_RING: case MT_RING:
case MT_FLOATINGITEM: case MT_FLOATINGITEM:
case MT_BLUESPHERE:
thing->shadowscale = FRACUNIT/2; thing->shadowscale = FRACUNIT/2;
break; break;
case MT_DRIFTCLIP: case MT_DRIFTCLIP:
@ -9205,8 +9196,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->color = skincolor_blueteam; mobj->color = skincolor_blueteam;
break; break;
case MT_RING: case MT_RING:
case MT_COIN:
case MT_NIGHTSSTAR:
if (nummaprings >= 0) if (nummaprings >= 0)
nummaprings++; nummaprings++;
break; break;
@ -9564,10 +9553,7 @@ void P_RemoveMobj(mobj_t *mobj)
// Rings only, please! // Rings only, please!
if (mobj->spawnpoint && if (mobj->spawnpoint &&
(mobj->type == MT_RING (mobj->type == MT_RING
|| mobj->type == MT_COIN || mobj->type == MT_BLUESPHERE)
|| mobj->type == MT_NIGHTSSTAR
|| mobj->type == MT_REDTEAMRING
|| mobj->type == MT_BLUETEAMRING)
&& !(mobj->flags2 & MF2_DONTRESPAWN)) && !(mobj->flags2 & MF2_DONTRESPAWN))
{ {
itemrespawnque[iquehead] = mobj->spawnpoint; itemrespawnque[iquehead] = mobj->spawnpoint;
@ -9979,22 +9965,29 @@ void P_RespawnSpecials(void)
pcount++; pcount++;
} }
if (pcount == 1) // No respawn when alone if (gametyperules & GTR_SPHERES)
return;
else if (pcount > 1)
{ {
time = (120 - ((pcount-2) * 10))*TICRATE; time = ((MAXPLAYERS+1) - pcount) * (2*TICRATE);
}
// If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this. else
// 5 lap courses would have more retreaded ground, while 2 lap courses would have less. {
if ((mapheaderinfo[gamemap-1]->numlaps != 3) if (pcount == 1) // No respawn when alone
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE)) return;
time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps); else if (pcount > 1)
if (time < 10*TICRATE)
{ {
// Ensure it doesn't go into absurdly low values time = (120 - ((pcount-2) * 10))*TICRATE;
time = 10*TICRATE;
// If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this.
// 5 lap courses would have more retreaded ground, while 2 lap courses would have less.
if ((mapheaderinfo[gamemap-1]->numlaps != 3)
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE))
time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps);
if (time < 10*TICRATE)
{
// Ensure it doesn't go into absurdly low values
time = 10*TICRATE;
}
} }
} }
@ -10410,6 +10403,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
case MT_SPIKEBALL: case MT_SPIKEBALL:
case MT_EMBLEM: case MT_EMBLEM:
case MT_RING: case MT_RING:
case MT_BLUESPHERE:
offset += mthing->options & MTF_AMBUSH ? 24*mapobjectscale : 0; offset += mthing->options & MTF_AMBUSH ? 24*mapobjectscale : 0;
break; break;
@ -10516,8 +10510,11 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i)
{ {
// Don't need this for Kart YET!
(void)mthing; (void)mthing;
if ((gametyperules & GTR_SPHERES) && (i == MT_RING))
return MT_BLUESPHERE;
return i; return i;
} }

View file

@ -109,6 +109,7 @@ static void P_NetArchivePlayers(void)
WRITEANGLE(save_p, players[i].awayviewaiming); WRITEANGLE(save_p, players[i].awayviewaiming);
WRITEINT32(save_p, players[i].awayviewtics); WRITEINT32(save_p, players[i].awayviewtics);
WRITEINT16(save_p, players[i].rings); WRITEINT16(save_p, players[i].rings);
WRITEINT16(save_p, players[i].spheres);
for (j = 0; j < NUMPOWERS; j++) for (j = 0; j < NUMPOWERS; j++)
WRITEUINT16(save_p, players[i].powers[j]); WRITEUINT16(save_p, players[i].powers[j]);
@ -302,6 +303,7 @@ static void P_NetUnArchivePlayers(void)
players[i].awayviewaiming = READANGLE(save_p); players[i].awayviewaiming = READANGLE(save_p);
players[i].awayviewtics = READINT32(save_p); players[i].awayviewtics = READINT32(save_p);
players[i].rings = READINT16(save_p); players[i].rings = READINT16(save_p);
players[i].spheres = READINT16(save_p);
for (j = 0; j < NUMPOWERS; j++) for (j = 0; j < NUMPOWERS; j++)
players[i].powers[j] = READUINT16(save_p); players[i].powers[j] = READUINT16(save_p);