Gachabom initial pass

They simply use Kitchen Sink's item icon and Orbinaut's sprites.

The forward toss behavior needs fine-tuning to use more MT_BANANA style behavior.
This commit is contained in:
Sally Coolatta 2022-11-28 02:41:42 -05:00
parent a0bcd52bf1
commit 81cefa2697
15 changed files with 129 additions and 26 deletions

View file

@ -382,6 +382,7 @@ consvar_t cv_superring = CVAR_INIT ("superring", "On", CV_NETVAR, CV_OnOff,
consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR, CV_OnOff, NULL); consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_droptarget = CVAR_INIT ("droptarget", "On", CV_NETVAR, CV_OnOff, NULL); consvar_t cv_droptarget = CVAR_INIT ("droptarget", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_gardentop = CVAR_INIT ("gardentop", "On", CV_NETVAR, CV_OnOff, NULL); consvar_t cv_gardentop = CVAR_INIT ("gardentop", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_gachabom = CVAR_INIT ("gachabom", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR, CV_OnOff, NULL); consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR, CV_OnOff, NULL); consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR, CV_OnOff, NULL);
@ -389,6 +390,7 @@ consvar_t cv_triplebanana = CVAR_INIT ("triplebanana", "On", CV_NETVAR, CV_O
consvar_t cv_tripleorbinaut = CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR, CV_OnOff, NULL); consvar_t cv_tripleorbinaut = CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_quadorbinaut = CVAR_INIT ("quadorbinaut", "On", CV_NETVAR, CV_OnOff, NULL); consvar_t cv_quadorbinaut = CVAR_INIT ("quadorbinaut", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_dualjawz = CVAR_INIT ("dualjawz", "On", CV_NETVAR, CV_OnOff, NULL); consvar_t cv_dualjawz = CVAR_INIT ("dualjawz", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_triplegachabom = CVAR_INIT ("triplegachabom", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_kartspeed = CVAR_INIT ("gamespeed", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange); consvar_t cv_kartspeed = CVAR_INIT ("gamespeed", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange);
static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}}; static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}};

View file

@ -94,7 +94,8 @@ extern consvar_t
cv_superring, cv_superring,
cv_kitchensink, cv_kitchensink,
cv_droptarget, cv_droptarget,
cv_gardentop; cv_gardentop,
cv_gachabom;
extern consvar_t extern consvar_t
cv_dualsneaker, cv_dualsneaker,
@ -102,7 +103,8 @@ extern consvar_t
cv_triplebanana, cv_triplebanana,
cv_tripleorbinaut, cv_tripleorbinaut,
cv_quadorbinaut, cv_quadorbinaut,
cv_dualjawz; cv_dualjawz,
cv_triplegachabom;
extern consvar_t cv_kartspeed; extern consvar_t cv_kartspeed;
extern consvar_t cv_kartbumpers; extern consvar_t cv_kartbumpers;

View file

@ -154,7 +154,8 @@ Run this macro, then #undef FOREACH afterward
FOREACH (SUPERRING, 19),\ FOREACH (SUPERRING, 19),\
FOREACH (KITCHENSINK, 20),\ FOREACH (KITCHENSINK, 20),\
FOREACH (DROPTARGET, 21),\ FOREACH (DROPTARGET, 21),\
FOREACH (GARDENTOP, 22) FOREACH (GARDENTOP, 22),\
FOREACH (GACHABOM, 23)
typedef enum typedef enum
{ {
@ -171,6 +172,7 @@ typedef enum
KRITEM_TRIPLEORBINAUT, KRITEM_TRIPLEORBINAUT,
KRITEM_QUADORBINAUT, KRITEM_QUADORBINAUT,
KRITEM_DUALJAWZ, KRITEM_DUALJAWZ,
KRITEM_TRIPLEGACHABOM,
NUMKARTRESULTS NUMKARTRESULTS
} kartitems_t; } kartitems_t;

View file

@ -5374,6 +5374,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_SINK_SHIELD", "MT_SINK_SHIELD",
"MT_SINKTRAIL", "MT_SINKTRAIL",
"MT_GACHABOM",
"MT_DUELBOMB", // Duel mode bombs "MT_DUELBOMB", // Duel mode bombs
"MT_BATTLEBUMPER", // Battle Mode bumper "MT_BATTLEBUMPER", // Battle Mode bumper
@ -6778,6 +6780,7 @@ struct int_const_s const INT_CONST[] = {
{"KRITEM_TRIPLEORBINAUT",KRITEM_TRIPLEORBINAUT}, {"KRITEM_TRIPLEORBINAUT",KRITEM_TRIPLEORBINAUT},
{"KRITEM_QUADORBINAUT",KRITEM_QUADORBINAUT}, {"KRITEM_QUADORBINAUT",KRITEM_QUADORBINAUT},
{"KRITEM_DUALJAWZ",KRITEM_DUALJAWZ}, {"KRITEM_DUALJAWZ",KRITEM_DUALJAWZ},
{"KRITEM_TRIPLEGACHABOM",KRITEM_TRIPLEGACHABOM},
{"NUMKARTRESULTS",NUMKARTRESULTS}, {"NUMKARTRESULTS",NUMKARTRESULTS},
// kartshields_t // kartshields_t

View file

@ -24187,6 +24187,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_GACHABOM
-1, // doomednum
S_ORBINAUT1, // spawnstate
7, // spawnhealth
S_NULL, // seestate
sfx_tossed, // seesound
8, // reactiontime
sfx_s3k49, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_ORBINAUT_DEAD,// deathstate
S_NULL, // xdeathstate
sfx_s3k5d, // deathsound
64*FRACUNIT, // speed
24*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
100, // mass
1, // damage
sfx_s3k96, // activesound
MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN|MF_SLOPE, // flags
S_NULL // raisestate
},
{ // MT_DUELBOMB { // MT_DUELBOMB
2050, // doomednum 2050, // doomednum
S_SPB1, // spawnstate S_SPB1, // spawnstate

View file

@ -6426,6 +6426,8 @@ typedef enum mobj_type
MT_SINK_SHIELD, MT_SINK_SHIELD,
MT_SINKTRAIL, MT_SINKTRAIL,
MT_GACHABOM,
MT_DUELBOMB, // Duel mode bombs MT_DUELBOMB, // Duel mode bombs
MT_BATTLEBUMPER, // Battle Mode bumpers MT_BATTLEBUMPER, // Battle Mode bumpers

View file

@ -1373,6 +1373,11 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
case KITEM_FLAMESHIELD: case KITEM_FLAMESHIELD:
K_BotItemFlame(player, cmd); K_BotItemFlame(player, cmd);
break; break;
/*
case KITEM_GACHABOM:
K_BotItemGachabom(player, cmd);
break;
*/
} }
} }
} }

View file

@ -415,6 +415,7 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
case MT_SPB: case MT_SPB:
case MT_BUBBLESHIELDTRAP: case MT_BUBBLESHIELDTRAP:
case MT_DUELBOMB: case MT_DUELBOMB:
case MT_GACHABOM:
K_AddDodgeObject(thing, side, 20); K_AddDodgeObject(thing, side, 20);
break; break;
case MT_SHRINK_GUN: case MT_SHRINK_GUN:

View file

@ -86,7 +86,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD
|| t2->type == MT_ORBINAUT || t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_ORBINAUT || t2->type == MT_ORBINAUT_SHIELD
|| t2->type == MT_JAWZ || t2->type == MT_JAWZ_SHIELD || t2->type == MT_JAWZ || t2->type == MT_JAWZ_SHIELD
|| t2->type == MT_BALLHOG) || t2->type == MT_BALLHOG || t2->type == MT_GACHABOM)
{ {
// Other Item Damage // Other Item Damage
angle_t bounceangle = K_GetCollideAngle(t1, t2); angle_t bounceangle = K_GetCollideAngle(t1, t2);
@ -340,7 +340,8 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
} }
} }
else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ
|| t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD) || t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD
|| t2->type == MT_GACHABOM)
{ {
// Bomb death // Bomb death
angle_t bounceangle = K_GetCollideAngle(t1, t2); angle_t bounceangle = K_GetCollideAngle(t1, t2);
@ -401,7 +402,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD
|| t2->type == MT_ORBINAUT || t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_ORBINAUT || t2->type == MT_ORBINAUT_SHIELD
|| t2->type == MT_JAWZ || t2->type == MT_JAWZ_SHIELD || t2->type == MT_JAWZ || t2->type == MT_JAWZ_SHIELD
|| t2->type == MT_BALLHOG) || t2->type == MT_BALLHOG || t2->type == MT_GACHABOM)
{ {
// Other Item Damage // Other Item Damage
angle_t bounceangle = K_GetCollideAngle(t1, t2); angle_t bounceangle = K_GetCollideAngle(t1, t2);

View file

@ -736,6 +736,9 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny)
return (tiny ? "K_ISDTRG" : "K_ITDTRG"); return (tiny ? "K_ISDTRG" : "K_ITDTRG");
case KITEM_GARDENTOP: case KITEM_GARDENTOP:
return (tiny ? "K_ISGTOP" : "K_ITGTOP"); return (tiny ? "K_ISGTOP" : "K_ITGTOP");
case KITEM_GACHABOM: // temp
case KRITEM_TRIPLEGACHABOM: // temp
return (tiny ? "K_ISSINK" : "K_ITSINK");
case KRITEM_TRIPLEORBINAUT: case KRITEM_TRIPLEORBINAUT:
return (tiny ? "K_ISORBN" : "K_ITORB3"); return (tiny ? "K_ISORBN" : "K_ITORB3");
case KRITEM_QUADORBINAUT: case KRITEM_QUADORBINAUT:
@ -772,6 +775,7 @@ static patch_t *K_GetCachedItemPatch(INT32 item, UINT8 offset)
kp_kitchensink, kp_kitchensink,
kp_droptarget, kp_droptarget,
kp_gardentop, kp_gardentop,
kp_kitchensink, // temp
}; };
if (item == KITEM_SAD || (item > KITEM_NONE && item < NUMKARTITEMS)) if (item == KITEM_SAD || (item > KITEM_NONE && item < NUMKARTITEMS))
@ -1208,6 +1212,7 @@ static void K_drawKartItem(void)
default: default:
localpatch = K_GetCachedItemPatch(item, offset); localpatch = K_GetCachedItemPatch(item, offset);
break;
} }
} }
else else

View file

@ -423,12 +423,14 @@ consvar_t *KartItemCVars[NUMKARTRESULTS-1] =
&cv_kitchensink, &cv_kitchensink,
&cv_droptarget, &cv_droptarget,
&cv_gardentop, &cv_gardentop,
&cv_gachabom,
&cv_dualsneaker, &cv_dualsneaker,
&cv_triplesneaker, &cv_triplesneaker,
&cv_triplebanana, &cv_triplebanana,
&cv_tripleorbinaut, &cv_tripleorbinaut,
&cv_quadorbinaut, &cv_quadorbinaut,
&cv_dualjawz &cv_dualjawz,
&cv_triplegachabom
}; };
#define NUMKARTODDS 80 #define NUMKARTODDS 80
@ -459,12 +461,14 @@ static UINT8 K_KartItemOddsRace[NUMKARTRESULTS-1][8] =
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink { 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink
{ 3, 0, 0, 0, 0, 0, 0, 0 }, // Drop Target { 3, 0, 0, 0, 0, 0, 0, 0 }, // Drop Target
{ 0, 0, 0, 3, 5, 0, 0, 0 }, // Garden Top { 0, 0, 0, 3, 5, 0, 0, 0 }, // Garden Top
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // Gachabom
{ 0, 0, 2, 2, 2, 0, 0, 0 }, // Sneaker x2 { 0, 0, 2, 2, 2, 0, 0, 0 }, // Sneaker x2
{ 0, 0, 0, 0, 4, 4, 4, 0 }, // Sneaker x3 { 0, 0, 0, 0, 4, 4, 4, 0 }, // Sneaker x3
{ 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3 { 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3
{ 0, 0, 1, 0, 0, 0, 0, 0 }, // Orbinaut x3 { 0, 0, 1, 0, 0, 0, 0, 0 }, // Orbinaut x3
{ 0, 0, 0, 2, 0, 0, 0, 0 }, // Orbinaut x4 { 0, 0, 0, 2, 0, 0, 0, 0 }, // Orbinaut x4
{ 0, 0, 1, 2, 1, 0, 0, 0 } // Jawz x2 { 0, 0, 1, 2, 1, 0, 0, 0 }, // Jawz x2
{ 0, 0, 0, 0, 0, 0, 0, 0 } // Gachabom x3
}; };
static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS][2] = static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS][2] =
@ -492,12 +496,14 @@ static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS][2] =
{ 0, 0 }, // Kitchen Sink { 0, 0 }, // Kitchen Sink
{ 2, 0 }, // Drop Target { 2, 0 }, // Drop Target
{ 4, 0 }, // Garden Top { 4, 0 }, // Garden Top
{ 0, 0 }, // Gachabom
{ 0, 0 }, // Sneaker x2 { 0, 0 }, // Sneaker x2
{ 0, 1 }, // Sneaker x3 { 0, 1 }, // Sneaker x3
{ 0, 0 }, // Banana x3 { 0, 0 }, // Banana x3
{ 2, 0 }, // Orbinaut x3 { 2, 0 }, // Orbinaut x3
{ 1, 1 }, // Orbinaut x4 { 1, 1 }, // Orbinaut x4
{ 5, 1 } // Jawz x2 { 5, 1 }, // Jawz x2
{ 0, 0 } // Gachabom x3
}; };
// TODO: add back when this gets used // TODO: add back when this gets used
@ -527,12 +533,14 @@ static UINT8 K_KartItemOddsSpecial[NUMKARTRESULTS-1][4] =
{ 0, 0, 0, 0 }, // Kitchen Sink { 0, 0, 0, 0 }, // Kitchen Sink
{ 0, 0, 0, 0 }, // Drop Target { 0, 0, 0, 0 }, // Drop Target
{ 0, 0, 0, 0 }, // Garden Top { 0, 0, 0, 0 }, // Garden Top
{ 0, 0, 0, 0 }, // Gachabom
{ 0, 1, 1, 0 }, // Sneaker x2 { 0, 1, 1, 0 }, // Sneaker x2
{ 0, 0, 1, 1 }, // Sneaker x3 { 0, 0, 1, 1 }, // Sneaker x3
{ 0, 0, 0, 0 }, // Banana x3 { 0, 0, 0, 0 }, // Banana x3
{ 0, 1, 1, 0 }, // Orbinaut x3 { 0, 1, 1, 0 }, // Orbinaut x3
{ 0, 0, 1, 1 }, // Orbinaut x4 { 0, 0, 1, 1 }, // Orbinaut x4
{ 0, 0, 1, 1 } // Jawz x2 { 0, 0, 1, 1 }, // Jawz x2
{ 0, 0, 0, 0 } // Gachabom x3
}; };
#endif #endif
@ -599,6 +607,9 @@ SINT8 K_ItemResultToType(SINT8 getitem)
case KRITEM_DUALJAWZ: case KRITEM_DUALJAWZ:
return KITEM_JAWZ; return KITEM_JAWZ;
case KRITEM_TRIPLEGACHABOM:
return KITEM_GACHABOM;
default: default:
I_Error("Bad item cooldown redirect for result %d\n", getitem); I_Error("Bad item cooldown redirect for result %d\n", getitem);
break; break;
@ -619,6 +630,7 @@ UINT8 K_ItemResultToAmount(SINT8 getitem)
case KRITEM_TRIPLESNEAKER: case KRITEM_TRIPLESNEAKER:
case KRITEM_TRIPLEBANANA: case KRITEM_TRIPLEBANANA:
case KRITEM_TRIPLEORBINAUT: case KRITEM_TRIPLEORBINAUT:
case KRITEM_TRIPLEGACHABOM:
return 3; return 3;
case KRITEM_QUADORBINAUT: case KRITEM_QUADORBINAUT:
@ -1370,24 +1382,24 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
} }
else if (gametype == GT_BATTLE) else if (gametype == GT_BATTLE)
{ {
if (mashed && (modeattacking || bossinfo.boss || cv_banana.value)) // ANY mashed value? You get a banana. if (mashed && (modeattacking || bossinfo.boss || cv_gachabom.value)) // ANY mashed value? You get a Gachabom.
{ {
K_KartGetItemResult(player, KITEM_BANANA); K_KartGetItemResult(player, KITEM_GACHABOM);
player->karthud[khud_itemblinkmode] = 1; player->karthud[khud_itemblinkmode] = 1;
if (P_IsDisplayPlayer(player)) if (P_IsDisplayPlayer(player))
S_StartSound(NULL, sfx_itrolm); S_StartSound(NULL, sfx_itrolm);
} }
else if (bossinfo.boss) else if (bossinfo.boss)
{ {
K_KartGetItemResult(player, KITEM_ORBINAUT); K_KartGetItemResult(player, KITEM_ORBINAUT); // FIXME
player->karthud[khud_itemblinkmode] = 0; player->karthud[khud_itemblinkmode] = 0;
if (P_IsDisplayPlayer(player)) if (P_IsDisplayPlayer(player))
S_StartSound(NULL, sfx_itrolf); S_StartSound(NULL, sfx_itrolf);
} }
else else
{ {
if (modeattacking || cv_tripleorbinaut.value) // Waited patiently? You get Orbinaut x3! if (modeattacking || cv_triplegachabom.value) // Waited patiently? You get Gachabom x3!
K_KartGetItemResult(player, KRITEM_TRIPLEORBINAUT); K_KartGetItemResult(player, KRITEM_TRIPLEGACHABOM);
else // Default to sad if nothing's enabled... else // Default to sad if nothing's enabled...
K_KartGetItemResult(player, KITEM_SAD); K_KartGetItemResult(player, KITEM_SAD);
player->karthud[khud_itemblinkmode] = 0; player->karthud[khud_itemblinkmode] = 0;
@ -1550,6 +1562,7 @@ fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against)
break; break;
case MT_ORBINAUT: case MT_ORBINAUT:
case MT_ORBINAUT_SHIELD: case MT_ORBINAUT_SHIELD:
case MT_GACHABOM:
case MT_DUELBOMB: case MT_DUELBOMB:
if (against->player) if (against->player)
weight = K_PlayerWeight(against, NULL); weight = K_PlayerWeight(against, NULL);
@ -5271,7 +5284,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
finalscale = source->scale; finalscale = source->scale;
} }
if (dir == -1 && (type == MT_ORBINAUT || type == MT_BALLHOG)) if (dir == -1 && (type == MT_ORBINAUT || type == MT_GACHABOM || type == MT_BALLHOG))
{ {
// Backwards nerfs // Backwards nerfs
finalspeed /= 8; finalspeed /= 8;
@ -5328,6 +5341,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
switch (type) switch (type)
{ {
case MT_ORBINAUT: case MT_ORBINAUT:
case MT_GACHABOM:
Obj_OrbinautThrown(th, finalspeed, dir); Obj_OrbinautThrown(th, finalspeed, dir);
break; break;
case MT_JAWZ: case MT_JAWZ:
@ -6175,6 +6189,12 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
dir = defaultDir; dir = defaultDir;
} }
if (mapthing == MT_GACHABOM && dir > 0)
{
// This item is both a missile and not!
missile = false;
}
if (missile) // Shootables if (missile) // Shootables
{ {
if (dir < 0 && mapthing != MT_SPB && mapthing != MT_GARDENTOP) if (dir < 0 && mapthing != MT_SPB && mapthing != MT_GARDENTOP)
@ -6242,6 +6262,16 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
mo->rollangle = FixedAngle(P_RandomRange(PR_DECORATION, -180, 180) << FRACBITS); mo->rollangle = FixedAngle(P_RandomRange(PR_DECORATION, -180, 180) << FRACBITS);
} }
if (mapthing == MT_GACHABOM)
{
// Set dropped flag
mo->flags2 |= MF2_AMBUSH;
mo->movecount = 2;
P_SetMobjState(mo, mo->info->deathstate);
mo->tics = -1;
mo->color = player->skincolor;
}
// this is the small graphic effect that plops in you when you throw an item: // this is the small graphic effect that plops in you when you throw an item:
throwmo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FIREDITEM); throwmo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FIREDITEM);
P_SetTarget(&throwmo->target, player->mo); P_SetTarget(&throwmo->target, player->mo);
@ -11418,6 +11448,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_UpdateHnextList(player, true); K_UpdateHnextList(player, true);
} }
break; break;
case KITEM_GACHABOM:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{
K_ThrowKartItem(player, true, MT_GACHABOM, 0, 0, 0);
K_PlayAttackTaunt(player->mo);
player->itemamount--;
K_UpdateHnextList(player, false);
}
break;
case KITEM_SAD: case KITEM_SAD:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO
&& !player->sadtimer) && !player->sadtimer)

View file

@ -184,7 +184,7 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
if (t2->player) if (t2->player)
{ {
if ((t2->player->flashing > 0 && t2->hitlag == 0) if ((t2->player->flashing > 0 && t2->hitlag == 0)
&& !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ)) && !(t1->type == MT_ORBINAUT || t1->type == MT_JAWZ || t1->type == MT_GACHABOM))
return true; return true;
if (t2->player->hyudorotimer) if (t2->player->hyudorotimer)
@ -209,7 +209,7 @@ boolean Obj_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ else if (t2->type == MT_ORBINAUT || t2->type == MT_JAWZ
|| t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD || t2->type == MT_ORBINAUT_SHIELD || t2->type == MT_JAWZ_SHIELD
|| t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD || t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD
|| t2->type == MT_BALLHOG) || t2->type == MT_BALLHOG || t2->type == MT_GACHABOM)
{ {
// Other Item Damage // Other Item Damage
angle_t bounceangle = K_GetCollideAngle(t1, t2); angle_t bounceangle = K_GetCollideAngle(t1, t2);

View file

@ -955,7 +955,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|| target->type == MT_BANANA || target->type == MT_BANANA_SHIELD || target->type == MT_BANANA || target->type == MT_BANANA_SHIELD
|| target->type == MT_DROPTARGET || target->type == MT_DROPTARGET_SHIELD || target->type == MT_DROPTARGET || target->type == MT_DROPTARGET_SHIELD
|| target->type == MT_EGGMANITEM || target->type == MT_EGGMANITEM_SHIELD || target->type == MT_EGGMANITEM || target->type == MT_EGGMANITEM_SHIELD
|| target->type == MT_BALLHOG || target->type == MT_SPB)) // kart dead items || target->type == MT_BALLHOG || target->type == MT_SPB
|| target->type == MT_GACHABOM)) // kart dead items
target->flags |= MF_NOGRAVITY; // Don't drop Tails 03-08-2000 target->flags |= MF_NOGRAVITY; // Don't drop Tails 03-08-2000
else else
target->flags &= ~MF_NOGRAVITY; // lose it if you for whatever reason have it, I'm looking at you shields target->flags &= ~MF_NOGRAVITY; // lose it if you for whatever reason have it, I'm looking at you shields

View file

@ -849,7 +849,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
// Bubble Shield reflect // Bubble Shield reflect
if (((thing->type == MT_BUBBLESHIELD && thing->target->player && thing->target->player->bubbleblowup) if (((thing->type == MT_BUBBLESHIELD && thing->target->player && thing->target->player->bubbleblowup)
|| (thing->player && thing->player->bubbleblowup)) || (thing->player && thing->player->bubbleblowup))
&& (tm.thing->type == MT_ORBINAUT || tm.thing->type == MT_JAWZ && (tm.thing->type == MT_ORBINAUT || tm.thing->type == MT_JAWZ || tm.thing->type == MT_GACHABOM
|| tm.thing->type == MT_BANANA || tm.thing->type == MT_EGGMANITEM || tm.thing->type == MT_BALLHOG || tm.thing->type == MT_BANANA || tm.thing->type == MT_EGGMANITEM || tm.thing->type == MT_BALLHOG
|| tm.thing->type == MT_SSMINE || tm.thing->type == MT_LANDMINE || tm.thing->type == MT_SINK || tm.thing->type == MT_SSMINE || tm.thing->type == MT_LANDMINE || tm.thing->type == MT_SINK
|| tm.thing->type == MT_GARDENTOP || tm.thing->type == MT_GARDENTOP
@ -865,7 +865,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
} }
else if (((tm.thing->type == MT_BUBBLESHIELD && tm.thing->target->player && tm.thing->target->player->bubbleblowup) else if (((tm.thing->type == MT_BUBBLESHIELD && tm.thing->target->player && tm.thing->target->player->bubbleblowup)
|| (tm.thing->player && tm.thing->player->bubbleblowup)) || (tm.thing->player && tm.thing->player->bubbleblowup))
&& (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ && (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_GACHABOM
|| thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG || thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG
|| thing->type == MT_SSMINE || tm.thing->type == MT_LANDMINE || thing->type == MT_SINK || thing->type == MT_SSMINE || tm.thing->type == MT_LANDMINE || thing->type == MT_SINK
|| thing->type == MT_GARDENTOP || thing->type == MT_GARDENTOP
@ -886,7 +886,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
// Droptarget reflect // Droptarget reflect
if ((thing->type == MT_DROPTARGET || thing->type == MT_DROPTARGET_SHIELD) if ((thing->type == MT_DROPTARGET || thing->type == MT_DROPTARGET_SHIELD)
&& (tm.thing->type == MT_ORBINAUT || tm.thing->type == MT_JAWZ && (tm.thing->type == MT_ORBINAUT || tm.thing->type == MT_JAWZ || tm.thing->type == MT_GACHABOM
|| tm.thing->type == MT_BANANA || tm.thing->type == MT_EGGMANITEM || tm.thing->type == MT_BALLHOG || tm.thing->type == MT_BANANA || tm.thing->type == MT_EGGMANITEM || tm.thing->type == MT_BALLHOG
|| tm.thing->type == MT_SSMINE || tm.thing->type == MT_LANDMINE || tm.thing->type == MT_SINK || tm.thing->type == MT_SSMINE || tm.thing->type == MT_LANDMINE || tm.thing->type == MT_SINK
|| tm.thing->type == MT_GARDENTOP || tm.thing->type == MT_GARDENTOP
@ -901,7 +901,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
return K_DropTargetCollide(thing, tm.thing) ? BMIT_CONTINUE : BMIT_ABORT; return K_DropTargetCollide(thing, tm.thing) ? BMIT_CONTINUE : BMIT_ABORT;
} }
else if ((tm.thing->type == MT_DROPTARGET || tm.thing->type == MT_DROPTARGET_SHIELD) else if ((tm.thing->type == MT_DROPTARGET || tm.thing->type == MT_DROPTARGET_SHIELD)
&& (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ && (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_GACHABOM
|| thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG || thing->type == MT_BANANA || thing->type == MT_EGGMANITEM || thing->type == MT_BALLHOG
|| thing->type == MT_SSMINE || tm.thing->type == MT_LANDMINE || thing->type == MT_SINK || thing->type == MT_SSMINE || tm.thing->type == MT_LANDMINE || thing->type == MT_SINK
|| thing->type == MT_GARDENTOP || thing->type == MT_GARDENTOP
@ -921,7 +921,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|| thing->type == MT_DROPTARGET_SHIELD || tm.thing->type == MT_DROPTARGET_SHIELD) || thing->type == MT_DROPTARGET_SHIELD || tm.thing->type == MT_DROPTARGET_SHIELD)
return BMIT_CONTINUE; return BMIT_CONTINUE;
if (tm.thing->type == MT_ORBINAUT || tm.thing->type == MT_JAWZ if (tm.thing->type == MT_ORBINAUT || tm.thing->type == MT_JAWZ || tm.thing->type == MT_GACHABOM
|| tm.thing->type == MT_ORBINAUT_SHIELD || tm.thing->type == MT_JAWZ_SHIELD || tm.thing->type == MT_ORBINAUT_SHIELD || tm.thing->type == MT_JAWZ_SHIELD
|| tm.thing->type == MT_GARDENTOP) || tm.thing->type == MT_GARDENTOP)
{ {
@ -933,7 +933,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
return Obj_OrbinautJawzCollide(tm.thing, thing) ? BMIT_CONTINUE : BMIT_ABORT; return Obj_OrbinautJawzCollide(tm.thing, thing) ? BMIT_CONTINUE : BMIT_ABORT;
} }
else if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ else if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_GACHABOM
|| thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD || thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD
|| thing->type == MT_GARDENTOP) || thing->type == MT_GARDENTOP)
{ {

View file

@ -1195,6 +1195,13 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
case MT_BATTLEBUMPER: case MT_BATTLEBUMPER:
gravityadd /= 2; gravityadd /= 2;
break; break;
case MT_GACHABOM:
if (!(mo->flags2 & MF2_AMBUSH))
{
// Use normal gravity, unless if it was tossed.
break;
}
/*FALLTHRU*/
case MT_BANANA: case MT_BANANA:
case MT_EGGMANITEM: case MT_EGGMANITEM:
case MT_SSMINE: case MT_SSMINE:
@ -1742,7 +1749,7 @@ void P_XYMovement(mobj_t *mo)
//{ SRB2kart - Orbinaut, Ballhog //{ SRB2kart - Orbinaut, Ballhog
// Bump sparks // Bump sparks
if (mo->type == MT_ORBINAUT || mo->type == MT_BALLHOG) if (mo->type == MT_ORBINAUT || mo->type == MT_BALLHOG || mo->type == MT_GACHABOM)
{ {
mobj_t *fx; mobj_t *fx;
fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP); fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP);
@ -1756,6 +1763,7 @@ void P_XYMovement(mobj_t *mo)
switch (mo->type) switch (mo->type)
{ {
case MT_ORBINAUT: // Orbinaut speed decreasing case MT_ORBINAUT: // Orbinaut speed decreasing
case MT_GACHABOM:
case MT_GARDENTOP: case MT_GARDENTOP:
if (mo->health > 1) if (mo->health > 1)
{ {
@ -5174,6 +5182,7 @@ boolean P_IsKartFieldItem(INT32 type)
case MT_SINK: case MT_SINK:
case MT_DROPTARGET: case MT_DROPTARGET:
case MT_DUELBOMB: case MT_DUELBOMB:
case MT_GACHABOM:
return true; return true;
default: default:
@ -6540,6 +6549,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
case MT_LANDMINE: case MT_LANDMINE:
//case MT_DROPTARGET: //case MT_DROPTARGET:
case MT_SPB: case MT_SPB:
case MT_GACHABOM:
if (P_IsObjectOnGround(mobj)) if (P_IsObjectOnGround(mobj))
{ {
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
@ -6936,6 +6946,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
} }
break; break;
case MT_ORBINAUT: case MT_ORBINAUT:
case MT_GACHABOM:
{ {
Obj_OrbinautThink(mobj); Obj_OrbinautThink(mobj);
P_MobjCheckWater(mobj); P_MobjCheckWater(mobj);
@ -9743,6 +9754,7 @@ void P_MobjThinker(mobj_t *mobj)
|| mobj->type == MT_CANNONBALLDECOR || mobj->type == MT_CANNONBALLDECOR
|| mobj->type == MT_FALLINGROCK || mobj->type == MT_FALLINGROCK
|| mobj->type == MT_ORBINAUT || mobj->type == MT_ORBINAUT
|| mobj->type == MT_GACHABOM
|| mobj->type == MT_JAWZ || mobj->type == MT_JAWZ
|| (mobj->type == MT_DROPTARGET && mobj->reactiontime)) || (mobj->type == MT_DROPTARGET && mobj->reactiontime))
{ {
@ -10020,6 +10032,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
case MT_ROCKETSNEAKER: case MT_ROCKETSNEAKER:
case MT_SPB: case MT_SPB:
case MT_DUELBOMB: case MT_DUELBOMB:
case MT_GACHABOM:
thing->shadowscale = 3*FRACUNIT/2; thing->shadowscale = 3*FRACUNIT/2;
break; break;
case MT_BANANA_SHIELD: case MT_BANANA_SHIELD: