Update UCRP_UFOATTACKMETHOD into UCRP_TARGETATTACKMETHOD

Supports Prison Eggs and Gachabom now as well.
For the original behaviour, combine with the new UCRP_SMASHUFO.
This commit is contained in:
toaster 2023-10-17 21:03:20 +01:00
parent b91823540b
commit 01b97cb829
7 changed files with 124 additions and 58 deletions

View file

@ -396,8 +396,9 @@ typedef enum
UFOD_ORBINAUT = 1<<4,
UFOD_JAWZ = 1<<5,
UFOD_SPB = 1<<6,
UFOD_GACHABOM = 1<<7,
// free up to and including 1<<31
} ufodamaging_t;
} targetdamaging_t;
struct roundconditions_t
{
@ -416,7 +417,7 @@ struct roundconditions_t
UINT8 hittrackhazard[((MAX_LAPS+1)/8) + 1];
ufodamaging_t ufodamaging;
targetdamaging_t targetdamaging;
mobjeflag_t wet_player;

View file

@ -2896,7 +2896,8 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
else if ((offset=0) || fastcmp(params[0], "FINISHCOOL")
|| (++offset && fastcmp(params[0], "FINISHPERFECT"))
|| (++offset && fastcmp(params[0], "FINISHALLPRISONS"))
|| (++offset && fastcmp(params[0], "NOCONTEST")))
|| (++offset && fastcmp(params[0], "NOCONTEST"))
|| (++offset && fastcmp(params[0], "SMASHUFO")))
{
//PARAMCHECK(1);
ty = UCRP_FINISHCOOL + offset;
@ -3007,19 +3008,26 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
}
}
}
else if (fastcmp(params[0], "UFOATTACKMETHOD"))
else if (fastcmp(params[0], "TARGETATTACKMETHOD"))
{
PARAMCHECK(1);
ty = UCRP_UFOATTACKMETHOD;
ty = UCRP_TARGETATTACKMETHOD;
// 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;
// See targetdamaging_t
if (fastcmp(params[1], "BOOST"))
re = UFOD_BOOST;
else if (fastcmp(params[1], "WHIP"))
re = UFOD_WHIP;
else if (fastcmp(params[1], "BANANA"))
re = UFOD_BANANA;
else if (fastcmp(params[1], "ORBINAUT"))
re = UFOD_ORBINAUT;
else if (fastcmp(params[1], "JAWZ"))
re = UFOD_JAWZ;
else if (fastcmp(params[1], "SPB"))
re = UFOD_SPB;
else if (fastcmp(params[1], "GACHABOM"))
re = UFOD_GACHABOM;
else
{
deh_warning("Unknown attack method %s for condition ID %d", params[1], id+1);

View file

@ -1505,6 +1505,15 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
case UCRP_NOCONTEST:
return (player->pflags & PF_NOCONTEST);
case UCRP_SMASHUFO:
return (
specialstageinfo.valid == true
&& (
P_MobjWasRemoved(specialstageinfo.ufo)
|| specialstageinfo.ufo->health <= 1
)
);
case UCRP_MAKERETIRE:
{
// You can't "make" someone retire in coop.
@ -1683,15 +1692,8 @@ 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_TARGETATTACKMETHOD:
return (player->roundconditions.targetdamaging == (targetdamaging_t)cn->requirement);
case UCRP_WETPLAYER:
return (((player->roundconditions.wet_player & cn->requirement) == 0)
@ -2314,10 +2316,15 @@ static const char *M_GetConditionString(condition_t *cn)
case UCRP_FINISHPERFECT:
return "finish a perfect round";
case UCRP_FINISHALLPRISONS:
return "break every prison";
return "break every Prison Egg";
case UCRP_NOCONTEST:
return "NO CONTEST";
case UCRP_SMASHUFO:
if (!gamedata->everseenspecial)
return NULL;
return "smash the UFO Catcher";
case UCRP_MAKERETIRE:
{
if (cn->requirement < 0 || !skins[cn->requirement].realname[0])
@ -2387,7 +2394,7 @@ static const char *M_GetConditionString(condition_t *cn)
return va("%s on lap %u", work, cn->extrainfo1);
}
case UCRP_UFOATTACKMETHOD:
case UCRP_TARGETATTACKMETHOD:
{
if (!gamedata->everseenspecial)
return NULL;
@ -2396,24 +2403,28 @@ static const char *M_GetConditionString(condition_t *cn)
switch (cn->requirement)
{
case 1:
// See targetdamaging_t
case UFOD_BOOST:
work = "boost power";
break;
case 2:
case UFOD_WHIP:
work = "Insta-Whip";
break;
case 3:
case UFOD_BANANA:
work = "Bananas";
break;
case 4:
case UFOD_ORBINAUT:
work = "Orbinauts";
break;
case 5:
case UFOD_JAWZ:
work = "Jawz";
break;
case 6:
case UFOD_SPB:
work = "Self Propelled Bombs";
break;
case UFOD_GACHABOM:
work = "Gachabom";
break;
default:
break;
}
@ -2421,7 +2432,7 @@ static const char *M_GetConditionString(condition_t *cn)
if (work == NULL)
return va("INVALID ATTACK CONDITION \"%d:%d\"", cn->type, cn->requirement);
return va("smash the UFO Catcher using only %s", work);
return va("using only %s", work);
}
case UCRP_WETPLAYER:

View file

@ -97,6 +97,7 @@ typedef enum
UCRP_FINISHPERFECT, // Finish a perfect race
UCRP_FINISHALLPRISONS, // Break all prisons
UCRP_NOCONTEST, // No Contest
UCRP_SMASHUFO, // Smash the UFO Catcher
UCRP_MAKERETIRE, // Make another player of [skin] No Contest
@ -124,7 +125,7 @@ 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_TARGETATTACKMETHOD, // Break targets/UFO using only one method
UCRP_WETPLAYER, // Don't touch [strictness] [fluid]
} conditiontype_t;

View file

@ -764,7 +764,7 @@ static void UFOKillPieces(mobj_t *ufo)
static UINT8 GetUFODamage(mobj_t *inflictor, UINT8 damageType)
{
UINT8 ret = 0;
ufodamaging_t ufodamaging = UFOD_GENERIC;
targetdamaging_t targetdamaging = UFOD_GENERIC;
if (inflictor != NULL && P_MobjWasRemoved(inflictor) == false)
{
@ -773,46 +773,52 @@ static UINT8 GetUFODamage(mobj_t *inflictor, UINT8 damageType)
// Shields deal chip damage.
case MT_JAWZ_SHIELD:
{
ufodamaging = UFOD_JAWZ;
targetdamaging = UFOD_JAWZ;
ret = 10;
break;
}
case MT_ORBINAUT_SHIELD:
{
ufodamaging = UFOD_ORBINAUT;
targetdamaging = UFOD_ORBINAUT;
ret = 10;
break;
}
case MT_INSTAWHIP:
{
ufodamaging = UFOD_WHIP;
targetdamaging = UFOD_WHIP;
ret = 10;
break;
}
case MT_JAWZ:
{
// Thrown Jawz deal a bit extra.
ufodamaging = UFOD_JAWZ;
targetdamaging = UFOD_JAWZ;
ret = 15;
break;
}
case MT_ORBINAUT:
{
// Thrown orbinauts deal double damage.
ufodamaging = UFOD_ORBINAUT;
targetdamaging = UFOD_ORBINAUT;
ret = 20;
break;
}
case MT_GACHABOM:
{
// Thrown gachabom need to be tracked, but have no special damage value as of yet.
targetdamaging = UFOD_GACHABOM;
break;
}
case MT_SPB:
{
// SPB deals triple damage.
ufodamaging |= UFOD_SPB;
targetdamaging |= UFOD_SPB;
ret = 30;
break;
}
case MT_BANANA:
{
ufodamaging = UFOD_BANANA;
targetdamaging = UFOD_BANANA;
// Banana snipes deal triple damage,
// laid down bananas deal regular damage.
@ -828,7 +834,7 @@ static UINT8 GetUFODamage(mobj_t *inflictor, UINT8 damageType)
case MT_PLAYER:
{
// Players deal damage relative to how many sneakers they used.
ufodamaging = UFOD_BOOST;
targetdamaging = UFOD_BOOST;
ret = 15 * max(1, inflictor->player->numsneakers);
break;
}
@ -845,20 +851,9 @@ 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;
}
}
P_TrackRoundConditionTargetDamage(targetdamaging);
if (ret)
if (ret != 0)
return ret;
// Guess from damage type.

View file

@ -977,10 +977,21 @@ void P_TouchCheatcheck(mobj_t *post, player_t *player, boolean snaptopost)
player->cheatchecknum = post->health;
}
static void P_AddBrokenPrison(mobj_t *target, mobj_t *source)
void P_TrackRoundConditionTargetDamage(targetdamaging_t targetdamaging)
{
(void)target;
UINT8 i;
for (i = 0; i <= splitscreen; i++)
{
if (!playeringame[g_localplayers[i]])
continue;
if (players[g_localplayers[i]].spectator)
continue;
players[i].roundconditions.targetdamaging |= targetdamaging;
}
}
static void P_AddBrokenPrison(mobj_t *target, mobj_t *inflictor, mobj_t *source)
{
if (!battleprisons)
return;
@ -1002,6 +1013,43 @@ static void P_AddBrokenPrison(mobj_t *target, mobj_t *source)
K_SpawnBattlePoints(source->player, NULL, 1);
}
targetdamaging_t targetdamaging = UFOD_GENERIC;
if (P_MobjWasRemoved(inflictor) == true)
;
else switch (inflictor->type)
{
case MT_GACHABOM:
targetdamaging = UFOD_GACHABOM;
break;
case MT_ORBINAUT:
case MT_ORBINAUT_SHIELD:
targetdamaging = UFOD_ORBINAUT;
break;
case MT_BANANA:
targetdamaging = UFOD_BANANA;
break;
case MT_INSTAWHIP:
targetdamaging = UFOD_WHIP;
break;
// This is only accessible for MT_CDUFO's touch!
case MT_PLAYER:
targetdamaging = UFOD_BOOST;
break;
// The following can't be accessed in standard play...
// but the cost of tracking them here is trivial :D
case MT_JAWZ:
case MT_JAWZ_SHIELD:
targetdamaging = UFOD_JAWZ;
break;
case MT_SPB:
targetdamaging = UFOD_SPB;
break;
default:
break;
}
P_TrackRoundConditionTargetDamage(targetdamaging);
if (gamedata->prisoneggstothispickup)
{
gamedata->prisoneggstothispickup--;
@ -2008,7 +2056,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
S_StartSound(target, sfx_mbs60);
P_AddBrokenPrison(target, source);
P_AddBrokenPrison(target, inflictor, source);
}
break;
@ -2018,7 +2066,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->momz = -(3*mapobjectscale)/2;
target->fuse = 2*TICRATE;
P_AddBrokenPrison(target, source);
P_AddBrokenPrison(target, inflictor, source);
break;
case MT_BATTLEBUMPER:

View file

@ -546,6 +546,8 @@ void P_UpdateLastPickup(player_t *player, UINT8 type);
boolean P_CanPickupEmblem(player_t *player, INT32 emblemID);
boolean P_EmblemWasCollected(INT32 emblemID);
void P_TrackRoundConditionTargetDamage(targetdamaging_t targetdamaging);
//
// P_SPEC
//