mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-26 23:41:07 +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
|
||||
};
|
||||
|
||||
// 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
|
||||
struct skybox_t {
|
||||
mobj_t * viewpoint;
|
||||
|
|
@ -682,6 +697,7 @@ struct player_t
|
|||
#endif
|
||||
|
||||
sonicloopvars_t loop;
|
||||
roundconditions_t roundconditions;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -2617,6 +2617,45 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
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
|
||||
{
|
||||
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 kickstartaccel;
|
||||
|
||||
roundconditions_t roundconditions;
|
||||
boolean saveroundconditions;
|
||||
|
||||
score = players[player].score;
|
||||
lives = players[player].lives;
|
||||
ctfteam = players[player].ctfteam;
|
||||
|
|
@ -2461,6 +2464,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
khudfinish = 0;
|
||||
khudcardanimation = 0;
|
||||
starpostnum = 0;
|
||||
|
||||
saveroundconditions = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2509,6 +2514,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
starpostnum = players[player].starpostnum;
|
||||
|
||||
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)
|
||||
|
|
@ -2592,6 +2600,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
memcpy(&p->itemRoulette, &itemRoulette, sizeof (p->itemRoulette));
|
||||
memcpy(&p->respawn, &respawn, sizeof (p->respawn));
|
||||
|
||||
if (saveroundconditions)
|
||||
memcpy(&p->roundconditions, &roundconditions, sizeof (p->roundconditions));
|
||||
|
||||
if (follower)
|
||||
P_RemoveMobj(follower);
|
||||
|
||||
|
|
|
|||
|
|
@ -411,7 +411,12 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
// Banana snipe!
|
||||
if (t1->health > 1)
|
||||
{
|
||||
if (t1->target && t1->target->player)
|
||||
t1->target->player->roundconditions.landmine_dunk = true;
|
||||
|
||||
S_StartSound(t2, sfx_bsnipe);
|
||||
}
|
||||
|
||||
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)
|
||||
player->offroad = offroadstrength;
|
||||
|
||||
if (player->offroad > (2*offroadstrength) / TICRATE)
|
||||
player->roundconditions.touched_offroad = true;
|
||||
}
|
||||
else
|
||||
player->offroad = 0;
|
||||
|
|
@ -4065,7 +4068,11 @@ void K_ApplyTripWire(player_t *player, tripwirestate_t state)
|
|||
K_TumblePlayer(player, NULL, NULL);
|
||||
|
||||
if (state == TRIPSTATE_PASSED)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_ssa015);
|
||||
if (player->hyudorotimer > 0)
|
||||
player->roundconditions.tripwire_hyuu = true;
|
||||
}
|
||||
else if (state == TRIPSTATE_BLOCKED)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_kc40);
|
||||
|
|
@ -5731,6 +5738,9 @@ void K_DoSneaker(player_t *player, INT32 type)
|
|||
{
|
||||
const fixed_t intendedboost = FRACUNIT/2;
|
||||
|
||||
if (player->floorboost != 0)
|
||||
player->roundconditions.touched_sneakerpanel = true;
|
||||
|
||||
if (player->floorboost == 0 || player->floorboost == 3)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
case UCRP_WETPLAYER:
|
||||
{
|
||||
if (cn->extrainfo1)
|
||||
{
|
||||
char *l;
|
||||
|
||||
for (l = cn->stringvar; *l != '\0'; l++)
|
||||
{
|
||||
*l = tolower(*l);
|
||||
}
|
||||
|
||||
cn->extrainfo1 = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -773,6 +790,28 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
&& !K_CanChangeRules(false) // too easy to change cv_timelimit
|
||||
&& player->realtime < timelimitintics
|
||||
&& (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;
|
||||
}
|
||||
|
|
@ -1137,6 +1176,29 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
G_TicsToSeconds(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:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
12
src/m_cond.h
12
src/m_cond.h
|
|
@ -75,6 +75,18 @@ typedef enum
|
|||
UCRP_FINISHTIME, // Finish <= [time, tics]
|
||||
UCRP_FINISHTIMEEXACT, // Finish == [time, tics]
|
||||
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;
|
||||
|
||||
// Condition Set information
|
||||
|
|
|
|||
|
|
@ -1940,6 +1940,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
{
|
||||
case DMG_DEATHPIT:
|
||||
// Respawn kill types
|
||||
player->roundconditions.fell_off = true;
|
||||
K_DoIngameRespawn(player);
|
||||
return false;
|
||||
case DMG_SPECTATOR:
|
||||
|
|
@ -2025,6 +2026,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
{
|
||||
player_t *player;
|
||||
boolean force = false;
|
||||
boolean spbpop = false;
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
case MT_SPB:
|
||||
spbpop = (damagetype & DMG_TYPEMASK) == DMG_VOLTAGE;
|
||||
if (spbpop && source && source->player)
|
||||
{
|
||||
source->player->roundconditions.spb_neuter = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2076,7 +2086,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
if (!force)
|
||||
{
|
||||
if (!(target->type == MT_SPB && (damagetype & DMG_TYPEMASK) == DMG_VOLTAGE))
|
||||
if (!spbpop)
|
||||
{
|
||||
if (!(target->flags & MF_SHOOTABLE))
|
||||
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
|
||||
if ((damagetype & DMG_DEATHMASK))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3421,6 +3421,10 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
{
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -518,6 +518,11 @@ INT32 P_GivePlayerRings(player_t *player, INT32 num_rings)
|
|||
|
||||
player->rings += num_rings;
|
||||
|
||||
if (player->rings < 0)
|
||||
{
|
||||
player->roundconditions.debt_rings = true;
|
||||
}
|
||||
|
||||
return num_rings;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ TYPEDEF (discordRequest_t);
|
|||
// d_player.h
|
||||
TYPEDEF (respawnvars_t);
|
||||
TYPEDEF (botvars_t);
|
||||
TYPEDEF (roundconditions_t);
|
||||
TYPEDEF (skybox_t);
|
||||
TYPEDEF (itemroulette_t);
|
||||
TYPEDEF (player_t);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue