mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'capsules' into 'master'
Item Capsules See merge request KartKrew/Kart!440
This commit is contained in:
commit
d5c30742dd
13 changed files with 642 additions and 11 deletions
|
|
@ -425,7 +425,7 @@ typedef struct player_s
|
||||||
UINT8 ringdelay; // (0 to 3) - 3 tic delay between every ring usage
|
UINT8 ringdelay; // (0 to 3) - 3 tic delay between every ring usage
|
||||||
UINT16 ringboost; // Ring boost timer
|
UINT16 ringboost; // Ring boost timer
|
||||||
UINT8 sparkleanim; // (0 to 19) - Angle offset for ring sparkle animation
|
UINT8 sparkleanim; // (0 to 19) - Angle offset for ring sparkle animation
|
||||||
UINT8 superring; // Spawn rings on top of you every tic!
|
UINT16 superring; // Spawn rings on top of you every tic!
|
||||||
|
|
||||||
UINT8 curshield; // see kartshields_t
|
UINT8 curshield; // see kartshields_t
|
||||||
UINT8 bubblecool; // Bubble Shield use cooldown
|
UINT8 bubblecool; // Bubble Shield use cooldown
|
||||||
|
|
|
||||||
|
|
@ -334,6 +334,7 @@ actionpointer_t actionpointers[] =
|
||||||
{{A_ReaperThinker}, "A_REAPERTHINKER"},
|
{{A_ReaperThinker}, "A_REAPERTHINKER"},
|
||||||
{{A_FlameShieldPaper}, "A_FLAMESHIELDPAPER"},
|
{{A_FlameShieldPaper}, "A_FLAMESHIELDPAPER"},
|
||||||
{{A_InvincSparkleRotate}, "A_INVINCSPARKLEROTATE"},
|
{{A_InvincSparkleRotate}, "A_INVINCSPARKLEROTATE"},
|
||||||
|
{{A_SpawnItemCapsuleParts}, "A_SPAWNITEMCAPSULEPARTS"},
|
||||||
|
|
||||||
{{NULL}, "NONE"},
|
{{NULL}, "NONE"},
|
||||||
|
|
||||||
|
|
@ -3484,6 +3485,15 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
||||||
|
|
||||||
"S_ITEMICON",
|
"S_ITEMICON",
|
||||||
|
|
||||||
|
// Item capsules
|
||||||
|
"S_ITEMCAPSULE",
|
||||||
|
"S_ITEMCAPSULE_TOP_SIDE",
|
||||||
|
"S_ITEMCAPSULE_BOTTOM_SIDE_AIR",
|
||||||
|
"S_ITEMCAPSULE_BOTTOM_SIDE_GROUND",
|
||||||
|
"S_ITEMCAPSULE_TOP",
|
||||||
|
"S_ITEMCAPSULE_BOTTOM",
|
||||||
|
"S_ITEMCAPSULE_INSIDE",
|
||||||
|
|
||||||
// Signpost sparkles
|
// Signpost sparkles
|
||||||
"S_SIGNSPARK1",
|
"S_SIGNSPARK1",
|
||||||
"S_SIGNSPARK2",
|
"S_SIGNSPARK2",
|
||||||
|
|
@ -5438,6 +5448,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
||||||
"MT_RANDOMITEM",
|
"MT_RANDOMITEM",
|
||||||
"MT_RANDOMITEMPOP",
|
"MT_RANDOMITEMPOP",
|
||||||
"MT_FLOATINGITEM",
|
"MT_FLOATINGITEM",
|
||||||
|
"MT_ITEMCAPSULE",
|
||||||
|
"MT_ITEMCAPSULE_PART",
|
||||||
|
|
||||||
"MT_SIGNSPARKLE",
|
"MT_SIGNSPARKLE",
|
||||||
|
|
||||||
|
|
|
||||||
64
src/info.c
64
src/info.c
|
|
@ -537,6 +537,8 @@ char sprnames[NUMSPRITES + 1][5] =
|
||||||
"KINB", // Darker invincibility sparkle trail
|
"KINB", // Darker invincibility sparkle trail
|
||||||
"KINF", // Invincibility flash
|
"KINF", // Invincibility flash
|
||||||
"INVI", // Invincibility speedlines
|
"INVI", // Invincibility speedlines
|
||||||
|
"ICAP", // Item capsules
|
||||||
|
|
||||||
"WIPD", // Wipeout dust trail
|
"WIPD", // Wipeout dust trail
|
||||||
"DRIF", // Drift Sparks
|
"DRIF", // Drift Sparks
|
||||||
"BDRF", // Brake drift sparks
|
"BDRF", // Brake drift sparks
|
||||||
|
|
@ -4065,6 +4067,14 @@ state_t states[NUMSTATES] =
|
||||||
|
|
||||||
{SPR_NULL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMICON
|
{SPR_NULL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMICON
|
||||||
|
|
||||||
|
{SPR_ICAP, FF_ADD|0, -1, {A_SpawnItemCapsuleParts}, 0, 0, S_NULL}, // S_ITEMCAPSULE
|
||||||
|
{SPR_ICAP, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_TOP_SIDE
|
||||||
|
{SPR_ICAP, FF_VERTICALFLIP|FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM_SIDE_AIR
|
||||||
|
{SPR_ICAP, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM_SIDE_GROUND
|
||||||
|
{SPR_ICAP, FF_FLOORSPRITE|3, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_TOP
|
||||||
|
{SPR_ICAP, FF_FLOORSPRITE|4, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM
|
||||||
|
{SPR_ICAP, FF_FLOORSPRITE|5, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_INSIDE
|
||||||
|
|
||||||
{SPR_SGNS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1
|
{SPR_SGNS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1
|
||||||
{SPR_SGNS, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2
|
{SPR_SGNS, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2
|
||||||
{SPR_SGNS, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_SIGNSPARK4}, // S_SIGNSPARK3
|
{SPR_SGNS, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_SIGNSPARK4}, // S_SIGNSPARK3
|
||||||
|
|
@ -23055,6 +23065,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_ITEMCAPSULE
|
||||||
|
2010, // doomednum
|
||||||
|
S_ITEMCAPSULE, // 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_INVISIBLE, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_itcaps, // deathsound
|
||||||
|
0, // speed
|
||||||
|
56*FRACUNIT, // radius
|
||||||
|
112*FRACUNIT, // height
|
||||||
|
1, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_SLIDEME|MF_SPECIAL|MF_RUNSPAWNFUNC|MF_DONTENCOREMAP, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_ITEMCAPSULE_PART
|
||||||
|
-1, // doomednum
|
||||||
|
S_INVISIBLE, // spawnstate
|
||||||
|
1000, // 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_None, // deathsound
|
||||||
|
0, // speed
|
||||||
|
26*FRACUNIT, // radius
|
||||||
|
14*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_SCENERY|MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_SIGNSPARKLE
|
{ // MT_SIGNSPARKLE
|
||||||
-1, // doomednum
|
-1, // doomednum
|
||||||
S_SIGNSPARK1, // spawnstate
|
S_SIGNSPARK1, // spawnstate
|
||||||
|
|
|
||||||
14
src/info.h
14
src/info.h
|
|
@ -287,6 +287,7 @@ enum actionnum
|
||||||
A_REAPERTHINKER,
|
A_REAPERTHINKER,
|
||||||
A_FLAMESHIELDPAPER,
|
A_FLAMESHIELDPAPER,
|
||||||
A_INVINCSPARKLEROTATE,
|
A_INVINCSPARKLEROTATE,
|
||||||
|
A_SPAWNITEMCAPSULEPARTS,
|
||||||
NUMACTIONS
|
NUMACTIONS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -557,6 +558,7 @@ void A_ReaperThinker();
|
||||||
void A_MementosTPParticles();
|
void A_MementosTPParticles();
|
||||||
void A_FlameShieldPaper();
|
void A_FlameShieldPaper();
|
||||||
void A_InvincSparkleRotate();
|
void A_InvincSparkleRotate();
|
||||||
|
void A_SpawnItemCapsuleParts();
|
||||||
|
|
||||||
extern boolean actionsoverridden[NUMACTIONS];
|
extern boolean actionsoverridden[NUMACTIONS];
|
||||||
|
|
||||||
|
|
@ -1078,6 +1080,7 @@ typedef enum sprite
|
||||||
SPR_KINB, // Darker invincibility sparkle trail
|
SPR_KINB, // Darker invincibility sparkle trail
|
||||||
SPR_KINF, // Invincibility flash
|
SPR_KINF, // Invincibility flash
|
||||||
SPR_INVI, // Invincibility speedlines
|
SPR_INVI, // Invincibility speedlines
|
||||||
|
SPR_ICAP, // Item capsules
|
||||||
|
|
||||||
SPR_WIPD, // Wipeout dust trail
|
SPR_WIPD, // Wipeout dust trail
|
||||||
SPR_DRIF, // Drift Sparks
|
SPR_DRIF, // Drift Sparks
|
||||||
|
|
@ -4457,6 +4460,15 @@ typedef enum state
|
||||||
|
|
||||||
S_ITEMICON,
|
S_ITEMICON,
|
||||||
|
|
||||||
|
// Item capsules
|
||||||
|
S_ITEMCAPSULE,
|
||||||
|
S_ITEMCAPSULE_TOP_SIDE,
|
||||||
|
S_ITEMCAPSULE_BOTTOM_SIDE_AIR,
|
||||||
|
S_ITEMCAPSULE_BOTTOM_SIDE_GROUND,
|
||||||
|
S_ITEMCAPSULE_TOP,
|
||||||
|
S_ITEMCAPSULE_BOTTOM,
|
||||||
|
S_ITEMCAPSULE_INSIDE,
|
||||||
|
|
||||||
// Signpost sparkles
|
// Signpost sparkles
|
||||||
S_SIGNSPARK1,
|
S_SIGNSPARK1,
|
||||||
S_SIGNSPARK2,
|
S_SIGNSPARK2,
|
||||||
|
|
@ -6448,6 +6460,8 @@ typedef enum mobj_type
|
||||||
MT_RANDOMITEM,
|
MT_RANDOMITEM,
|
||||||
MT_RANDOMITEMPOP,
|
MT_RANDOMITEMPOP,
|
||||||
MT_FLOATINGITEM,
|
MT_FLOATINGITEM,
|
||||||
|
MT_ITEMCAPSULE,
|
||||||
|
MT_ITEMCAPSULE_PART,
|
||||||
|
|
||||||
MT_SIGNSPARKLE,
|
MT_SIGNSPARKLE,
|
||||||
|
|
||||||
|
|
|
||||||
50
src/k_kart.c
50
src/k_kart.c
|
|
@ -1916,7 +1916,7 @@ void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master)
|
||||||
K_FlipFromObject(mo, master);
|
K_FlipFromObject(mo, master);
|
||||||
|
|
||||||
// visibility (usually for hyudoro)
|
// visibility (usually for hyudoro)
|
||||||
mo->renderflags = (master->renderflags & RF_DONTDRAW);
|
mo->renderflags = (mo->renderflags & ~RF_DONTDRAW) | (master->renderflags & RF_DONTDRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
// same as above, but does not adjust Z height when flipping
|
// same as above, but does not adjust Z height when flipping
|
||||||
|
|
@ -1927,7 +1927,7 @@ void K_GenericExtraFlagsNoZAdjust(mobj_t *mo, mobj_t *master)
|
||||||
mo->flags2 = (mo->flags2 & ~MF2_OBJECTFLIP)|(master->flags2 & MF2_OBJECTFLIP);
|
mo->flags2 = (mo->flags2 & ~MF2_OBJECTFLIP)|(master->flags2 & MF2_OBJECTFLIP);
|
||||||
|
|
||||||
// visibility (usually for hyudoro)
|
// visibility (usually for hyudoro)
|
||||||
mo->renderflags = (master->renderflags & RF_DONTDRAW);
|
mo->renderflags = (mo->renderflags & ~RF_DONTDRAW) | (master->renderflags & RF_DONTDRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4470,7 +4470,7 @@ static mobj_t *K_FindLastTrailMobj(player_t *player)
|
||||||
return trail;
|
return trail;
|
||||||
}
|
}
|
||||||
|
|
||||||
static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow)
|
mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow)
|
||||||
{
|
{
|
||||||
mobj_t *mo;
|
mobj_t *mo;
|
||||||
INT32 dir;
|
INT32 dir;
|
||||||
|
|
@ -9002,7 +9002,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KITEM_SUPERRING:
|
case KITEM_SUPERRING:
|
||||||
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO && player->superring < (UINT8_MAX - (10*3)))
|
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO && player->superring < (UINT16_MAX - (10*3)))
|
||||||
{
|
{
|
||||||
player->superring += (10*3);
|
player->superring += (10*3);
|
||||||
player->itemamount--;
|
player->itemamount--;
|
||||||
|
|
@ -9409,4 +9409,46 @@ void K_CheckSpectateStatus(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT8 K_GetInvincibilityItemFrame(void)
|
||||||
|
{
|
||||||
|
return ((leveltime % (7*3)) / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 K_GetOrbinautItemFrame(UINT8 count)
|
||||||
|
{
|
||||||
|
return min(count - 1, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean K_IsSPBInGame(void)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
thinker_t *think;
|
||||||
|
|
||||||
|
// is there an SPB chasing anyone?
|
||||||
|
if (spbplace != -1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// do any players have an SPB in their item slot?
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (!playeringame[i] || players[i].spectator)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (players[i].itemtype == KITEM_SPB)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// spbplace is still -1 until a fired SPB finds a target, so look for an in-map SPB just in case
|
||||||
|
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
|
||||||
|
{
|
||||||
|
if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (((mobj_t *)think)->type == MT_SPB)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ void K_SpawnSparkleTrail(mobj_t *mo);
|
||||||
void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad);
|
void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad);
|
||||||
void K_SpawnDraftDust(mobj_t *mo);
|
void K_SpawnDraftDust(mobj_t *mo);
|
||||||
void K_DriftDustHandling(mobj_t *spawner);
|
void K_DriftDustHandling(mobj_t *spawner);
|
||||||
|
mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow);
|
||||||
void K_PuntMine(mobj_t *mine, mobj_t *punter);
|
void K_PuntMine(mobj_t *mine, mobj_t *punter);
|
||||||
void K_DoSneaker(player_t *player, INT32 type);
|
void K_DoSneaker(player_t *player, INT32 type);
|
||||||
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound);
|
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound);
|
||||||
|
|
@ -118,6 +119,9 @@ SINT8 K_Sliptiding(player_t *player);
|
||||||
void K_AdjustPlayerFriction(player_t *player);
|
void K_AdjustPlayerFriction(player_t *player);
|
||||||
void K_MoveKartPlayer(player_t *player, boolean onground);
|
void K_MoveKartPlayer(player_t *player, boolean onground);
|
||||||
void K_CheckSpectateStatus(void);
|
void K_CheckSpectateStatus(void);
|
||||||
|
UINT8 K_GetInvincibilityItemFrame(void);
|
||||||
|
UINT8 K_GetOrbinautItemFrame(UINT8 count);
|
||||||
|
boolean K_IsSPBInGame(void);
|
||||||
|
|
||||||
// sound stuff for lua
|
// sound stuff for lua
|
||||||
void K_PlayAttackTaunt(mobj_t *source);
|
void K_PlayAttackTaunt(mobj_t *source);
|
||||||
|
|
|
||||||
189
src/p_enemy.c
189
src/p_enemy.c
|
|
@ -321,6 +321,7 @@ void A_ReaperThinker(mobj_t *actor);
|
||||||
void A_MementosTPParticles(mobj_t *actor);
|
void A_MementosTPParticles(mobj_t *actor);
|
||||||
void A_FlameShieldPaper(mobj_t *actor);
|
void A_FlameShieldPaper(mobj_t *actor);
|
||||||
void A_InvincSparkleRotate(mobj_t *actor);
|
void A_InvincSparkleRotate(mobj_t *actor);
|
||||||
|
void A_SpawnItemCapsuleParts(mobj_t *actor);
|
||||||
|
|
||||||
//for p_enemy.c
|
//for p_enemy.c
|
||||||
|
|
||||||
|
|
@ -14651,3 +14652,191 @@ void A_InvincSparkleRotate(mobj_t *actor)
|
||||||
|
|
||||||
actor->angle += ANG1*10*(actor->extravalue2); // Arbitrary value, change this if you want, I suppose.
|
actor->angle += ANG1*10*(actor->extravalue2); // Arbitrary value, change this if you want, I suppose.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void P_RefreshItemCapsuleParts(mobj_t *mobj)
|
||||||
|
{
|
||||||
|
UINT8 numNumbers = 0;
|
||||||
|
INT32 count = 0;
|
||||||
|
INT32 itemType = mobj->threshold;
|
||||||
|
mobj_t *part;
|
||||||
|
skincolornum_t color;
|
||||||
|
UINT32 newRenderFlags = 0;
|
||||||
|
boolean colorized;
|
||||||
|
|
||||||
|
if (itemType < 1 || itemType >= NUMKARTITEMS)
|
||||||
|
itemType = KITEM_SAD;
|
||||||
|
|
||||||
|
// update invincibility properties
|
||||||
|
if (itemType == KITEM_INVINCIBILITY)
|
||||||
|
{
|
||||||
|
mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_FULLBRIGHT;
|
||||||
|
mobj->colorized = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_SEMIBRIGHT;
|
||||||
|
mobj->color = SKINCOLOR_NONE;
|
||||||
|
mobj->colorized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update cap colors
|
||||||
|
if (itemType == KITEM_SUPERRING)
|
||||||
|
{
|
||||||
|
color = SKINCOLOR_GOLD;
|
||||||
|
newRenderFlags |= RF_SEMIBRIGHT;
|
||||||
|
}
|
||||||
|
else if (mobj->spawnpoint && (mobj->spawnpoint->options & MTF_EXTRA))
|
||||||
|
color = SKINCOLOR_SAPPHIRE;
|
||||||
|
else if (itemType == KITEM_SPB)
|
||||||
|
color = SKINCOLOR_JET;
|
||||||
|
else
|
||||||
|
color = SKINCOLOR_NONE;
|
||||||
|
|
||||||
|
colorized = (color != SKINCOLOR_NONE);
|
||||||
|
part = mobj;
|
||||||
|
while (!P_MobjWasRemoved(part->hnext))
|
||||||
|
{
|
||||||
|
part = part->hnext;
|
||||||
|
part->color = color;
|
||||||
|
part->colorized = colorized;
|
||||||
|
part->renderflags = (part->renderflags & ~RF_BRIGHTMASK) | newRenderFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update inside item frame
|
||||||
|
part = mobj->tracer;
|
||||||
|
if (P_MobjWasRemoved(part))
|
||||||
|
return;
|
||||||
|
|
||||||
|
part->threshold = mobj->threshold;
|
||||||
|
part->movecount = mobj->movecount;
|
||||||
|
|
||||||
|
switch (itemType)
|
||||||
|
{
|
||||||
|
case KITEM_ORBINAUT:
|
||||||
|
part->sprite = SPR_ITMO;
|
||||||
|
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetOrbinautItemFrame(mobj->movecount);
|
||||||
|
break;
|
||||||
|
case KITEM_INVINCIBILITY:
|
||||||
|
part->sprite = SPR_ITMI;
|
||||||
|
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame();
|
||||||
|
break;
|
||||||
|
case KITEM_SAD:
|
||||||
|
part->sprite = SPR_ITEM;
|
||||||
|
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
part->sprite = SPR_ITEM;
|
||||||
|
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(itemType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update number frame
|
||||||
|
if (K_GetShieldFromItem(itemType) != KSHIELD_NONE) // shields don't stack, so don't show a number
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (itemType)
|
||||||
|
{
|
||||||
|
case KITEM_ORBINAUT: // only display the number when the sprite no longer changes
|
||||||
|
if (mobj->movecount - 1 > K_GetOrbinautItemFrame(mobj->movecount))
|
||||||
|
count = mobj->movecount;
|
||||||
|
break;
|
||||||
|
case KITEM_SUPERRING: // always display the number, and multiply it by 5
|
||||||
|
count = mobj->movecount * 5;
|
||||||
|
break;
|
||||||
|
case KITEM_SAD: // never display the number
|
||||||
|
case KITEM_SPB:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (mobj->movecount > 1)
|
||||||
|
count = mobj->movecount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
if (P_MobjWasRemoved(part->tracer))
|
||||||
|
{
|
||||||
|
P_SetTarget(&part->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY));
|
||||||
|
P_SetTarget(&part->tracer->target, part);
|
||||||
|
P_SetMobjState(part->tracer, S_INVISIBLE);
|
||||||
|
part->tracer->spriteyoffset = 10*FRACUNIT;
|
||||||
|
part->tracer->spritexoffset = 13*numNumbers*FRACUNIT;
|
||||||
|
}
|
||||||
|
part = part->tracer;
|
||||||
|
part->sprite = SPR_ITMN;
|
||||||
|
part->frame = FF_FULLBRIGHT|(count % 10);
|
||||||
|
count /= 10;
|
||||||
|
numNumbers++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete any extra overlays (I guess in case the number changes?)
|
||||||
|
if (part->tracer)
|
||||||
|
{
|
||||||
|
P_RemoveMobj(part->tracer);
|
||||||
|
P_SetTarget(&part->tracer, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CAPSULESIDES 5
|
||||||
|
#define ANG_CAPSULE (UINT32_MAX / CAPSULESIDES)
|
||||||
|
#define ROTATIONSPEED (2*ANG2)
|
||||||
|
void A_SpawnItemCapsuleParts(mobj_t *actor)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
mobj_t *part;
|
||||||
|
fixed_t buttScale = 0;
|
||||||
|
statenum_t buttState = S_ITEMCAPSULE_BOTTOM_SIDE_AIR;
|
||||||
|
angle_t spin = ANGLE_MAX - ROTATIONSPEED;
|
||||||
|
|
||||||
|
if (LUA_CallAction(A_SPAWNITEMCAPSULEPARTS, actor))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (P_IsObjectOnGround(actor))
|
||||||
|
{
|
||||||
|
buttScale = 13*FRACUNIT/10;
|
||||||
|
buttState = S_ITEMCAPSULE_BOTTOM_SIDE_GROUND;
|
||||||
|
spin = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// inside item
|
||||||
|
part = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART);
|
||||||
|
P_SetTarget(&part->target, actor);
|
||||||
|
P_SetMobjState(part, S_ITEMICON);
|
||||||
|
part->movedir = ROTATIONSPEED; // rotation speed
|
||||||
|
part->extravalue1 = 175*FRACUNIT/100; // relative scale
|
||||||
|
part->flags2 |= MF2_CLASSICPUSH; // classicpush = centered horizontally
|
||||||
|
P_SetTarget(&actor->tracer, part); // pointer to this item, so we can modify its sprite/frame
|
||||||
|
|
||||||
|
// capsule caps
|
||||||
|
part = actor;
|
||||||
|
for (i = 0; i < CAPSULESIDES; i++)
|
||||||
|
{
|
||||||
|
// a bottom side
|
||||||
|
P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART));
|
||||||
|
P_SetTarget(&part->hnext->hprev, part);
|
||||||
|
part = part->hnext;
|
||||||
|
P_SetTarget(&part->target, actor);
|
||||||
|
P_SetMobjState(part, buttState);
|
||||||
|
part->angle = i * ANG_CAPSULE;
|
||||||
|
part->movedir = spin; // rotation speed
|
||||||
|
part->movefactor = 0; // z offset
|
||||||
|
part->extravalue1 = buttScale; // relative scale
|
||||||
|
|
||||||
|
// a top side
|
||||||
|
P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART));
|
||||||
|
P_SetTarget(&part->hnext->hprev, part);
|
||||||
|
part = part->hnext;
|
||||||
|
P_SetTarget(&part->target, actor);
|
||||||
|
P_SetMobjState(part, S_ITEMCAPSULE_TOP_SIDE);
|
||||||
|
part->angle = i * ANG_CAPSULE;
|
||||||
|
part->movedir = spin; // rotation speed
|
||||||
|
part->movefactor = actor->info->height - part->info->height; // z offset
|
||||||
|
}
|
||||||
|
|
||||||
|
P_RefreshItemCapsuleParts(actor);
|
||||||
|
}
|
||||||
|
#undef CAPSULESIDES
|
||||||
|
#undef ANG_CAPSULE
|
||||||
|
#undef ROTATIONSPEED
|
||||||
|
|
|
||||||
129
src/p_inter.c
129
src/p_inter.c
|
|
@ -277,6 +277,24 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
P_SetTarget(&special->target, toucher);
|
P_SetTarget(&special->target, toucher);
|
||||||
P_KillMobj(special, toucher, toucher, DMG_NORMAL);
|
P_KillMobj(special, toucher, toucher, DMG_NORMAL);
|
||||||
break;
|
break;
|
||||||
|
case MT_ITEMCAPSULE:
|
||||||
|
if (special->threshold != KITEM_SUPERRING
|
||||||
|
&& special->threshold != KITEM_SPB
|
||||||
|
&& !P_CanPickupItem(player, 1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (special->scale < special->extravalue1) // don't break it while it's respawning
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (special->threshold == KITEM_SPB && K_IsSPBInGame()) // don't spawn a second SPB
|
||||||
|
return;
|
||||||
|
|
||||||
|
S_StartSound(toucher, special->info->deathsound);
|
||||||
|
P_KillMobj(special, toucher, toucher, DMG_NORMAL);
|
||||||
|
return;
|
||||||
case MT_KARMAHITBOX:
|
case MT_KARMAHITBOX:
|
||||||
if (!special->target->player)
|
if (!special->target->player)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1282,6 +1300,117 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MT_ITEMCAPSULE:
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
mobj_t *attacker = inflictor ? inflictor : source;
|
||||||
|
mobj_t *part = target->hnext;
|
||||||
|
angle_t angle = FixedAngle(360*P_RandomFixed());
|
||||||
|
INT16 spacing = (target->radius >> 1) / target->scale;
|
||||||
|
|
||||||
|
// set respawn fuse
|
||||||
|
if (modeattacking) // no respawns
|
||||||
|
;
|
||||||
|
else if (target->threshold == KITEM_SUPERRING)
|
||||||
|
target->fuse = 20*TICRATE;
|
||||||
|
else
|
||||||
|
target->fuse = 40*TICRATE;
|
||||||
|
|
||||||
|
// burst effects
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
mobj_t *blast = P_SpawnMobjFromMobj(target, 0, 0, target->info->height >> 1, MT_BATTLEBUMPER_BLAST);
|
||||||
|
blast->angle = angle + i*ANGLE_90;
|
||||||
|
P_SetScale(blast, 2*blast->scale/3);
|
||||||
|
blast->destscale = 2*blast->scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dust effects
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
mobj_t *puff = P_SpawnMobjFromMobj(
|
||||||
|
target,
|
||||||
|
P_RandomRange(-spacing, spacing) * FRACUNIT,
|
||||||
|
P_RandomRange(-spacing, spacing) * FRACUNIT,
|
||||||
|
P_RandomRange(0, 4*spacing) * FRACUNIT,
|
||||||
|
MT_SPINDASHDUST
|
||||||
|
);
|
||||||
|
|
||||||
|
P_SetScale(puff, (puff->destscale *= 2));
|
||||||
|
puff->momz = puff->scale * P_MobjFlip(puff);
|
||||||
|
|
||||||
|
P_Thrust(puff, R_PointToAngle2(target->x, target->y, puff->x, puff->y), 3*puff->scale);
|
||||||
|
if (attacker)
|
||||||
|
{
|
||||||
|
puff->momx += attacker->momx;
|
||||||
|
puff->momy += attacker->momy;
|
||||||
|
puff->momz += attacker->momz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove inside item
|
||||||
|
if (target->tracer && !P_MobjWasRemoved(target->tracer))
|
||||||
|
P_RemoveMobj(target->tracer);
|
||||||
|
|
||||||
|
// bust capsule caps
|
||||||
|
while (part && !P_MobjWasRemoved(part))
|
||||||
|
{
|
||||||
|
P_InstaThrust(part, part->angle + ANGLE_90, 6 * part->target->scale);
|
||||||
|
P_SetObjectMomZ(part, 6 * FRACUNIT, false);
|
||||||
|
part->fuse = TICRATE/2;
|
||||||
|
part->flags &= ~MF_NOGRAVITY;
|
||||||
|
|
||||||
|
if (attacker)
|
||||||
|
{
|
||||||
|
part->momx += attacker->momx;
|
||||||
|
part->momy += attacker->momy;
|
||||||
|
part->momz += attacker->momz;
|
||||||
|
}
|
||||||
|
part = part->hnext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// give the player an item!
|
||||||
|
if (source && source->player)
|
||||||
|
{
|
||||||
|
player_t *player = source->player;
|
||||||
|
|
||||||
|
// special behavior for ring capsules
|
||||||
|
if (target->threshold == KITEM_SUPERRING)
|
||||||
|
{
|
||||||
|
player->superring = min(player->superring + 5*target->movecount*3, UINT16_MAX);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// special behavior for SPB capsules
|
||||||
|
if (target->threshold == KITEM_SPB)
|
||||||
|
{
|
||||||
|
K_ThrowKartItem(player, true, MT_SPB, 1, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target->threshold < 1 || target->threshold >= NUMKARTITEMS) // bruh moment prevention
|
||||||
|
{
|
||||||
|
player->itemtype = KITEM_SAD;
|
||||||
|
player->itemamount = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player->itemtype = target->threshold;
|
||||||
|
if (K_GetShieldFromItem(player->itemtype) != KSHIELD_NONE) // never give more than 1 shield
|
||||||
|
player->itemamount = 1;
|
||||||
|
else
|
||||||
|
player->itemamount = max(1, target->movecount);
|
||||||
|
}
|
||||||
|
player->karthud[khud_itemblink] = TICRATE;
|
||||||
|
player->karthud[khud_itemblinkmode] = 0;
|
||||||
|
player->itemroulette = 0;
|
||||||
|
player->roulettetype = 0;
|
||||||
|
if (P_IsDisplayPlayer(player))
|
||||||
|
S_StartSound(NULL, sfx_itrolf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MT_BATTLECAPSULE:
|
case MT_BATTLECAPSULE:
|
||||||
{
|
{
|
||||||
mobj_t *cur;
|
mobj_t *cur;
|
||||||
|
|
|
||||||
|
|
@ -365,6 +365,8 @@ void P_InternalFlickyBubble(mobj_t *actor);
|
||||||
void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez);
|
void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez);
|
||||||
void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angle);
|
void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angle);
|
||||||
|
|
||||||
|
void P_RefreshItemCapsuleParts(mobj_t *mobj);
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_MAP
|
// P_MAP
|
||||||
//
|
//
|
||||||
|
|
|
||||||
181
src/p_mobj.c
181
src/p_mobj.c
|
|
@ -3748,6 +3748,57 @@ static void P_RingThinker(mobj_t *mobj)
|
||||||
P_CycleMobjState(mobj);
|
P_CycleMobjState(mobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void P_ItemCapsulePartThinker(mobj_t *mobj)
|
||||||
|
{
|
||||||
|
if (mobj->fuse > 0) // dead
|
||||||
|
{
|
||||||
|
mobj->fuse--;
|
||||||
|
if (mobj->fuse == 0)
|
||||||
|
{
|
||||||
|
P_RemoveMobj(mobj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mobj->renderflags ^= RF_DONTDRAW;
|
||||||
|
}
|
||||||
|
else // alive
|
||||||
|
{
|
||||||
|
mobj_t *target = mobj->target;
|
||||||
|
fixed_t targetScale, z;
|
||||||
|
|
||||||
|
if (P_MobjWasRemoved(target))
|
||||||
|
{
|
||||||
|
P_RemoveMobj(mobj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// match the capsule's scale
|
||||||
|
if (mobj->extravalue1)
|
||||||
|
targetScale = FixedMul(mobj->extravalue1, target->scale);
|
||||||
|
else
|
||||||
|
targetScale = target->scale;
|
||||||
|
|
||||||
|
if (mobj->scale != targetScale)
|
||||||
|
P_SetScale(mobj, mobj->destscale = targetScale);
|
||||||
|
|
||||||
|
// find z position
|
||||||
|
K_GenericExtraFlagsNoZAdjust(mobj, target);
|
||||||
|
if (mobj->flags & MFE_VERTICALFLIP)
|
||||||
|
z = target->z + target->height - mobj->height - FixedMul(mobj->scale, mobj->movefactor);
|
||||||
|
else
|
||||||
|
z = target->z + FixedMul(mobj->scale, mobj->movefactor);
|
||||||
|
|
||||||
|
// rotate & move to capsule
|
||||||
|
mobj->angle += mobj->movedir;
|
||||||
|
if (mobj->flags2 & MF2_CLASSICPUSH) // centered
|
||||||
|
P_TeleportMove(mobj, target->x, target->y, z);
|
||||||
|
else
|
||||||
|
P_TeleportMove(mobj,
|
||||||
|
target->x + P_ReturnThrustX(mobj, mobj->angle + ANGLE_90, mobj->radius),
|
||||||
|
target->y + P_ReturnThrustY(mobj, mobj->angle + ANGLE_90, mobj->radius),
|
||||||
|
z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_BossTargetPlayer
|
// P_BossTargetPlayer
|
||||||
// If closest is true, find the closest player.
|
// If closest is true, find the closest player.
|
||||||
|
|
@ -5457,11 +5508,11 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
||||||
{
|
{
|
||||||
case KITEM_ORBINAUT:
|
case KITEM_ORBINAUT:
|
||||||
mobj->tracer->sprite = SPR_ITMO;
|
mobj->tracer->sprite = SPR_ITMO;
|
||||||
mobj->tracer->frame = FF_FULLBRIGHT|(min(mobj->target->player->itemamount-1, 3));
|
mobj->tracer->frame = FF_FULLBRIGHT|K_GetOrbinautItemFrame(mobj->target->player->itemamount);
|
||||||
break;
|
break;
|
||||||
case KITEM_INVINCIBILITY:
|
case KITEM_INVINCIBILITY:
|
||||||
mobj->tracer->sprite = SPR_ITMI;
|
mobj->tracer->sprite = SPR_ITMI;
|
||||||
mobj->tracer->frame = FF_FULLBRIGHT|((leveltime % (7*3)) / 3);
|
mobj->tracer->frame = FF_FULLBRIGHT|K_GetInvincibilityItemFrame();
|
||||||
break;
|
break;
|
||||||
case KITEM_SAD:
|
case KITEM_SAD:
|
||||||
mobj->tracer->sprite = SPR_ITEM;
|
mobj->tracer->sprite = SPR_ITEM;
|
||||||
|
|
@ -5589,6 +5640,9 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
||||||
P_SetMobjStateNF(smok, smok->info->painstate); // same function, diff sprite
|
P_SetMobjStateNF(smok, smok->info->painstate); // same function, diff sprite
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MT_ITEMCAPSULE_PART:
|
||||||
|
P_ItemCapsulePartThinker(mobj);
|
||||||
|
break;
|
||||||
case MT_BATTLECAPSULE_PIECE:
|
case MT_BATTLECAPSULE_PIECE:
|
||||||
if (mobj->extravalue2)
|
if (mobj->extravalue2)
|
||||||
mobj->frame |= FF_VERTICALFLIP;
|
mobj->frame |= FF_VERTICALFLIP;
|
||||||
|
|
@ -6063,11 +6117,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
{
|
{
|
||||||
case KITEM_ORBINAUT:
|
case KITEM_ORBINAUT:
|
||||||
mobj->sprite = SPR_ITMO;
|
mobj->sprite = SPR_ITMO;
|
||||||
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(min(mobj->movecount-1, 3));
|
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetOrbinautItemFrame(mobj->movecount);
|
||||||
break;
|
break;
|
||||||
case KITEM_INVINCIBILITY:
|
case KITEM_INVINCIBILITY:
|
||||||
mobj->sprite = SPR_ITMI;
|
mobj->sprite = SPR_ITMI;
|
||||||
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|((leveltime % (7*3)) / 3);
|
mobj->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame();
|
||||||
break;
|
break;
|
||||||
case KITEM_SAD:
|
case KITEM_SAD:
|
||||||
mobj->sprite = SPR_ITEM;
|
mobj->sprite = SPR_ITEM;
|
||||||
|
|
@ -6084,6 +6138,38 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MT_ITEMCAPSULE:
|
||||||
|
// scale the capsule
|
||||||
|
if (mobj->scale < mobj->extravalue1)
|
||||||
|
{
|
||||||
|
fixed_t oldHeight = mobj->height;
|
||||||
|
|
||||||
|
if ((mobj->extravalue1 - mobj->scale) < mobj->scalespeed)
|
||||||
|
P_SetScale(mobj, mobj->destscale = mobj->extravalue1);
|
||||||
|
else
|
||||||
|
P_SetScale(mobj, mobj->destscale = mobj->scale + mobj->scalespeed);
|
||||||
|
|
||||||
|
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||||
|
mobj->z -= (mobj->height - oldHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update & animate capsule
|
||||||
|
if (!P_MobjWasRemoved(mobj->tracer))
|
||||||
|
{
|
||||||
|
mobj_t *part = mobj->tracer;
|
||||||
|
|
||||||
|
if (mobj->threshold != part->threshold
|
||||||
|
|| mobj->movecount != part->movecount) // change the capsule properties if the item type or amount is updated
|
||||||
|
P_RefreshItemCapsuleParts(mobj);
|
||||||
|
|
||||||
|
// animate invincibility capsules
|
||||||
|
if (mobj->threshold == KITEM_INVINCIBILITY)
|
||||||
|
{
|
||||||
|
mobj->color = K_RainbowColor(leveltime);
|
||||||
|
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MT_ORBINAUT:
|
case MT_ORBINAUT:
|
||||||
{
|
{
|
||||||
boolean grounded = P_IsObjectOnGround(mobj);
|
boolean grounded = P_IsObjectOnGround(mobj);
|
||||||
|
|
@ -8405,6 +8491,17 @@ static boolean P_FuseThink(mobj_t *mobj)
|
||||||
|
|
||||||
P_RemoveMobj(mobj); // make sure they disappear
|
P_RemoveMobj(mobj); // make sure they disappear
|
||||||
return false;
|
return false;
|
||||||
|
case MT_ITEMCAPSULE:
|
||||||
|
if (mobj->spawnpoint)
|
||||||
|
P_SpawnMapThing(mobj->spawnpoint);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mobj_t *newMobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type);
|
||||||
|
newMobj->threshold = mobj->threshold;
|
||||||
|
newMobj->movecount = mobj->movecount;
|
||||||
|
}
|
||||||
|
P_RemoveMobj(mobj);
|
||||||
|
return false;
|
||||||
case MT_SMK_ICEBLOCK:
|
case MT_SMK_ICEBLOCK:
|
||||||
{
|
{
|
||||||
mobj_t *cur = mobj->hnext, *next;
|
mobj_t *cur = mobj->hnext, *next;
|
||||||
|
|
@ -8975,6 +9072,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
||||||
case MT_FLOATINGITEM:
|
case MT_FLOATINGITEM:
|
||||||
case MT_BLUESPHERE:
|
case MT_BLUESPHERE:
|
||||||
case MT_EMERALD:
|
case MT_EMERALD:
|
||||||
|
case MT_ITEMCAPSULE:
|
||||||
thing->shadowscale = FRACUNIT/2;
|
thing->shadowscale = FRACUNIT/2;
|
||||||
break;
|
break;
|
||||||
case MT_DRIFTCLIP:
|
case MT_DRIFTCLIP:
|
||||||
|
|
@ -9333,6 +9431,40 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
mobj->fuse = 100;
|
mobj->fuse = 100;
|
||||||
break;
|
break;
|
||||||
// SRB2Kart
|
// SRB2Kart
|
||||||
|
case MT_ITEMCAPSULE:
|
||||||
|
{
|
||||||
|
fixed_t oldHeight = mobj->height;
|
||||||
|
|
||||||
|
// set default item & count
|
||||||
|
#if 0 // set to 1 to test capsules with random items, e.g. with objectplace
|
||||||
|
if (P_RandomChance(FRACUNIT/3))
|
||||||
|
mobj->threshold = KITEM_SUPERRING;
|
||||||
|
else if (P_RandomChance(FRACUNIT/3))
|
||||||
|
mobj->threshold = KITEM_SPB;
|
||||||
|
else if (P_RandomChance(FRACUNIT/3))
|
||||||
|
mobj->threshold = KITEM_ORBINAUT;
|
||||||
|
else
|
||||||
|
mobj->threshold = P_RandomRange(1, NUMKARTITEMS - 1);
|
||||||
|
mobj->movecount = P_RandomChance(FRACUNIT/3) ? 1 : P_RandomKey(32) + 1;
|
||||||
|
#else
|
||||||
|
mobj->threshold = KITEM_SUPERRING; // default item is super ring
|
||||||
|
mobj->movecount = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// grounded/aerial properties
|
||||||
|
P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 0);
|
||||||
|
if (!P_IsObjectOnGround(mobj))
|
||||||
|
mobj->flags |= MF_NOGRAVITY;
|
||||||
|
|
||||||
|
// set starting scale
|
||||||
|
mobj->extravalue1 = mobj->scale; // this acts as the capsule's destscale; we're avoiding P_MobjScaleThink because we want aerial capsules not to scale from their center
|
||||||
|
mobj->scalespeed >>= 1;
|
||||||
|
P_SetScale(mobj, mobj->destscale = mapobjectscale >> 4);
|
||||||
|
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||||
|
mobj->z += (oldHeight - mobj->height);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MT_KARMAHITBOX:
|
case MT_KARMAHITBOX:
|
||||||
{
|
{
|
||||||
const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->scale);
|
const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->scale);
|
||||||
|
|
@ -10072,6 +10204,11 @@ void P_RespawnSpecials(void)
|
||||||
pcount++;
|
pcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 // set to 1 to enable quick respawns for testing
|
||||||
|
if (true)
|
||||||
|
time = 5*TICRATE;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if (gametyperules & GTR_SPHERES)
|
if (gametyperules & GTR_SPHERES)
|
||||||
{
|
{
|
||||||
if (pcount > 2)
|
if (pcount > 2)
|
||||||
|
|
@ -10618,6 +10755,21 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
|
||||||
if (modifiedgame && !savemoddata)
|
if (modifiedgame && !savemoddata)
|
||||||
return false; // No cheating!!
|
return false; // No cheating!!
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MT_ITEMCAPSULE:
|
||||||
|
{
|
||||||
|
boolean isRingCapsule = (mthing->angle < 1 || mthing->angle == KITEM_SUPERRING || mthing->angle >= NUMKARTITEMS);
|
||||||
|
|
||||||
|
// don't spawn ring capsules in GTR_SPHERES gametypes
|
||||||
|
if (isRingCapsule && (gametyperules & GTR_SPHERES))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// in record attack, only spawn ring capsules
|
||||||
|
// (behavior can be inverted with the Extra flag, i.e. item capsule spawns and ring capsule does not)
|
||||||
|
if (modeattacking
|
||||||
|
&& (!(mthing->options & MTF_EXTRA) == !isRingCapsule))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -11567,6 +11719,27 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MT_ITEMCAPSULE:
|
||||||
|
{
|
||||||
|
// Angle = item type
|
||||||
|
if (mthing->angle > 0 && mthing->angle < NUMKARTITEMS)
|
||||||
|
mobj->threshold = mthing->angle;
|
||||||
|
|
||||||
|
// Parameter = extra items (x5 for rings)
|
||||||
|
mobj->movecount += mthing->extrainfo;
|
||||||
|
|
||||||
|
// Special = +16 items (+80 for rings)
|
||||||
|
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||||
|
mobj->movecount += 16;
|
||||||
|
|
||||||
|
// Ambush = double size (grounded) / half size (aerial)
|
||||||
|
if (!(mthing->options & MTF_AMBUSH) == !P_IsObjectOnGround(mobj))
|
||||||
|
{
|
||||||
|
mobj->extravalue1 = min(mobj->extravalue1 << 1, FixedDiv(64*FRACUNIT, mobj->info->radius)); // don't make them larger than the blockmap can handle
|
||||||
|
mobj->scalespeed <<= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MT_AAZTREE_HELPER:
|
case MT_AAZTREE_HELPER:
|
||||||
{
|
{
|
||||||
fixed_t top = mobj->z;
|
fixed_t top = mobj->z;
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,7 @@ static void P_NetArchivePlayers(void)
|
||||||
WRITEUINT8(save_p, players[i].ringdelay);
|
WRITEUINT8(save_p, players[i].ringdelay);
|
||||||
WRITEUINT16(save_p, players[i].ringboost);
|
WRITEUINT16(save_p, players[i].ringboost);
|
||||||
WRITEUINT8(save_p, players[i].sparkleanim);
|
WRITEUINT8(save_p, players[i].sparkleanim);
|
||||||
WRITEUINT8(save_p, players[i].superring);
|
WRITEUINT16(save_p, players[i].superring);
|
||||||
|
|
||||||
WRITEUINT8(save_p, players[i].curshield);
|
WRITEUINT8(save_p, players[i].curshield);
|
||||||
WRITEUINT8(save_p, players[i].bubblecool);
|
WRITEUINT8(save_p, players[i].bubblecool);
|
||||||
|
|
@ -532,7 +532,7 @@ static void P_NetUnArchivePlayers(void)
|
||||||
players[i].ringdelay = READUINT8(save_p);
|
players[i].ringdelay = READUINT8(save_p);
|
||||||
players[i].ringboost = READUINT16(save_p);
|
players[i].ringboost = READUINT16(save_p);
|
||||||
players[i].sparkleanim = READUINT8(save_p);
|
players[i].sparkleanim = READUINT8(save_p);
|
||||||
players[i].superring = READUINT8(save_p);
|
players[i].superring = READUINT16(save_p);
|
||||||
|
|
||||||
players[i].curshield = READUINT8(save_p);
|
players[i].curshield = READUINT8(save_p);
|
||||||
players[i].bubblecool = READUINT8(save_p);
|
players[i].bubblecool = READUINT8(save_p);
|
||||||
|
|
|
||||||
|
|
@ -966,6 +966,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
||||||
{"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // :shitsfree:
|
{"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // :shitsfree:
|
||||||
{"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Debug notification
|
{"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Debug notification
|
||||||
{"cock", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Hammer cocks, bang bang
|
{"cock", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Hammer cocks, bang bang
|
||||||
|
{"itcaps", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, "Item capsule"},
|
||||||
|
|
||||||
// SRB2Kart - Engine sounds
|
// SRB2Kart - Engine sounds
|
||||||
// Engine class A
|
// Engine class A
|
||||||
|
|
|
||||||
|
|
@ -1030,6 +1030,7 @@ typedef enum
|
||||||
sfx_itfree,
|
sfx_itfree,
|
||||||
sfx_dbgsal,
|
sfx_dbgsal,
|
||||||
sfx_cock,
|
sfx_cock,
|
||||||
|
sfx_itcaps,
|
||||||
|
|
||||||
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
|
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
|
||||||
// Engine class A - Low Speed, Low Weight
|
// Engine class A - Low Speed, Low Weight
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue