diff --git a/src/d_main.c b/src/d_main.c index ed8a4b4a..734c1a00 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -828,6 +828,8 @@ static void IdentifyVersion(void) D_AddFile(va(pandf,srb2waddir,"AllKartSounds.wad")); D_AddFile(va(pandf,srb2waddir,"KartTextures.wad")); D_AddFile(va(pandf,srb2waddir,"KMFixes3.wad")); + D_AddFile(va(pandf,srb2waddir,"SNSAssets.wad")); + D_AddFile(va(pandf,srb2waddir,"k_SNSRainbowRoad.wad")); #if !defined (HAVE_SDL) || defined (HAVE_MIXER) { diff --git a/src/dehacked.c b/src/dehacked.c index 2a1771c4..9d4e56af 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1801,6 +1801,7 @@ static actionpointer_t actionpointers[] = {{A_DualAction}, "A_DUALACTION"}, {{A_RemoteAction}, "A_REMOTEACTION"}, {{A_ToggleFlameJet}, "A_TOGGLEFLAMEJET"}, + {{A_ItemPop}, "A_ITEMPOP"}, // SRB2kart {{A_RedShellChase}, "A_REDSHELLCHASE"}, // SRB2kart {{A_BobombExplode}, "A_BOBOMBEXPLODE"}, // SRB2kart {{A_OrbitNights}, "A_ORBITNIGHTS"}, diff --git a/src/info.c b/src/info.c index e5d8292a..e042e33b 100644 --- a/src/info.c +++ b/src/info.c @@ -2557,6 +2557,7 @@ state_t states[NUMSTATES] = {SPR_RNDM, 21, 3, {A_AttractChase}, 0, 0, S_RANDOMITEM23}, // S_RANDOMITEM22 {SPR_RNDM, 22, 3, {A_AttractChase}, 0, 0, S_RANDOMITEM24}, // S_RANDOMITEM23 {SPR_RNDM, 23, 3, {A_AttractChase}, 0, 0, S_RANDOMITEM1}, // S_RANDOMITEM24 + {SPR_RNDM, 0, 1, {A_ItemPop}, 0, 0, S_NULL}, // S_DEADRANDOMITEM {SPR_SPRK, 0, 2, {NULL}, 0, 0, S_RANDOMITEMPOP2}, // S_RANDOMITEMPOP1 {SPR_SPRK, 1, 2, {NULL}, 0, 0, S_RANDOMITEMPOP3}, // S_RANDOMITEMPOP2 @@ -14048,7 +14049,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_RANDOMBOX3, // deathstate + S_DEADRANDOMITEM, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound 64*FRACUNIT, // speed @@ -14058,7 +14059,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags + MF_SOLID|MF_SHOOTABLE|MF_MONITOR, // flags S_NULL // raisestate }, @@ -14139,7 +14140,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index b35f1b88..2100423c 100644 --- a/src/info.h +++ b/src/info.h @@ -163,6 +163,7 @@ void A_RandomStateRange(); void A_DualAction(); void A_RemoteAction(); void A_ToggleFlameJet(); +void A_ItemPop(); // SRB2kart void A_RedShellChase(); // SRB2kart void A_BobombExplode(); // SRB2kart void A_OrbitNights(); @@ -3026,6 +3027,7 @@ typedef enum state S_RANDOMITEM22, S_RANDOMITEM23, S_RANDOMITEM24, + S_DEADRANDOMITEM, // Random Item Pop S_RANDOMITEMPOP1, diff --git a/src/k_kart.c b/src/k_kart.c index 27b6fe1d..c158294e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -746,7 +746,7 @@ static void K_KartGetItemResult(player_t *player, fixed_t getitem, boolean retro player->kartstuff[k_itemroulette] = 0; // Since we're done, clear the roulette number if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_mkitemF); + S_StartSound(NULL, sfx_mkitmF); } /** \brief Item Roulette for Kart @@ -783,7 +783,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) // This makes the roulette produce the random noises. if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsLocalPlayer(player)) - S_StartSound(NULL,sfx_mkitem1 + ((player->kartstuff[k_itemroulette] / 3) % 8)); + S_StartSound(NULL,sfx_mkitm1 + ((player->kartstuff[k_itemroulette] / 3) % 8)); // If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item. // I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think. @@ -814,11 +814,16 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) player->pflags |= PF_ATTACKDOWN; player->kartstuff[k_itemclose] = 0; // Reset the item window closer. + player->kartstuff[k_itemroulette] = 0; // And the roulette is done! // Yes I know I'm defining variables half-way into the function, but they aren't needed until now :/ fixed_t prandom = P_RandomFixed(); fixed_t ppos = player->kartstuff[k_position] - 1; + // Tiny catcher in case player position is unset. + if (ppos == 0) + ppos = 1; + // Check the game type to differentiate odds. //if (gametype == GT_RETRO) //{ diff --git a/src/p_enemy.c b/src/p_enemy.c index 1ade380c..2c486e8b 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -187,6 +187,7 @@ void A_RandomStateRange(mobj_t *actor); void A_DualAction(mobj_t *actor); void A_RemoteAction(mobj_t *actor); void A_ToggleFlameJet(mobj_t *actor); +void A_ItemPop(mobj_t *actor); // SRB2kart void A_RedShellChase(mobj_t *actor); // SRB2kart void A_BobombExplode(mobj_t *actor); // SRB2kart void A_OrbitNights(mobj_t *actor); @@ -8073,7 +8074,70 @@ void A_ToggleFlameJet(mobj_t* actor) } } -//{ SRB2kart - A_RedShellChase and A_BobombExplode +//{ SRB2kart - A_ItemPop, A_RedShellChase and A_BobombExplode +void A_ItemPop(mobj_t *actor) +{ + mobj_t *remains; + mobjtype_t item = 0; + + // de-solidify + P_UnsetThingPosition(actor); + actor->flags &= ~MF_SOLID; + actor->flags |= MF_NOCLIP; + P_SetThingPosition(actor); + + remains = P_SpawnMobj(actor->x, actor->y, actor->z, MT_RANDOMITEMPOP); + remains->type = actor->type; // Transfer type information + P_UnsetThingPosition(remains); + if (sector_list) + { + P_DelSeclist(sector_list); + sector_list = NULL; + } + remains->flags = actor->flags; // Transfer flags + P_SetThingPosition(remains); + remains->flags2 = actor->flags2; // Transfer flags2 + remains->fuse = actor->fuse; // Transfer respawn timer + remains->threshold = 68; + remains->skin = NULL; + + actor->flags2 |= MF2_BOSSNOTRAP; // Dummy flag to mark this as an exploded TV until it respawns + tmthing = remains; + + if (actor->info->deathsound) S_StartSound(remains, actor->info->deathsound); + + switch (actor->type) + { + case MT_RANDOMITEM: // Random! + { + if (actor->target && actor->target->player + && !(actor->target->player->kartstuff[k_greenshell] & 2 || actor->target->player->kartstuff[k_triplegreenshell] & 8 + || actor->target->player->kartstuff[k_redshell] & 2 || actor->target->player->kartstuff[k_tripleredshell] & 8 + || actor->target->player->kartstuff[k_banana] & 2 || actor->target->player->kartstuff[k_triplebanana] & 8 + || actor->target->player->kartstuff[k_fakeitem] & 2 || actor->target->player->kartstuff[k_magnet] + || actor->target->player->kartstuff[k_bobomb] & 2 || actor->target->player->kartstuff[k_blueshell] + || actor->target->player->kartstuff[k_mushroom] || actor->target->player->kartstuff[k_fireflower] + || actor->target->player->kartstuff[k_star] || actor->target->player->kartstuff[k_goldshroom] + || actor->target->player->kartstuff[k_lightning] || actor->target->player->kartstuff[k_megashroom] + || actor->target->player->kartstuff[k_itemroulette] + || actor->target->player->kartstuff[k_boo] || actor->target->player->kartstuff[k_bootaketimer] + || actor->target->player->kartstuff[k_boostolentimer]) + ) + actor->target->player->kartstuff[k_itemroulette] = 1; + else if(cv_debug && !(actor->target && actor->target->player)) + CONS_Printf("ERROR: Powerup has no target!\n"); + + remains->flags &= ~MF_AMBUSH; + break; + } + default: + item = actor->info->damage; + break; + } + + P_RemoveMobj(actor); +} + void A_RedShellChase(mobj_t *actor) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 59916c58..90b61b60 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -260,7 +260,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) // Adjust the player's animation speed to match their velocity. if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST)) { - fixed_t speed = FixedDiv(player->speed, mobj->scale); + fixed_t speed = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor)); // fixed_t speed = FixedDiv(player->speed, mobj->scale); if (player->panim == PA_ROLL) { if (speed > 16<friction = FRACUNIT - 0x100; - mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158; + //mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158; } else mo->friction = ORIG_FRICTION; @@ -1471,7 +1471,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) // spinning friction if (player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH)) { - const fixed_t ns = FixedDiv(549*FRICTION,500*FRACUNIT); + const fixed_t ns = FixedDiv(549*ORIG_FRICTION,500*FRACUNIT); //const fixed_t ns = FixedDiv(549*FRICTION,500*FRACUNIT); mo->momx = FixedMul(mo->momx, ns); mo->momy = FixedMul(mo->momy, ns); } @@ -2490,7 +2490,7 @@ static boolean P_ZMovement(mobj_t *mo) // Stolen from P_SpawnFriction mo->friction = FRACUNIT - 0x100; - mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158; + //mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158; } else if (mo->type == MT_FALLINGROCK) { @@ -7827,7 +7827,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->friction = ORIG_FRICTION; - mobj->movefactor = ORIG_FRICTION_FACTOR; + mobj->movefactor = FRACUNIT; //mobj->movefactor = ORIG_FRICTION_FACTOR; // All mobjs are created at 100% scale. mobj->scale = FRACUNIT; @@ -9920,7 +9920,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) mthing->mobj = mobj; } // All manners of rings and coins - else if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum || + else if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum || mthing->type == mobjinfo[MT_RANDOMITEM].doomednum || mthing->type == mobjinfo[MT_REDTEAMRING].doomednum || mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) { mobjtype_t ringthing = MT_RING; @@ -9941,6 +9941,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) case 309: // No team rings in non-CTF ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; break; + case 2000: // SRB2kart + ringthing = MT_RANDOMITEM; + break; default: // Spawn rings as blue spheres in special stages, ala S3+K. if (G_IsSpecialStage(gamemap) && useNightsSS) diff --git a/src/p_saveg.c b/src/p_saveg.c index 5e457ca3..aee50e61 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1083,7 +1083,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff |= MD_TRACER; if (mobj->friction != ORIG_FRICTION) diff |= MD_FRICTION; - if (mobj->movefactor != ORIG_FRICTION_FACTOR) + if (mobj->movefactor != FRACUNIT) //if (mobj->movefactor != ORIG_FRICTION_FACTOR) diff |= MD_MOVEFACTOR; if (mobj->fuse) diff |= MD_FUSE; @@ -2060,7 +2060,7 @@ static void LoadMobjThinker(actionf_p1 thinker) if (diff & MD_MOVEFACTOR) mobj->movefactor = READFIXED(save_p); else - mobj->movefactor = ORIG_FRICTION_FACTOR; + mobj->movefactor = FRACUNIT; //mobj->movefactor = ORIG_FRICTION_FACTOR; if (diff & MD_FUSE) mobj->fuse = READINT32(save_p); if (diff & MD_WATERTOP) diff --git a/src/p_spec.c b/src/p_spec.c index d116d00a..18378b84 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3646,9 +3646,9 @@ DoneSection2: // Process Section 3 switch (special) { - case 1: // Ice/Sludge + case 1: // Unused (was "Ice/Sludge") case 2: // Wind/Current - case 3: // Ice/Sludge and Wind/Current + case 3: // Unused (was "Ice/Sludge and Wind/Current") case 4: // Conveyor Belt break; @@ -6945,12 +6945,12 @@ void T_Friction(friction_t *f) sec = sectors + f->affectee; - // Make sure the sector type hasn't changed + // Get FOF control sector (was "Make sure the sector type hasn't changed") if (f->roverfriction) - { + //{ referrer = sectors + f->referrer; - if (!(GETSECSPECIAL(referrer->special, 3) == 1 + /* if (!(GETSECSPECIAL(referrer->special, 3) == 1 || GETSECSPECIAL(referrer->special, 3) == 3)) return; } @@ -6959,7 +6959,7 @@ void T_Friction(friction_t *f) if (!(GETSECSPECIAL(sec->special, 3) == 1 || GETSECSPECIAL(sec->special, 3) == 3)) return; - } + }*/ // Assign the friction value to players on the floor, non-floating, // and clipped. Normally the object's friction value is kept at @@ -6990,14 +6990,16 @@ void T_Friction(friction_t *f) || (f->friction < thing->friction)) { thing->friction = f->friction; - thing->movefactor = f->movefactor; + if (thing->player) + thing->movefactor = f->movefactor; } } else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? || f->friction < thing->friction)) { thing->friction = f->friction; - thing->movefactor = f->movefactor; + if (thing->player) + thing->movefactor = f->movefactor; } } node = node->m_snext; @@ -7013,29 +7015,36 @@ static void P_SpawnFriction(void) size_t i; line_t *l = lines; register INT32 s; - fixed_t length; // line length controls magnitude + fixed_t strength; // frontside texture offset controls magnitude //fixed_t length; // line length controls magnitude fixed_t friction; // friction value to be applied during movement INT32 movefactor; // applied to each player move to simulate inertia for (i = 0; i < numlines; i++, l++) if (l->special == 540) { - length = P_AproxDistance(l->dx, l->dy)>>FRACBITS; - friction = (0x1EB8*length)/0x80 + 0xD000; + //length = P_AproxDistance(l->dx, l->dy)>>FRACBITS; + //friction = (0x1EB8*length)/0x80 + 0xD000; + strength = sides[l->sidenum[0]].textureoffset>>FRACBITS; + if (strength > 0) // sludge + strength = strength*2; // otherwise, the maximum sludginess value is +967... + + // The following check might seem odd. At the time of movement, + // the move distance is multiplied by 'friction/0x10000', so a + // higher friction value actually means 'less friction'. + friction = ORIG_FRICTION - (0x1EB8*strength)/0x80; // ORIG_FRICTION is 0xE800 if (friction > FRACUNIT) friction = FRACUNIT; if (friction < 0) friction = 0; - // The following check might seem odd. At the time of movement, - // the move distance is multiplied by 'friction/0x10000', so a - // higher friction value actually means 'less friction'. - - if (friction > ORIG_FRICTION) // ice - movefactor = ((0x10092 - friction)*(0x70))/0x158; + //if (friction > ORIG_FRICTION) // ice + // movefactor = ((0x10092 - friction)*(0x70))/0x158; + movefactor = FixedDiv(ORIG_FRICTION, friction); + if (movefactor < FRACUNIT) + movefactor = 8*movefactor - 7*FRACUNIT; else - movefactor = ((friction - 0xDB34)*(0xA))/0x80; + movefactor = FRACUNIT; //movefactor = ((friction - 0xDB34)*(0xA))/0x80; // killough 8/28/98: prevent odd situations if (movefactor < 32) @@ -7289,12 +7298,14 @@ void T_Pusher(pusher_t *p) { referrer = §ors[p->referrer]; - if (!(GETSECSPECIAL(referrer->special, 3) == 2 - || GETSECSPECIAL(referrer->special, 3) == 3)) + //if (!(GETSECSPECIAL(referrer->special, 3) == 2 + // || GETSECSPECIAL(referrer->special, 3) == 3)) + if (GETSECSPECIAL(referrer->special, 3) != 2) return; } - else if (!(GETSECSPECIAL(sec->special, 3) == 2 - || GETSECSPECIAL(sec->special, 3) == 3)) + //else if (!(GETSECSPECIAL(sec->special, 3) == 2 + // || GETSECSPECIAL(sec->special, 3) == 3)) + else if (GETSECSPECIAL(sec->special, 3) != 2) return; // For constant pushers (wind/current) there are 3 situations: diff --git a/src/p_user.c b/src/p_user.c index cf181827..0be8bd7a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4694,11 +4694,14 @@ static void P_3dMovement(player_t *player) } // Better maneuverability while flying - if(player->powers[pw_tailsfly]) - { - thrustfactor = player->thrustfactor*2; - acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration; - } + //if(player->powers[pw_tailsfly]) + //{ + // thrustfactor = player->thrustfactor*2; + // acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration; + //} + + if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration... + acceleration = FixedMul(acceleration<mo->movefactor)>>FRACBITS; // Forward movement if (player->climbing) @@ -6361,7 +6364,7 @@ static void P_SkidStuff(player_t *player) // If your push angle is more than this close to a full 180 degrees, trigger a skid. if (dang > ANGLE_157h) { - player->skidtime = TICRATE/2; + player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; //player->skidtime = TICRATE/2; S_StartSound(player->mo, sfx_skid); if (player->panim != PA_WALK) P_SetPlayerMobjState(player->mo, S_KART_WALK2); // SRB2kart - was S_PLAY_RUN4 @@ -6400,6 +6403,11 @@ static void P_MovePlayer(player_t *player) cmd = &player->cmd; runspd = FixedMul(player->runspeed, player->mo->scale); + // Let's have some movement speed fun on low-friction surfaces, JUST for players... + // (high friction surfaces shouldn't have any adjustment, since the acceleration in + // this game is super high and that ends up cheesing high-friction surfaces.) + runspd = FixedMul(runspd, player->mo->movefactor); + // Control relinquishing stuff! if (player->powers[pw_ingoop]) player->pflags |= PF_FULLSTASIS; @@ -6636,6 +6644,8 @@ static void P_MovePlayer(player_t *player) //else if (onground && (player->mo->state == &states[S_PLAY_SPRING] || player->panim == PA_FALL || player->mo->state == &states[S_PLAY_CARRY]) && !player->mo->momz) // P_SetPlayerMobjState(player->mo, S_PLAY_STND); + player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame. + // If you are stopped and are still walking, stand still! if (!player->mo->momx && !player->mo->momy && !player->mo->momz && player->panim == PA_WALK) P_SetPlayerMobjState(player->mo, S_KART_STND); // SRB2kart - was S_PLAY_STND diff --git a/src/sounds.h b/src/sounds.h index 05380785..01d7cc5c 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -549,16 +549,16 @@ typedef enum sfx_shbrk, sfx_mkdrft, sfx_mkslid, - sfx_mkitem, - sfx_mkitem1, - sfx_mkitem2, - sfx_mkitem3, - sfx_mkitem4, - sfx_mkitem5, - sfx_mkitem6, - sfx_mkitem7, - sfx_mkitem8, - sfx_mkitemF, + sfx_mkitm, + sfx_mkitm1, + sfx_mkitm2, + sfx_mkitm3, + sfx_mkitm4, + sfx_mkitm5, + sfx_mkitm6, + sfx_mkitm7, + sfx_mkitm8, + sfx_mkitmF, sfx_taunt1, sfx_taunt2,