Dropping items!

* Shield Drop...
	* Whatever you've got orbiting or trailing you, DROP THEM WHERE THEY STAND. (Except for the ghost sink. That one's OK.)
	* Pops your Thunder Shield.
	* Happens upon ANY hit, except for deathpits.
* HUD Drop...
	* Also does the above, except for the Thunder Shield thing.
	* If there's any item left in your item box, pop it out as a little hovering, rotating Minecraft item!
	* You can pick up the Minecraft item by driving over it if your item box is sufficiently empty, or the item which is contained within it is of the same type.
	* Happens upon Size Down and battle elimination.
	* Can also be forced on with `cv_kartdebughuddrop on`!
* Some other random stuff.
	* Fix a bunch of `a->scale = b`'s into `P_SetScale(a, b)` form, for maximum validity.
	* Make K_CleanHnextList and K_UpdateHnextList one function, since they only differed by one continue clause (and the type of their input parameter).
	* Allow shrunken players to pick up item boxes again.
	* Fix MF_NOCLIPTHING. (Gonna pass this fix to vanilla when I get the chance, too.)
	* Break NiGHTS a little through my machinations.
This commit is contained in:
toaster 2018-09-06 22:17:29 +01:00
parent 36356f8a64
commit 4de68f7fe2
12 changed files with 446 additions and 110 deletions

View File

@ -370,6 +370,7 @@ static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"},
consvar_t cv_kartdebugamount = {"kartdebugamount", "1", CV_NETVAR|CV_CHEAT, kartdebugamount_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugshrink = {"kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugdistribution = {"kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};

View File

@ -133,7 +133,7 @@ extern consvar_t cv_karteliminatelast;
extern consvar_t cv_votetime;
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution;
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
extern consvar_t cv_kartdebugcheckpoint;
extern consvar_t cv_itemfinder;

View File

@ -6233,6 +6233,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_RANDOMITEMPOP4",
//}
"S_ITEMICON",
// Drift Sparks
"S_DRIFTSPARK1",
"S_DRIFTSPARK2",
@ -7208,6 +7210,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_BLUEDIAG",
"MT_RANDOMITEM",
"MT_RANDOMITEMPOP",
"MT_FLOATINGITEM",
"MT_SNEAKERTRAIL",
"MT_SPARKLETRAIL",

View File

@ -2566,6 +2566,8 @@ state_t states[NUMSTATES] =
{SPR_RPOP, FF_FULLBRIGHT|2, 5, {NULL}, 0, 0, S_RANDOMITEMPOP4}, // S_RANDOMITEMPOP3
{SPR_RPOP, FF_FULLBRIGHT|3, 5, {NULL}, 0, 0, S_NULL}, // S_RANDOMITEMPOP4
{SPR_NULL, 0|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMICON
{SPR_DRIF, 0|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK2}, // S_DRIFTSPARK1
{SPR_DRIF, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK3}, // S_DRIFTSPARK2
{SPR_DRIF, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK1}, // S_DRIFTSPARK3
@ -14390,6 +14392,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_FLOATINGITEM
-1, // doomednum
S_ITEMICON, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_mcitm1, // deathsound
0, // speed
24*FRACUNIT, // radius
24*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_SLIDEME|MF_SPECIAL, // flags
S_NULL // raisestate
},
{ // MT_SNEAKERTRAIL
-1, // doomednum
S_KARTFIRE1, // spawnstate

View File

@ -3078,6 +3078,8 @@ typedef enum state
S_RANDOMITEMPOP4,
//}
S_ITEMICON,
// Drift Sparks
S_DRIFTSPARK1,
S_DRIFTSPARK2,
@ -4070,6 +4072,7 @@ typedef enum mobj_type
MT_BLUEDIAG,
MT_RANDOMITEM,
MT_RANDOMITEMPOP,
MT_FLOATINGITEM,
MT_SNEAKERTRAIL,
MT_SPARKLETRAIL,

View File

@ -414,6 +414,7 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartdebugamount);
CV_RegisterVar(&cv_kartdebugshrink);
CV_RegisterVar(&cv_kartdebugdistribution);
CV_RegisterVar(&cv_kartdebughuddrop);
CV_RegisterVar(&cv_kartdebugcheckpoint);
}
@ -1101,7 +1102,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
fx->eflags |= MFE_VERTICALFLIP;
else
fx->eflags &= ~MFE_VERTICALFLIP;
fx->scale = mobj1->scale;
P_SetScale(fx, mobj1->scale);
// Because this is done during collision now, rmomx and rmomy need to be recalculated
// so that friction doesn't immediately decide to stop the player if they're at a standstill
@ -1715,6 +1716,10 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem
P_SetPlayerMobjState(player->mo, S_KART_SPIN);
player->kartstuff[k_instashield] = 15;
if (cv_kartdebughuddrop.value)
K_DropItems(player);
else
K_DropHnextList(player);
return;
}
@ -1784,6 +1789,10 @@ void K_SquishPlayer(player_t *player, mobj_t *source)
P_PlayRinglossSound(player->mo);
player->kartstuff[k_instashield] = 15;
if (cv_kartdebughuddrop.value)
K_DropItems(player);
else
K_DropHnextList(player);
return;
}
@ -1861,6 +1870,10 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju
}
player->kartstuff[k_instashield] = 15;
if (cv_kartdebughuddrop.value)
K_DropItems(player);
else
K_DropHnextList(player);
return;
}
@ -1936,6 +1949,10 @@ void K_StealBumper(player_t *player, player_t *victim, boolean force)
victim->kartstuff[k_comebacktimer] = comebacktime;*/
victim->kartstuff[k_instashield] = 15;
if (cv_kartdebughuddrop.value)
K_DropItems(victim);
else
K_DropHnextList(victim);
return;
}
@ -2043,14 +2060,14 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
{
dust = P_SpawnMobj(source->x, source->y, source->z, MT_SMOKE);
dust->angle = (ANGLE_180/16) * i;
dust->scale = source->scale;
P_SetScale(dust, source->scale);
dust->destscale = source->scale*10;
P_InstaThrust(dust, dust->angle, FixedMul(20*FRACUNIT, source->scale));
truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT,
source->y + P_RandomRange(-radius, radius)*FRACUNIT,
source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMEXPLODE);
truc->scale = source->scale*2;
P_SetScale(truc, source->scale);
truc->destscale = source->scale*6;
speed = FixedMul(10*FRACUNIT, source->scale)>>FRACBITS;
truc->momx = P_RandomRange(-speed, speed)*FRACUNIT;
@ -2065,7 +2082,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
dust = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT,
source->y + P_RandomRange(-radius, radius)*FRACUNIT,
source->z + P_RandomRange(0, height)*FRACUNIT, MT_SMOKE);
dust->scale = source->scale;
P_SetScale(dust, source->scale);
dust->destscale = source->scale*10;
dust->tics = 30;
dust->momz = P_RandomRange(FixedMul(3*FRACUNIT, source->scale)>>FRACBITS, FixedMul(7*FRACUNIT, source->scale)>>FRACBITS)*FRACUNIT;
@ -2073,7 +2090,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
truc = P_SpawnMobj(source->x + P_RandomRange(-radius, radius)*FRACUNIT,
source->y + P_RandomRange(-radius, radius)*FRACUNIT,
source->z + P_RandomRange(0, height)*FRACUNIT, MT_BOOMPARTICLE);
truc->scale = source->scale;
P_SetScale(truc, source->scale);
truc->destscale = source->scale*5;
speed = FixedMul(20*FRACUNIT, source->scale)>>FRACBITS;
truc->momx = P_RandomRange(-speed, speed)*FRACUNIT;
@ -2350,7 +2367,7 @@ void K_DriftDustHandling(mobj_t *spawner)
dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*FRACUNIT/4);
dust->momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*FRACUNIT/4);
dust->momz = P_MobjFlip(spawner) * P_RandomRange(1, 4)<<FRACBITS;
dust->scale = spawner->scale/2;
P_SetScale(dust, spawner->scale/2);
dust->destscale = spawner->scale * 3;
if (leveltime % 6 == 0)
@ -2808,46 +2825,190 @@ killnext:
}
// Just for firing/dropping items.
void K_CleanHnextList(mobj_t *work)
{
mobj_t *nextwork;
if (!work)
return;
work = work->hnext;
while (work && !P_MobjWasRemoved(work))
{
nextwork = work->hnext;
P_RemoveMobj(work);
work = nextwork;
}
}
// Ditto.
void K_UpdateHnextList(player_t *player)
void K_UpdateHnextList(player_t *player, boolean clean)
{
mobj_t *work = player->mo, *nextwork;
if (!work)
return;
work = work->hnext;
nextwork = work->hnext;
while (work && !P_MobjWasRemoved(work))
while ((work = nextwork) && !P_MobjWasRemoved(work))
{
nextwork = work->hnext;
if (work->movedir > 0 && work->movedir > (UINT16)player->kartstuff[k_itemamount])
P_RemoveMobj(work);
if (!clean && (!work->movedir || work->movedir <= (UINT16)player->kartstuff[k_itemamount]))
continue;
work = nextwork;
P_RemoveMobj(work);
}
}
// For getting hit!
void K_DropHnextList(player_t *player)
{
mobj_t *work = player->mo, *nextwork, *dropwork;
INT32 flip;
mobjtype_t type;
boolean orbit, ponground;
if (!work)
return;
flip = P_MobjFlip(player->mo);
ponground = P_IsObjectOnGround(player->mo);
if (player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD && player->kartstuff[k_itemamount])
{
K_DoThunderShield(player);
player->kartstuff[k_itemamount] = 0;
player->kartstuff[k_itemtype] = KITEM_NONE;
}
nextwork = work->hnext;
while ((work = nextwork) && !P_MobjWasRemoved(work))
{
nextwork = work->hnext;
switch (work->type)
{
// Kart orbit items
case MT_ORBINAUT_SHIELD:
orbit = true;
type = MT_ORBINAUT;
break;
case MT_JAWZ_SHIELD:
orbit = true;
type = MT_JAWZ_DUD;
break;
// Kart trailing items
case MT_BANANA_SHIELD:
orbit = false;
type = MT_BANANA;
break;
case MT_SSMINE_SHIELD:
orbit = false;
type = MT_SSMINE;
break;
case MT_FAKESHIELD:
orbit = false;
type = MT_FAKEITEM;
break;
// intentionally do nothing
case MT_SINK_SHIELD:
return;
default:
continue;
}
dropwork = P_SpawnMobj(work->x, work->y, work->z, type);
P_SetTarget(&dropwork->target, player->mo);
dropwork->angle = work->angle;
dropwork->flags2 = work->flags2;
dropwork->flags |= MF_NOCLIPTHING;
dropwork->floorz = work->floorz;
dropwork->ceilingz = work->ceilingz;
if (ponground)
{
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
// This should set it for FOFs
//P_TeleportMove(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing
if (flip == 1)
{
if (dropwork->floorz > dropwork->target->z - dropwork->height)
{
dropwork->z = dropwork->floorz;
}
}
else
{
if (dropwork->ceilingz < dropwork->target->z + dropwork->target->height + dropwork->height)
{
dropwork->z = dropwork->ceilingz - dropwork->height;
}
}
}
if (orbit) // splay out
{
dropwork->flags2 |= MF2_AMBUSH;
dropwork->z += flip;
dropwork->momx = player->mo->momx>>1;
dropwork->momy = player->mo->momy>>1;
dropwork->momz = 3*flip*mapheaderinfo[gamemap-1]->mobj_scale;
P_Thrust(dropwork, work->angle - ANGLE_90, 6*(mapheaderinfo[gamemap-1]->mobj_scale));
dropwork->movecount = 2;
dropwork->movedir = work->angle - ANGLE_90;
P_SetMobjState(dropwork, dropwork->info->deathstate);
dropwork->tics = -1;
if (type == MT_JAWZ_DUD)
dropwork->z += 20*flip*dropwork->scale;
else
{
dropwork->color = work->color;
dropwork->angle -= ANGLE_90;
}
}
else // plop on the ground
{
dropwork->flags &= ~MF_NOCLIPTHING;
dropwork->threshold = 10;
}
P_RemoveMobj(work);
}
{
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
P_SetTarget(&player->mo->hnext, NULL);
player->kartstuff[k_bananadrag] = 0;
if (player->kartstuff[k_eggmanheld])
player->kartstuff[k_eggmanheld] = 0;
else if (player->kartstuff[k_itemheld])
{
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
player->kartstuff[k_itemtype] = KITEM_NONE;
}
}
}
// For getting EXTRA hit!
void K_DropItems(player_t *player)
{
boolean thunderhack = (player->kartstuff[k_curshield] && player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD);
if (thunderhack)
player->kartstuff[k_itemtype] = KITEM_NONE;
K_DropHnextList(player);
if (player->mo && player->kartstuff[k_itemamount])
{
mobj_t *drop = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_FLOATINGITEM);
P_SetScale(drop, drop->scale>>5);
drop->destscale = (3*drop->destscale)/2;;
drop->angle = player->mo->angle + ANGLE_90;
drop->momx = player->mo->momx>>1;
drop->momy = player->mo->momy>>1;
P_Thrust(drop,
FixedAngle(P_RandomFixed()*180) + player->mo->angle + ANGLE_90,
8*(mapheaderinfo[gamemap-1]->mobj_scale));
drop->momz = P_MobjFlip(player->mo)*3*(mapheaderinfo[gamemap-1]->mobj_scale);
drop->threshold = (thunderhack ? KITEM_THUNDERSHIELD : player->kartstuff[k_itemtype]);
drop->movecount = player->kartstuff[k_itemamount];
drop->flags |= MF_NOCLIPTHING;
}
K_StripItems(player);
}
// When an item in the hnext chain dies.
void K_RepairOrbitChain(mobj_t *orbit)
{
@ -3859,20 +4020,18 @@ static void K_KartUpdatePosition(player_t *player)
//
void K_StripItems(player_t *player)
{
player->kartstuff[k_itemtype] = 0;
player->kartstuff[k_itemtype] = KITEM_NONE;
player->kartstuff[k_itemamount] = 0;
player->kartstuff[k_itemheld] = 0;
player->kartstuff[k_itemroulette] = 0;
player->kartstuff[k_roulettetype] = 0;
player->kartstuff[k_rocketsneakertimer] = 0;
player->kartstuff[k_invincibilitytimer] = 0;
player->kartstuff[k_growshrinktimer] = 0;
if (!player->kartstuff[k_itemroulette] || player->kartstuff[k_roulettetype] != 2)
{
player->kartstuff[k_itemroulette] = 0;
player->kartstuff[k_roulettetype] = 0;
}
player->kartstuff[k_eggmanheld] = 0;
player->kartstuff[k_eggmanexplode] = 0;
player->kartstuff[k_eggmanblame] = 0;
player->kartstuff[k_hyudorotimer] = 0;
player->kartstuff[k_stealingtimer] = 0;
@ -3884,7 +4043,19 @@ void K_StripItems(player_t *player)
player->kartstuff[k_sadtimer] = 0;
K_CleanHnextList(player->mo);
K_UpdateHnextList(player, true);
}
void K_StripOther(player_t *player)
{
player->kartstuff[k_itemroulette] = 0;
player->kartstuff[k_roulettetype] = 0;
player->kartstuff[k_invincibilitytimer] = 0;
player->kartstuff[k_growshrinktimer] = 0;
player->kartstuff[k_eggmanexplode] = 0;
player->kartstuff[k_eggmanblame] = 0;
}
//
@ -3950,7 +4121,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_ThrowKartItem(player, false, MT_FAKEITEM, -1, 0);
K_PlayTauntSound(player->mo);
player->kartstuff[k_eggmanheld] = 0;
K_CleanHnextList(player->mo);
K_UpdateHnextList(player, true);
}
// Rocket Sneaker
else if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO
@ -4037,7 +4208,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_ThrowKartItem(player, false, MT_BANANA, -1, 0);
K_PlayTauntSound(player->mo);
player->kartstuff[k_itemamount]--;
K_UpdateHnextList(player);
K_UpdateHnextList(player, false);
}
break;
case KITEM_EGGMAN:
@ -4097,7 +4268,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_ThrowKartItem(player, true, MT_ORBINAUT, 1, 0);
K_PlayTauntSound(player->mo);
player->kartstuff[k_itemamount]--;
K_UpdateHnextList(player);
K_UpdateHnextList(player, false);
}
break;
case KITEM_JAWZ:
@ -4140,7 +4311,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_ThrowKartItem(player, true, MT_JAWZ_DUD, -1, 0);
K_PlayTauntSound(player->mo);
player->kartstuff[k_itemamount]--;
K_UpdateHnextList(player);
K_UpdateHnextList(player, false);
}
break;
case KITEM_MINE:
@ -4166,7 +4337,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_PlayTauntSound(player->mo);
player->kartstuff[k_itemamount]--;
player->kartstuff[k_itemheld] = 0;
K_CleanHnextList(player->mo);
K_UpdateHnextList(player, true);
}
break;
case KITEM_BALLHOG:
@ -4293,7 +4464,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_PlayTauntSound(player->mo);
player->kartstuff[k_itemamount]--;
player->kartstuff[k_itemheld] = 0;
K_CleanHnextList(player->mo);
K_UpdateHnextList(player, true);
}
break;
case KITEM_SAD:
@ -4372,7 +4543,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) // dead in match? you da bomb
{
K_StripItems(player);
K_DropItems(player); //K_StripItems(player);
K_StripOther(player);
player->mo->flags2 |= MF2_SHADOW;
player->powers[pw_flashing] = player->kartstuff[k_comebacktimer];
}

View File

@ -39,14 +39,16 @@ void K_DriftDustHandling(mobj_t *spawner);
void K_DoSneaker(player_t *player, boolean doPFlag);
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, boolean mute);
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);
void K_CleanHnextList(mobj_t *work);
void K_UpdateHnextList(player_t *player);
void K_UpdateHnextList(player_t *player, boolean clean);
void K_DropHnextList(player_t *player);
void K_RepairOrbitChain(mobj_t *orbit);
player_t *K_FindJawzTarget(mobj_t *actor, player_t *source);
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
fixed_t K_GetKartDriftSparkValue(player_t *player);
void K_DropItems(player_t *player);
void K_StripItems(player_t *player);
void K_StripOther(player_t *player);
void K_MomentumToFacing(player_t *player);
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower);
fixed_t K_GetKartAccel(player_t *player);

View File

@ -181,13 +181,13 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
{
// Item-specific timer going off
if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer]
|| player->kartstuff[k_growshrinktimer] != 0 || player->kartstuff[k_rocketsneakertimer]
|| player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_rocketsneakertimer]
|| player->kartstuff[k_eggmanexplode])
return false;
// Item slot already taken up
if (player->kartstuff[k_itemroulette]
|| player->kartstuff[k_itemamount]
|| (weapon != 3 && player->kartstuff[k_itemamount])
|| player->kartstuff[k_itemheld])
return false;
}
@ -429,6 +429,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// We now identify by object type, not sprite! Tails 04-11-2001
switch (special->type)
{
case MT_FLOATINGITEM: // SRB2kart
if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold))
return;
if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0)
return;
player->kartstuff[k_itemtype] = special->threshold;
player->kartstuff[k_itemamount] += special->movecount;
if (player->kartstuff[k_itemamount] > 255)
player->kartstuff[k_itemamount] = 255;
S_StartSound(special, special->info->deathsound);
P_SetTarget(&special->tracer, toucher);
special->flags2 |= MF2_NIGHTSPULL;
special->destscale = mapheaderinfo[gamemap-1]->mobj_scale>>5;
special->scalespeed <<= 1;
special->flags &= ~MF_SPECIAL;
return;
case MT_RANDOMITEM: // SRB2kart
if (!P_CanPickupItem(player, 1))
return;
@ -469,9 +490,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
S_StartSound(poof, special->info->deathsound);
K_StripItems(player);
if (player->kartstuff[k_itemroulette] <= 0)
player->kartstuff[k_itemroulette] = 1;
K_DropItems(player); //K_StripItems(player);
K_StripOther(player);
player->kartstuff[k_itemroulette] = 1;
player->kartstuff[k_roulettetype] = 2;
if (special->target && special->target->player
&& (G_RaceGametype() || special->target->player->kartstuff[k_bumper] > 0))
@ -2626,6 +2647,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
}
}
if ((target->type == MT_JAWZ || target->type == MT_JAWZ_DUD || target->type == MT_JAWZ_SHIELD) && !(target->flags2 & MF2_AMBUSH))
{
target->z += P_MobjFlip(target)*20*target->scale;
}
if (target->type == MT_SPIKE && inflictor && target->info->deathstate != S_NULL)
{
const fixed_t x=target->x,y=target->y,z=target->z;
@ -3335,6 +3361,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
player->mo->destscale = 6*player->mo->destscale/8;
// Wipeout
K_DropItems(player);
K_SpinPlayer(player, source, 1, false);
damage = player->mo->health - 1;
P_RingDamage(player, inflictor, source, damage);
@ -3346,7 +3373,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
quake.time = 5;
}
K_StripItems(player);
player->kartstuff[k_growshrinktimer] -= (200+(40*(16-player->kartstuff[k_position])));
}
// Grow? Let's take that away.

View File

@ -497,7 +497,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
}
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)))
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)) || (thing->flags & MF_NOCLIPTHING))
return true;
// Don't collide with your buddies while NiGHTS-flying.

View File

@ -6006,7 +6006,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
return;
// change angle
source->angle = R_PointToAngle2(source->x, source->y, tx, ty);
//source->angle = R_PointToAngle2(source->x, source->y, tx, ty);
// change slope
dist = P_AproxDistance(P_AproxDistance(tx - source->x, ty - source->y), tz - source->z);
@ -6015,7 +6015,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
dist = 1;
if (nightsgrab)
speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(8*FRACUNIT, source->scale);
speedmul = P_AproxDistance(dest->momx, dest->momy) + source->scale;
else
speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(source->info->speed, source->scale);
@ -6348,6 +6348,9 @@ void P_RunShadows(void)
break;
}
}
if (mobj->target->type == MT_FLOATINGITEM)
P_SetScale(mobj, mobj->scale/2);
}
P_SetTarget(&shadowcap, NULL);
}
@ -6727,7 +6730,7 @@ void P_MobjThinker(mobj_t *mobj)
/*if (mobj->health > 0 && mobj->target && mobj->target->player
&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
{
// Was this so hard? -- Handled this with K_UpdateHnextList and K_ClearHnextList instead of thinking it away...
// Was this so hard? -- Handled this with K_UpdateHnextList instead of thinking it away...
if ((mobj->type == MT_ORBINAUT_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_ORBINAUT)
|| (mobj->type == MT_JAWZ_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_JAWZ)
|| (mobj->movedir > 0 && ((UINT16)mobj->target->player->kartstuff[k_itemamount] < mobj->movedir))
@ -6911,14 +6914,16 @@ void P_MobjThinker(mobj_t *mobj)
mobj->x = mobj->target->x;
mobj->y = mobj->target->y;
mobj->angle = R_PointToAngle(mobj->x, mobj->y) + ANGLE_90; // literally only happened because i wanted to ^L^R the SPR_ITEM's
if (!(mobj->target->eflags & MFE_VERTICALFLIP))
{
mobj->z = mobj->target->z + P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT;
mobj->z = mobj->target->z + P_GetPlayerHeight(mobj->target->player)+(16+11)*mapheaderinfo[gamemap-1]->mobj_scale;
mobj->eflags &= ~MFE_VERTICALFLIP;
}
else
{
mobj->z = mobj->target->z - P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT;
mobj->z = mobj->target->z - P_GetPlayerHeight(mobj->target->player)+(16+11)*mapheaderinfo[gamemap-1]->mobj_scale;
mobj->eflags |= MFE_VERTICALFLIP;
}
P_SetThingPosition(mobj);
@ -6934,7 +6939,8 @@ void P_MobjThinker(mobj_t *mobj)
mobj->tracer = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY);
P_SetTarget(&mobj->tracer->target, mobj);
P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM);
P_SetScale(mobj->tracer, mobj->scale);
P_SetMobjState(mobj->tracer, S_ITEMICON); // null sprite and frame to be overwritten later
P_SetScale(mobj->tracer, (mobj->tracer->destscale = mobj->scale));
}
if (!(mobj->flags2 & MF2_DONTDRAW))
@ -7027,7 +7033,7 @@ void P_MobjThinker(mobj_t *mobj)
else
{
P_SetMobjState(mobj, S_PLAYERARROW);
P_SetMobjState(mobj->tracer, S_INVISIBLE);
P_SetMobjState(mobj->tracer, S_ITEMICON); // null sprite and frame to be overwritten later
}
mobj->tracer->destscale = scale;
@ -7097,12 +7103,12 @@ void P_MobjThinker(mobj_t *mobj)
if (!(mobj->target->eflags & MFE_VERTICALFLIP))
{
mobj->z = mobj->target->z + (P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT+(64*mobj->scale));
mobj->z = mobj->target->z + (P_GetPlayerHeight(mobj->target->player)+16*mapheaderinfo[gamemap-1]->mobj_scale+(64*mobj->scale));
mobj->eflags &= ~MFE_VERTICALFLIP;
}
else
{
mobj->z = mobj->target->z - (P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT+(64*mobj->scale));
mobj->z = mobj->target->z - (P_GetPlayerHeight(mobj->target->player)+16*mapheaderinfo[gamemap-1]->mobj_scale+(64*mobj->scale));
mobj->eflags |= MFE_VERTICALFLIP;
}
P_SetThingPosition(mobj);
@ -8007,46 +8013,120 @@ void P_MobjThinker(mobj_t *mobj)
mobj->threshold = 0;
}
break;
case MT_ORBINAUT:
case MT_FLOATINGITEM:
{
sector_t *sec2;
fixed_t finalspeed = mobj->info->speed;
P_SpawnGhostMobj(mobj);
if (gamespeed == 0)
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
else if (gamespeed == 2)
finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4);
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
if (mobj->health <= 5)
if (mobj->flags & MF_NOCLIPTHING)
{
INT32 i;
for (i = 5; i >= mobj->health; i--)
if (P_IsObjectOnGround(mobj))
{
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
mobj->momx = 1;
mobj->momy = 0;
mobj->flags &= ~MF_NOCLIPTHING;
mobj->flags |= MF_NOGRAVITY;
}
finalspeed = FixedMul(finalspeed, mapheaderinfo[gamemap-1]->mobj_scale);
P_InstaThrust(mobj, mobj->angle, finalspeed);
}
else
{
finalspeed = FixedMul(finalspeed, mapheaderinfo[gamemap-1]->mobj_scale);
P_InstaThrust(mobj, mobj->angle, finalspeed);
mobj->angle += 2*ANG2;
if (mobj->flags2 & MF2_NIGHTSPULL)
{
if (!mobj->tracer || !mobj->tracer->health
|| mobj->scale <= mapheaderinfo[gamemap-1]->mobj_scale>>5)
{
P_RemoveMobj(mobj);
return;
}
P_Attract(mobj, mobj->tracer, true);
}
else
{
fixed_t adj = FixedMul(FRACUNIT - FINECOSINE((mobj->movedir>>ANGLETOFINESHIFT) & FINEMASK), (mapheaderinfo[gamemap-1]->mobj_scale<<3));
mobj->movedir += 2*ANG2;
if (mobj->eflags & MFE_VERTICALFLIP)
mobj->z = mobj->ceilingz - mobj->height - adj;
else
mobj->z = mobj->floorz + adj;
}
}
sec2 = P_ThingOnSpecial3DFloor(mobj);
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
K_DoPogoSpring(mobj, 0, false);
switch (mobj->threshold)
{
case KITEM_ORBINAUT:
mobj->sprite = SPR_ITMO;
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(min(mobj->movecount-1, 3));
break;
case KITEM_INVINCIBILITY:
mobj->sprite = SPR_ITMI;
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|((leveltime % (7*3)) / 3);
break;
case KITEM_SAD:
mobj->sprite = SPR_ITEM;
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE;
break;
default:
mobj->sprite = SPR_ITEM;
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(mobj->threshold);
break;
}
break;
}
case MT_ORBINAUT:
{
boolean grounded = P_IsObjectOnGround(mobj);
if (mobj->flags2 & MF2_AMBUSH)
{
if (grounded && (mobj->flags & MF_NOCLIPTHING))
{
mobj->momx = 1;
mobj->momy = 0;
mobj->frame = 3;
S_StartSound(mobj, mobj->info->activesound);
mobj->flags &= ~MF_NOCLIPTHING;
}
else if (mobj->movecount)
mobj->movecount--;
else if (mobj->frame < 3)
{
mobj->movecount = 2;
mobj->frame++;
}
}
else
{
fixed_t finalspeed = mobj->info->speed;
if (mobj->threshold > 0)
mobj->threshold--;
P_SpawnGhostMobj(mobj);
if (leveltime % 6 == 0)
S_StartSound(mobj, mobj->info->activesound);
if (gamespeed == 0)
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
else if (gamespeed == 2)
finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4);
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
if (mobj->health <= 5)
{
INT32 i;
for (i = 5; i >= mobj->health; i--)
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
}
finalspeed = FixedMul(finalspeed, mapheaderinfo[gamemap-1]->mobj_scale);
P_InstaThrust(mobj, mobj->angle, finalspeed);
if (grounded)
{
sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj);
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
K_DoPogoSpring(mobj, 0, false);
}
if (mobj->threshold > 0)
mobj->threshold--;
if (leveltime % 6 == 0)
S_StartSound(mobj, mobj->info->activesound);
}
break;
}
case MT_JAWZ:
@ -8119,23 +8199,38 @@ void P_MobjThinker(mobj_t *mobj)
}
case MT_JAWZ_DUD:
{
sector_t *sec2;
boolean grounded = P_IsObjectOnGround(mobj);
if (mobj->flags2 & MF2_AMBUSH)
{
if (grounded && (mobj->flags & MF_NOCLIPTHING))
{
mobj->momx = 1;
mobj->momy = 0;
S_StartSound(mobj, mobj->info->deathsound);
mobj->flags &= ~MF_NOCLIPTHING;
}
}
else
{
P_SpawnGhostMobj(mobj);
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
P_InstaThrust(mobj, mobj->angle, mobj->info->speed);
P_SpawnGhostMobj(mobj);
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
P_InstaThrust(mobj, mobj->angle, mobj->info->speed);
if (grounded)
{
sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj);
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
K_DoPogoSpring(mobj, 0, false);
}
sec2 = P_ThingOnSpecial3DFloor(mobj);
if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1)
|| (P_IsObjectOnRealGround(mobj, mobj->subsector->sector)
&& GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1))
K_DoPogoSpring(mobj, 0, false);
if (mobj->threshold > 0)
mobj->threshold--;
if (mobj->threshold > 0)
mobj->threshold--;
if (leveltime % TICRATE == 0)
S_StartSound(mobj, mobj->info->activesound);
if (leveltime % TICRATE == 0)
S_StartSound(mobj, mobj->info->activesound);
}
break;
}
@ -9155,6 +9250,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_BIGMACE: case MT_SMALLMACE:
case MT_FALLINGROCK:
//case MT_RANDOMITEM:
case MT_FLOATINGITEM:
case MT_BATTLEBUMPER:
case MT_BANANA: case MT_BANANA_SHIELD:
//case MT_FAKEITEM: case MT_FAKESHIELD:
@ -9254,6 +9350,8 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->mobj_scale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
P_SetScale(mobj, mobj->destscale);
// set subsector and/or block links
P_SetThingPosition(mobj);
I_Assert(mobj->subsector != NULL);

View File

@ -811,6 +811,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"noooo1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"noooo2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"hogbom", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"mcitm1", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"dbgsal", false, 110, 8, -1, NULL, 0, -1, -1, LUMPERROR},
// SRB2kart - Skin sounds

View File

@ -883,6 +883,7 @@ typedef enum
sfx_noooo1,
sfx_noooo2,
sfx_hogbom,
sfx_mcitm1,
sfx_dbgsal,
sfx_kwin,