mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-26 20:11:47 +00:00
roundconditions_t - State tracking for events which occour mid-match and don't stay that way
- Exists on every player struct to simplify writes, but A) not netsynced and B) only checked for local players
- Updated in the relevant locations - no centralised ticking at the moment
- Has a number of new associated conditions that require playing (UCRP's).
- The following require [True/False] as supplementary information.
- FallOff
- TouchOffroad
- TouchSneakerPanel
- RingDebt
- The following have no supplementary information because they're universally a specific achievement.
- TripwireHyuu
- SPBNeuter
- LandmineDunk
- HitMidair
- The following has specific requirements that can be set.
- WetPlayer [name of fluid]
- Append "Strict" to forbid even skimming the surface of the map's fluid.
This commit is contained in:
parent
d540921f78
commit
baeb48ca1f
11 changed files with 184 additions and 1 deletions
|
|
@ -333,6 +333,21 @@ struct botvars_t
|
||||||
tic_t spindashconfirm; // When high enough, they will try spindashing
|
tic_t spindashconfirm; // When high enough, they will try spindashing
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// player_t struct for round-specific condition tracking
|
||||||
|
|
||||||
|
struct roundconditions_t
|
||||||
|
{
|
||||||
|
// Trivial Yes/no events across multiple UCRP's
|
||||||
|
boolean fell_off;
|
||||||
|
boolean touched_offroad;
|
||||||
|
boolean touched_sneakerpanel;
|
||||||
|
boolean debt_rings;
|
||||||
|
boolean tripwire_hyuu;
|
||||||
|
boolean spb_neuter;
|
||||||
|
boolean landmine_dunk;
|
||||||
|
boolean hit_midair;
|
||||||
|
};
|
||||||
|
|
||||||
// player_t struct for all skybox variables
|
// player_t struct for all skybox variables
|
||||||
struct skybox_t {
|
struct skybox_t {
|
||||||
mobj_t * viewpoint;
|
mobj_t * viewpoint;
|
||||||
|
|
@ -682,6 +697,7 @@ struct player_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sonicloopvars_t loop;
|
sonicloopvars_t loop;
|
||||||
|
roundconditions_t roundconditions;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -2617,6 +2617,45 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((offset=0) || fastcmp(params[0], "FALLOFF")
|
||||||
|
|| (++offset && fastcmp(params[0], "TOUCHOFFROAD"))
|
||||||
|
|| (++offset && fastcmp(params[0], "TOUCHSNEAKERPANEL"))
|
||||||
|
|| (++offset && fastcmp(params[0], "RINGDEBT")))
|
||||||
|
{
|
||||||
|
PARAMCHECK(1);
|
||||||
|
ty = UCRP_FALLOFF + offset;
|
||||||
|
re = 1;
|
||||||
|
|
||||||
|
if (params[1][0] == 'F' || params[1][0] == 'N' || params[1][0] == '0')
|
||||||
|
re = 0;
|
||||||
|
}
|
||||||
|
else if ((offset=0) || fastcmp(params[0], "TRIPWIREHYUU")
|
||||||
|
|| (++offset && fastcmp(params[0], "SPBNEUTER"))
|
||||||
|
|| (++offset && fastcmp(params[0], "LANDMINEDUNK"))
|
||||||
|
|| (++offset && fastcmp(params[0], "HITMIDAIR")))
|
||||||
|
{
|
||||||
|
//PARAMCHECK(1);
|
||||||
|
ty = UCRP_TRIPWIREHYUU + offset;
|
||||||
|
}
|
||||||
|
else if (fastcmp(params[0], "WETPLAYER"))
|
||||||
|
{
|
||||||
|
PARAMCHECK(1);
|
||||||
|
ty = UCRP_WETPLAYER;
|
||||||
|
re = MFE_UNDERWATER;
|
||||||
|
x1 = 1;
|
||||||
|
stringvar = Z_StrDup(params[1]);
|
||||||
|
|
||||||
|
if (params[2])
|
||||||
|
{
|
||||||
|
if (fastcmp(params[2], "STRICT"))
|
||||||
|
re |= MFE_TOUCHWATER;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
deh_warning("liquid strictness requirement \"%s\" invalid for condition ID %d", params[2], id+1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
deh_warning("Invalid condition name %s for condition ID %d", params[0], id+1);
|
deh_warning("Invalid condition name %s for condition ID %d", params[0], id+1);
|
||||||
|
|
|
||||||
11
src/g_game.c
11
src/g_game.c
|
|
@ -2371,6 +2371,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
INT32 khudfault;
|
INT32 khudfault;
|
||||||
INT32 kickstartaccel;
|
INT32 kickstartaccel;
|
||||||
|
|
||||||
|
roundconditions_t roundconditions;
|
||||||
|
boolean saveroundconditions;
|
||||||
|
|
||||||
score = players[player].score;
|
score = players[player].score;
|
||||||
lives = players[player].lives;
|
lives = players[player].lives;
|
||||||
ctfteam = players[player].ctfteam;
|
ctfteam = players[player].ctfteam;
|
||||||
|
|
@ -2461,6 +2464,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
khudfinish = 0;
|
khudfinish = 0;
|
||||||
khudcardanimation = 0;
|
khudcardanimation = 0;
|
||||||
starpostnum = 0;
|
starpostnum = 0;
|
||||||
|
|
||||||
|
saveroundconditions = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -2509,6 +2514,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
starpostnum = players[player].starpostnum;
|
starpostnum = players[player].starpostnum;
|
||||||
|
|
||||||
pflags |= (players[player].pflags & (PF_STASIS|PF_ELIMINATED|PF_NOCONTEST|PF_FAULT|PF_LOSTLIFE));
|
pflags |= (players[player].pflags & (PF_STASIS|PF_ELIMINATED|PF_NOCONTEST|PF_FAULT|PF_LOSTLIFE));
|
||||||
|
|
||||||
|
memcpy(&roundconditions, &players[player].roundconditions, sizeof (roundconditions));
|
||||||
|
saveroundconditions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!betweenmaps)
|
if (!betweenmaps)
|
||||||
|
|
@ -2592,6 +2600,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
memcpy(&p->itemRoulette, &itemRoulette, sizeof (p->itemRoulette));
|
memcpy(&p->itemRoulette, &itemRoulette, sizeof (p->itemRoulette));
|
||||||
memcpy(&p->respawn, &respawn, sizeof (p->respawn));
|
memcpy(&p->respawn, &respawn, sizeof (p->respawn));
|
||||||
|
|
||||||
|
if (saveroundconditions)
|
||||||
|
memcpy(&p->roundconditions, &roundconditions, sizeof (p->roundconditions));
|
||||||
|
|
||||||
if (follower)
|
if (follower)
|
||||||
P_RemoveMobj(follower);
|
P_RemoveMobj(follower);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -411,7 +411,12 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
|
||||||
|
|
||||||
// Banana snipe!
|
// Banana snipe!
|
||||||
if (t1->health > 1)
|
if (t1->health > 1)
|
||||||
|
{
|
||||||
|
if (t1->target && t1->target->player)
|
||||||
|
t1->target->player->roundconditions.landmine_dunk = true;
|
||||||
|
|
||||||
S_StartSound(t2, sfx_bsnipe);
|
S_StartSound(t2, sfx_bsnipe);
|
||||||
|
}
|
||||||
|
|
||||||
if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD)
|
if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
10
src/k_kart.c
10
src/k_kart.c
|
|
@ -1118,6 +1118,9 @@ static void K_UpdateOffroad(player_t *player)
|
||||||
|
|
||||||
if (player->offroad > offroadstrength)
|
if (player->offroad > offroadstrength)
|
||||||
player->offroad = offroadstrength;
|
player->offroad = offroadstrength;
|
||||||
|
|
||||||
|
if (player->offroad > (2*offroadstrength) / TICRATE)
|
||||||
|
player->roundconditions.touched_offroad = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
player->offroad = 0;
|
player->offroad = 0;
|
||||||
|
|
@ -4065,7 +4068,11 @@ void K_ApplyTripWire(player_t *player, tripwirestate_t state)
|
||||||
K_TumblePlayer(player, NULL, NULL);
|
K_TumblePlayer(player, NULL, NULL);
|
||||||
|
|
||||||
if (state == TRIPSTATE_PASSED)
|
if (state == TRIPSTATE_PASSED)
|
||||||
|
{
|
||||||
S_StartSound(player->mo, sfx_ssa015);
|
S_StartSound(player->mo, sfx_ssa015);
|
||||||
|
if (player->hyudorotimer > 0)
|
||||||
|
player->roundconditions.tripwire_hyuu = true;
|
||||||
|
}
|
||||||
else if (state == TRIPSTATE_BLOCKED)
|
else if (state == TRIPSTATE_BLOCKED)
|
||||||
{
|
{
|
||||||
S_StartSound(player->mo, sfx_kc40);
|
S_StartSound(player->mo, sfx_kc40);
|
||||||
|
|
@ -5731,6 +5738,9 @@ void K_DoSneaker(player_t *player, INT32 type)
|
||||||
{
|
{
|
||||||
const fixed_t intendedboost = FRACUNIT/2;
|
const fixed_t intendedboost = FRACUNIT/2;
|
||||||
|
|
||||||
|
if (player->floorboost != 0)
|
||||||
|
player->roundconditions.touched_sneakerpanel = true;
|
||||||
|
|
||||||
if (player->floorboost == 0 || player->floorboost == 3)
|
if (player->floorboost == 0 || player->floorboost == 3)
|
||||||
{
|
{
|
||||||
const sfxenum_t normalsfx = sfx_cdfm01;
|
const sfxenum_t normalsfx = sfx_cdfm01;
|
||||||
|
|
|
||||||
62
src/m_cond.c
62
src/m_cond.c
|
|
@ -593,6 +593,23 @@ void M_UpdateConditionSetsPending(void)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case UCRP_WETPLAYER:
|
||||||
|
{
|
||||||
|
if (cn->extrainfo1)
|
||||||
|
{
|
||||||
|
char *l;
|
||||||
|
|
||||||
|
for (l = cn->stringvar; *l != '\0'; l++)
|
||||||
|
{
|
||||||
|
*l = tolower(*l);
|
||||||
|
}
|
||||||
|
|
||||||
|
cn->extrainfo1 = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -773,6 +790,28 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
||||||
&& !K_CanChangeRules(false) // too easy to change cv_timelimit
|
&& !K_CanChangeRules(false) // too easy to change cv_timelimit
|
||||||
&& player->realtime < timelimitintics
|
&& player->realtime < timelimitintics
|
||||||
&& (timelimitintics + extratimeintics + secretextratime - player->realtime) >= (unsigned)cn->requirement);
|
&& (timelimitintics + extratimeintics + secretextratime - player->realtime) >= (unsigned)cn->requirement);
|
||||||
|
|
||||||
|
case UCRP_FALLOFF:
|
||||||
|
return (player->roundconditions.fell_off == (cn->requirement == 1));
|
||||||
|
case UCRP_TOUCHOFFROAD:
|
||||||
|
return (player->roundconditions.touched_offroad == (cn->requirement == 1));
|
||||||
|
case UCRP_TOUCHSNEAKERPANEL:
|
||||||
|
return (player->roundconditions.touched_sneakerpanel == (cn->requirement == 1));
|
||||||
|
case UCRP_RINGDEBT:
|
||||||
|
return (!(gametyperules & GTR_SPHERES) && (player->roundconditions.debt_rings == (cn->requirement == 1)));
|
||||||
|
|
||||||
|
case UCRP_TRIPWIREHYUU:
|
||||||
|
return (player->roundconditions.tripwire_hyuu);
|
||||||
|
case UCRP_SPBNEUTER:
|
||||||
|
return (player->roundconditions.spb_neuter);
|
||||||
|
case UCRP_LANDMINEDUNK:
|
||||||
|
return (player->roundconditions.landmine_dunk);
|
||||||
|
case UCRP_HITMIDAIR:
|
||||||
|
return (player->roundconditions.hit_midair);
|
||||||
|
|
||||||
|
case UCRP_WETPLAYER:
|
||||||
|
return (((player->roundconditions.wet_player & cn->requirement) == 0)
|
||||||
|
|| player->roundconditions.fell_off); // Levels with water tend to texture their pits as water too
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1137,6 +1176,29 @@ static const char *M_GetConditionString(condition_t *cn)
|
||||||
G_TicsToSeconds(cn->requirement),
|
G_TicsToSeconds(cn->requirement),
|
||||||
G_TicsToCentiseconds(cn->requirement));
|
G_TicsToCentiseconds(cn->requirement));
|
||||||
|
|
||||||
|
case UCRP_FALLOFF:
|
||||||
|
return (cn->requirement == 1) ? "fall off the course" : "without falling off";
|
||||||
|
case UCRP_TOUCHOFFROAD:
|
||||||
|
return (cn->requirement == 1) ? "touch offroad" : "without touching any offroad";
|
||||||
|
case UCRP_TOUCHSNEAKERPANEL:
|
||||||
|
return (cn->requirement == 1) ? "touch a Sneaker Panel" : "without touching any Sneaker Panels";
|
||||||
|
case UCRP_RINGDEBT:
|
||||||
|
return (cn->requirement == 1) ? "go into Ring debt" : "without going into Ring debt";
|
||||||
|
|
||||||
|
case UCRP_TRIPWIREHYUU:
|
||||||
|
return "go through Tripwire after getting snared by Hyudoro";
|
||||||
|
case UCRP_SPBNEUTER:
|
||||||
|
return "shock a Self Propelled Bomb into submission";
|
||||||
|
case UCRP_LANDMINEDUNK:
|
||||||
|
return "dunk a Landmine on another racer's head";
|
||||||
|
case UCRP_HITMIDAIR:
|
||||||
|
return "hit another racer with a projectile while you're both in the air";
|
||||||
|
|
||||||
|
case UCRP_WETPLAYER:
|
||||||
|
return va("without %s %s",
|
||||||
|
(cn->requirement & MFE_TOUCHWATER) ? "touching any" : "going into",
|
||||||
|
cn->stringvar);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
src/m_cond.h
12
src/m_cond.h
|
|
@ -75,6 +75,18 @@ typedef enum
|
||||||
UCRP_FINISHTIME, // Finish <= [time, tics]
|
UCRP_FINISHTIME, // Finish <= [time, tics]
|
||||||
UCRP_FINISHTIMEEXACT, // Finish == [time, tics]
|
UCRP_FINISHTIMEEXACT, // Finish == [time, tics]
|
||||||
UCRP_FINISHTIMELEFT, // Finish with at least [time, tics] to spare
|
UCRP_FINISHTIMELEFT, // Finish with at least [time, tics] to spare
|
||||||
|
|
||||||
|
UCRP_FALLOFF, // Fall off (or don't)
|
||||||
|
UCRP_TOUCHOFFROAD, // Touch offroad (or don't)
|
||||||
|
UCRP_TOUCHSNEAKERPANEL, // Either touch sneaker panel (or don't)
|
||||||
|
UCRP_RINGDEBT, // Go into debt (or don't)
|
||||||
|
|
||||||
|
UCRP_TRIPWIREHYUU, // Go through tripwire with Hyudoro
|
||||||
|
UCRP_SPBNEUTER, // Kill an SPB with Lightning
|
||||||
|
UCRP_LANDMINEDUNK, // huh? you died? that's weird. all i did was try to hug you...
|
||||||
|
UCRP_HITMIDAIR, // Hit another player mid-air with a kartfielditem
|
||||||
|
|
||||||
|
UCRP_WETPLAYER, // Touch [fluid]
|
||||||
} conditiontype_t;
|
} conditiontype_t;
|
||||||
|
|
||||||
// Condition Set information
|
// Condition Set information
|
||||||
|
|
|
||||||
|
|
@ -1940,6 +1940,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
||||||
{
|
{
|
||||||
case DMG_DEATHPIT:
|
case DMG_DEATHPIT:
|
||||||
// Respawn kill types
|
// Respawn kill types
|
||||||
|
player->roundconditions.fell_off = true;
|
||||||
K_DoIngameRespawn(player);
|
K_DoIngameRespawn(player);
|
||||||
return false;
|
return false;
|
||||||
case DMG_SPECTATOR:
|
case DMG_SPECTATOR:
|
||||||
|
|
@ -2025,6 +2026,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
{
|
{
|
||||||
player_t *player;
|
player_t *player;
|
||||||
boolean force = false;
|
boolean force = false;
|
||||||
|
boolean spbpop = false;
|
||||||
|
|
||||||
INT32 laglength = 6;
|
INT32 laglength = 6;
|
||||||
|
|
||||||
|
|
@ -2058,6 +2060,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
Obj_MonitorOnDamage(target, inflictor, damage);
|
Obj_MonitorOnDamage(target, inflictor, damage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MT_SPB:
|
||||||
|
spbpop = (damagetype & DMG_TYPEMASK) == DMG_VOLTAGE;
|
||||||
|
if (spbpop && source && source->player)
|
||||||
|
{
|
||||||
|
source->player->roundconditions.spb_neuter = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2076,7 +2086,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
|
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
if (!(target->type == MT_SPB && (damagetype & DMG_TYPEMASK) == DMG_VOLTAGE))
|
if (!spbpop)
|
||||||
{
|
{
|
||||||
if (!(target->flags & MF_SHOOTABLE))
|
if (!(target->flags & MF_SHOOTABLE))
|
||||||
return false; // shouldn't happen...
|
return false; // shouldn't happen...
|
||||||
|
|
@ -2130,6 +2140,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inflictor && source && source->player)
|
||||||
|
{
|
||||||
|
if (P_IsKartFieldItem(source->type)
|
||||||
|
&& target->player->airtime > TICRATE/2
|
||||||
|
&& source->player->airtime > TICRATE/2)
|
||||||
|
source->player->roundconditions.hit_midair = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Instant-Death
|
// Instant-Death
|
||||||
if ((damagetype & DMG_DEATHMASK))
|
if ((damagetype & DMG_DEATHMASK))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3421,6 +3421,10 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->roundconditions.wet_player |= (mobj->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER|MFE_GOOWATER));
|
||||||
|
if (p->roundconditions.wet_player)
|
||||||
|
CONS_Printf("%u\n", p->roundconditions.wet_player);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobj->flags & MF_APPLYTERRAIN)
|
if (mobj->flags & MF_APPLYTERRAIN)
|
||||||
|
|
|
||||||
|
|
@ -518,6 +518,11 @@ INT32 P_GivePlayerRings(player_t *player, INT32 num_rings)
|
||||||
|
|
||||||
player->rings += num_rings;
|
player->rings += num_rings;
|
||||||
|
|
||||||
|
if (player->rings < 0)
|
||||||
|
{
|
||||||
|
player->roundconditions.debt_rings = true;
|
||||||
|
}
|
||||||
|
|
||||||
return num_rings;
|
return num_rings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ TYPEDEF (discordRequest_t);
|
||||||
// d_player.h
|
// d_player.h
|
||||||
TYPEDEF (respawnvars_t);
|
TYPEDEF (respawnvars_t);
|
||||||
TYPEDEF (botvars_t);
|
TYPEDEF (botvars_t);
|
||||||
|
TYPEDEF (roundconditions_t);
|
||||||
TYPEDEF (skybox_t);
|
TYPEDEF (skybox_t);
|
||||||
TYPEDEF (itemroulette_t);
|
TYPEDEF (itemroulette_t);
|
||||||
TYPEDEF (player_t);
|
TYPEDEF (player_t);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue