diff --git a/src/deh_tables.c b/src/deh_tables.c index 5c04f4cc1..a6a7c35cb 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -338,6 +338,7 @@ actionpointer_t actionpointers[] = {{A_MementosTPParticles}, "A_MEMENTOSTPPARTICLES"}, {{A_ReaperThinker}, "A_REAPERTHINKER"}, {{A_FlameShieldPaper}, "A_FLAMESHIELDPAPER"}, + {{A_InvincSparkleRotate}, "A_INVINCSPARKLEROTATE"}, {{NULL}, "NONE"}, @@ -3605,17 +3606,31 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_KARTAIZDRIFTSTRAT", // Invincibility Sparks - "S_KARTINVULN_SMALL1", - "S_KARTINVULN_SMALL2", - "S_KARTINVULN_SMALL3", - "S_KARTINVULN_SMALL4", - "S_KARTINVULN_SMALL5", + "S_KARTINVULN1", + "S_KARTINVULN2", + "S_KARTINVULN3", + "S_KARTINVULN4", + "S_KARTINVULN5", + "S_KARTINVULN6", + "S_KARTINVULN7", + "S_KARTINVULN8", + "S_KARTINVULN9", + "S_KARTINVULN10", + "S_KARTINVULN11", + "S_KARTINVULN12", - "S_KARTINVULN_LARGE1", - "S_KARTINVULN_LARGE2", - "S_KARTINVULN_LARGE3", - "S_KARTINVULN_LARGE4", - "S_KARTINVULN_LARGE5", + "S_KARTINVULNB1", + "S_KARTINVULNB2", + "S_KARTINVULNB3", + "S_KARTINVULNB4", + "S_KARTINVULNB5", + "S_KARTINVULNB6", + "S_KARTINVULNB7", + "S_KARTINVULNB8", + "S_KARTINVULNB9", + "S_KARTINVULNB10", + "S_KARTINVULNB11", + "S_KARTINVULNB12", // Invincibility flash overlay "S_INVULNFLASH1", @@ -3623,6 +3638,22 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_INVULNFLASH3", "S_INVULNFLASH4", + "S_KARTINVLINES1", + "S_KARTINVLINES2", + "S_KARTINVLINES3", + "S_KARTINVLINES4", + "S_KARTINVLINES5", + "S_KARTINVLINES6", + "S_KARTINVLINES7", + "S_KARTINVLINES8", + "S_KARTINVLINES9", + "S_KARTINVLINES10", + "S_KARTINVLINES11", + "S_KARTINVLINES12", + "S_KARTINVLINES13", + "S_KARTINVLINES14", + "S_KARTINVLINES15", + // Wipeout dust trail "S_WIPEOUTTRAIL1", "S_WIPEOUTTRAIL2", diff --git a/src/info.c b/src/info.c index 243957ccf..4cf5d757c 100644 --- a/src/info.c +++ b/src/info.c @@ -533,8 +533,10 @@ char sprnames[NUMSPRITES + 1][5] = "BOST", // Sneaker booster flame "BOSM", // Sneaker booster smoke "KFRE", // Sneaker fire trail - "KINV", // Invincibility sparkle trail + "KINV", // Lighter invincibility sparkle trail + "KINB", // Darker invincibility sparkle trail "KINF", // Invincibility flash + "INVI", // Invincibility speedlines "WIPD", // Wipeout dust trail "DRIF", // Drift Sparks "BDRF", // Brake drift sparks @@ -4166,23 +4168,53 @@ state_t states[NUMSTATES] = {SPR_AIDU, FF_ANIMATE|FF_PAPERSPRITE, 5*2, {NULL}, 5, 2, S_NULL}, // S_KARTAIZDRIFTSTRAT - {SPR_KINV, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL2}, // S_KARTINVULN_SMALL1 - {SPR_KINV, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL3}, // S_KARTINVULN_SMALL2 - {SPR_KINV, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL4}, // S_KARTINVULN_SMALL3 - {SPR_KINV, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_KARTINVULN_SMALL5}, // S_KARTINVULN_SMALL4 - {SPR_KINV, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_NULL}, // S_KARTINVULN_SMALL5 + {SPR_KINV, FF_FULLBRIGHT, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN2}, // S_KARTINVULN1 + {SPR_KINV, FF_FULLBRIGHT|1, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN3}, // S_KARTINVULN2 + {SPR_KINV, FF_FULLBRIGHT|2, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN4}, // S_KARTINVULN3 + {SPR_KINV, FF_FULLBRIGHT|3, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN5}, // S_KARTINVULN4 + {SPR_KINV, FF_FULLBRIGHT|4, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN6}, // S_KARTINVULN5 + {SPR_KINV, FF_FULLBRIGHT|5, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN7}, // S_KARTINVULN6 + {SPR_KINV, FF_FULLBRIGHT|6, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN8}, // S_KARTINVULN7 + {SPR_KINV, FF_FULLBRIGHT|7, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN9}, // S_KARTINVULN8 + {SPR_KINV, FF_FULLBRIGHT|8, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN10}, // S_KARTINVULN9 + {SPR_KINV, FF_FULLBRIGHT|9, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN11}, // S_KARTINVULN10 + {SPR_KINV, FF_FULLBRIGHT|10, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULN12}, // S_KARTINVULN11 + {SPR_KINV, FF_FULLBRIGHT|11, 1, {A_InvincSparkleRotate}, 0, 0, S_NULL}, // S_KARTINVULN12 - {SPR_KINV, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_KARTINVULN_LARGE2}, // S_KARTINVULN_LARGE1 - {SPR_KINV, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_KARTINVULN_LARGE3}, // S_KARTINVULN_LARGE2 - {SPR_KINV, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_KARTINVULN_LARGE4}, // S_KARTINVULN_LARGE3 - {SPR_KINV, FF_FULLBRIGHT|6, 1, {NULL}, 0, 0, S_KARTINVULN_LARGE5}, // S_KARTINVULN_LARGE4 - {SPR_KINV, FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_NULL}, // S_KARTINVULN_LARGE5 + {SPR_KINB, FF_FULLBRIGHT, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB2}, // S_KARTINVULNB1 + {SPR_KINB, FF_FULLBRIGHT|1, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB3}, // S_KARTINVULNB2 + {SPR_KINB, FF_FULLBRIGHT|2, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB4}, // S_KARTINVULNB3 + {SPR_KINB, FF_FULLBRIGHT|3, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB5}, // S_KARTINVULNB4 + {SPR_KINB, FF_FULLBRIGHT|4, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB6}, // S_KARTINVULNB5 + {SPR_KINB, FF_FULLBRIGHT|5, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB7}, // S_KARTINVULNB6 + {SPR_KINB, FF_FULLBRIGHT|6, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB8}, // S_KARTINVULNB7 + {SPR_KINB, FF_FULLBRIGHT|7, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB9}, // S_KARTINVULNB8 + {SPR_KINB, FF_FULLBRIGHT|8, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB10}, // S_KARTINVULNB9 + {SPR_KINB, FF_FULLBRIGHT|9, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB11}, // S_KARTINVULNB10 + {SPR_KINB, FF_FULLBRIGHT|10, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB12}, // S_KARTINVULNB11 + {SPR_KINB, FF_FULLBRIGHT|11, 1, {A_InvincSparkleRotate}, 0, 0, S_NULL}, // S_KARTINVULNB12 {SPR_KINF, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH2}, // S_INVULNFLASH1 {SPR_NULL, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH3}, // S_INVULNFLASH2 {SPR_KINF, FF_FULLBRIGHT|FF_TRANS90|1, 1, {NULL}, 0, 0, S_INVULNFLASH4}, // S_INVULNFLASH3 {SPR_NULL, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH1}, // S_INVULNFLASH4 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_KARTINVLINES2}, // S_KARTINVLINES1 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|1, 1, {NULL}, 0, 0, S_KARTINVLINES3}, // S_KARTINVLINES2 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|2, 1, {NULL}, 0, 0, S_KARTINVLINES4}, // S_KARTINVLINES3 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|3, 1, {NULL}, 0, 0, S_KARTINVLINES5}, // S_KARTINVLINES4 + {SPR_INVI, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE|4, 1, {NULL}, 2, 1, S_KARTINVLINES6}, // S_KARTINVLINES5 + {SPR_INVI, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE|4, 1, {NULL}, 2, 1, S_KARTINVLINES7}, // S_KARTINVLINES6 + {SPR_INVI, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE|4, 1, {NULL}, 2, 1, S_KARTINVLINES8}, // S_KARTINVLINES7 + {SPR_INVI, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE|4, 1, {NULL}, 2, 1, S_KARTINVLINES9}, // S_KARTINVLINES8 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|5, 1, {NULL}, 0, 0, S_KARTINVLINES10}, // S_KARTINVLINES9 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|6, 3, {NULL}, 0, 0, S_KARTINVLINES11}, // S_KARTINVLINES10 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|7, 1, {NULL}, 0, 0, S_KARTINVLINES12}, // S_KARTINVLINES11 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|8, 1, {NULL}, 0, 0, S_KARTINVLINES13}, // S_KARTINVLINES12 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|9, 1, {NULL}, 0, 0, S_KARTINVLINES14}, // S_KARTINVLINES13 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|10, 1, {NULL}, 0, 0, S_KARTINVLINES15}, // S_KARTINVLINES14 + {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|11, 1, {NULL}, 0, 0, S_NULL}, // S_KARTINVLINES15 + {SPR_WIPD, 0, 3, {NULL}, 0, 0, S_WIPEOUTTRAIL2}, // S_WIPEOUTTRAIL1 {SPR_WIPD, 1, 3, {NULL}, 0, 0, S_WIPEOUTTRAIL3}, // S_WIPEOUTTRAIL2 {SPR_WIPD, 2, 3, {NULL}, 0, 0, S_WIPEOUTTRAIL4}, // S_WIPEOUTTRAIL3 @@ -4214,7 +4246,7 @@ state_t states[NUMSTATES] = {SPR_ORBN, 0, 1, {NULL}, 0, 0, S_ORBINAUT2}, // S_ORBINAUT1 {SPR_ORBN, 1, 1, {NULL}, 0, 0, S_ORBINAUT3}, // S_ORBINAUT2 {SPR_ORBN, 2, 1, {NULL}, 0, 0, S_ORBINAUT4}, // S_ORBINAUT3 - {SPR_ORBN, 3, 1, {NULL}, 0, 0, S_ORBINAUT5}, // S_ORBINAUT4 + {SPR_ORBN, 3, 1, {NULL}, 0, 0, S_ORBINAUT5}, // S_ORBINAUT4S_ORBINAUT4 {SPR_ORBN, 4, 1, {NULL}, 0, 0, S_ORBINAUT6}, // S_ORBINAUT5 {SPR_ORBN, 5, 1, {NULL}, 0, 0, S_ORBINAUT1}, // S_ORBINAUT6 {SPR_ORBN, 0, 175, {NULL}, 0, 0, S_NULL}, // S_ORBINAUT_DEAD @@ -23280,7 +23312,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_SPARKLETRAIL -1, // doomednum - S_KARTINVULN_SMALL1, // spawnstate + S_NULL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/info.h b/src/info.h index 85b496bb1..527dc5a05 100644 --- a/src/info.h +++ b/src/info.h @@ -291,6 +291,7 @@ enum actionnum A_MEMENTOSTPPARTICLES, A_REAPERTHINKER, A_FLAMESHIELDPAPER, + A_INVINCSPARKLEROTATE, NUMACTIONS }; @@ -565,6 +566,7 @@ void A_MayonakaArrow(); void A_ReaperThinker(); void A_MementosTPParticles(); void A_FlameShieldPaper(); +void A_InvincSparkleRotate(); extern boolean actionsoverridden[NUMACTIONS]; @@ -1082,8 +1084,11 @@ typedef enum sprite SPR_BOST, // Sneaker booster flame SPR_BOSM, // Sneaker booster smoke SPR_KFRE, // Sneaker fire trail - SPR_KINV, // Invincibility sparkle trail + SPR_KINV, // Lighter invincibility sparkle trail + SPR_KINB, // Darker invincibility sparkle trail SPR_KINF, // Invincibility flash + SPR_INVI, // Invincibility speedlines + SPR_WIPD, // Wipeout dust trail SPR_DRIF, // Drift Sparks SPR_BDRF, // Brake drift sparks @@ -4574,17 +4579,31 @@ typedef enum state S_KARTAIZDRIFTSTRAT, // Invincibility Sparks - S_KARTINVULN_SMALL1, - S_KARTINVULN_SMALL2, - S_KARTINVULN_SMALL3, - S_KARTINVULN_SMALL4, - S_KARTINVULN_SMALL5, + S_KARTINVULN1, + S_KARTINVULN2, + S_KARTINVULN3, + S_KARTINVULN4, + S_KARTINVULN5, + S_KARTINVULN6, + S_KARTINVULN7, + S_KARTINVULN8, + S_KARTINVULN9, + S_KARTINVULN10, + S_KARTINVULN11, + S_KARTINVULN12, - S_KARTINVULN_LARGE1, - S_KARTINVULN_LARGE2, - S_KARTINVULN_LARGE3, - S_KARTINVULN_LARGE4, - S_KARTINVULN_LARGE5, + S_KARTINVULNB1, + S_KARTINVULNB2, + S_KARTINVULNB3, + S_KARTINVULNB4, + S_KARTINVULNB5, + S_KARTINVULNB6, + S_KARTINVULNB7, + S_KARTINVULNB8, + S_KARTINVULNB9, + S_KARTINVULNB10, + S_KARTINVULNB11, + S_KARTINVULNB12, // Invincibility flash S_INVULNFLASH1, @@ -4592,6 +4611,22 @@ typedef enum state S_INVULNFLASH3, S_INVULNFLASH4, + S_KARTINVLINES1, + S_KARTINVLINES2, + S_KARTINVLINES3, + S_KARTINVLINES4, + S_KARTINVLINES5, + S_KARTINVLINES6, + S_KARTINVLINES7, + S_KARTINVLINES8, + S_KARTINVLINES9, + S_KARTINVLINES10, + S_KARTINVLINES11, + S_KARTINVLINES12, + S_KARTINVLINES13, + S_KARTINVLINES14, + S_KARTINVLINES15, + // Wipeout dust trail S_WIPEOUTTRAIL1, S_WIPEOUTTRAIL2, diff --git a/src/k_kart.c b/src/k_kart.c index 19d8cf924..f3d40653a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -401,6 +401,22 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] = #define DISTVAR (2048) // Magic number distance for use with item roulette tiers +// Array of states to pick the starting point of the animation, based on the actual time left for invincibility. +static INT32 K_SparkleTrailStartStates[KART_NUMINVSPARKLESANIM][2] = { + {S_KARTINVULN12, S_KARTINVULNB12}, + {S_KARTINVULN11, S_KARTINVULNB11}, + {S_KARTINVULN10, S_KARTINVULNB10}, + {S_KARTINVULN9, S_KARTINVULNB9}, + {S_KARTINVULN8, S_KARTINVULNB8}, + {S_KARTINVULN7, S_KARTINVULNB7}, + {S_KARTINVULN6, S_KARTINVULNB6}, + {S_KARTINVULN5, S_KARTINVULNB5}, + {S_KARTINVULN4, S_KARTINVULNB4}, + {S_KARTINVULN3, S_KARTINVULNB3}, + {S_KARTINVULN2, S_KARTINVULNB2}, + {S_KARTINVULN1, S_KARTINVULNB1} +}; + INT32 K_GetShieldFromItem(INT32 item) { switch (item) @@ -1792,6 +1808,51 @@ void K_SpawnDriftBoostClipSpark(mobj_t *clip) spark->momy = clip->momx/2; } +void K_SpawnNormalSpeedLines(player_t *player) +{ + mobj_t *fast = P_SpawnMobj(player->mo->x + (P_RandomRange(-36,36) * player->mo->scale), + player->mo->y + (P_RandomRange(-36,36) * player->mo->scale), + player->mo->z + (player->mo->height/2) + (P_RandomRange(-20,20) * player->mo->scale), + MT_FASTLINE); + + P_SetTarget(&fast->target, player->mo); + fast->angle = K_MomentumAngle(player->mo); + fast->momx = 3*player->mo->momx/4; + fast->momy = 3*player->mo->momy/4; + fast->momz = 3*player->mo->momz/4; + + K_MatchGenericExtraFlags(fast, player->mo); + + // Make it red when you have the eggman speed boost + if (player->kartstuff[k_eggmanexplode]) + { + fast->color = SKINCOLOR_RED; + fast->colorized = true; + } +} + +void K_SpawnInvincibilitySpeedLines(mobj_t *mo) +{ + mobj_t *fast = P_SpawnMobjFromMobj(mo, + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(0, 64) * FRACUNIT, + MT_FASTLINE); + + fast->momx = 3*mo->momx/4; + fast->momy = 3*mo->momy/4; + fast->momz = 3*mo->momz/4; + + P_SetTarget(&fast->target, mo); + fast->angle = K_MomentumAngle(mo); + fast->color = mo->color; + fast->colorized = true; + K_MatchGenericExtraFlags(fast, mo); + P_SetMobjState(fast, S_KARTINVLINES1); + if (mo->player->kartstuff[k_invincibilitytimer] < 10*TICRATE) + fast->destscale = 6*((mo->player->kartstuff[k_invincibilitytimer]/TICRATE)*FRACUNIT)/8; +} + static SINT8 K_GlanceAtPlayers(player_t *glancePlayer) { const fixed_t maxdistance = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); @@ -2488,7 +2549,7 @@ static void K_GetKartBoostPower(player_t *player) if (player->kartstuff[k_draftpower] > 0) // Drafting { // 30% - 44%, each point of speed adds 1.75% - fixed_t draftspeed = ((3*FRACUNIT)/10) + ((player->kartspeed-1) * ((7*FRACUNIT)/400)); + fixed_t draftspeed = ((3*FRACUNIT)/10) + ((player->kartspeed-1) * ((7*FRACUNIT)/400)); speedboost += FixedMul(draftspeed, player->kartstuff[k_draftpower]); // (Drafting suffers no boost stack penalty.) numboosts++; } @@ -3758,20 +3819,44 @@ void K_SpawnBoostTrail(player_t *player) void K_SpawnSparkleTrail(mobj_t *mo) { - const INT32 rad = (mo->radius*2)>>FRACBITS; + const INT32 rad = (mo->radius*3)/FRACUNIT; mobj_t *sparkle; INT32 i; + UINT8 invanimnum; // Current sparkle animation number + INT32 invtime;// Invincibility time left, in seconds + UINT8 index = 1; + fixed_t newx, newy, newz; I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); - for (i = 0; i < 3; i++) + if ((mo->player->kartstuff[k_sneakertimer] + || mo->player->kartstuff[k_ringboost] || mo->player->kartstuff[k_driftboost] + || mo->player->kartstuff[k_startboost] || mo->player->kartstuff[k_eggmanexplode])) { - fixed_t newx = mo->x + mo->momx + (P_RandomRange(-rad, rad)<y + mo->momy + (P_RandomRange(-rad, rad)<z + mo->momz + (P_RandomRange(0, mo->height>>FRACBITS)<player->kartstuff[k_invincibilitytimer]/TICRATE+1; + + //CONS_Printf("%d\n", index); + + for (i = 0; i < 8; i++) + { + newx = mo->x + (P_RandomRange(-rad, rad)*FRACUNIT); + newy = mo->y + (P_RandomRange(-rad, rad)*FRACUNIT); + newz = mo->z + (P_RandomRange(0, mo->height>>FRACBITS)*FRACUNIT); sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL); + sparkle->angle = R_PointToAngle2(mo->x, mo->y, sparkle->x, sparkle->y); + sparkle->movefactor = R_PointToDist2(mo->x, mo->y, sparkle->x, sparkle->y); // Save the distance we spawned away from the player. + //CONS_Printf("movefactor: %d\n", sparkle->movefactor/FRACUNIT); + sparkle->extravalue1 = (sparkle->z - mo->z); // Keep track of our Z position relative to the player's, I suppose. + sparkle->extravalue2 = P_RandomRange(0, 1) ? 1 : -1; // Rotation direction? + sparkle->cvmem = P_RandomRange(-25, 25)*mo->scale; // Vertical "angle" K_FlipFromObject(sparkle, mo); //if (i == 0) @@ -3780,11 +3865,13 @@ void K_SpawnSparkleTrail(mobj_t *mo) P_SetTarget(&sparkle->target, mo); sparkle->destscale = mo->destscale; P_SetScale(sparkle, mo->scale); - sparkle->color = mo->color; - //sparkle->colorized = mo->colorized; } - P_SetMobjState(sparkle, S_KARTINVULN_LARGE1); + invanimnum = (invtime >= 11) ? 11 : invtime; + //CONS_Printf("%d\n", invanimnum); + P_SetMobjState(sparkle, K_SparkleTrailStartStates[invanimnum][index]); + sparkle->colorized = true; + sparkle->color = mo->color; } void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad) @@ -6047,25 +6134,10 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) || player->kartstuff[k_driftboost] || player->kartstuff[k_startboost] || player->kartstuff[k_eggmanexplode]) { - mobj_t *fast = P_SpawnMobj(player->mo->x + (P_RandomRange(-36,36) * player->mo->scale), - player->mo->y + (P_RandomRange(-36,36) * player->mo->scale), - player->mo->z + (player->mo->height/2) + (P_RandomRange(-20,20) * player->mo->scale), - MT_FASTLINE); - - P_SetTarget(&fast->target, player->mo); - fast->angle = K_MomentumAngle(player->mo); - fast->momx = 3*player->mo->momx/4; - fast->momy = 3*player->mo->momy/4; - fast->momz = 3*player->mo->momz/4; - - K_MatchGenericExtraFlags(fast, player->mo); - - // Make it red when you have the eggman speed boost - if (player->kartstuff[k_eggmanexplode]) - { - fast->color = SKINCOLOR_RED; - fast->colorized = true; - } + if (player->kartstuff[k_invincibilitytimer]) + K_SpawnInvincibilitySpeedLines(player->mo); + else + K_SpawnNormalSpeedLines(player); } if (player->kartstuff[k_numboosts] > 0) // Boosting after images diff --git a/src/k_kart.h b/src/k_kart.h index 9d6d00abc..09665d8ab 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -12,6 +12,14 @@ #define KART_FULLTURN 800 +/* +Number of animations for the invincibility sparkles +If states are ever added or removed +Make sure this matches the actual number of states +*/ +#define KART_NUMINVSPARKLESANIM 12 + + player_t *K_GetItemBoxPlayer(mobj_t *mobj); angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); @@ -37,6 +45,8 @@ void K_GenericExtraFlagsNoZAdjust(mobj_t *mo, mobj_t *master); void K_SpawnDashDustRelease(player_t *player); void K_SpawnDriftBoostClip(player_t *player); void K_SpawnDriftBoostClipSpark(mobj_t *clip); +void K_SpawnNormalSpeedLines(player_t *player); +void K_SpawnInvincibilitySpeedLines(mobj_t *mo); void K_KartMoveAnimation(player_t *player); void K_KartPlayerHUDUpdate(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); diff --git a/src/p_enemy.c b/src/p_enemy.c index c257baf77..8ef33a38e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -325,6 +325,7 @@ void A_MayonakaArrow(mobj_t *actor); void A_ReaperThinker(mobj_t *actor); void A_MementosTPParticles(mobj_t *actor); void A_FlameShieldPaper(mobj_t *actor); +void A_InvincSparkleRotate(mobj_t *actor); //for p_enemy.c @@ -14796,3 +14797,26 @@ void A_FlameShieldPaper(mobj_t *actor) paper->extravalue1 = i; } } + +void A_InvincSparkleRotate(mobj_t *actor) +{ + fixed_t sx, sy, sz; // Teleport dests. + + if (LUA_CallAction(A_INVINCSPARKLEROTATE, actor)) + return; + + if (!actor->target || P_MobjWasRemoved(actor->target)) + return; + + //CONS_Printf("%d\n", actor->movefactor/FRACUNIT); + sx = actor->target->x + FixedMul((actor->movefactor), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT)); + sy = actor->target->y + FixedMul((actor->movefactor), FINESINE((actor->angle)>>ANGLETOFINESHIFT)); + sz = actor->target->z + (actor->extravalue1) + FixedMul((actor->cvmem), FINECOSINE((leveltime*ANG1*10 + actor->angle)>>ANGLETOFINESHIFT)); + P_TeleportMove(actor, sx, sy, sz); + + actor->momx = actor->target->momx; + actor->momy = actor->target->momy; + actor->momz = actor->target->momz; // Give momentum for eventual interp builds idk. + + actor->angle += ANG1*10*(actor->extravalue2); // Arbitrary value, change this if you want, I suppose. +} \ No newline at end of file diff --git a/src/p_inter.c b/src/p_inter.c index 257e87e47..5077ef366 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1399,7 +1399,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget else { flingAngle = target->angle + ANGLE_180; - + if (P_RandomByte() & 1) { flingAngle -= ANGLE_45; @@ -1826,6 +1826,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da boolean force = false; INT32 laglength = 10; + INT32 kinvextend = 0; if (objectplacing) return false; @@ -1981,6 +1982,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source && source != player->mo && source->player) { + // Extend the invincibility if the hit was a direct hit. + if (inflictor == source && source->player->kartstuff[k_invincibilitytimer]) + { + kinvextend = (source->player->kartstuff[k_invincibilitytimer])+5*TICRATE; + //CONS_Printf("extend k_invincibilitytimer for %s - old value %d new value %d\n", player_names[source->player - players], source->player->kartstuff[k_invincibilitytimer]/TICRATE, kinvextend/TICRATE); + source->player->kartstuff[k_invincibilitytimer] = kinvextend; + } + K_PlayHitEmSound(source); K_BattleAwardHit(source->player, player, inflictor, takeBumpers); diff --git a/src/p_user.c b/src/p_user.c index 1db930700..0ea75e3bf 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2595,7 +2595,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) // // SRB2Kart: Use for GP? -/* +/* static void P_ConsiderAllGone(void) { INT32 i, lastdeadplayer = -1, deadtimercheck = INT32_MAX;