mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-04 20:56:14 +00:00
Merge remote-tracking branch 'origin/master' into postrace-director
This commit is contained in:
commit
9d3c0f0c68
30 changed files with 418 additions and 171 deletions
|
|
@ -3589,13 +3589,15 @@ bool CallFunc_SetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A
|
|||
INT32 value = 0;
|
||||
|
||||
tag = argV[0];
|
||||
mobj = P_FindMobjFromTID(tag, mobj, info->mo);
|
||||
mobj_t *next = P_FindMobjFromTID(tag, mobj, info->mo);
|
||||
|
||||
property = argV[1];
|
||||
value = argV[2];
|
||||
|
||||
while (mobj != NULL)
|
||||
while ((mobj = next) != NULL)
|
||||
{
|
||||
// First in case of deletion. (Can't check for value == S_NULL because of A_ calls, etc)
|
||||
next = P_FindMobjFromTID(tag, mobj, info->mo);
|
||||
|
||||
#define PROP_READONLY(x, y) \
|
||||
case x: \
|
||||
|
|
@ -3830,8 +3832,6 @@ bool CallFunc_SetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A
|
|||
}
|
||||
}
|
||||
|
||||
mobj = P_FindMobjFromTID(tag, mobj, info->mo);
|
||||
|
||||
#undef PROP_FLAGS
|
||||
#undef PROP_SCALE
|
||||
#undef PROP_MOBJ
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ public:
|
|||
|
||||
Vector& operator=(const Vector& rhs)
|
||||
{
|
||||
clear();
|
||||
for (auto itr = rhs.begin(); itr != rhs.end(); itr++)
|
||||
{
|
||||
push_back(*itr);
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ shouldsign_t ShouldSignChallenge(uint8_t *message)
|
|||
if ((max(now, then) - min(now, then)) > 60*15)
|
||||
return SIGN_BADTIME;
|
||||
|
||||
// ____ _____ ___ ____ _
|
||||
// ____ _____ ___ ____ _
|
||||
// / ___|_ _/ _ \| _ \| |
|
||||
// \___ \ | || | | | |_) | |
|
||||
// ___) || || |_| | __/|_|
|
||||
|
|
@ -2436,6 +2436,11 @@ static void CL_ConnectToServer(void)
|
|||
|
||||
joinedIP[0] = '\0'; // And empty this for good measure regardless of whether or not we actually used it.
|
||||
|
||||
// Enable sound input/microphone in netgames, activating the microphone device.
|
||||
if (netgame)
|
||||
{
|
||||
S_SoundInputSetEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
static void Command_connect(void)
|
||||
|
|
@ -2502,6 +2507,8 @@ static void Command_connect(void)
|
|||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n"));
|
||||
D_CloseConnection();
|
||||
|
||||
S_SoundInputSetEnabled(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -3659,6 +3666,7 @@ void D_QuitNetGame(void)
|
|||
K_ClearClientPowerLevels();
|
||||
G_ObliterateParties();
|
||||
K_ResetMidVote();
|
||||
S_SoundInputSetEnabled(false);
|
||||
|
||||
DEBFILE("===========================================================================\n"
|
||||
" Log finish\n"
|
||||
|
|
@ -7376,9 +7384,6 @@ void NetVoiceUpdate(void)
|
|||
return;
|
||||
}
|
||||
|
||||
// This necessarily runs every frame, not every tic
|
||||
S_SoundInputSetEnabled(true);
|
||||
|
||||
UINT32 bytes_dequed = 0;
|
||||
do
|
||||
{
|
||||
|
|
|
|||
|
|
@ -297,6 +297,7 @@ actionpointer_t actionpointers[] =
|
|||
{{A_MakeSSCandle}, "A_MAKESSCANDLE"},
|
||||
{{A_HologramRandomTranslucency}, "A_HOLOGRAMRANDOMTRANSLUCENCY"},
|
||||
{{A_SSChainShatter}, "A_SSCHAINSHATTER"},
|
||||
{{A_GenericBumper}, "A_GENERICBUMPER"},
|
||||
|
||||
{{NULL}, "NONE"},
|
||||
|
||||
|
|
|
|||
|
|
@ -2368,6 +2368,8 @@ void G_BeginRecording(void)
|
|||
WRITEUINT8(demobuf.p, player->skin);
|
||||
WRITEUINT8(demobuf.p, player->lastfakeskin);
|
||||
|
||||
WRITEUINT8(demobuf.p, player->team);
|
||||
|
||||
// Color
|
||||
demobuf.p += copy_fixed_buf(demobuf.p, skincolors[player->skincolor].name, g_buffer_sizes.color_name);
|
||||
|
||||
|
|
@ -3500,6 +3502,8 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum)
|
|||
demo.currentskinid[p] = 0;
|
||||
lastfakeskin[p] = READUINT8(demobuf.p);
|
||||
|
||||
players[p].team = READUINT8(demobuf.p);
|
||||
|
||||
// Color
|
||||
demobuf.p += copy_fixed_buf(color, demobuf.p, g_buffer_sizes.color_name);
|
||||
for (i = 0; i < numskincolors; i++)
|
||||
|
|
@ -3783,6 +3787,8 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
|
|||
ghskin = &skins[skinlist[i].mapping];
|
||||
p++; // lastfakeskin
|
||||
|
||||
p++; // team
|
||||
|
||||
// Color
|
||||
p += copy_fixed_buf(color, p, ghostsizes.color_name);
|
||||
|
||||
|
|
|
|||
15
src/g_game.c
15
src/g_game.c
|
|
@ -1556,7 +1556,7 @@ boolean G_CouldView(INT32 playernum)
|
|||
return false;
|
||||
|
||||
// SRB2Kart: we have no team-based modes, YET...
|
||||
if (G_GametypeHasTeams())
|
||||
if (G_GametypeHasTeams() && !demo.playback)
|
||||
{
|
||||
if (players[consoleplayer].spectator == false && player->team != players[consoleplayer].team)
|
||||
return false;
|
||||
|
|
@ -2352,8 +2352,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
bot = players[player].bot;
|
||||
botdifficulty = players[player].botvars.difficulty;
|
||||
|
||||
cangrabitems = players[player].cangrabitems;
|
||||
|
||||
botdiffincrease = players[player].botvars.diffincrease;
|
||||
botrival = players[player].botvars.rival;
|
||||
|
||||
|
|
@ -2439,13 +2437,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
tallyactive = false;
|
||||
|
||||
cangrabitems = 0;
|
||||
if (gametyperules & GTR_SPHERES
|
||||
|| gametyperules & GTR_CATCHER
|
||||
|| G_TimeAttackStart()
|
||||
|| gametype == GT_TUTORIAL
|
||||
|| !M_NotFreePlay()
|
||||
|| K_GetNumWaypoints() == 0)
|
||||
cangrabitems = EARLY_ITEM_FLICKER;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2501,6 +2492,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
{
|
||||
tally = players[player].tally;
|
||||
}
|
||||
|
||||
cangrabitems = players[player].cangrabitems;
|
||||
}
|
||||
|
||||
spectatorReentry = (betweenmaps ? 0 : players[player].spectatorReentry);
|
||||
|
|
@ -5426,6 +5419,8 @@ void G_InitNew(UINT8 pencoremode, INT32 map, boolean resetplayer, boolean skippr
|
|||
players[i].xtralife = 0;
|
||||
players[i].totalring = 0;
|
||||
players[i].score = 0;
|
||||
if (roundqueue.position == 0) // Don't unassign teams in tournament play
|
||||
players[i].team = TEAM_UNASSIGNED;
|
||||
}
|
||||
|
||||
if (resetplayer || !(gametyperules & GTR_CHECKPOINTS && map == gamemap))
|
||||
|
|
|
|||
|
|
@ -3640,7 +3640,7 @@ state_t states[NUMSTATES] =
|
|||
{SPR_S_SP, FF_ANIMATE|FF_SEMIBRIGHT, -1, {NULL}, 3, 2, S_NULL}, // S_SLSTMACE
|
||||
|
||||
// MT_SEALEDSTAR_BUMPER
|
||||
{SPR_SBMP, 0|FF_FULLBRIGHT, -1, {NULL}, 2, 8, S_SEALEDSTAR_BUMPER}, // S_SEALEDSTAR_BUMPER
|
||||
{SPR_SBMP, 0|FF_FULLBRIGHT, -1, {A_GenericBumper}, 0, 56, S_SEALEDSTAR_BUMPER}, // S_SEALEDSTAR_BUMPER
|
||||
{SPR_SBMP, 1|FF_ANIMATE|FF_FULLBRIGHT, 8, {NULL}, 1, 2, S_SEALEDSTAR_BUMPER}, // S_SEALEDSTAR_BUMPERHIT
|
||||
|
||||
// MT_SSCHAIN_SPAWNER
|
||||
|
|
@ -22233,7 +22233,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SPECIAL|MF_NOGRAVITY, // flags
|
||||
MF_NOGRAVITY|MF_SOLID, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_SSCHAIN_SPAWNER
|
||||
|
|
|
|||
|
|
@ -289,6 +289,7 @@ enum actionnum
|
|||
A_MAKESSCANDLE,
|
||||
A_HOLOGRAMRANDOMTRANSLUCENCY,
|
||||
A_SSCHAINSHATTER,
|
||||
A_GENERICBUMPER,
|
||||
NUMACTIONS
|
||||
};
|
||||
|
||||
|
|
@ -557,6 +558,7 @@ void A_BlendEyePuyoHack();
|
|||
void A_MakeSSCandle();
|
||||
void A_HologramRandomTranslucency();
|
||||
void A_SSChainShatter();
|
||||
void A_GenericBumper();
|
||||
|
||||
extern boolean actionsoverridden[NUMACTIONS];
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
|||
if (t1->type == MT_BALLHOGBOOM && t2->type == MT_BALLHOGBOOM)
|
||||
return true; // Ballhogs don't collide with eachother
|
||||
|
||||
if (K_TryPickMeUp(t1, t2))
|
||||
if (K_TryPickMeUp(t1, t2, false))
|
||||
return true;
|
||||
|
||||
if (t2->player)
|
||||
|
|
@ -178,7 +178,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
|
|||
if (t1->health <= 0 || t2->health <= 0)
|
||||
return true;
|
||||
|
||||
if (K_TryPickMeUp(t1, t2))
|
||||
if (K_TryPickMeUp(t1, t2, false))
|
||||
return true;
|
||||
|
||||
if (!P_CanPickupItem(t2->player, PICKUP_EGGBOX))
|
||||
|
|
@ -434,7 +434,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
|
|||
if (t1->health <= 0 || t2->health <= 0)
|
||||
return true;
|
||||
|
||||
if (K_TryPickMeUp(t1, t2))
|
||||
if (K_TryPickMeUp(t1, t2, false))
|
||||
return true;
|
||||
|
||||
if (t2->player)
|
||||
|
|
@ -544,7 +544,7 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2)
|
|||
if (t2->player && (t2->player->hyudorotimer || t2->player->justbumped))
|
||||
return true;
|
||||
|
||||
if (K_TryPickMeUp(t1, t2))
|
||||
if (K_TryPickMeUp(t1, t2, false))
|
||||
return true;
|
||||
|
||||
if (draggeddroptarget && P_MobjWasRemoved(draggeddroptarget))
|
||||
|
|
@ -777,6 +777,12 @@ static inline BlockItReturn_t PIT_LightningShieldAttack(mobj_t *thing)
|
|||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
// see if it went over / under
|
||||
if (lightningSource->z - lightningDist > thing->z + thing->height)
|
||||
return BMIT_CONTINUE; // overhead
|
||||
if (lightningSource->z + lightningSource->height + lightningDist < thing->z)
|
||||
return BMIT_CONTINUE; // underneath
|
||||
|
||||
#if 0
|
||||
if (P_CheckSight(lightningSource, thing) == false)
|
||||
{
|
||||
|
|
@ -1036,7 +1042,14 @@ boolean K_InstaWhipCollide(mobj_t *shield, mobj_t *victim)
|
|||
}
|
||||
else if (victim->type == MT_DROPTARGET || victim->type == MT_DROPTARGET_SHIELD)
|
||||
{
|
||||
K_DropTargetCollide(victim, shield);
|
||||
if (K_TryPickMeUp(attacker, victim, true))
|
||||
{
|
||||
shield->hitlag = attacker->hitlag; // players hitlag is handled in K_TryPickMeUp, and we need to set for the shield too
|
||||
}
|
||||
else
|
||||
{
|
||||
K_DropTargetCollide(victim, shield);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
@ -1053,8 +1066,13 @@ boolean K_InstaWhipCollide(mobj_t *shield, mobj_t *victim)
|
|||
shield->extravalue1 = 1;
|
||||
}
|
||||
|
||||
if (P_DamageMobj(victim, shield, attacker, 1, DMG_NORMAL))
|
||||
if (K_TryPickMeUp(attacker, victim, true))
|
||||
{
|
||||
shield->hitlag = attacker->hitlag; // players hitlag is handled in K_TryPickMeUp, and we need to set for the shield too
|
||||
}
|
||||
else
|
||||
{
|
||||
P_DamageMobj(victim, shield, attacker, 1, DMG_NORMAL);
|
||||
K_AddHitLag(attacker, attackerHitlag, false);
|
||||
shield->hitlag = attacker->hitlag;
|
||||
}
|
||||
|
|
@ -1068,7 +1086,7 @@ boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2)
|
|||
if (((t1->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||
return true;
|
||||
|
||||
if (K_TryPickMeUp(t1, t2))
|
||||
if (K_TryPickMeUp(t1, t2, false))
|
||||
return true;
|
||||
|
||||
if (t2->player)
|
||||
|
|
|
|||
189
src/k_hud.cpp
189
src/k_hud.cpp
|
|
@ -240,7 +240,7 @@ static patch_t *kp_duel_you;
|
|||
static patch_t *kp_duel_sticker;
|
||||
static patch_t *kp_duel_under;
|
||||
static patch_t *kp_duel_over;
|
||||
static patch_t *kp_duel_margin[6];
|
||||
static patch_t *kp_duel_margin[24];
|
||||
|
||||
patch_t *kp_autoroulette;
|
||||
patch_t *kp_autoring;
|
||||
|
|
@ -1074,9 +1074,13 @@ void K_LoadKartHUDGraphics(void)
|
|||
HU_UpdatePatch(&kp_duel_under, "DUEL_B");
|
||||
HU_UpdatePatch(&kp_duel_over, "DUEL_B2");
|
||||
HU_UpdatePatch(&kp_duel_you, "DUEL_YOU");
|
||||
for (i = 0; i < 6; i++)
|
||||
|
||||
sprintf(buffer, "DUELMBxx");
|
||||
for (i = 0; i < MARGINLEVELS; i++)
|
||||
{
|
||||
HU_UpdatePatch(&kp_duel_margin[i], "DUELMB0%d", i);
|
||||
buffer[6] = '0'+(i/10);
|
||||
buffer[7] = '0'+(i%10);
|
||||
HU_UpdatePatch(&kp_duel_margin[i], "%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3250,6 +3254,8 @@ INT32 K_GetTransFlagFromFixed(fixed_t value)
|
|||
}
|
||||
|
||||
static tic_t duel_lastleveltime = 0;
|
||||
static INT32 duel_marginanim = 0;
|
||||
static INT32 duel_lastmargin = 0;
|
||||
static INT32 youheight = 0;
|
||||
|
||||
static void K_drawKartDuelScores(void)
|
||||
|
|
@ -3289,8 +3295,6 @@ static void K_drawKartDuelScores(void)
|
|||
INT32 youfill = skincolors[stplyr->skincolor].ramp[ri];
|
||||
INT32 foefill = skincolors[foe->skincolor].ramp[ri];
|
||||
|
||||
INT32 margin = std::min(overtimecheckpoints, (UINT8)5); // Absolutely what the fuck kind of cast.
|
||||
|
||||
V_DrawScaledPatch(basex, basey, flags, kp_duel_sticker);
|
||||
|
||||
INT32 scoredelta = stplyr->duelscore - foe->duelscore;
|
||||
|
|
@ -3322,7 +3326,6 @@ static void K_drawKartDuelScores(void)
|
|||
else if (targetyouheight < youheight)
|
||||
youheight -= slide;
|
||||
}
|
||||
duel_lastleveltime = leveltime;
|
||||
|
||||
INT32 foeheight = 2*barheight-youheight; // barheight is a single tied bar, so total height of the full gauge is 2x barheight
|
||||
|
||||
|
|
@ -3397,7 +3400,138 @@ static void K_drawKartDuelScores(void)
|
|||
V_DrawMappedPatch(drawx+xoff, drawy+yoff, flags|flipflag, faceprefix[workingskin][FACE_RANK], colormap);
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(basex, basey, flags, kp_duel_margin[margin]);
|
||||
// Dogshit. Should have just figured out how to do log base 5 in C++.
|
||||
// However, I think this works anyway.
|
||||
// I did my best to comment this but the algorithm is honestly just bad and hard to
|
||||
// reason about. Please don't try to maintain this, just yell at me if it needs any
|
||||
// adjustments. -Tyron 2025-05-29
|
||||
|
||||
// DESIGN INTENT: Create realistic-looking Puyo garbage stacks, while using the
|
||||
// leading garbage symbol as an indicator of the current Margin Boost value.
|
||||
|
||||
INT32 rawmargin = overtimecheckpoints; // The actual Margin Boost value.
|
||||
INT32 boostspersymbol = 3; // How many boosts should it take to see a new symbol?
|
||||
// rawmargin = (leveltime/10)%(3*boostspersymbol);
|
||||
|
||||
if (duel_lastleveltime != leveltime) // Trigger the "slide" animation when rawmargin changes.
|
||||
{
|
||||
duel_marginanim = std::min(duel_marginanim + 1, 100); // not magic just arbitrary
|
||||
if (duel_lastmargin != rawmargin)
|
||||
{
|
||||
duel_marginanim = 0;
|
||||
duel_lastmargin = rawmargin;
|
||||
}
|
||||
}
|
||||
|
||||
duel_lastleveltime = leveltime;
|
||||
|
||||
// CONS_Printf("=== RAWMARGIN %d\n", rawmargin);
|
||||
|
||||
if (rawmargin == 0)
|
||||
return;
|
||||
|
||||
rawmargin--; // Start at 0, idiot
|
||||
|
||||
// We're invoking the RNG to get a slightly chaotic symbol distribution,
|
||||
// but we're a HUD hook, so we need to keep the results of the call consistent.
|
||||
P_SetRandSeed(PR_NUISANCE, 69 + rawmargin);
|
||||
|
||||
INT32 highsymbol = rawmargin/boostspersymbol + 1; // Highest symbol that should appear.
|
||||
INT32 symbolsperupgrade = 5; // What is each symbol worth relative to each other? Like, 5 Stars = 1 Moon, etc.
|
||||
|
||||
// Okay, so we would LOVE to do this in a way that isn't a big clusterfuck, like just
|
||||
// doing rawmargin^3 and then subtracting powers of 5 out of that. Unfortunately, UINT64
|
||||
// is too small for the values that feel intuitively right here, so we have to do some of
|
||||
// the math on a limited set of symbols, then shift up. This is the concept of "symbol
|
||||
// headroom" that's in use here.
|
||||
//
|
||||
// (Note that Puyo~n uses a super inconsistent symbol table, probably to avoid this problem,
|
||||
// but we're assholes and want things to feel logically consistent I guess?
|
||||
// I dunno. I sort of feel like I should have just directly used the Puyo~n garbage table and
|
||||
// avoided most of this, LOL)
|
||||
|
||||
INT32 symbolheadroom = 5; // Maximum # symbols we can "step down".
|
||||
INT32 frac = rawmargin % boostspersymbol; // Used in intermediate calculations.
|
||||
INT32 minsymbol = std::max(1, highsymbol - symbolheadroom); // The lowest symbol that should appear.
|
||||
INT32 symbolheadroominuse = highsymbol - minsymbol; // The # of symbols we are stepping down.
|
||||
INT32 minscore = std::pow(symbolsperupgrade, symbolheadroominuse+1);
|
||||
INT32 maxscore = std::pow(symbolsperupgrade, symbolheadroominuse+2) - 1;
|
||||
|
||||
// CONS_Printf("min %d max %d\n", minscore, maxscore);
|
||||
|
||||
// We show the player successive combos with the same leading symbol, but we
|
||||
// waht them to feel intuitively like they're increasing each time.
|
||||
// Maxscore and minscore have been mapped to the correct power-of-N, so any
|
||||
// point we pick between them will lead with the correct symbol once we adjust
|
||||
// for symbol headroom. Pick a point that's appropriate for how "far" into the
|
||||
// current symbol we are.
|
||||
fixed_t lobound = FRACUNIT * frac / boostspersymbol;
|
||||
fixed_t hibound = FRACUNIT * (frac+1) / boostspersymbol;
|
||||
fixed_t roll = P_RandomRange(PR_NUISANCE, lobound, hibound);
|
||||
|
||||
INT32 margin = Easing_Linear(roll, minscore, maxscore); // The score we're trying to draw a garbage stack for.
|
||||
|
||||
INT32 margindigits[5];
|
||||
memset(margindigits, -1, sizeof(margindigits));
|
||||
|
||||
INT32 nummargindigits = 0;
|
||||
|
||||
// CONS_Printf("margin %d min %d max %d roll %d shiu %d ms %d\n", margin, minscore, maxscore, roll, symbolheadroominuse, minsymbol);
|
||||
|
||||
if (rawmargin/boostspersymbol >= (MARGINLEVELS-1))
|
||||
{
|
||||
// Capped out. Show 5 Chaos.
|
||||
nummargindigits = 5;
|
||||
for(UINT8 i = 0; i < nummargindigits; i++)
|
||||
{
|
||||
margindigits[i] = MARGINLEVELS-1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Subtract powers of N from our chosen score to create a decent-enough-looking
|
||||
// garbage stack, then queue up the right patches to be drawn, shifting all the math
|
||||
// up by "minsymbol"—remember, once maxsymbol goes above symbolheadroom, we are doing
|
||||
// a low-precision version of the math that ignores low enough symbols.
|
||||
while (margin > 0)
|
||||
{
|
||||
INT32 significant_margin = 0;
|
||||
for (UINT8 i = symbolheadroominuse+1; i >= 0; i--)
|
||||
{
|
||||
INT32 test = std::pow(symbolsperupgrade, i);
|
||||
// CONS_Printf("testing %d (%d)\n", i, test);
|
||||
if (margin >= test)
|
||||
{
|
||||
significant_margin = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
INT32 index = significant_margin;
|
||||
|
||||
margindigits[nummargindigits] = index + minsymbol - 1;
|
||||
// CONS_Printf("digit %d %d\n", nummargindigits, margindigits[nummargindigits]);
|
||||
|
||||
nummargindigits++;
|
||||
|
||||
// CONS_Printf("margin was %d ", margin);
|
||||
margin -= std::pow(symbolsperupgrade, index);
|
||||
// CONS_Printf("is %d\n", margin);
|
||||
|
||||
if (nummargindigits >= 3 + frac)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
INT32 marginspacing = std::min(6, duel_marginanim);
|
||||
INT32 marginx = ((nummargindigits-1) * marginspacing)/2;
|
||||
|
||||
for (INT32 i = nummargindigits - 1; i >= 0; i--)
|
||||
{
|
||||
// CONS_Printf("draw %d - %d\n", i, margindigits[i]);
|
||||
V_DrawScaledPatch(basex + marginx, basey, flags, kp_duel_margin[margindigits[i]]);
|
||||
marginx -= marginspacing;
|
||||
}
|
||||
}
|
||||
|
||||
static INT32 easedallyscore = 0;
|
||||
|
|
@ -3480,6 +3614,9 @@ static void K_drawKartTeamScores(void)
|
|||
UINT16 enemyscore = g_teamscores[enemies];
|
||||
UINT16 totalscore = allyscore + enemyscore;
|
||||
|
||||
if (totalscore == 0)
|
||||
return;
|
||||
|
||||
using srb2::Draw;
|
||||
srb2::Draw::Font scorefont = Draw::Font::kTimer;
|
||||
|
||||
|
|
@ -3535,7 +3672,7 @@ static void K_drawKartTeamScores(void)
|
|||
{
|
||||
INT32 delta = abs(easedallyscore - allyscore); // how wrong is display score?
|
||||
|
||||
if (scorechangecooldown == 0)
|
||||
if (scorechangecooldown == 0 && delta)
|
||||
{
|
||||
if (allyscore > easedallyscore)
|
||||
{
|
||||
|
|
@ -3702,6 +3839,11 @@ static void K_drawKartTeamScores(void)
|
|||
*/
|
||||
}
|
||||
|
||||
static boolean K_DrawingLaps()
|
||||
{
|
||||
return (numlaps != 1 && !K_InRaceDuel() && (UINT16)stplyr->exp != UINT16_MAX);
|
||||
}
|
||||
|
||||
static boolean K_drawKartLaps(void)
|
||||
{
|
||||
INT32 splitflags = V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN;
|
||||
|
|
@ -4141,7 +4283,16 @@ static void K_drawKartAccessibilityIcons(boolean gametypeinfoshown, INT32 fx)
|
|||
}
|
||||
else
|
||||
{
|
||||
fx = LAPS_X+44;
|
||||
fx = LAPS_X + 33;
|
||||
|
||||
if ((gametyperules & (GTR_BUMPERS|GTR_CIRCUIT)) == GTR_BUMPERS)
|
||||
fx -= 14;
|
||||
|
||||
if (K_DrawingLaps())
|
||||
{
|
||||
fx += 30;
|
||||
}
|
||||
|
||||
fy = LAPS_Y;
|
||||
if (R_GetViewNumber() & 1) // If we are not P1 or P3...
|
||||
{
|
||||
|
|
@ -7113,35 +7264,39 @@ static void K_DrawMessageFeed(void)
|
|||
|
||||
text.font(Draw::Font::kMenu);
|
||||
|
||||
UINT8 x = BASEVIDWIDTH/2;
|
||||
UINT8 y = 10;
|
||||
UINT32 vw = vid.width / vid.dupx;
|
||||
UINT32 vh = vid.height / vid.dupy;
|
||||
|
||||
UINT32 x = vw / 2;
|
||||
UINT32 y = 10;
|
||||
|
||||
SINT8 shift = 0;
|
||||
if (r_splitscreen >= 2)
|
||||
{
|
||||
text.font(Draw::Font::kThin);
|
||||
shift = -2;
|
||||
|
||||
x = BASEVIDWIDTH/4;
|
||||
x = vw/4;
|
||||
y = 5;
|
||||
|
||||
if (i % 2)
|
||||
x += BASEVIDWIDTH/2;
|
||||
x += vw / 2;
|
||||
|
||||
if (i >= 2)
|
||||
y += BASEVIDHEIGHT / 2;
|
||||
y += vh / 2;
|
||||
}
|
||||
else if (r_splitscreen >= 1)
|
||||
{
|
||||
y = 5;
|
||||
|
||||
if (i >= 1)
|
||||
y += BASEVIDHEIGHT / 2;
|
||||
y += vh / 2;
|
||||
}
|
||||
|
||||
UINT16 sw = text.width();
|
||||
|
||||
K_DrawSticker(x - sw/2, y, sw, 0, true);
|
||||
Draw(x, y+shift).align(Draw::Align::kCenter).text(text);
|
||||
K_DrawSticker(x - sw/2, y, sw, V_SNAPTOTOP|V_SNAPTOLEFT, true);
|
||||
Draw(x, y+shift).align(Draw::Align::kCenter).flags(V_SNAPTOTOP|V_SNAPTOLEFT).text(text);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ extern "C" {
|
|||
|
||||
#define POS_DELAY_TIME 10
|
||||
|
||||
#define MARGINLEVELS 24
|
||||
|
||||
extern INT32 MINI_X, MINI_Y;
|
||||
|
||||
struct trackingResult_t
|
||||
|
|
|
|||
|
|
@ -143,6 +143,8 @@ struct TargetTracking
|
|||
return false;
|
||||
|
||||
default:
|
||||
if (K_IsPickMeUpItem(mobj->type))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -277,28 +279,17 @@ private:
|
|||
{{6, 2, {kp_spraycantarget_far[1]}, V_ADD}}, // 4P
|
||||
}},
|
||||
};
|
||||
|
||||
case MT_JAWZ:
|
||||
case MT_JAWZ_SHIELD:
|
||||
case MT_ORBINAUT:
|
||||
case MT_ORBINAUT_SHIELD:
|
||||
case MT_DROPTARGET:
|
||||
case MT_DROPTARGET_SHIELD:
|
||||
case MT_LANDMINE:
|
||||
case MT_BANANA:
|
||||
case MT_BANANA_SHIELD:
|
||||
case MT_GACHABOM:
|
||||
case MT_EGGMANITEM:
|
||||
case MT_EGGMANITEM_SHIELD:
|
||||
case MT_BUBBLESHIELDTRAP:
|
||||
return {
|
||||
{ // Near
|
||||
{2, TICRATE/2, {kp_pickmeup}, 0}, // 1P
|
||||
{{2, TICRATE/2, {kp_pickmeup}, 0}}, // 4P
|
||||
},
|
||||
};
|
||||
|
||||
default:
|
||||
if (K_IsPickMeUpItem(mobj->type))
|
||||
{
|
||||
return {
|
||||
{ // Near
|
||||
{2, TICRATE/2, {kp_pickmeup}, 0}, // 1P
|
||||
{{2, TICRATE/2, {kp_pickmeup}, 0}}, // 4P
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
{ // Near
|
||||
{8, 2, {kp_capsuletarget_near[0]}}, // 1P
|
||||
|
|
@ -902,32 +893,17 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player)
|
|||
if (tracking)
|
||||
{
|
||||
fixed_t itemOffset = 36*mobj->scale;
|
||||
switch (mobj->type)
|
||||
|
||||
if (K_IsPickMeUpItem(mobj->type))
|
||||
{
|
||||
case MT_JAWZ:
|
||||
case MT_JAWZ_SHIELD:
|
||||
case MT_ORBINAUT:
|
||||
case MT_ORBINAUT_SHIELD:
|
||||
case MT_DROPTARGET:
|
||||
case MT_DROPTARGET_SHIELD:
|
||||
case MT_LANDMINE:
|
||||
case MT_BANANA:
|
||||
case MT_BANANA_SHIELD:
|
||||
case MT_GACHABOM:
|
||||
case MT_BUBBLESHIELDTRAP:
|
||||
case MT_EGGMANITEM:
|
||||
case MT_EGGMANITEM_SHIELD:
|
||||
if (stplyr->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
pos.z -= itemOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.z += itemOffset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (stplyr->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
pos.z -= itemOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.z += itemOffset;
|
||||
}
|
||||
}
|
||||
|
||||
K_ObjectTracking(&tr.result, &pos, false);
|
||||
|
|
|
|||
52
src/k_kart.c
52
src/k_kart.c
|
|
@ -497,7 +497,7 @@ fixed_t K_GetKartGameSpeedScalar(SINT8 value)
|
|||
value = 3;
|
||||
|
||||
fixed_t base = ((13 + (3*value)) << FRACBITS) / 16;
|
||||
fixed_t duel = overtimecheckpoints*(1<<FRACBITS)/16;
|
||||
fixed_t duel = overtimecheckpoints*(1<<FRACBITS)/32;
|
||||
|
||||
return base + duel;
|
||||
}
|
||||
|
|
@ -9781,6 +9781,21 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
player->invincibilitytimer--;
|
||||
}
|
||||
|
||||
// The precise ordering of start-of-level made me want to cut my head off,
|
||||
// so let's try this instead. Whatever!
|
||||
if (leveltime <= starttime || player->gradingpointnum == 0)
|
||||
{
|
||||
if ((gametyperules & GTR_SPHERES)
|
||||
|| (gametyperules & GTR_CATCHER)
|
||||
|| G_TimeAttackStart()
|
||||
|| (gametype == GT_TUTORIAL)
|
||||
|| !M_NotFreePlay()
|
||||
|| (K_GetNumWaypoints() == 0))
|
||||
player->cangrabitems = EARLY_ITEM_FLICKER;
|
||||
else
|
||||
player->cangrabitems = 0;
|
||||
}
|
||||
|
||||
if (player->cangrabitems && player->cangrabitems <= EARLY_ITEM_FLICKER)
|
||||
player->cangrabitems++;
|
||||
|
||||
|
|
@ -11455,6 +11470,14 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
|
|||
turnfixed = FixedMul(turnfixed, 2*FRACUNIT); // Base increase to turning
|
||||
}
|
||||
|
||||
/*
|
||||
if (overtimecheckpoints)
|
||||
{
|
||||
fixed_t assistpercent = FRACUNIT * overtimecheckpoints / 32;
|
||||
turnfixed += FixedMul(Easing_Linear(assistpercent, 0, FRACUNIT/2), turnfixed);
|
||||
}
|
||||
*/
|
||||
|
||||
if (player->drift != 0 && P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (G_CompatLevel(0x000A))
|
||||
|
|
@ -15772,6 +15795,29 @@ void K_BotHitPenalty(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
boolean K_IsPickMeUpItem(mobjtype_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MT_JAWZ:
|
||||
case MT_JAWZ_SHIELD:
|
||||
case MT_ORBINAUT:
|
||||
case MT_ORBINAUT_SHIELD:
|
||||
case MT_DROPTARGET:
|
||||
case MT_DROPTARGET_SHIELD:
|
||||
case MT_LANDMINE:
|
||||
case MT_BANANA:
|
||||
case MT_BANANA_SHIELD:
|
||||
case MT_GACHABOM:
|
||||
case MT_EGGMANITEM:
|
||||
case MT_EGGMANITEM_SHIELD:
|
||||
case MT_BUBBLESHIELDTRAP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean K_PickUp(player_t *player, mobj_t *picked)
|
||||
{
|
||||
SINT8 type = -1;
|
||||
|
|
@ -15862,7 +15908,7 @@ static boolean K_PickUp(player_t *player, mobj_t *picked)
|
|||
}
|
||||
|
||||
// ACHTUNG this destroys items when returning true, make sure to bail out
|
||||
boolean K_TryPickMeUp(mobj_t *m1, mobj_t *m2)
|
||||
boolean K_TryPickMeUp(mobj_t *m1, mobj_t *m2, boolean allowHostile)
|
||||
{
|
||||
if (!m1 || P_MobjWasRemoved(m1))
|
||||
return false;
|
||||
|
|
@ -15897,7 +15943,7 @@ boolean K_TryPickMeUp(mobj_t *m1, mobj_t *m2)
|
|||
if (inflictor->target->player && G_SameTeam(inflictor->target->player, victim->player))
|
||||
allied = true;
|
||||
|
||||
if (!allied)
|
||||
if (!allied && !allowHostile)
|
||||
return false;
|
||||
|
||||
// CONS_Printf("target check passed\n");
|
||||
|
|
|
|||
|
|
@ -325,7 +325,9 @@ boolean K_LegacyRingboost(player_t *player);
|
|||
|
||||
void K_BotHitPenalty(player_t *player);
|
||||
|
||||
boolean K_TryPickMeUp(mobj_t *m1, mobj_t *m2);
|
||||
boolean K_IsPickMeUpItem(mobjtype_t type);
|
||||
|
||||
boolean K_TryPickMeUp(mobj_t *m1, mobj_t *m2, boolean allowHostile);
|
||||
|
||||
fixed_t K_TeamComebackMultiplier(player_t *player);
|
||||
|
||||
|
|
|
|||
|
|
@ -411,7 +411,6 @@ void Obj_SSGobletMobjThink(mobj_t* mo);
|
|||
void Obj_SSLampMapThingSpawn(mobj_t* mo, mapthing_t* mt);
|
||||
void Obj_SSWindowMapThingSpawn(mobj_t* mo, mapthing_t* mt);
|
||||
void Obj_SLSTMaceMobjThink(mobj_t* mo);
|
||||
void Obj_SSBumperTouchSpecial(mobj_t* special, mobj_t* toucher);
|
||||
void Obj_SSBumperMobjSpawn(mobj_t* mo);
|
||||
void Obj_SSChainMobjThink(mobj_t* mo);
|
||||
void Obj_SSGachaTargetMobjSpawn(mobj_t* mo);
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ typedef enum
|
|||
PR_ITEM_SPAWNER = PROLDDEMO, // Battle mode item spawners
|
||||
PR_TEAMS, // Teamplay shuffling
|
||||
|
||||
PR_NUISANCE, // Margin Boost HUD
|
||||
|
||||
PRNUMSYNCED,
|
||||
|
||||
PR_INTERPHUDRANDOM = PRNUMSYNCED, // Interpolation-accomodating HUD randomisation
|
||||
|
|
|
|||
|
|
@ -72,6 +72,24 @@ static boolean input_routine(INT32)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void init_routine(void)
|
||||
{
|
||||
if (!netgame)
|
||||
{
|
||||
S_SoundInputSetEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean quit_routine(void)
|
||||
{
|
||||
if (!netgame)
|
||||
{
|
||||
S_SoundInputSetEnabled(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
menu_t OPTIONS_VoiceDef = {
|
||||
sizeof (OPTIONS_Voice) / sizeof (menuitem_t),
|
||||
&OPTIONS_MainDef,
|
||||
|
|
@ -85,7 +103,7 @@ menu_t OPTIONS_VoiceDef = {
|
|||
draw_routine,
|
||||
M_DrawOptionsCogs,
|
||||
tick_routine,
|
||||
NULL,
|
||||
NULL,
|
||||
init_routine,
|
||||
quit_routine,
|
||||
input_routine,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ struct Visual : Mobj
|
|||
}
|
||||
|
||||
move_origin(shield()->pos());
|
||||
scale(5 * shield()->follow()->scale() / 4);
|
||||
|
||||
renderflags = (renderflags & ~RF_DONTDRAW) |
|
||||
(shield()->state()->num() == S_INVISIBLE ? 0 : RF_DONTDRAW);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ struct Visual : Mobj
|
|||
}
|
||||
|
||||
move_origin(shield()->pos());
|
||||
scale(5 * shield()->follow()->scale() / 4);
|
||||
dispoffset = state()->num() == S_THNB1 ? -1 : 1;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (K_TryPickMeUp(t1, t2))
|
||||
if (K_TryPickMeUp(t1, t2, false))
|
||||
return true;
|
||||
|
||||
if (t1->type == MT_GARDENTOP)
|
||||
|
|
|
|||
|
|
@ -542,58 +542,6 @@ void Obj_SLSTMaceMobjThink(mobj_t* mo)
|
|||
}
|
||||
}
|
||||
|
||||
#define BUMPER_STRENGTH (56)
|
||||
|
||||
void Obj_SSBumperTouchSpecial(mobj_t* special, mobj_t* toucher)
|
||||
{
|
||||
angle_t hang;
|
||||
angle_t vang;
|
||||
fixed_t str;
|
||||
int i;
|
||||
|
||||
hang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y);
|
||||
vang = 0;
|
||||
|
||||
if (P_IsObjectOnGround(toucher) == false)
|
||||
{
|
||||
vang = R_PointToAngle2(
|
||||
FixedHypot(special->x, special->y), special->z + (special->height >> 1),
|
||||
FixedHypot(toucher->x, toucher->y), toucher->z + (toucher->height >> 1)
|
||||
);
|
||||
}
|
||||
|
||||
str = (BUMPER_STRENGTH * special->scale) >> 1;
|
||||
|
||||
toucher->momx = FixedMul(FixedMul(str, FCOS(hang)), abs(FCOS(vang)));
|
||||
toucher->momy = FixedMul(FixedMul(str, FSIN(hang)), abs(FCOS(vang)));
|
||||
toucher->momz = FixedMul(str, FSIN(vang));
|
||||
|
||||
if (toucher->player)
|
||||
{
|
||||
if (toucher->player->tiregrease == 0)
|
||||
{
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
mobj_t *grease = P_SpawnMobjFromMobj(toucher, 0, 0, 0, MT_TIREGREASE);
|
||||
P_SetTarget(&grease->target, toucher);
|
||||
grease->angle = toucher->angle;
|
||||
grease->extravalue1 = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (toucher->player->tiregrease < 2*TICRATE) // greasetics
|
||||
{
|
||||
toucher->player->tiregrease = 2*TICRATE;
|
||||
}
|
||||
}
|
||||
|
||||
if (special->state != &states[special->info->seestate])
|
||||
{
|
||||
S_StartSound(special, special->info->deathsound);
|
||||
P_SetMobjState(special, special->info->seestate);
|
||||
}
|
||||
}
|
||||
|
||||
void Obj_SSBumperMobjSpawn(mobj_t* mo)
|
||||
{
|
||||
mo->shadowscale = FRACUNIT;
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ void A_BlendEyePuyoHack(mobj_t *actor);
|
|||
void A_MakeSSCandle(mobj_t *actor);
|
||||
void A_HologramRandomTranslucency(mobj_t *actor);
|
||||
void A_SSChainShatter(mobj_t *actor);
|
||||
void A_GenericBumper(mobj_t *actor);
|
||||
|
||||
//for p_enemy.c
|
||||
|
||||
|
|
@ -12668,3 +12669,54 @@ void A_SSChainShatter(mobj_t* actor)
|
|||
|
||||
actor->fuse = 1;
|
||||
}
|
||||
|
||||
// var1 = If -1, triggered by collision event
|
||||
// var2 = Strength value
|
||||
//
|
||||
// mobjinfo dependencies:
|
||||
// - deathsound - bumper noise
|
||||
// - seestate - bumper flashing state
|
||||
//
|
||||
void A_GenericBumper(mobj_t* actor)
|
||||
{
|
||||
if (var1 != -1)
|
||||
return;
|
||||
|
||||
mobj_t *other = actor->target;
|
||||
|
||||
if (!other)
|
||||
return;
|
||||
|
||||
// This code was ported from Lua
|
||||
// Original was Balloon Park's bumpers?
|
||||
INT32 hang = R_PointToAngle2(
|
||||
actor->x, actor->y,
|
||||
other->x, other->y
|
||||
);
|
||||
|
||||
INT32 vang = 0;
|
||||
|
||||
if (!P_IsObjectOnGround(other))
|
||||
{
|
||||
vang = R_PointToAngle2(
|
||||
FixedHypot(actor->x, actor->y), actor->z + (actor->height / 2),
|
||||
FixedHypot(other->x, other->y), other->z + (other->height / 2)
|
||||
);
|
||||
}
|
||||
|
||||
INT32 baseStrength = abs(astate->var2);
|
||||
fixed_t strength = (baseStrength * actor->scale) / 2;
|
||||
|
||||
other->momx = FixedMul(FixedMul(strength, FCOS(hang)), abs(FCOS(vang)));
|
||||
other->momy = FixedMul(FixedMul(strength, FSIN(hang)), abs(FCOS(vang)));
|
||||
other->momz = FixedMul(strength, FSIN(vang));
|
||||
|
||||
if (other->player)
|
||||
K_SetTireGrease(other->player, max(other->player->tiregrease, 2*TICRATE));
|
||||
|
||||
if (actor->state != &states[actor->info->seestate])
|
||||
{
|
||||
S_StartSound(actor, actor->info->deathsound);
|
||||
P_SetMobjState(actor, actor->info->seestate);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -667,7 +667,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (!player->mo || player->spectator)
|
||||
return;
|
||||
|
||||
if (K_TryPickMeUp(special, toucher))
|
||||
if (K_TryPickMeUp(special, toucher, false))
|
||||
return;
|
||||
|
||||
// attach to player!
|
||||
|
|
@ -1083,10 +1083,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
Obj_TrickBalloonTouchSpecial(special, toucher);
|
||||
return;
|
||||
|
||||
case MT_SEALEDSTAR_BUMPER:
|
||||
Obj_SSBumperTouchSpecial(special, toucher);
|
||||
return;
|
||||
|
||||
case MT_PULLUPHOOK:
|
||||
Obj_PulleyHookTouch(special, toucher);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -612,6 +612,9 @@ void P_InitTIDHash(void);
|
|||
void P_AddThingTID(mobj_t *mo);
|
||||
void P_RemoveThingTID(mobj_t *mo);
|
||||
void P_SetThingTID(mobj_t *mo, mtag_t tid);
|
||||
|
||||
// This function cannot be safely called after *i is removed!
|
||||
// Please call at start of loops if *i is to be mutated
|
||||
mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator);
|
||||
|
||||
void P_DeleteMobjStringArgs(mobj_t *mobj);
|
||||
|
|
|
|||
14
src/p_map.c
14
src/p_map.c
|
|
@ -1552,7 +1552,19 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
if (!K_PuntCollide(thing, g_tm.thing))
|
||||
{
|
||||
K_KartSolidBounce(g_tm.thing, thing);
|
||||
state_t *st = &states[thing->info->spawnstate];
|
||||
|
||||
if (st->action.acp1 == A_GenericBumper)
|
||||
{
|
||||
P_SetTarget(&thing->target, g_tm.thing);
|
||||
|
||||
var1 = -1;
|
||||
var2 = 0;
|
||||
astate = st;
|
||||
st->action.acp1(thing);
|
||||
}
|
||||
else
|
||||
K_KartSolidBounce(g_tm.thing, thing);
|
||||
}
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15417,6 +15417,8 @@ void P_SetThingTID(mobj_t *mo, mtag_t tid)
|
|||
//
|
||||
// P_FindMobjFromTID
|
||||
// Mobj tag search function.
|
||||
// This function cannot be safely called after *i is removed!
|
||||
// Please call at start of loops if *i is to be mutated
|
||||
//
|
||||
mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3275,8 +3275,13 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
|
|||
return false;
|
||||
}
|
||||
|
||||
while ((targetThing = P_FindMobjFromTID(args[1], targetThing, mo)) != NULL)
|
||||
mobj_t *next = P_FindMobjFromTID(args[1], targetThing, mo);
|
||||
|
||||
while ((targetThing = next) != NULL)
|
||||
{
|
||||
// First in case of deletion. (Can't check for state == S_NULL because of A_ calls, etc)
|
||||
next = P_FindMobjFromTID(args[1], targetThing, mo);
|
||||
|
||||
if (targetThing->player != NULL)
|
||||
{
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -3763,7 +3763,6 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
}
|
||||
player->spectator = false;
|
||||
player->pflags &= ~PF_WANTSTOJOIN;
|
||||
player->spectatewait = 0;
|
||||
player->team = TEAM_UNASSIGNED; // We will auto-assign later.
|
||||
player->playerstate = PST_REBORN;
|
||||
player->enteredGame = true;
|
||||
|
|
@ -3778,6 +3777,10 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
// a surprise tool that will help us later...
|
||||
text = va("\x82*%s entered the game.", player_names[player-players]);
|
||||
|
||||
if (P_IsMachineLocalPlayer(player) && player->spectatewait > TICRATE)
|
||||
S_StartSound(NULL, sfx_s3ka9);
|
||||
player->spectatewait = 0;
|
||||
|
||||
HU_AddChatText(text, false);
|
||||
return true; // no more player->mo, cannot continue.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,7 +198,6 @@ static void (*music_fade_callback)();
|
|||
|
||||
static SDL_AudioDeviceID g_device_id;
|
||||
static SDL_AudioDeviceID g_input_device_id;
|
||||
static boolean g_input_device_paused;
|
||||
|
||||
void* I_GetSfx(sfxinfo_t* sfx)
|
||||
{
|
||||
|
|
@ -999,14 +998,14 @@ void I_UpdateAudioRecorder(void)
|
|||
|
||||
boolean I_SoundInputIsEnabled(void)
|
||||
{
|
||||
return g_input_device_id != 0 && !g_input_device_paused;
|
||||
return g_input_device_id != 0;
|
||||
}
|
||||
|
||||
boolean I_SoundInputSetEnabled(boolean enabled)
|
||||
{
|
||||
if (g_input_device_id == 0 && enabled)
|
||||
{
|
||||
if (SDL_GetNumAudioDevices(true) == 0)
|
||||
if (!sound_started || SDL_GetNumAudioDevices(true) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1023,21 +1022,17 @@ boolean I_SoundInputSetEnabled(boolean enabled)
|
|||
CONS_Alert(CONS_WARNING, "Failed to open input audio device: %s\n", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
g_input_device_paused = true;
|
||||
}
|
||||
|
||||
if (enabled && g_input_device_paused)
|
||||
{
|
||||
SDL_PauseAudioDevice(g_input_device_id, SDL_FALSE);
|
||||
g_input_device_paused = false;
|
||||
}
|
||||
else if (!enabled && !g_input_device_paused)
|
||||
else if (g_input_device_id != 0 && !enabled)
|
||||
{
|
||||
SDL_PauseAudioDevice(g_input_device_id, SDL_TRUE);
|
||||
SDL_ClearQueuedAudio(g_input_device_id);
|
||||
g_input_device_paused = true;
|
||||
SDL_CloseAudioDevice(g_input_device_id);
|
||||
g_input_device_id = 0;
|
||||
}
|
||||
return !g_input_device_paused;
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
UINT32 I_SoundInputDequeueSamples(void *data, UINT32 len)
|
||||
|
|
|
|||
|
|
@ -2544,9 +2544,10 @@ void Y_StartIntermission(void)
|
|||
}
|
||||
|
||||
K_CashInPowerLevels();
|
||||
SV_BumpMatchStats();
|
||||
}
|
||||
|
||||
SV_BumpMatchStats();
|
||||
|
||||
if (!timer)
|
||||
{
|
||||
Y_EndIntermission();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue