mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
UCRP_UFOATTACKMETHOD
`Condition1 = UfoAttackMethod [type]`
- "smash a UFO Catcher using only [type]"
- Combine with `Prefix_SealedStar` or `Prefix_IsMap [special stage stage]`
- Shows up as "???"
- Types supported:
- `Boost` - "boost power" (sneakers)
- `Whip` - "Insta-Whip"
- `Banana` - "Bananas"
- `Orbinaut`- "Orbinauts"
- `Jawz` - "Jawz"
- `SPB` - "Self Propelled Bombs"
- Other types could be added on request, these were just the easy ones
In addition, the prototype for P_MobjWasRemoved was moved to `p_mobj.h`.
It's EXTREMELY important that we're able to safely check mobj pointers anywhere a mobj_t is possible to observe, without including the full `p_local.h`...
This commit is contained in:
parent
f0d1813752
commit
d11fe78e90
7 changed files with 139 additions and 10 deletions
|
|
@ -387,6 +387,18 @@ struct botvars_t
|
|||
|
||||
// player_t struct for round-specific condition tracking
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UFOD_GENERIC = 1,
|
||||
UFOD_BOOST = 1<<1,
|
||||
UFOD_WHIP = 1<<2,
|
||||
UFOD_BANANA = 1<<3,
|
||||
UFOD_ORBINAUT = 1<<4,
|
||||
UFOD_JAWZ = 1<<5,
|
||||
UFOD_SPB = 1<<6,
|
||||
// free up to and including 1<<31
|
||||
} ufodamaging_t;
|
||||
|
||||
struct roundconditions_t
|
||||
{
|
||||
// Reduce the number of checks by only updating when this is true
|
||||
|
|
@ -404,6 +416,8 @@ struct roundconditions_t
|
|||
|
||||
UINT8 hittrackhazard[((MAX_LAPS+1)/8) + 1];
|
||||
|
||||
ufodamaging_t ufodamaging;
|
||||
|
||||
mobjeflag_t wet_player;
|
||||
|
||||
// 32 triggers, one bit each, for map execution
|
||||
|
|
|
|||
|
|
@ -3007,6 +3007,25 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (fastcmp(params[0], "UFOATTACKMETHOD"))
|
||||
{
|
||||
PARAMCHECK(1);
|
||||
ty = UCRP_UFOATTACKMETHOD;
|
||||
|
||||
// See ufodamaging_t
|
||||
if ((offset=1) || fastcmp(params[1], "BOOST")
|
||||
|| (++offset && fastcmp(params[1], "WHIP"))
|
||||
|| (++offset && fastcmp(params[1], "BANANA"))
|
||||
|| (++offset && fastcmp(params[1], "ORBINAUT"))
|
||||
|| (++offset && fastcmp(params[1], "JAWZ"))
|
||||
|| (++offset && fastcmp(params[1], "SPB")))
|
||||
re = offset;
|
||||
else
|
||||
{
|
||||
deh_warning("Unknown attack method %s for condition ID %d", params[1], id+1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("Invalid condition name %s for condition ID %d", params[0], id+1);
|
||||
|
|
|
|||
47
src/m_cond.c
47
src/m_cond.c
|
|
@ -1683,6 +1683,16 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
return (!(player->roundconditions.hittrackhazard[requiredlap] & requiredbit) != (cn->requirement == 1));
|
||||
}
|
||||
|
||||
case UCRP_UFOATTACKMETHOD:
|
||||
return (
|
||||
specialstageinfo.valid == true
|
||||
&& (
|
||||
P_MobjWasRemoved(specialstageinfo.ufo)
|
||||
|| specialstageinfo.ufo->health <= 1
|
||||
)
|
||||
&& player->roundconditions.ufodamaging == (ufodamaging_t)(1<<cn->requirement)
|
||||
);
|
||||
|
||||
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
|
||||
|
|
@ -2377,6 +2387,43 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
return va("%s on lap %u", work, cn->extrainfo1);
|
||||
}
|
||||
|
||||
case UCRP_UFOATTACKMETHOD:
|
||||
{
|
||||
if (!gamedata->everseenspecial)
|
||||
return NULL;
|
||||
|
||||
work = NULL;
|
||||
|
||||
switch (cn->requirement)
|
||||
{
|
||||
case 1:
|
||||
work = "boost power";
|
||||
break;
|
||||
case 2:
|
||||
work = "Insta-Whip";
|
||||
break;
|
||||
case 3:
|
||||
work = "Bananas";
|
||||
break;
|
||||
case 4:
|
||||
work = "Orbinauts";
|
||||
break;
|
||||
case 5:
|
||||
work = "Jawz";
|
||||
break;
|
||||
case 6:
|
||||
work = "Self Propelled Bombs";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (work == NULL)
|
||||
return va("INVALID ATTACK CONDITION \"%d:%d\"", cn->type, cn->requirement);
|
||||
|
||||
return va("smash the UFO Catcher using only %s", work);
|
||||
}
|
||||
|
||||
case UCRP_WETPLAYER:
|
||||
return va("without %s %s",
|
||||
(cn->requirement & MFE_TOUCHWATER) ? "touching any" : "going into",
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ typedef enum
|
|||
|
||||
UCRP_TRACKHAZARD, // (Don't) get hit by a track hazard (maybe specific lap)
|
||||
|
||||
UCRP_UFOATTACKMETHOD, // Defeat a UFO Catcher using only one method
|
||||
|
||||
UCRP_WETPLAYER, // Don't touch [strictness] [fluid]
|
||||
} conditiontype_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -763,52 +763,80 @@ static void UFOKillPieces(mobj_t *ufo)
|
|||
|
||||
static UINT8 GetUFODamage(mobj_t *inflictor, UINT8 damageType)
|
||||
{
|
||||
UINT8 ret = 0;
|
||||
ufodamaging_t ufodamaging = UFOD_GENERIC;
|
||||
|
||||
if (inflictor != NULL && P_MobjWasRemoved(inflictor) == false)
|
||||
{
|
||||
switch (inflictor->type)
|
||||
{
|
||||
// Shields deal chip damage.
|
||||
case MT_JAWZ_SHIELD:
|
||||
{
|
||||
ufodamaging = UFOD_JAWZ;
|
||||
ret = 10;
|
||||
break;
|
||||
}
|
||||
case MT_ORBINAUT_SHIELD:
|
||||
{
|
||||
ufodamaging = UFOD_ORBINAUT;
|
||||
ret = 10;
|
||||
break;
|
||||
}
|
||||
case MT_INSTAWHIP:
|
||||
{
|
||||
// Shields deal chip damage.
|
||||
return 10;
|
||||
ufodamaging = UFOD_WHIP;
|
||||
ret = 10;
|
||||
break;
|
||||
}
|
||||
case MT_JAWZ:
|
||||
{
|
||||
// Thrown Jawz deal a bit extra.
|
||||
return 15;
|
||||
ufodamaging = UFOD_JAWZ;
|
||||
ret = 15;
|
||||
break;
|
||||
}
|
||||
case MT_ORBINAUT:
|
||||
{
|
||||
// Thrown orbinauts deal double damage.
|
||||
return 20;
|
||||
ufodamaging = UFOD_ORBINAUT;
|
||||
ret = 20;
|
||||
break;
|
||||
}
|
||||
case MT_SPB:
|
||||
{
|
||||
// SPB deals triple damage.
|
||||
return 30;
|
||||
ufodamaging |= UFOD_SPB;
|
||||
ret = 30;
|
||||
break;
|
||||
}
|
||||
case MT_BANANA:
|
||||
{
|
||||
ufodamaging = UFOD_BANANA;
|
||||
|
||||
// Banana snipes deal triple damage,
|
||||
// laid down bananas deal regular damage.
|
||||
if (inflictor->health > 1)
|
||||
{
|
||||
return 30;
|
||||
ret = 30;
|
||||
break;
|
||||
}
|
||||
|
||||
return 10;
|
||||
ret = 10;
|
||||
break;
|
||||
}
|
||||
case MT_PLAYER:
|
||||
{
|
||||
// Players deal damage relative to how many sneakers they used.
|
||||
return 15 * max(1, inflictor->player->numsneakers);
|
||||
ufodamaging = UFOD_BOOST;
|
||||
ret = 15 * max(1, inflictor->player->numsneakers);
|
||||
break;
|
||||
}
|
||||
case MT_SPECIAL_UFO:
|
||||
{
|
||||
// UFODebugSetHealth
|
||||
return 1;
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
|
@ -817,6 +845,23 @@ static UINT8 GetUFODamage(mobj_t *inflictor, UINT8 damageType)
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
// We have to iterate over all players, otherwise a player who gets exactly one hit in will trick the Challenges system.
|
||||
UINT8 i;
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (!playeringame[g_localplayers[i]])
|
||||
continue;
|
||||
if (players[g_localplayers[i]].spectator)
|
||||
continue;
|
||||
players[i].roundconditions.ufodamaging |= ufodamaging;
|
||||
players[i].roundconditions.checkthisframe = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
// Guess from damage type.
|
||||
switch (damageType & DMG_TYPEMASK)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -260,7 +260,6 @@ void P_RecalcPrecipInSector(sector_t *sector);
|
|||
void P_PrecipitationEffects(void);
|
||||
|
||||
void P_RemoveMobj(mobj_t *th);
|
||||
boolean P_MobjWasRemoved(const mobj_t *th);
|
||||
void P_RemoveSavegameMobj(mobj_t *th);
|
||||
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
|
||||
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
|
||||
|
|
|
|||
|
|
@ -509,6 +509,9 @@ struct precipmobj_t
|
|||
tic_t lastThink;
|
||||
};
|
||||
|
||||
// It's extremely important that all mobj_t*-reading code have access to this.
|
||||
boolean P_MobjWasRemoved(const mobj_t *th);
|
||||
|
||||
struct actioncache_t
|
||||
{
|
||||
actioncache_t *next;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue