From 8ab32ca93a3ccfd36a0e92d2784246d1df63afcf Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 10 Jul 2016 02:05:59 +0100 Subject: [PATCH 001/100] Significant improvements to the Character select screen in preperation of implementing unlockable characters. * Characters disabled through SOC are outright removed. No awkward gap in scrolling - no hint they were ever there in the first place. * Vertical loop - the character select images are visually continuous. No matter where you are in the chain, you'll always see a hint of the character above or below your current selection in the chain. * Smooth scrolling - Moto and Prime showed me a gfy from back during 2.1 development where it was super smooth. I didn't make it as slow as that one, but the smoothness was easy to add and the reason it was removed previously - gaps in the character select leading to varying speeds - is no longer relevant. --- src/m_menu.c | 78 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index c225e7f15..32b1a7220 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -170,6 +170,7 @@ static saveinfo_t savegameinfo[MAXSAVEGAMES]; // Extra info about the save games INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 +static boolean lastdirection = true; // toaster - Only You Can Prevent Hacks - true is for forward, false is for backwards static INT16 skullAnimCounter = 10; // skull animation counter static boolean setupcontrols_secondaryplayer; @@ -2036,6 +2037,7 @@ static boolean M_ChangeStringCvar(INT32 choice) static void M_NextOpt(void) { INT16 oldItemOn = itemOn; // prevent infinite loop + lastdirection = true; do { @@ -2049,6 +2051,7 @@ static void M_NextOpt(void) static void M_PrevOpt(void) { INT16 oldItemOn = itemOn; // prevent infinite loop + lastdirection = false; do { @@ -4794,7 +4797,7 @@ static void M_DrawSetupChoosePlayerMenu(void) { const INT32 my = 24; patch_t *patch; - INT32 i, o, j; + INT32 i, o, j, prev, next; char *picname; // Black BG @@ -4804,29 +4807,55 @@ static void M_DrawSetupChoosePlayerMenu(void) // Character select profile images!1 M_DrawTextBox(0, my, 16, 20); - if (abs(itemOn*128*FRACUNIT - char_scroll) > 256*FRACUNIT) - char_scroll = itemOn*128*FRACUNIT; - else if (itemOn*128*FRACUNIT - char_scroll > 128*FRACUNIT) - char_scroll += 48*FRACUNIT; - else if (itemOn*128*FRACUNIT - char_scroll < -128*FRACUNIT) - char_scroll -= 48*FRACUNIT; - else if (itemOn*128*FRACUNIT > char_scroll+16*FRACUNIT) - char_scroll += 16*FRACUNIT; - else if (itemOn*128*FRACUNIT < char_scroll-16*FRACUNIT) - char_scroll -= 16*FRACUNIT; + i = (itemOn*128 - char_scroll/FRACUNIT); + + if (abs(i) > 128) + { + o = (lastdirection) ? -1 : 1; + char_scroll = (itemOn+o)*128*FRACUNIT; + } + + i = (itemOn*128 - char_scroll/FRACUNIT); + + if (abs(i) > 1) + char_scroll += i*FRACUNIT>>2; else // close enough. char_scroll = itemOn*128*FRACUNIT; // just be exact now. - i = (char_scroll+16*FRACUNIT)/(128*FRACUNIT); - o = ((char_scroll/FRACUNIT)+16)%128; + + o = ((char_scroll / FRACUNIT) + 16); + if (lastdirection) + o += 128; // This one-directional hack is to prevent visual glitches when going from the (currentMenu->numitems)nd character to the 1st character. + i = (o / 128); + o = (o % 128); + + // subtract 1 from i to counteract the +128 from the prior hack, if we made it happen + if (lastdirection) + { + j = i; + do + { + i--; + if (i < 0) + i = (currentMenu->numitems - 1); + } while (i != j && PlayerMenu[i].status == IT_DISABLED); // Skip over all disabled characters. + } // prev character - if (i-1 >= 0 && PlayerMenu[i-1].status != IT_DISABLED + prev = i; + do + { + prev--; + if (prev < 0) + prev = (currentMenu->numitems - 1); + } while (prev != i && PlayerMenu[prev].status == IT_DISABLED); // Skip over all disabled characters. + + if (prev >= 0 && PlayerMenu[prev].status != IT_DISABLED && o < 32) { - picname = description[i-1].picname; + picname = description[prev].picname; if (picname[0] == '\0') { - picname = strtok(Z_StrDup(description[i-1].skinname), "&"); + picname = strtok(Z_StrDup(description[prev].skinname), "&"); for (j = 0; j < numskins; j++) if (stricmp(skins[j].name, picname) == 0) { @@ -4846,13 +4875,21 @@ static void M_DrawSetupChoosePlayerMenu(void) } // next character - if (i+1 < currentMenu->numitems && PlayerMenu[i+1].status != IT_DISABLED + next = i; + do + { + next++; + if (next >= currentMenu->numitems) + next = 0; + } while (next != i && PlayerMenu[next].status == IT_DISABLED); // Skip over all disabled characters. + + if (next < currentMenu->numitems && PlayerMenu[next].status != IT_DISABLED && o < 128) { - picname = description[i+1].picname; + picname = description[next].picname; if (picname[0] == '\0') { - picname = strtok(Z_StrDup(description[i+1].skinname), "&"); + picname = strtok(Z_StrDup(description[next].skinname), "&"); for (j = 0; j < numskins; j++) if (stricmp(skins[j].name, picname) == 0) { @@ -4872,6 +4909,9 @@ static void M_DrawSetupChoosePlayerMenu(void) } // current character + if (PlayerMenu[i].status == IT_DISABLED) // Prevent flickering. + i = (lastdirection) ? prev : next; + if (i < currentMenu->numitems && PlayerMenu[i].status != IT_DISABLED) { picname = description[i].picname; From 7fe80a7f31ce7d1fc2940d9626cfddf458eb204c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 10 Jul 2016 12:35:24 +0100 Subject: [PATCH 002/100] Minor optimisations and clearer code. --- src/m_menu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 32b1a7220..9a08a5f80 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4812,7 +4812,7 @@ static void M_DrawSetupChoosePlayerMenu(void) if (abs(i) > 128) { o = (lastdirection) ? -1 : 1; - char_scroll = (itemOn+o)*128*FRACUNIT; + char_scroll = (itemOn + o)*128*FRACUNIT; } i = (itemOn*128 - char_scroll/FRACUNIT); @@ -4849,7 +4849,7 @@ static void M_DrawSetupChoosePlayerMenu(void) prev = (currentMenu->numitems - 1); } while (prev != i && PlayerMenu[prev].status == IT_DISABLED); // Skip over all disabled characters. - if (prev >= 0 && PlayerMenu[prev].status != IT_DISABLED + if (prev != i && o < 32) { picname = description[prev].picname; @@ -4883,7 +4883,7 @@ static void M_DrawSetupChoosePlayerMenu(void) next = 0; } while (next != i && PlayerMenu[next].status == IT_DISABLED); // Skip over all disabled characters. - if (next < currentMenu->numitems && PlayerMenu[next].status != IT_DISABLED + if (next != i && o < 128) { picname = description[next].picname; @@ -4910,9 +4910,9 @@ static void M_DrawSetupChoosePlayerMenu(void) // current character if (PlayerMenu[i].status == IT_DISABLED) // Prevent flickering. - i = (lastdirection) ? prev : next; + i = (lastdirection) ? prev : next; // This actually causes duplication at slow scroll speeds (<16FU per tic), but thankfully we always go quickly. - if (i < currentMenu->numitems && PlayerMenu[i].status != IT_DISABLED) + if (PlayerMenu[i].status != IT_DISABLED) { picname = description[i].picname; if (picname[0] == '\0') From d8d83337192baf385717270063b9f60d6710e1aa Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 10 Jul 2016 13:22:49 +0100 Subject: [PATCH 003/100] S_SKIN now supports both DS* and sfx_* prefixes for sounds. --- src/r_things.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 4b3f289df..97e4d0696 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2625,10 +2625,24 @@ void R_AddSkins(UINT16 wadnum) skin->jumpfactor = FLOAT_TO_FIXED(atof(value)); else if (!stricmp(stoken, "highresscale")) skin->highresscale = FLOAT_TO_FIXED(atof(value)); - else + else // let's check if it's a sound, otherwise error out { - INT32 found = false; + boolean found = false; sfxenum_t i; + size_t stokenadjust; + + // Remove the prefix. (We need to affect an adjusting variable so that we can print error messages if it's not actually a sound.) + if ((stoken[0] == 'D' || stoken[0] == 'd') && (stoken[1] == 'S' || stoken[1] == 's')) // DS* + stokenadjust = 2; + else // sfx_* + stokenadjust = 4; + + // Remove the prefix. (We can affect this directly since we're not going to use it again.) + if ((value[0] == 'D' || value[0] == 'd') && (value[1] == 'S' || value[1] == 's')) // DS* + value += 2; + else // sfx_* + value += 4; + // copy name of sounds that are remapped // for this skin for (i = 0; i < sfx_skinsoundslot0; i++) @@ -2637,15 +2651,15 @@ void R_AddSkins(UINT16 wadnum) continue; if (S_sfx[i].skinsound != -1 && !stricmp(S_sfx[i].name, - stoken + 2)) + stoken + stokenadjust)) { skin->soundsid[S_sfx[i].skinsound] = - S_AddSoundFx(value+2, S_sfx[i].singularity, S_sfx[i].pitch, true); + S_AddSoundFx(value, S_sfx[i].singularity, S_sfx[i].pitch, true); found = true; } } if (!found) - CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump# %d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); + CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); } next_token: stoken = strtok(NULL, "\r\n= "); From 8431f64300dabaecd64530832bc87547d1f536e5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 10 Jul 2016 18:41:38 +0100 Subject: [PATCH 004/100] A thorough reimplementation of Nojumpspin for the SPR2_ age. * SF_NOJUMPSPIN - Player's height is full whilst jumping, SPR2_JUMP defaults to SPR2_SPNG instead of SPR2_SPIN, and the player goes into fall frames if they start moving downwards or use their ability. * PA_JUMP - for jumping (upwards in the case of SF_NOJUMPSPIN. * SF_NOJUMPDAMAGE - Ala rosy.wad, don't damage enemies, etc when jumping into them. * SF_STOMPDAMAGE - Just for fun. Ala in Mario, always damage enemies when you land on top of them (your gravity reference, not theirs). * SF_MARIODAMAGE - SF_NOJUMPDAMAGE|SF_STOMPDAMAGE is reasonably accurate to the Mario games, and might as well be surfaced as such. Also, a minor change: * Instead of not spawning the revitem if your SPR2_ is SPR2_DASH, don't spawn it if it's set to 0. This requires the player.dta I uploaded a couple days ago to behave as it was previously. * Don't get stuck in spindash frames if your maxdash is 0, and don't flash rolling frames if you're on goop. --- src/d_player.h | 5 +++++ src/dehacked.c | 5 +++++ src/p_inter.c | 13 ++++++++++--- src/p_map.c | 9 +++++++-- src/p_mobj.c | 13 ++++++++----- src/p_user.c | 49 +++++++++++++++++++++++++++++-------------------- 6 files changed, 64 insertions(+), 30 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index f2e6fe735..5097be68d 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -39,6 +39,10 @@ typedef enum SF_NOSKID = 1<<4, // No skid particles etc SF_NOSPEEDADJUST = 1<<5, // Skin-specific version of disablespeedadjust SF_RUNONWATER = 1<<6, // Run on top of water FOFs? + SF_NOJUMPSPIN = 1<<7, // SPR2_JUMP defaults to SPR2_SPRG instead of SPR2_SPIN, falling states used, and player height is full when jumping? + SF_NOJUMPDAMAGE = 1<<8, // Don't damage enemies, etc whilst jumping? + SF_STOMPDAMAGE = 1<<9, // Always damage enemies, etc by landing on them, no matter your vunerability? + SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc. } skinflags_t; //Primary and secondary skin abilities @@ -166,6 +170,7 @@ typedef enum PA_RUN, PA_PAIN, PA_ROLL, + PA_JUMP, PA_SPRING, PA_FALL, PA_ABILITY, diff --git a/src/dehacked.c b/src/dehacked.c index a536b4e54..9134f54c1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7120,6 +7120,10 @@ struct { {"SF_NOSKID",SF_NOSKID}, {"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST}, {"SF_RUNONWATER",SF_RUNONWATER}, + {"SF_NOJUMPSPIN",SF_NOJUMPSPIN}, + {"SF_NOJUMPDAMAGE",SF_NOJUMPDAMAGE}, + {"SF_STOMPDAMAGE",SF_STOMPDAMAGE}, + {"SF_MARIODAMAGE",SF_MARIODAMAGE}, // Character abilities! // Primary @@ -7189,6 +7193,7 @@ struct { {"PA_RUN",PA_RUN}, {"PA_PAIN",PA_PAIN}, {"PA_ROLL",PA_ROLL}, + {"PA_JUMP",PA_JUMP}, {"PA_SPRING",PA_SPRING}, {"PA_FALL",PA_FALL}, {"PA_ABILITY",PA_ABILITY}, diff --git a/src/p_inter.c b/src/p_inter.c index 9d6230cb2..9c3b36a7e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -300,7 +300,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) + || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE)) + || (player->pflags & (PF_SPINNING|PF_GLIDING)) + || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? { if (P_MobjFlip(toucher)*toucher->momz < 0) @@ -343,7 +345,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_DamageMobj(toucher, special, special, 1, 0); } else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) + || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE)) + || (player->pflags & (PF_SPINNING|PF_GLIDING)) + || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? { if (P_MobjFlip(toucher)*toucher->momz < 0) @@ -1298,7 +1302,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(toucher, special->info->painsound); return; } - else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) + else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) + || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE)) + || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) + || (player->pflags & (PF_SPINNING|PF_GLIDING)) || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? { // Shatter the shield! diff --git a/src/p_map.c b/src/p_map.c index 668ba19c2..447a31b75 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -938,7 +938,9 @@ static boolean PIT_CheckThing(mobj_t *thing) && thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z) { if (thing->flags & MF_MONITOR - && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) + && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) + || ((tmthing->player->pflags & PF_JUMPED) && !(tmthing->player->charflags & SF_NOJUMPDAMAGE)) + || ((tmthing->player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))) { SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed. fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;; @@ -960,7 +962,10 @@ static boolean PIT_CheckThing(mobj_t *thing) } // Monitors are not treated as solid to players who are jumping, spinning or gliding, // unless it's a CTF team monitor and you're on the wrong team - else if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING) + else if (thing->flags & MF_MONITOR && tmthing->player + && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) + || ((tmthing->player->pflags & PF_JUMPED) && !(tmthing->player->charflags & SF_NOJUMPDAMAGE)) + || ((tmthing->player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))) && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2))) ; // z checking at last diff --git a/src/p_mobj.c b/src/p_mobj.c index 5fb3c81d7..43ae0ecfc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -238,11 +238,13 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) break; case S_PLAY_SPIN: case S_PLAY_DASH: - case S_PLAY_JUMP: case S_PLAY_SUPER_SPIN: - case S_PLAY_SUPER_JUMP: player->panim = PA_ROLL; break; + case S_PLAY_JUMP: + case S_PLAY_SUPER_JUMP: + player->panim = PA_JUMP; + break; case S_PLAY_SPRING: case S_PLAY_SUPER_SPRING: player->panim = PA_SPRING; @@ -286,7 +288,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST)) { fixed_t speed = FixedDiv(player->speed, mobj->scale); - if (player->panim == PA_ROLL) + if (player->panim == PA_ROLL || player->panim == PA_JUMP) { if (speed > 16<tics = 1; @@ -329,12 +331,13 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) // Player animations if (st->sprite == SPR_PLAY) { + skin_t *skin = ((skin_t *)mobj->skin); boolean noalt = false; UINT8 spr2 = st->frame & FF_FRAMEMASK; UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set - while (((skin_t *)mobj->skin)->sprites[spr2].numframes <= 0 + while (skin->sprites[spr2].numframes <= 0 && spr2 != SPR2_STND) { switch(spr2) @@ -352,7 +355,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_SPNG; break; case SPR2_JUMP: - spr2 = SPR2_SPIN; + spr2 = (skin->flags & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_SPIN; break; case SPR2_SPNG: // spring spr2 = SPR2_FALL; diff --git a/src/p_user.c b/src/p_user.c index 02e3308d0..b2592408a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3727,10 +3727,7 @@ void P_DoJump(player_t *player, boolean soundandstate) if (!player->spectator) S_StartSound(player->mo, sfx_jump); // Play jump sound! - if (!(player->charability2 == CA2_SPINDASH)) - P_SetPlayerMobjState(player->mo, S_PLAY_SPRING); - else - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } } @@ -3780,7 +3777,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) S_StartSound(player->mo, sfx_spndsh); // Make the rev sound! // Now spawn the color thok circle. - if (player->mo->sprite2 != SPR2_DASH) + if (player->revitem) { P_SpawnSpinMobj(player, player->revitem); if (demorecording) @@ -3827,19 +3824,29 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) } // Catapult the player from a spindash rev! - if (onground && !(player->pflags & PF_USEDOWN) && player->dashspeed && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING)) + if (onground && !(player->pflags & PF_USEDOWN) && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING)) { + player->pflags &= ~PF_STARTDASH; if (player->powers[pw_ingoop]) player->dashspeed = 0; - player->pflags &= ~PF_STARTDASH; if (!((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)) { - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); - P_InstaThrust(player->mo, player->mo->angle, player->dashspeed); // catapult forward ho!! + if (player->dashspeed) + { + P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_InstaThrust(player->mo, player->mo->angle, player->dashspeed); // catapult forward ho!! + } + else + { + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + player->pflags &= ~PF_SPINNING; + } + if (!player->spectator) S_StartSound(player->mo, sfx_zoom); } + player->dashspeed = 0; } @@ -6524,8 +6531,10 @@ static void P_MovePlayer(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_WALK); } - // If Springing, but travelling DOWNWARD, change back! - if (player->panim == PA_SPRING && P_MobjFlip(player->mo)*player->mo->momz < 0) + // If Springing (or nojumpspinning), but travelling DOWNWARD, change back! (nojumpspin also turns to fall once PF_THOKKED is added.) + if ((player->panim == PA_SPRING && P_MobjFlip(player->mo)*player->mo->momz < 0) + || ((((player->charflags & SF_NOJUMPSPIN) && (player->pflags & PF_JUMPED) && player->panim == PA_JUMP)) + && (P_MobjFlip(player->mo)*player->mo->momz < 0 || player->pflags & PF_THOKKED))) P_SetPlayerMobjState(player->mo, S_PLAY_FALL); // If Springing but on the ground, change back! else if (onground && (player->panim == PA_SPRING || player->panim == PA_FALL || player->panim == PA_RIDE) && !player->mo->momz) @@ -6844,7 +6853,7 @@ static void P_MovePlayer(player_t *player) #endif } // Otherwise, face the direction you're travelling. - else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_ROLL + else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_ROLL || player->panim == PA_JUMP || (player->mo->state-states == S_PLAY_FLY || player->mo->state-states == S_PLAY_FLY_TIRED)) player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); @@ -6893,7 +6902,7 @@ static void P_MovePlayer(player_t *player) if (player->skin == 0 && player->powers[pw_super] && player->speed > FixedMul(5<mo->scale) && P_MobjFlip(player->mo)*player->mo->momz <= 0) { - if (player->panim == PA_ROLL || player->mo->state-states == S_PLAY_PAIN || player->panim == PA_WALK) + if (player->panim == PA_ROLL || player->panim == PA_JUMP || player->mo->state-states == S_PLAY_PAIN || player->panim == PA_WALK) P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_FLOAT); player->mo->momz = 0; @@ -6980,7 +6989,7 @@ static void P_MovePlayer(player_t *player) // Less height while spinning. Good for spinning under things...? if ((player->mo->state == &states[player->mo->info->painstate] || player->mo->state == &states[S_PLAY_SUPER_PAIN]) - || (player->charability2 == CA2_SPINDASH && (player->pflags & (PF_SPINNING|PF_JUMPED))) + || (!(player->charflags & SF_NOJUMPSPIN) && (player->pflags & (PF_SPINNING|PF_JUMPED))) || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) player->mo->height = P_GetPlayerSpinHeight(player); @@ -7274,7 +7283,7 @@ static void P_DoRopeHang(player_t *player) player->pflags &= ~PF_ROPEHANG; if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) - && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) + && !(player->panim == PA_JUMP)) P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); return; } @@ -7391,7 +7400,7 @@ static void P_DoRopeHang(player_t *player) player->pflags &= ~PF_ROPEHANG; if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) - && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) + && !(player->panim == PA_JUMP)) P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } @@ -8733,7 +8742,7 @@ void P_PlayerThink(player_t *player) if (player->panim != PA_ABILITY) P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); } - else if ((player->pflags & PF_JUMPED) && !player->powers[pw_super] && player->panim != PA_ROLL && player->charability2 == CA2_SPINDASH) + else if ((player->pflags & PF_JUMPED) && !player->powers[pw_super] && player->panim != PA_JUMP && !(player->charflags & SF_NOJUMPSPIN)) P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); if (player->flashcount) @@ -8977,7 +8986,7 @@ void P_PlayerThink(player_t *player) else { P_DoZoomTube(player); - if (!(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) + if (!(player->panim == PA_ROLL)) P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); } player->rmomx = player->rmomy = 0; // no actual momentum from your controls @@ -9361,9 +9370,9 @@ void P_PlayerAfterThink(player_t *player) else if (player->pflags & PF_SLIDING) P_SetPlayerMobjState(player->mo, player->mo->info->painstate); else if (player->pflags & PF_JUMPED - && ((!player->powers[pw_super] && player->panim != PA_ROLL) + && ((!player->powers[pw_super] && player->panim != PA_JUMP) || player->mo->state == &states[player->mo->info->painstate]) - && player->charability2 == CA2_SPINDASH) + && !(player->charflags & SF_NOJUMPSPIN)) P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); if (player->pflags & PF_CARRIED && player->mo->tracer) From 7c63a96bf1e613d644e8681bd6bdda5f933436ab Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 10 Jul 2016 20:03:08 +0100 Subject: [PATCH 005/100] Logic error. Now works as described previously. --- src/p_user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index b2592408a..b579cbfe5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6989,7 +6989,8 @@ static void P_MovePlayer(player_t *player) // Less height while spinning. Good for spinning under things...? if ((player->mo->state == &states[player->mo->info->painstate] || player->mo->state == &states[S_PLAY_SUPER_PAIN]) - || (!(player->charflags & SF_NOJUMPSPIN) && (player->pflags & (PF_SPINNING|PF_JUMPED))) + || (!(player->charflags & SF_NOJUMPSPIN) && (player->pflags & PF_JUMPED)) + || (player->pflags & PF_SPINNING) || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) player->mo->height = P_GetPlayerSpinHeight(player); From eee6a6ff457c823559c2f77f6fc3b38d69c644c2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 11 Jul 2016 23:01:43 +0100 Subject: [PATCH 006/100] Optimisations to the character select screen. * If a character select character image is not set, don't iterate every tic - iterate on first image get and then save to the struct. * A character select screen with only two characters now has special case handling. * A memory leak in the making has been plugged. (specifically, picname not being Z_Free'd if the loop fails to do so) * Logic/operation simplification. Also, some typo corrections and clarity case movements of stuff in other files I've been looking at. --- src/dehacked.c | 2 +- src/m_menu.c | 122 +++++++++++++++++++++++++++---------------------- src/p_mobj.c | 13 +++--- 3 files changed, 76 insertions(+), 61 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 9134f54c1..7f53ec690 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -563,7 +563,7 @@ static void readPlayer(MYFILE *f, INT32 num) You MAY disable previous entries if you so desire... But try to enable something that's already enabled and you will be sent to a free slot. - Because of this, you are allowed to edit any previous entrys you like, but only if you + Because of this, you are allowed to edit any previous entries you like, but only if you signal that you are purposely doing so by disabling and then reenabling the slot. ... Or use MENUPOSITION first, that works too. Hell, you could edit multiple character diff --git a/src/m_menu.c b/src/m_menu.c index 9a08a5f80..08a21a4b2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4813,10 +4813,9 @@ static void M_DrawSetupChoosePlayerMenu(void) { o = (lastdirection) ? -1 : 1; char_scroll = (itemOn + o)*128*FRACUNIT; + i = -o*128; } - i = (itemOn*128 - char_scroll/FRACUNIT); - if (abs(i) > 1) char_scroll += i*FRACUNIT>>2; else // close enough. @@ -4840,7 +4839,7 @@ static void M_DrawSetupChoosePlayerMenu(void) } while (i != j && PlayerMenu[i].status == IT_DISABLED); // Skip over all disabled characters. } - // prev character + // Get prev character... prev = i; do { @@ -4849,74 +4848,85 @@ static void M_DrawSetupChoosePlayerMenu(void) prev = (currentMenu->numitems - 1); } while (prev != i && PlayerMenu[prev].status == IT_DISABLED); // Skip over all disabled characters. - if (prev != i - && o < 32) + if (prev != i) // If there's more than one character available... { - picname = description[prev].picname; - if (picname[0] == '\0') + // Let's get the next character now. + next = i; + do { - picname = strtok(Z_StrDup(description[prev].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) + next++; + if (next >= currentMenu->numitems) + next = 0; + } while (next != i && PlayerMenu[next].status == IT_DISABLED); // Skip over all disabled characters. + + // Draw prev character if it's visible and its number isn't greater than the current one + if ((o < 32) && !((prev == next) && prev > i)) // (prev != i) was previously a part of this, but we don't need to check again after above. + { + picname = description[prev].picname; + if (picname[0] == '\0') + { + picname = strtok(Z_StrDup(description[prev].skinname), "&"); + for (j = 0; j < numskins; j++) + if (stricmp(skins[j].name, picname) == 0) + { + Z_Free(picname); + picname = skins[j].charsel; + break; + } + if (j == numskins) // AAAAAAAAAA { Z_Free(picname); - picname = skins[j].charsel; - break; + picname = skins[0].charsel; } - if (j == numskins) // AAAAAAAAAA - picname = skins[0].charsel; + strncpy(description[prev].picname, picname, 8); // Only iterate once. + } + patch = W_CachePatchName(picname, PU_CACHE); + if (SHORT(patch->width) >= 256) + V_DrawCroppedPatch(8<height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height)); + else + V_DrawCroppedPatch(8<height) - 32 + o, SHORT(patch->width), SHORT(patch->height)); + W_UnlockCachedPatch(patch); } - patch = W_CachePatchName(picname, PU_CACHE); - if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height)); - else - V_DrawCroppedPatch(8<height) - 32 + o, SHORT(patch->width), SHORT(patch->height)); - W_UnlockCachedPatch(patch); - } - // next character - next = i; - do - { - next++; - if (next >= currentMenu->numitems) - next = 0; - } while (next != i && PlayerMenu[next].status == IT_DISABLED); // Skip over all disabled characters. - - if (next != i - && o < 128) - { - picname = description[next].picname; - if (picname[0] == '\0') + // Draw next character if it's visible and its number isn't less than the current one + if ((o < 128) && !((prev == next) && next < i)) // (next != i) was previously a part of this, but it's implicitly true if (prev != i) is true. { - picname = strtok(Z_StrDup(description[next].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) + picname = description[next].picname; + if (picname[0] == '\0') + { + picname = strtok(Z_StrDup(description[next].skinname), "&"); + for (j = 0; j < numskins; j++) + if (stricmp(skins[j].name, picname) == 0) + { + Z_Free(picname); + picname = skins[j].charsel; + break; + } + if (j == numskins) // AAAAAAAAAA { Z_Free(picname); - picname = skins[j].charsel; - break; + picname = skins[0].charsel; } - if (j == numskins) // AAAAAAAAAA - picname = skins[0].charsel; + strncpy(description[next].picname, picname, 8); // Only iterate once. + } + patch = W_CachePatchName(picname, PU_CACHE); + if (SHORT(patch->width) >= 256) + V_DrawCroppedPatch(8<width), o*2); + else + V_DrawCroppedPatch(8<width), o); + W_UnlockCachedPatch(patch); } - patch = W_CachePatchName(picname, PU_CACHE); - if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<width), o*2); - else - V_DrawCroppedPatch(8<width), o); - W_UnlockCachedPatch(patch); - } - // current character - if (PlayerMenu[i].status == IT_DISABLED) // Prevent flickering. - i = (lastdirection) ? prev : next; // This actually causes duplication at slow scroll speeds (<16FU per tic), but thankfully we always go quickly. + // current character + if (PlayerMenu[i].status == IT_DISABLED) // Prevent flickering. + i = (lastdirection) ? prev : next; // This actually causes duplication at slow scroll speeds (<16FU per tic), but thankfully we always go quickly. + } if (PlayerMenu[i].status != IT_DISABLED) { picname = description[i].picname; if (picname[0] == '\0') - { + { picname = strtok(Z_StrDup(description[i].skinname), "&"); for (j = 0; j < numskins; j++) if (stricmp(skins[j].name, picname) == 0) @@ -4926,8 +4936,12 @@ static void M_DrawSetupChoosePlayerMenu(void) break; } if (j == numskins) // AAAAAAAAAA + { + Z_Free(picname); picname = skins[0].charsel; - } + } + strncpy(description[i].picname, picname, 8); // Only iterate once. + } patch = W_CachePatchName(picname, PU_CACHE); if (o >= 0 && o <= 32) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 43ae0ecfc..653b6967e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -355,7 +355,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_SPNG; break; case SPR2_JUMP: - spr2 = (skin->flags & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_SPIN; + spr2 = (player->charflags & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_SPIN; break; case SPR2_SPNG: // spring spr2 = SPR2_FALL; @@ -384,11 +384,6 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_CLMB; break; - case SPR2_SIGN: - case SPR2_LIFE: - noalt = true; - break; - // Super sprites fallback to regular sprites case SPR2_SWLK: spr2 = SPR2_WALK; @@ -433,6 +428,12 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_SWLK; break; + // Sprites for non-player objects? There's nothing we can do. + case SPR2_SIGN: + case SPR2_LIFE: + noalt = true; + break; + // Dunno? Just go to standing then. default: spr2 = SPR2_STND; From ee92e043b98fe4b8d487bba0a4e60e494c71bffb Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 11 Jul 2016 23:40:31 +0100 Subject: [PATCH 007/100] Preparation for hidden characters, making sure R_SkinAvailable was being used where appropriate. Also, bugfix for something my optimisation introduced. --- src/dehacked.c | 2 ++ src/m_menu.c | 53 +++++++++++++++----------------------------------- src/r_things.c | 13 +++++-------- 3 files changed, 23 insertions(+), 45 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 7f53ec690..518e1c85c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -584,6 +584,8 @@ static void readPlayer(MYFILE *f, INT32 num) strlcpy(description[num].skinname, word2, sizeof description[num].skinname); strlwr(description[num].skinname); + + description[num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...) } else deh_warning("readPlayer %d: unknown word '%s'", num, word); diff --git a/src/m_menu.c b/src/m_menu.c index 08a21a4b2..f64fa2fc7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4859,25 +4859,18 @@ static void M_DrawSetupChoosePlayerMenu(void) next = 0; } while (next != i && PlayerMenu[next].status == IT_DISABLED); // Skip over all disabled characters. - // Draw prev character if it's visible and its number isn't greater than the current one + // Draw prev character if it's visible and its number isn't greater than the current one or there's more than two if ((o < 32) && !((prev == next) && prev > i)) // (prev != i) was previously a part of this, but we don't need to check again after above. { picname = description[prev].picname; if (picname[0] == '\0') { picname = strtok(Z_StrDup(description[prev].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) - { - Z_Free(picname); - picname = skins[j].charsel; - break; - } - if (j == numskins) // AAAAAAAAAA - { - Z_Free(picname); - picname = skins[0].charsel; - } + j = R_SkinAvailable(picname); + Z_Free(picname); + if (j == -1) + j = 0; + picname = skins[j].charsel; strncpy(description[prev].picname, picname, 8); // Only iterate once. } patch = W_CachePatchName(picname, PU_CACHE); @@ -4888,25 +4881,18 @@ static void M_DrawSetupChoosePlayerMenu(void) W_UnlockCachedPatch(patch); } - // Draw next character if it's visible and its number isn't less than the current one + // Draw next character if it's visible and its number isn't less than the current one or there's more than two if ((o < 128) && !((prev == next) && next < i)) // (next != i) was previously a part of this, but it's implicitly true if (prev != i) is true. { picname = description[next].picname; if (picname[0] == '\0') { picname = strtok(Z_StrDup(description[next].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) - { - Z_Free(picname); - picname = skins[j].charsel; - break; - } - if (j == numskins) // AAAAAAAAAA - { - Z_Free(picname); - picname = skins[0].charsel; - } + j = R_SkinAvailable(picname); + Z_Free(picname); + if (j == -1) + j = 0; + picname = skins[j].charsel; strncpy(description[next].picname, picname, 8); // Only iterate once. } patch = W_CachePatchName(picname, PU_CACHE); @@ -4928,18 +4914,11 @@ static void M_DrawSetupChoosePlayerMenu(void) if (picname[0] == '\0') { picname = strtok(Z_StrDup(description[i].skinname), "&"); - for (j = 0; j < numskins; j++) - if (stricmp(skins[j].name, picname) == 0) - { - Z_Free(picname); - picname = skins[j].charsel; - break; - } - if (j == numskins) // AAAAAAAAAA - { + j = R_SkinAvailable(picname); Z_Free(picname); - picname = skins[0].charsel; - } + if (j == -1) + j = 0; + picname = skins[j].charsel; strncpy(description[i].picname, picname, 8); // Only iterate once. } patch = W_CachePatchName(picname, PU_CACHE); diff --git a/src/r_things.c b/src/r_things.c index 97e4d0696..83b4a8118 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2337,6 +2337,7 @@ INT32 R_SkinAvailable(const char *name) for (i = 0; i < numskins; i++) { + // search in the skin list if (stricmp(skins[i].name,name)==0) return i; } @@ -2346,17 +2347,13 @@ INT32 R_SkinAvailable(const char *name) // network code calls this when a 'skin change' is received void SetPlayerSkin(INT32 playernum, const char *skinname) { - INT32 i; + INT32 i = R_SkinAvailable(skinname); player_t *player = &players[playernum]; - for (i = 0; i < numskins; i++) + if (i != -1) { - // search in the skin list - if (stricmp(skins[i].name, skinname) == 0) - { - SetPlayerSkinByNum(playernum, i); - return; - } + SetPlayerSkinByNum(playernum, i); + return; } if (P_IsLocalPlayer(player)) From b5108afe169ae46519a00790951a3873d71fb75f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 12 Jul 2016 03:15:58 +0100 Subject: [PATCH 008/100] Substantial re-engineering for the foundations of hidden characters. R_SkinUnlock defines the circumstances under which a skin is available. For simplicty's sake, I've currently bound it to an S_SKIN variable so I can toggle it easily, but it WILL be replaced with a hook into the savegame system at some point. * Currently has three tiers of unlock - freebie (forceskin or modeattacking via a loaded replay), Ringslinger Only, and SP/Coop and Ringslinger. * I don't know anything about netcode so I basically decided to make R_SkinUnlock relevant only under local circumstances, try as hard as possible to stop bad skin info from getting sent to the server, and then admit defeat once the server has the information. If this is a bad choice, please discipline me and show me how to fix it. * Character Select now checks for whether the character is hidden or not on menu load and does/undoes it based on that info, but will never touch one disabled via SOC. I also used this opportunity to optimise, checking for/filling out charsel pictures instead of doing it later. (It now also includes special casing for a select screen with zero characters!) * Mode Attack now hides hidden characters in its character select based on SP rules. Things that still need to be done: * ForceSkin_OnChange. Is there a graceful way to handle this? * No obvious skin name conflicts. Add a salt to the names of hidden skins, and then remove it when they're unhidden? * The gap between Knuckles' skin number and the first custom character anybody adds will be way too obvious. A seperate hidden skin numbering system? Start at 32 and count up from there? There's a few ways... --- src/d_netcmd.c | 8 ++-- src/m_menu.c | 115 +++++++++++++++++++++++++------------------------ src/r_things.c | 23 +++++++++- src/r_things.h | 3 ++ 4 files changed, 88 insertions(+), 61 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4b45ef1a7..fe7b032bf 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1092,7 +1092,7 @@ static void SendNameAndColor(void) SetPlayerSkinByNum(consoleplayer, 0); CV_StealthSet(&cv_skin, skins[0].name); } - else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1) + else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUnlock(foundskin)) { boolean notsame; @@ -1139,7 +1139,7 @@ static void SendNameAndColor(void) // check if player has the skin loaded (cv_skin may have // the name of a skin that was available in the previous game) cv_skin.value = R_SkinAvailable(cv_skin.string); - if (cv_skin.value < 0) + if ((cv_skin.value < 0) || !R_SkinUnlock(cv_skin.value)) { CV_StealthSet(&cv_skin, DEFAULTSKIN); cv_skin.value = 0; @@ -1217,7 +1217,7 @@ static void SendNameAndColor2(void) SetPlayerSkinByNum(secondplaya, forcedskin); CV_StealthSet(&cv_skin2, skins[forcedskin].name); } - else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1) + else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUnlock(foundskin)) { boolean notsame; @@ -4002,7 +4002,7 @@ static void Command_Archivetest_f(void) */ static void ForceSkin_OnChange(void) { - if ((server || adminplayer == consoleplayer) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins)) + if ((server || adminplayer == consoleplayer) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins || !R_SkinUnlock(cv_forceskin.value))) { if (cv_forceskin.value == -2) CV_SetValue(&cv_forceskin, numskins-1); diff --git a/src/m_menu.c b/src/m_menu.c index f64fa2fc7..53b5be270 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3429,9 +3429,9 @@ static void M_PatchSkinNameTable(void) for (j = 0; j < MAXSKINS; j++) { - if (skins[j].name[0] != '\0') + if (skins[j].name[0] != '\0' && R_SkinUnlock(j)) { - skins_cons_t[j].strvalue = skins[j].name; + skins_cons_t[j].strvalue = skins[j].realname; skins_cons_t[j].value = j+1; } else @@ -4771,14 +4771,42 @@ void M_ForceSaveSlotSelected(INT32 sslot) static void M_SetupChoosePlayer(INT32 choice) { + INT32 availablecount = 0; + INT32 i, skinnum; + char *name; (void)choice; - if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] != '\0') + for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks. { - M_ChoosePlayer(0); //oh for crying out loud just get STARTED, it doesn't matter! + if (PlayerMenu[i].status != IT_DISABLED) // If the character's disabled through SOC, there's nothing we can do for it. + { + name = strtok(Z_StrDup(description[i].skinname), "&"); + skinnum = R_SkinAvailable(name); + if ((skinnum != -1) && (R_SkinUnlock(skinnum))) + { + if (PlayerMenu[i].status == (IT_DISABLED|IT_CENTER)) + PlayerMenu[i].status = IT_CALL; + if (description[i].picname[0] == '\0') + strncpy(description[i].picname, skins[skinnum].charsel, 8); + } + else // Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. + PlayerMenu[i].status = (IT_DISABLED|IT_CENTER); + Z_Free(name); + + if (!(PlayerMenu[i].status & IT_DISABLED)) // If this character is available at all... + availablecount++; + } + } + + if (!(availablecount) + || (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] != '\0')) + { + PlayerMenu[0].status = (IT_CALL|IT_CENTER); // This is a hack to make availablecount not softlock the game. Again, I use IT_CENTER as a dummy flag. + M_ChoosePlayer(0); // oh for crying out loud just get STARTED, it doesn't matter! return; } + if (Playing() == false) { S_StopMusic(); @@ -4798,7 +4826,6 @@ static void M_DrawSetupChoosePlayerMenu(void) const INT32 my = 24; patch_t *patch; INT32 i, o, j, prev, next; - char *picname; // Black BG V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); @@ -4836,7 +4863,7 @@ static void M_DrawSetupChoosePlayerMenu(void) i--; if (i < 0) i = (currentMenu->numitems - 1); - } while (i != j && PlayerMenu[i].status == IT_DISABLED); // Skip over all disabled characters. + } while (i != j && PlayerMenu[i].status & IT_DISABLED); } // Get prev character... @@ -4846,7 +4873,7 @@ static void M_DrawSetupChoosePlayerMenu(void) prev--; if (prev < 0) prev = (currentMenu->numitems - 1); - } while (prev != i && PlayerMenu[prev].status == IT_DISABLED); // Skip over all disabled characters. + } while (prev != i && PlayerMenu[prev].status & IT_DISABLED); if (prev != i) // If there's more than one character available... { @@ -4857,23 +4884,12 @@ static void M_DrawSetupChoosePlayerMenu(void) next++; if (next >= currentMenu->numitems) next = 0; - } while (next != i && PlayerMenu[next].status == IT_DISABLED); // Skip over all disabled characters. + } while (next != i && PlayerMenu[next].status & IT_DISABLED); // Draw prev character if it's visible and its number isn't greater than the current one or there's more than two if ((o < 32) && !((prev == next) && prev > i)) // (prev != i) was previously a part of this, but we don't need to check again after above. { - picname = description[prev].picname; - if (picname[0] == '\0') - { - picname = strtok(Z_StrDup(description[prev].skinname), "&"); - j = R_SkinAvailable(picname); - Z_Free(picname); - if (j == -1) - j = 0; - picname = skins[j].charsel; - strncpy(description[prev].picname, picname, 8); // Only iterate once. - } - patch = W_CachePatchName(picname, PU_CACHE); + patch = W_CachePatchName(description[prev].picname, PU_CACHE); if (SHORT(patch->width) >= 256) V_DrawCroppedPatch(8<height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height)); else @@ -4884,18 +4900,7 @@ static void M_DrawSetupChoosePlayerMenu(void) // Draw next character if it's visible and its number isn't less than the current one or there's more than two if ((o < 128) && !((prev == next) && next < i)) // (next != i) was previously a part of this, but it's implicitly true if (prev != i) is true. { - picname = description[next].picname; - if (picname[0] == '\0') - { - picname = strtok(Z_StrDup(description[next].skinname), "&"); - j = R_SkinAvailable(picname); - Z_Free(picname); - if (j == -1) - j = 0; - picname = skins[j].charsel; - strncpy(description[next].picname, picname, 8); // Only iterate once. - } - patch = W_CachePatchName(picname, PU_CACHE); + patch = W_CachePatchName(description[next].picname, PU_CACHE); if (SHORT(patch->width) >= 256) V_DrawCroppedPatch(8<width), o*2); else @@ -4904,24 +4909,13 @@ static void M_DrawSetupChoosePlayerMenu(void) } // current character - if (PlayerMenu[i].status == IT_DISABLED) // Prevent flickering. + if (PlayerMenu[i].status & IT_DISABLED) // Prevent flickering. i = (lastdirection) ? prev : next; // This actually causes duplication at slow scroll speeds (<16FU per tic), but thankfully we always go quickly. } - if (PlayerMenu[i].status != IT_DISABLED) + if (!(PlayerMenu[i].status & IT_DISABLED)) { - picname = description[i].picname; - if (picname[0] == '\0') - { - picname = strtok(Z_StrDup(description[i].skinname), "&"); - j = R_SkinAvailable(picname); - Z_Free(picname); - if (j == -1) - j = 0; - picname = skins[j].charsel; - strncpy(description[i].picname, picname, 8); // Only iterate once. - } - patch = W_CachePatchName(picname, PU_CACHE); + patch = W_CachePatchName(description[i].picname, PU_CACHE); if (o >= 0 && o <= 32) { if (SHORT(patch->width) >= 256) @@ -4956,8 +4950,8 @@ static void M_ChoosePlayer(INT32 choice) INT32 skinnum; boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); - // skip this if forcecharacter - if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] == '\0') + // skip this if forcecharacter or no characters available + if (!(PlayerMenu[choice].status & IT_CENTER)) { // M_SetupChoosePlayer didn't call us directly, that means we've been properly set up. char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu @@ -6503,6 +6497,7 @@ static void M_DrawSetupMultiPlayerMenu(void) static void M_HandleSetupMultiPlayer(INT32 choice) { size_t l; + INT32 prev_setupm_fakeskin; boolean exitmenu = false; // exit to previous menu and send name change switch (choice) @@ -6521,7 +6516,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice) if (itemOn == 2) //player skin { S_StartSound(NULL,sfx_menu1); // Tails - setupm_fakeskin--; + prev_setupm_fakeskin = setupm_fakeskin; + do + { + setupm_fakeskin--; + if (setupm_fakeskin < 0) + setupm_fakeskin = numskins-1; + } + while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUnlock(setupm_fakeskin))); } else if (itemOn == 1) // player color { @@ -6534,7 +6536,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice) if (itemOn == 2) //player skin { S_StartSound(NULL,sfx_menu1); // Tails - setupm_fakeskin++; + prev_setupm_fakeskin = setupm_fakeskin; + do + { + setupm_fakeskin++; + if (setupm_fakeskin > numskins-1) + setupm_fakeskin = 0; + } + while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUnlock(setupm_fakeskin))); } else if (itemOn == 1) // player color { @@ -6568,12 +6577,6 @@ static void M_HandleSetupMultiPlayer(INT32 choice) break; } - // check skin - if (setupm_fakeskin < 0) - setupm_fakeskin = numskins-1; - if (setupm_fakeskin > numskins-1) - setupm_fakeskin = 0; - // check color if (setupm_fakecolor < 1) setupm_fakecolor = MAXSKINCOLORS-1; diff --git a/src/r_things.c b/src/r_things.c index 83b4a8118..9f2b5da8d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2305,6 +2305,8 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->highresscale = FRACUNIT>>1; + skin->availability = 2; + for (i = 0; i < sfx_skinsoundslot0; i++) if (S_sfx[i].skinsound != -1) skin->soundsid[S_sfx[i].skinsound] = i; @@ -2329,6 +2331,17 @@ void R_InitSkins(void) numskins = 0; } +// returns true if available in circumstances, otherwise nope +// warning don't use with an invalid skinnum +boolean R_SkinUnlock(INT32 skinnum) +{ + return ((skins[skinnum].availability == 2) // SP/Coop is strict + || (modeattacking) // If you have someone else's run you might as well take a look + || ((netgame) + && ((cv_forceskin.value == skinnum) // Forceskin is weak + || (G_RingSlingerGametype() && (skins[skinnum].availability != 0))))); // Ringslinger is disciplined +} + // returns true if the skin name is found (loaded from pwad) // warning return -1 if not found INT32 R_SkinAvailable(const char *name) @@ -2371,7 +2384,8 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) player_t *player = &players[playernum]; skin_t *skin = &skins[skinnum]; - if (skinnum >= 0 && skinnum < numskins) // Make sure it exists! + if ((skinnum >= 0 && skinnum < numskins) // Make sure it exists! + && (!P_IsLocalPlayer(player) || R_SkinUnlock(skinnum))) // ...but is it allowed? We must always allow external players to change skin. The server should vet that... { player->skin = skinnum; if (player->mo) @@ -2612,6 +2626,13 @@ void R_AddSkins(UINT16 wadnum) GETINT(acceleration) #undef GETINT + else if (!stricmp(stoken, "availability")) +#ifdef DEVELOP + skin->availability = atoi(value); +#else + ; +#endif + // custom translation table else if (!stricmp(stoken, "startcolor")) skin->starttranscolor = atoi(value); diff --git a/src/r_things.h b/src/r_things.h index 3fce5f3fd..23842094e 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -102,6 +102,8 @@ typedef struct sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table spritedef_t sprites[NUMPLAYERSPRITES]; + + UINT8 availability; // lock? safe to put here as is not networked } skin_t; // ----------- @@ -184,6 +186,7 @@ extern skin_t skins[MAXSKINS + 1]; void SetPlayerSkin(INT32 playernum,const char *skinname); void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 +boolean R_SkinUnlock(INT32 skinnum); INT32 R_SkinAvailable(const char *name); void R_AddSkins(UINT16 wadnum); From 80a3d79d4dbd4dfeb5a0642b305cfed249333223 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 12 Jul 2016 14:40:20 +0100 Subject: [PATCH 009/100] Some hacks added to forceskin to: * support hidden characters * take the skin->name, not the number * display the skin->name in the menu Also, minor tweaks to other things. --- src/command.c | 59 +++++++++++++++++++++++++++++++++++++++++--------- src/d_netcmd.c | 2 +- src/dehacked.c | 2 +- src/r_things.c | 22 +++++++++++++++---- 4 files changed, 69 insertions(+), 16 deletions(-) diff --git a/src/command.c b/src/command.c index 84d777acf..f87794346 100644 --- a/src/command.c +++ b/src/command.c @@ -1159,7 +1159,12 @@ found: var->value = (INT32)(d * FRACUNIT); } else - var->value = atoi(var->string); + { + if (var == &cv_forceskin) + var->value = R_SkinAvailable(var->string); + else + var->value = atoi(var->string); + } finish: // See the note above. @@ -1383,6 +1388,30 @@ void CV_StealthSet(consvar_t *var, const char *value) CV_SetCVar(var, value, true); } +/** Sets a numeric value to a variable, sometimes calling its callback + * function. + * + * \param var The variable. + * \param value The numeric value, converted to a string before setting. + * \param stealth Do we call the callback function or not? + */ +static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth) +{ + char val[32]; + + if (var == &cv_forceskin) // Special handling. + { + if ((value < 0) || (value >= numskins)) + sprintf(val, "None"); + else + sprintf(val, "%s", skins[value].name); + } + else + sprintf(val, "%d", value); + + CV_SetCVar(var, val, stealth); +} + /** Sets a numeric value to a variable without calling its callback * function. * @@ -1392,10 +1421,7 @@ void CV_StealthSet(consvar_t *var, const char *value) */ void CV_StealthSetValue(consvar_t *var, INT32 value) { - char val[32]; - - sprintf(val, "%d", value); - CV_SetCVar(var, val, true); + CV_SetValueMaybeStealth(var, value, true); } // New wrapper for what used to be CV_Set() @@ -1413,10 +1439,7 @@ void CV_Set(consvar_t *var, const char *value) */ void CV_SetValue(consvar_t *var, INT32 value) { - char val[32]; - - sprintf(val, "%d", value); - CV_SetCVar(var, val, false); + CV_SetValueMaybeStealth(var, value, false); } /** Adds a value to a console variable. @@ -1436,7 +1459,23 @@ void CV_AddValue(consvar_t *var, INT32 increment) // count pointlimit better if (var == &cv_pointlimit && (gametype == GT_MATCH)) increment *= 50; - newvalue = var->value + increment; + + if (var == &cv_forceskin) // Special handling. + { + INT32 oldvalue = var->value; + newvalue = oldvalue; + do + { + newvalue += increment; + if (newvalue < -1) + newvalue = (numskins - 1); + else if (newvalue >= numskins) + newvalue = -1; + } while ((oldvalue != newvalue) + && !(R_SkinUnlock(newvalue))); + } + else + newvalue = var->value + increment; if (var->PossibleValue) { diff --git a/src/d_netcmd.c b/src/d_netcmd.c index fe7b032bf..8552e51ae 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -332,7 +332,7 @@ consvar_t cv_usemapnumlaps = {"usemaplaps", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, // log elemental hazards -- not a netvar, is local to current player consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_forceskin = {"forceskin", "-1", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_forceskin = {"forceskin", "None", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_downloading = {"downloading", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allowexitlevel = {"allowexitlevel", "No", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/dehacked.c b/src/dehacked.c index 518e1c85c..af5c1c407 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -433,7 +433,7 @@ static void readAnimTex(MYFILE *f, INT32 num) static boolean findFreeSlot(INT32 *num) { // Send the character select entry to a free slot. - while (*num < 32 && PlayerMenu[*num].status != IT_DISABLED) + while (*num < 32 && !(PlayerMenu[*num].status & IT_DISABLED)) // Will overwrite hidden characters, but it works out. You can't unlock if you're adding extra characters anyways. *num = *num+1; // No more free slots. :( diff --git a/src/r_things.c b/src/r_things.c index 9f2b5da8d..056663445 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -18,6 +18,7 @@ #include "st_stuff.h" #include "w_wad.h" #include "z_zone.h" +#include "m_menu.h" // Player character select #include "m_misc.h" #include "i_video.h" // rendermode #include "r_things.h" @@ -2335,11 +2336,17 @@ void R_InitSkins(void) // warning don't use with an invalid skinnum boolean R_SkinUnlock(INT32 skinnum) { - return ((skins[skinnum].availability == 2) // SP/Coop is strict + return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... + || (skins[skinnum].availability == 2) // SP/Coop is strict || (modeattacking) // If you have someone else's run you might as well take a look || ((netgame) - && ((cv_forceskin.value == skinnum) // Forceskin is weak - || (G_RingSlingerGametype() && (skins[skinnum].availability != 0))))); // Ringslinger is disciplined + && ((dedicated) // Same reasoning as Command_Map_f - dedicated would be a nightmare otherwise + || ((cv_forceskin.value == skinnum) // Forceskin is weak + || (G_RingSlingerGametype() && (skins[skinnum].availability != 0)) // Ringslinger is disciplined + ) + ) + ) + ); } // returns true if the skin name is found (loaded from pwad) @@ -2348,6 +2355,9 @@ INT32 R_SkinAvailable(const char *name) { INT32 i; + if (stricmp("NONE",name) == 0) + return -1; + for (i = 0; i < numskins; i++) { // search in the skin list @@ -2628,7 +2638,10 @@ void R_AddSkins(UINT16 wadnum) else if (!stricmp(stoken, "availability")) #ifdef DEVELOP + { + PlayerMenu[R_SkinAvailable(skin->name)].status = (IT_DISABLED|IT_CENTER); skin->availability = atoi(value); + } #else ; #endif @@ -2704,7 +2717,8 @@ next_token: R_FlushTranslationColormapCache(); - CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); + if (skin->availability == 2) // Safe to print... + CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); #ifdef SKINVALUES skin_cons_t[numskins].value = numskins; skin_cons_t[numskins].strvalue = skin->name; From fcfe8c01321fffd9aae916418cd882499a136459 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 12 Jul 2016 20:10:01 +0100 Subject: [PATCH 010/100] More clearly defined handling for replacing character select images. Specifically takes into account whether the hidden character was added in this file or a seperate one. Also, removed some commented out code regarding character selects, and removed a useless case for R_SkinAvailable(). --- src/dehacked.c | 49 ++++++++++++------------------------------------- src/m_menu.h | 1 + src/r_things.c | 16 +++++++++++----- 3 files changed, 24 insertions(+), 42 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index af5c1c407..f8e631160 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -430,16 +430,20 @@ static void readAnimTex(MYFILE *f, INT32 num) } */ -static boolean findFreeSlot(INT32 *num) +static boolean findFreeSlot(INT32 *num, UINT16 wadnum) { // Send the character select entry to a free slot. - while (*num < 32 && !(PlayerMenu[*num].status & IT_DISABLED)) // Will overwrite hidden characters, but it works out. You can't unlock if you're adding extra characters anyways. + while (*num < 32 && !(PlayerMenu[*num].status & IT_DISABLED && description[*num].wadnum != wadnum)) // Will kill hidden characters from other files, but that's okay. *num = *num+1; // No more free slots. :( if (*num >= 32) return false; + PlayerMenu[*num].status = IT_CALL; + description[*num].wadnum = wadnum; + description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...) + // Found one! ^_^ return true; } @@ -473,9 +477,8 @@ static void readPlayer(MYFILE *f, INT32 num) { char *playertext = NULL; - if (!slotfound && (slotfound = findFreeSlot(&num)) == false) + if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false) goto done; - PlayerMenu[num].status = IT_CALL; for (i = 0; i < MAXLINELEN-3; i++) { @@ -521,34 +524,12 @@ static void readPlayer(MYFILE *f, INT32 num) word2[strlen(word2)-1] = '\0'; i = atoi(word2); - /*if (fastcmp(word, "PLAYERNAME")) + if (fastcmp(word, "PICNAME")) { - if (!slotfound && (slotfound = findFreeSlot(&num)) == false) - goto done; - DEH_WriteUndoline(word, description[num].text, UNDO_NONE); - strlcpy(description[num].text, word2, sizeof (description[num].text)); - for (word2 = description[num].text; *word2; word2++) - if (*word2 == '_') - *word2 = ' '; - PlayerMenu[num].text = description[num].text; - }*/ -/* else if (fastcmp(word, "MENUPOSITION")) - { // Make sure you make MENUPOSITION the first thing under CHARACTER if you're using it! - // This is to manually choose a slot and overwrite existing characters! It is NOT necessary for most individual character wads!! -#ifdef DELFILE - if (disableundo) -#endif - { - slotfound = true; - num = i; - } - } */ - /*else*/ if (fastcmp(word, "PICNAME")) - { - if (!slotfound && (slotfound = findFreeSlot(&num)) == false) + if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false) goto done; DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE); - PlayerMenu[num].status = IT_CALL; + strncpy(description[num].picname, word2, 8); } else if (fastcmp(word, "STATUS")) @@ -565,11 +546,8 @@ static void readPlayer(MYFILE *f, INT32 num) Because of this, you are allowed to edit any previous entries you like, but only if you signal that you are purposely doing so by disabling and then reenabling the slot. - - ... Or use MENUPOSITION first, that works too. Hell, you could edit multiple character - slots in a single section that way, due to how SOC editing works. */ - if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num)) == false) + if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false) goto done; DEH_WriteUndoline(word, va("%d", PlayerMenu[num].status), UNDO_NONE); PlayerMenu[num].status = (INT16)i; @@ -577,15 +555,12 @@ static void readPlayer(MYFILE *f, INT32 num) else if (fastcmp(word, "SKINNAME")) { // Send to free slot. - if (!slotfound && (slotfound = findFreeSlot(&num)) == false) + if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false) goto done; DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE); - PlayerMenu[num].status = IT_CALL; strlcpy(description[num].skinname, word2, sizeof description[num].skinname); strlwr(description[num].skinname); - - description[num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...) } else deh_warning("readPlayer %d: unknown word '%s'", num, word); diff --git a/src/m_menu.h b/src/m_menu.h index 2ff1cea90..d578e155e 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -177,6 +177,7 @@ typedef struct char notes[441]; char picname[8]; char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 + UINT16 wadnum; // for duplicate characters } description_t; // mode descriptions for video mode menu diff --git a/src/r_things.c b/src/r_things.c index 056663445..2b036fb56 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2355,9 +2355,6 @@ INT32 R_SkinAvailable(const char *name) { INT32 i; - if (stricmp("NONE",name) == 0) - return -1; - for (i = 0; i < numskins; i++) { // search in the skin list @@ -2531,10 +2528,11 @@ void R_AddSkins(UINT16 wadnum) if (!stricmp(stoken, "name")) { + INT32 skinnum = R_SkinAvailable(value); // the skin name must uniquely identify a single skin // I'm lazy so if name is already used I leave the 'skin x' // default skin name set in Sk_SetDefaultValue - if (R_SkinAvailable(value) == -1) + if (skinnum == -1) { STRBUFCPY(skin->name, value); strlwr(skin->name); @@ -2639,7 +2637,15 @@ void R_AddSkins(UINT16 wadnum) else if (!stricmp(stoken, "availability")) #ifdef DEVELOP { - PlayerMenu[R_SkinAvailable(skin->name)].status = (IT_DISABLED|IT_CENTER); + char *name; + INT32 i; + for (i = 0; i < 32; i++) + { + name = strtok(Z_StrDup(description[i].skinname), "&"); + if (name == skin->name && PlayerMenu[i].status != IT_DISABLED) + PlayerMenu[i].status = (IT_DISABLED|IT_CENTER); + Z_Free(name); + } skin->availability = atoi(value); } #else From b2bfe3737a24b7106619e5bae84a7619424d6a8d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 13 Jul 2016 12:17:53 +0100 Subject: [PATCH 011/100] Rudimentary SOC shuffling if you add a character with the same name as a previous character to prevent character select from breaking. --- src/r_things.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 2b036fb56..ba5d33b7a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2529,13 +2529,13 @@ void R_AddSkins(UINT16 wadnum) if (!stricmp(stoken, "name")) { INT32 skinnum = R_SkinAvailable(value); + strlwr(value); // the skin name must uniquely identify a single skin // I'm lazy so if name is already used I leave the 'skin x' // default skin name set in Sk_SetDefaultValue if (skinnum == -1) { STRBUFCPY(skin->name, value); - strlwr(skin->name); } // I'm not lazy, so if the name is already used I make the name 'namex' // using the default skin name's number set above @@ -2549,10 +2549,20 @@ void R_AddSkins(UINT16 wadnum) value2[stringspace - 1] = '\0'; if (R_SkinAvailable(value2) == -1) { - STRBUFCPY(skin->name, - value2); - strlwr(skin->name); + char* name; + INT32 i; + STRBUFCPY(skin->name, value2); + for (i = 0; i < 32; i++) + { + name = strtok(Z_StrDup(description[i].skinname), "&"); + strlwr(name); + if (name == value && description[i].wadnum == wadnum) // Update all character selects added with this WAD to refer to the new name. + STRBUFCPY(description[i].skinname, value2); // Breaks char&char2. + Z_Free(name); + } } + else + CONS_Debug(DBG_SETUP, "R_AddSkins: Duplicate skin name replacement failure, S_SKIN lump #%d (WAD %s)\n", lump, wadfiles[wadnum]->filename); Z_Free(value2); } From 8087cde5dbf92505f0c2c02e02568f095711569b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 13 Jul 2016 13:26:21 +0100 Subject: [PATCH 012/100] Correcting a few cockups. --- src/dehacked.c | 2 +- src/m_menu.c | 64 +++++++++++++++++++++++++------------------------- src/r_things.c | 24 ++++--------------- 3 files changed, 37 insertions(+), 53 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index f8e631160..f8046c48c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -433,7 +433,7 @@ static void readAnimTex(MYFILE *f, INT32 num) static boolean findFreeSlot(INT32 *num, UINT16 wadnum) { // Send the character select entry to a free slot. - while (*num < 32 && !(PlayerMenu[*num].status & IT_DISABLED && description[*num].wadnum != wadnum)) // Will kill hidden characters from other files, but that's okay. + while (*num < 32 && (!(PlayerMenu[*num].status & IT_DISABLED) || description[*num].wadnum == wadnum)) // Will kill hidden characters from other files, but that's okay. *num = *num+1; // No more free slots. :( diff --git a/src/m_menu.c b/src/m_menu.c index 53b5be270..5f0390749 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -110,38 +110,38 @@ const char *quitmsg[NUM_QUITMESSAGES]; // Stuff for customizing the player select screen Tails 09-22-2003 description_t description[32] = { - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""}, - {"???", "", ""} + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0}, + {"???", "", "", 0} }; static char *char_notes = NULL; static fixed_t char_scroll = 0; diff --git a/src/r_things.c b/src/r_things.c index ba5d33b7a..9f138fdd3 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2530,14 +2530,10 @@ void R_AddSkins(UINT16 wadnum) { INT32 skinnum = R_SkinAvailable(value); strlwr(value); - // the skin name must uniquely identify a single skin - // I'm lazy so if name is already used I leave the 'skin x' - // default skin name set in Sk_SetDefaultValue if (skinnum == -1) - { STRBUFCPY(skin->name, value); - } - // I'm not lazy, so if the name is already used I make the name 'namex' + // the skin name must uniquely identify a single skin + // if the name is already used I make the name 'namex' // using the default skin name's number set above else { @@ -2548,21 +2544,9 @@ void R_AddSkins(UINT16 wadnum) "%s%d", value, numskins); value2[stringspace - 1] = '\0'; if (R_SkinAvailable(value2) == -1) - { - char* name; - INT32 i; + // I'm lazy so if NEW name is already used I leave the 'skin x' +- // default skin name set in Sk_SetDefaultValue STRBUFCPY(skin->name, value2); - for (i = 0; i < 32; i++) - { - name = strtok(Z_StrDup(description[i].skinname), "&"); - strlwr(name); - if (name == value && description[i].wadnum == wadnum) // Update all character selects added with this WAD to refer to the new name. - STRBUFCPY(description[i].skinname, value2); // Breaks char&char2. - Z_Free(name); - } - } - else - CONS_Debug(DBG_SETUP, "R_AddSkins: Duplicate skin name replacement failure, S_SKIN lump #%d (WAD %s)\n", lump, wadfiles[wadnum]->filename); Z_Free(value2); } From c2aba462984d8fbf75f32a306aad2c9721942dac Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 13 Jul 2016 15:15:45 +0100 Subject: [PATCH 013/100] New S_SKIN attributes. * radius - sets the player's radius for that skin. * height - sets the player's normal height for that skin. * spinheight - sets the player's spinheight for that skin. * shieldscale - see http://i.imgur.com/BQ5DhKC.png for justification --- src/lua_skinlib.c | 20 ++++++++++++++++++++ src/p_local.h | 1 + src/p_mobj.c | 2 +- src/p_user.c | 20 ++++++++++++++++---- src/r_things.c | 22 +++++++++++++++++----- src/r_things.h | 6 ++++++ 6 files changed, 61 insertions(+), 10 deletions(-) diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 28d5fed23..40737ccc1 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -44,6 +44,10 @@ enum skin { skin_accelstart, skin_acceleration, skin_jumpfactor, + skin_radius, + skin_height, + skin_spinheight, + skin_shieldscale, skin_starttranscolor, skin_prefcolor, skin_highresscale, @@ -74,6 +78,10 @@ static const char *const skin_opt[] = { "accelstart", "acceleration", "jumpfactor", + "radius", + "height", + "spinheight", + "shieldscale", "starttranscolor", "prefcolor", "highresscale", @@ -173,6 +181,18 @@ static int skin_get(lua_State *L) case skin_jumpfactor: lua_pushfixed(L, skin->jumpfactor); break; + case skin_radius: + lua_pushfixed(L, skin->radius); + break; + case skin_height: + lua_pushfixed(L, skin->height); + break; + case skin_spinheight: + lua_pushfixed(L, skin->spinheight); + break; + case skin_shieldscale: + lua_pushfixed(L, skin->shieldscale); + break; case skin_starttranscolor: lua_pushinteger(L, skin->starttranscolor); break; diff --git a/src/p_local.h b/src/p_local.h index 57ca425e1..7b662ef23 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -119,6 +119,7 @@ extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed; extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate; extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate; +fixed_t P_GetPlayerRadius(player_t *player); fixed_t P_GetPlayerHeight(player_t *player); fixed_t P_GetPlayerSpinHeight(player_t *player); INT32 P_GetPlayerControlDirection(player_t *player); diff --git a/src/p_mobj.c b/src/p_mobj.c index 653b6967e..b60a5075c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6097,7 +6097,7 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) thing->flags |= MF_NOCLIPHEIGHT; thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP); - P_SetScale(thing, thing->target->scale); + P_SetScale(thing, FixedMul(thing->target->scale, skins[thing->target->player->skin].shieldscale)); P_UnsetThingPosition(thing); thing->x = thing->target->x; thing->y = thing->target->y; diff --git a/src/p_user.c b/src/p_user.c index b579cbfe5..c63b57702 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1296,6 +1296,17 @@ void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative) mo->momz = value; } +// +// P_GetPlayerRadius +// +// Returns the radius +// of the player. +// +fixed_t P_GetPlayerRadius(player_t *player) +{ + return FixedMul(skins[player->skin].radius, player->mo->scale); +} + // // P_GetPlayerHeight // @@ -1304,7 +1315,7 @@ void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative) // fixed_t P_GetPlayerHeight(player_t *player) { - return FixedMul(player->mo->info->height, player->mo->scale); + return FixedMul(skins[player->skin].height, player->mo->scale); } // @@ -1315,7 +1326,7 @@ fixed_t P_GetPlayerHeight(player_t *player) // fixed_t P_GetPlayerSpinHeight(player_t *player) { - return FixedMul(FixedMul(player->mo->info->height, player->mo->scale),2*FRACUNIT/3); + return FixedMul(skins[player->skin].spinheight, player->mo->scale); } // @@ -6536,8 +6547,8 @@ static void P_MovePlayer(player_t *player) || ((((player->charflags & SF_NOJUMPSPIN) && (player->pflags & PF_JUMPED) && player->panim == PA_JUMP)) && (P_MobjFlip(player->mo)*player->mo->momz < 0 || player->pflags & PF_THOKKED))) P_SetPlayerMobjState(player->mo, S_PLAY_FALL); - // If Springing but on the ground, change back! - else if (onground && (player->panim == PA_SPRING || player->panim == PA_FALL || player->panim == PA_RIDE) && !player->mo->momz) + // If doing an air animation but on the ground, change back! + else if (onground && (player->panim == PA_SPRING || player->panim == PA_FALL || player->panim == PA_RIDE || player->panim == PA_JUMP) && !player->mo->momz) P_SetPlayerMobjState(player->mo, S_PLAY_STND); // If you are stopped and are still walking, stand still! @@ -6996,6 +7007,7 @@ static void P_MovePlayer(player_t *player) player->mo->height = P_GetPlayerSpinHeight(player); else player->mo->height = P_GetPlayerHeight(player); + player->mo->radius = P_GetPlayerRadius(player); if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling player->mo->z -= player->mo->height - oldheight; diff --git a/src/r_things.c b/src/r_things.c index 9f138fdd3..1a0e6dcfe 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2300,6 +2300,12 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->mindash = 15<maxdash = 90<radius = mobjinfo[MT_PLAYER].radius; + skin->height = mobjinfo[MT_PLAYER].height; + skin->spinheight = FixedMul(skin->height, 2*FRACUNIT/3); + + skin->shieldscale = FRACUNIT; + skin->thokitem = -1; skin->spinitem = -1; skin->revitem = -1; @@ -2545,7 +2551,7 @@ void R_AddSkins(UINT16 wadnum) value2[stringspace - 1] = '\0'; if (R_SkinAvailable(value2) == -1) // I'm lazy so if NEW name is already used I leave the 'skin x' -- // default skin name set in Sk_SetDefaultValue + // default skin name set in Sk_SetDefaultValue STRBUFCPY(skin->name, value2); Z_Free(value2); } @@ -2620,6 +2626,9 @@ void R_AddSkins(UINT16 wadnum) GETSPEED(mindash) GETSPEED(maxdash) GETSPEED(actionspd) + GETSPEED(radius) + GETSPEED(height) + GETSPEED(spinheight) #undef GETSPEED #define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value); @@ -2652,10 +2661,13 @@ void R_AddSkins(UINT16 wadnum) else if (!stricmp(stoken, "prefcolor")) skin->prefcolor = R_GetColorByName(value); - else if (!stricmp(stoken, "jumpfactor")) - skin->jumpfactor = FLOAT_TO_FIXED(atof(value)); - else if (!stricmp(stoken, "highresscale")) - skin->highresscale = FLOAT_TO_FIXED(atof(value)); + +#define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value)); + GETFLOAT(jumpfactor) + GETFLOAT(highresscale) + GETFLOAT(shieldscale) +#undef GETFLOAT + else // let's check if it's a sound, otherwise error out { boolean found = false; diff --git a/src/r_things.h b/src/r_things.h index 23842094e..cdd22ba66 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -93,6 +93,12 @@ typedef struct fixed_t jumpfactor; // multiple of standard jump height + fixed_t radius; // Bounding box changes. + fixed_t height; + fixed_t spinheight; + + fixed_t shieldscale; // no change to bounding box, but helps set the shield's sprite size + // Definable color translation table UINT8 starttranscolor; UINT8 prefcolor; From 824458a5ff40e8c9fa5a1983c999503002d727d5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 13 Jul 2016 18:18:18 +0100 Subject: [PATCH 014/100] Swimming animation! Since I know we want it for Smiles eventually. Also, I guess CA_SWIM isn't forced into running on water anymore. --- src/dehacked.c | 3 ++- src/info.c | 2 ++ src/info.h | 2 ++ src/p_mobj.c | 8 ++++++-- src/p_user.c | 17 +++++++++++++---- src/r_things.c | 2 +- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index f8046c48c..aafdcf289 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3783,8 +3783,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PLAY_EDGE", "S_PLAY_RIDE", - // CA_FLY + // CA_FLY/SWIM "S_PLAY_FLY", + "S_PLAY_SWIM", "S_PLAY_FLY_TIRED", // CA_GLIDEANDCLIMB diff --git a/src/info.c b/src/info.c index dc71ad163..9fd2aee38 100644 --- a/src/info.c +++ b/src/info.c @@ -78,6 +78,7 @@ char spr2names[NUMPLAYERSPRITES][5] = "LIFE", "FLY_", + "SWIM", "TIRE", "GLID", @@ -146,6 +147,7 @@ state_t states[NUMSTATES] = // Tails abilities {SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY + {SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM {SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED // Knuckles abilities diff --git a/src/info.h b/src/info.h index 46fdde46b..610839060 100644 --- a/src/info.h +++ b/src/info.h @@ -597,6 +597,7 @@ enum playersprite SPR2_LIFE, SPR2_FLY , + SPR2_SWIM, SPR2_TIRE, SPR2_GLID, @@ -659,6 +660,7 @@ typedef enum state // CA_FLY S_PLAY_FLY, + S_PLAY_SWIM, S_PLAY_FLY_TIRED, // CA_GLIDEANDCLIMB diff --git a/src/p_mobj.c b/src/p_mobj.c index b60a5075c..373326999 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -254,6 +254,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) player->panim = PA_FALL; break; case S_PLAY_FLY: + case S_PLAY_SWIM: case S_PLAY_GLIDE: player->panim = PA_ABILITY; break; @@ -370,9 +371,12 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) case SPR2_FLY: spr2 = SPR2_SPNG; break; - case SPR2_TIRE: + case SPR2_SWIM: spr2 = SPR2_FLY; break; + case SPR2_TIRE: + spr2 = (player->charability == CA_FLY) ? SPR2_FLY : SPR2_SWIM; + break; case SPR2_GLID: spr2 = SPR2_FLY; @@ -3248,7 +3252,7 @@ static boolean P_SceneryZMovement(mobj_t *mo) boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) { if (!(player->pflags & PF_NIGHTSMODE) && !player->homing - && (((player->charability == CA_SWIM) || player->powers[pw_super] || player->charflags & SF_RUNONWATER) && player->mo->ceilingz-*rover->topheight >= player->mo->height) + && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER) && player->mo->ceilingz-*rover->topheight >= player->mo->height) && (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale) && !(player->pflags & PF_SLIDING) && abs(player->mo->z - *rover->topheight) < FixedMul(30*FRACUNIT, player->mo->scale)) diff --git a/src/p_user.c b/src/p_user.c index c63b57702..6f7313db7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4104,14 +4104,17 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; case CA_FLY: - case CA_SWIM: // Swim + case CA_SWIM: // If currently in the air from a jump, and you pressed the // button again and have the ability to fly, do so! if (player->charability == CA_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) ; // Can't do anything if you're a fish out of water! else if (!(player->pflags & PF_THOKKED) && !(player->powers[pw_tailsfly])) { - P_SetPlayerMobjState(player->mo, S_PLAY_FLY); // Change to the flying animation + if (player->mo->eflags & MFE_UNDERWATER) + P_SetPlayerMobjState(player->mo, S_PLAY_SWIM); // Change to the swimming animation + else + P_SetPlayerMobjState(player->mo, S_PLAY_FLY); // Change to the flying animation player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer @@ -4121,8 +4124,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; case CA_GLIDEANDCLIMB: // Now Knuckles-type abilities are checked. - // If you can turn super and aren't already, - // and you don't have a shield, do it! if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY) { INT32 glidespeed = player->actionspd; @@ -6728,6 +6729,14 @@ static void P_MovePlayer(player_t *player) if (player->panim != PA_ABILITY) player->powers[pw_tailsfly] = 0; + if (player->charability == CA_FLY || player->charability == CA_SWIM) // Frustratingly has to remain seperate from the below block. + { + if (player->mo->state-states == S_PLAY_FLY && player->mo->eflags & MFE_UNDERWATER) + P_SetPlayerMobjState(player->mo, S_PLAY_SWIM); // Change to the swimming animation + else if (player->mo->state-states == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) + P_SetPlayerMobjState(player->mo, S_PLAY_FLY); // Change to the flying animation + } + if (player->charability == CA_FLY || (player->charability == CA_SWIM && player->mo->eflags & MFE_UNDERWATER)) { // Fly counter for Tails. diff --git a/src/r_things.c b/src/r_things.c index 1a0e6dcfe..aae649a8f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2339,7 +2339,7 @@ void R_InitSkins(void) } // returns true if available in circumstances, otherwise nope -// warning don't use with an invalid skinnum +// warning don't use with an invalid skinnum other than -1 which always returns true boolean R_SkinUnlock(INT32 skinnum) { return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... From a108fcce5b710dded65c566f2f4c7b3ff435dd91 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 13 Jul 2016 19:10:31 +0100 Subject: [PATCH 015/100] Simplification of the hide check after discussion with Rob. --- src/r_things.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index aae649a8f..ba76dc5ce 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2312,7 +2312,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->highresscale = FRACUNIT>>1; - skin->availability = 2; + skin->availability = 1; for (i = 0; i < sfx_skinsoundslot0; i++) if (S_sfx[i].skinsound != -1) @@ -2343,16 +2343,10 @@ void R_InitSkins(void) boolean R_SkinUnlock(INT32 skinnum) { return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... - || (skins[skinnum].availability == 2) // SP/Coop is strict + || (skins[skinnum].availability) || (modeattacking) // If you have someone else's run you might as well take a look - || ((netgame) - && ((dedicated) // Same reasoning as Command_Map_f - dedicated would be a nightmare otherwise - || ((cv_forceskin.value == skinnum) // Forceskin is weak - || (G_RingSlingerGametype() && (skins[skinnum].availability != 0)) // Ringslinger is disciplined - ) - ) - ) - ); + || ((netgame) && (cv_forceskin.value == skinnum)) // Forceskin is weak + ); } // returns true if the skin name is found (loaded from pwad) From 2ee22fc40a2862e2fa3eb0697172ea9c16572fe5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 13 Jul 2016 20:14:07 +0100 Subject: [PATCH 016/100] Dedicated servers have all skins unlocked for the purpose of forceskin. Meanwhile, a sneaky sneaky for hiding hidden characters further. --- src/d_netcmd.c | 2 +- src/r_things.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 8552e51ae..21008cbcf 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4002,7 +4002,7 @@ static void Command_Archivetest_f(void) */ static void ForceSkin_OnChange(void) { - if ((server || adminplayer == consoleplayer) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins || !R_SkinUnlock(cv_forceskin.value))) + if ((server || adminplayer == consoleplayer) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins || !(dedicated || R_SkinUnlock(cv_forceskin.value)))) // Dedicated servers have everything when it comes to forceskin because they have no gamedata. { if (cv_forceskin.value == -2) CV_SetValue(&cv_forceskin, numskins-1); diff --git a/src/r_things.c b/src/r_things.c index ba76dc5ce..4198ce99b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2434,6 +2434,8 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) P_SetScale(player->mo, player->mo->scale); return; } + else if !R_SkinUnlock(skinnum) // Sneaky sneaky. + skinnum = -1; if (P_IsLocalPlayer(player)) CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum); From f1b1e1aa9b1a3f620ffdd1ee909ef22d17f357e1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 13 Jul 2016 20:19:52 +0100 Subject: [PATCH 017/100] I'm stupid. --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 4198ce99b..685a9cfaa 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2434,7 +2434,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) P_SetScale(player->mo, player->mo->scale); return; } - else if !R_SkinUnlock(skinnum) // Sneaky sneaky. + else if (skinnum >= 0 && skinnum < numskins) skinnum = -1; if (P_IsLocalPlayer(player)) From 76910a8e118224d09ca4f370c5d2cb3f718b5a3c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 13 Jul 2016 20:24:39 +0100 Subject: [PATCH 018/100] Sorry, one last change. I know I should be more certain when committing. --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 685a9cfaa..ca183d8f8 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2435,7 +2435,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) return; } else if (skinnum >= 0 && skinnum < numskins) - skinnum = -1; + skinnum = 255; // Cheeky emulation. if (P_IsLocalPlayer(player)) CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum); From 6e0c9f7e184c81aa47905ba1c8f46801024010db Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 13 Jul 2016 22:28:23 +0100 Subject: [PATCH 019/100] The "forcecharacter" level header now allows for hidden characters. Also, new default for revitem to match player.dta, and an updated Force Skin netgame option name to reflect the fact it's string based now. --- src/m_menu.c | 2 +- src/r_things.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 5f0390749..7975dd992 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1343,7 +1343,7 @@ static menuitem_t OP_NetgameOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Sudden Death", &cv_suddendeath, 90}, {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 98}, - {IT_STRING | IT_CVAR, NULL, "Force Skin #", &cv_forceskin, 114}, + {IT_STRING | IT_CVAR, NULL, "Force Skin", &cv_forceskin, 114}, {IT_STRING | IT_CVAR, NULL, "Restrict skin changes", &cv_restrictskinchange, 122}, {IT_STRING | IT_CVAR, NULL, "Autobalance Teams", &cv_autobalance, 138}, diff --git a/src/r_things.c b/src/r_things.c index ca183d8f8..6c47f0a1f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2308,7 +2308,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->thokitem = -1; skin->spinitem = -1; - skin->revitem = -1; + skin->revitem = 0; skin->highresscale = FRACUNIT>>1; @@ -2345,7 +2345,8 @@ boolean R_SkinUnlock(INT32 skinnum) return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... || (skins[skinnum].availability) || (modeattacking) // If you have someone else's run you might as well take a look - || ((netgame) && (cv_forceskin.value == skinnum)) // Forceskin is weak + || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. + || ((netgame) && (cv_forceskin.value == skinnum)) // Force 2. ); } From 674ec3e51578136ea3b4492c1f5bc1669ac0c189 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 14 Jul 2016 12:31:20 +0100 Subject: [PATCH 020/100] Correction of the new default revitem setup. --- src/info.c | 2 +- src/r_things.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index 9fd2aee38..93c32801e 100644 --- a/src/info.c +++ b/src/info.c @@ -2639,7 +2639,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MT_THOK, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE, // flags - (statenum_t)MT_THOK // raisestate + (statenum_t)MT_NULL // raisestate }, { // MT_BLUECRAWLA diff --git a/src/r_things.c b/src/r_things.c index 6c47f0a1f..6aa196583 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2308,7 +2308,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->thokitem = -1; skin->spinitem = -1; - skin->revitem = 0; + skin->revitem = -1; skin->highresscale = FRACUNIT>>1; From c5f6ae8aaac13eed33e311df2f7ac1c224d8756d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 14 Jul 2016 13:24:57 +0100 Subject: [PATCH 021/100] Fixed forceskin to not always allow due to bad logic. --- src/command.c | 4 ++++ src/d_netcmd.c | 15 ++++----------- src/locale/en.po | 5 ----- src/locale/srb2.pot | 5 ----- src/r_things.c | 2 +- 5 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src/command.c b/src/command.c index f87794346..44454ce50 100644 --- a/src/command.c +++ b/src/command.c @@ -1161,7 +1161,11 @@ found: else { if (var == &cv_forceskin) + { var->value = R_SkinAvailable(var->string); + if (!R_SkinUnlock(var->value)) + var->value = -1; + } else var->value = atoi(var->string); } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 21008cbcf..65b415e65 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4002,17 +4002,10 @@ static void Command_Archivetest_f(void) */ static void ForceSkin_OnChange(void) { - if ((server || adminplayer == consoleplayer) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins || !(dedicated || R_SkinUnlock(cv_forceskin.value)))) // Dedicated servers have everything when it comes to forceskin because they have no gamedata. + if ((server || adminplayer == consoleplayer) && ((cv_forceskin.value == -1 && stricmp(cv_forceskin.string, "None")) || !(R_SkinUnlock(cv_forceskin.value)))) { - if (cv_forceskin.value == -2) - CV_SetValue(&cv_forceskin, numskins-1); - else - { - // hack because I can't restrict this and still allow added skins to be used with forceskin. - if (!menuactive) - CONS_Printf(M_GetText("Valid skin numbers are 0 to %d (-1 disables)\n"), numskins - 1); - CV_SetValue(&cv_forceskin, -1); - } + CONS_Printf("Please provide a valid skin name (\"None\" disables).\n"); + CV_SetValue(&cv_forceskin, -1); return; } @@ -4024,7 +4017,7 @@ static void ForceSkin_OnChange(void) CONS_Printf("The server has lifted the forced skin restrictions.\n"); else { - CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].name); + CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].realname); ForceAllSkins(cv_forceskin.value); } } diff --git a/src/locale/en.po b/src/locale/en.po index 2665082a2..069930b81 100644 --- a/src/locale/en.po +++ b/src/locale/en.po @@ -1377,11 +1377,6 @@ msgstr "" msgid "modifiedgame is false, you can unlock secrets\n" msgstr "" -#: d_netcmd.c:4599 -#, c-format -msgid "Valid skin numbers are 0 to %d (-1 disables)\n" -msgstr "" - #: d_netcmd.c:4617 d_netcmd.c:4629 msgid "You may not change your name when chat is muted.\n" msgstr "" diff --git a/src/locale/srb2.pot b/src/locale/srb2.pot index 37d14f8b7..ced13bbe6 100644 --- a/src/locale/srb2.pot +++ b/src/locale/srb2.pot @@ -1362,11 +1362,6 @@ msgstr "" msgid "No CHEAT-marked variables are changed -- Cheats are disabled.\n" msgstr "" -#: d_netcmd.c:4439 -#, c-format -msgid "Valid skin numbers are 0 to %d (-1 disables)\n" -msgstr "" - #: d_netcmd.c:4457 d_netcmd.c:4469 msgid "You may not change your name when chat is muted.\n" msgstr "" diff --git a/src/r_things.c b/src/r_things.c index 6aa196583..0167f43b5 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2346,7 +2346,7 @@ boolean R_SkinUnlock(INT32 skinnum) || (skins[skinnum].availability) || (modeattacking) // If you have someone else's run you might as well take a look || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. - || ((netgame) && (cv_forceskin.value == skinnum)) // Force 2. + || (netgame && !(server || adminplayer == consoleplayer) && (cv_forceskin.value == skinnum)) // Force 2. ); } From caed5718c1d06cafc3544cf8c7f548820192b311 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 14 Jul 2016 14:39:22 +0100 Subject: [PATCH 022/100] Characters can now be unlocked just like any existing unlockable. Setup: * S_SKIN needs an "availability" line. Set to 0 to have always available, otherwise is assumed to be UINT8 unlockable number. If it's a valid unlockable, its name will be copied over with the character's realname. * Define an unlockable via SOC or hardcode. If you don't want it visible on the Secrets menu, just set its type to None. Everything else is as normal - you can set the conditionset to whatever, objective, height, nochecklist, nocecho... --- src/r_things.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 0167f43b5..9a20432c1 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -18,7 +18,7 @@ #include "st_stuff.h" #include "w_wad.h" #include "z_zone.h" -#include "m_menu.h" // Player character select +#include "m_menu.h" // character select #include "m_misc.h" #include "i_video.h" // rendermode #include "r_things.h" @@ -29,6 +29,7 @@ #include "dehacked.h" // get_number (for thok) #include "d_netfil.h" // blargh. for nameonly(). #include "m_cheat.h" // objectplace +#include "m_cond.h" #ifdef HWRENDER #include "hardware/hw_md2.h" #endif @@ -2312,7 +2313,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->highresscale = FRACUNIT>>1; - skin->availability = 1; + skin->availability = 0; for (i = 0; i < sfx_skinsoundslot0; i++) if (S_sfx[i].skinsound != -1) @@ -2343,7 +2344,8 @@ void R_InitSkins(void) boolean R_SkinUnlock(INT32 skinnum) { return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... - || (skins[skinnum].availability) + || (skins[skinnum].availability == 0) + || (unlockables[skins[skinnum].availability - 1].unlocked) || (modeattacking) // If you have someone else's run you might as well take a look || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. || (netgame && !(server || adminplayer == consoleplayer) && (cv_forceskin.value == skinnum)) // Force 2. @@ -2635,22 +2637,11 @@ void R_AddSkins(UINT16 wadnum) #undef GETINT else if (!stricmp(stoken, "availability")) -#ifdef DEVELOP { - char *name; - INT32 i; - for (i = 0; i < 32; i++) - { - name = strtok(Z_StrDup(description[i].skinname), "&"); - if (name == skin->name && PlayerMenu[i].status != IT_DISABLED) - PlayerMenu[i].status = (IT_DISABLED|IT_CENTER); - Z_Free(name); - } skin->availability = atoi(value); + if (skin->availability && (skin->availability < MAXUNLOCKABLES)) + STRBUFCPY(unlockables[skin->availability - 1].name, skin->realname); } -#else - ; -#endif // custom translation table else if (!stricmp(stoken, "startcolor")) From 417e9187d92eaa92e54bfb109adf816501ef9282 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 14 Jul 2016 14:45:15 +0100 Subject: [PATCH 023/100] Realised the potential for out-of-bounds memory accessing, so put some limits in place to prevent that from happening. (skin->availability is a UINT8, so it'll never be negative) --- src/r_things.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 9a20432c1..7cdd9d36a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2639,7 +2639,9 @@ void R_AddSkins(UINT16 wadnum) else if (!stricmp(stoken, "availability")) { skin->availability = atoi(value); - if (skin->availability && (skin->availability < MAXUNLOCKABLES)) + if (skin->availability >= MAXUNLOCKABLES) + skin->availability = 0; + if (skin->availability) STRBUFCPY(unlockables[skin->availability - 1].name, skin->realname); } From 4c6ed6da76f0c6dc306dca0cfac065cc4ee79972 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 14 Jul 2016 15:51:03 +0100 Subject: [PATCH 024/100] The availability unlockable number for a skin is now available, read only, to Lua. --- src/lua_skinlib.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 40737ccc1..2d1caef04 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -51,7 +51,8 @@ enum skin { skin_starttranscolor, skin_prefcolor, skin_highresscale, - skin_soundsid + skin_soundsid, + skin_availability }; static const char *const skin_opt[] = { "valid", @@ -86,6 +87,7 @@ static const char *const skin_opt[] = { "prefcolor", "highresscale", "soundsid", + "availability", NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field]) @@ -205,6 +207,9 @@ static int skin_get(lua_State *L) case skin_soundsid: LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID); break; + case skin_availability: + lua_pushinteger(L, skin->availability); + break; } return 1; } From b8fe20a086c8abd4222c19cbbd33700cd91031c6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 14 Jul 2016 16:27:48 +0100 Subject: [PATCH 025/100] Changing irrelevant comment. --- src/r_things.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.h b/src/r_things.h index cdd22ba66..430cdd639 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -109,7 +109,7 @@ typedef struct spritedef_t sprites[NUMPLAYERSPRITES]; - UINT8 availability; // lock? safe to put here as is not networked + UINT8 availability; // lock? } skin_t; // ----------- From 9b68da63de0710b48baf6bc80266c55dbf412d6a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 14 Jul 2016 17:10:17 +0100 Subject: [PATCH 026/100] Minor cockup with availability handling not being updated when I changed how it worked. --- src/r_things.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 7cdd9d36a..ca4779ffa 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2344,7 +2344,7 @@ void R_InitSkins(void) boolean R_SkinUnlock(INT32 skinnum) { return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... - || (skins[skinnum].availability == 0) + || (!skins[skinnum].availability) || (unlockables[skins[skinnum].availability - 1].unlocked) || (modeattacking) // If you have someone else's run you might as well take a look || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. @@ -2719,7 +2719,7 @@ next_token: R_FlushTranslationColormapCache(); - if (skin->availability == 2) // Safe to print... + if (!skin->availability) // Safe to print... CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); #ifdef SKINVALUES skin_cons_t[numskins].value = numskins; From 01dc98f8f0b5e6cf58f185812557bae6c8380f25 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 15 Jul 2016 16:48:30 +0100 Subject: [PATCH 027/100] New frame flags for more complicated animations. * FF_MIDDLESTARTCHANCE - has a 50% chance of starting the spr2 or FF_ANIMATE animation halfway in * FF_SPR2ENDSTATE - if var1 == S_NULL, don't loop, just stop incrementing the frames. Otherwise, go to the state represented by var1. The former is just something I did for fun, the latter is something that'll come in handy when porting in new-character-moves. --- src/dehacked.c | 2 ++ src/info.c | 6 ++--- src/p_mobj.c | 72 ++++++++++++++++++++++++++++++++++++++++++++------ src/p_pspr.h | 8 ++++-- 4 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index aafdcf289..cc8bd44a0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6967,6 +6967,8 @@ struct { // Frame settings {"FF_FRAMEMASK",FF_FRAMEMASK}, + {"FF_SPR2ENDSTATE",FF_SPR2ENDSTATE}, + {"FF_MIDDLESTARTCHANCE",FF_MIDDLESTARTCHANCE}, {"FF_ANIMATE",FF_ANIMATE}, {"FF_FULLBRIGHT",FF_FULLBRIGHT}, {"FF_TRANSMASK",FF_TRANSMASK}, diff --git a/src/info.c b/src/info.c index 93c32801e..badc28545 100644 --- a/src/info.c +++ b/src/info.c @@ -131,8 +131,8 @@ state_t states[NUMSTATES] = // Player {SPR_PLAY, SPR2_STND, 105, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_STND {SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT - {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK - {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN + {SPR_PLAY, SPR2_WALK|FF_MIDDLESTARTCHANCE, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK + {SPR_PLAY, SPR2_RUN |FF_MIDDLESTARTCHANCE, 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN {SPR_PLAY, SPR2_PAIN, 350, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_PAIN {SPR_PLAY, SPR2_DEAD, 4, {NULL}, 0, 0, S_PLAY_DEAD}, // S_PLAY_DEAD {SPR_PLAY, SPR2_DRWN, 4, {NULL}, 0, 0, S_PLAY_DRWN}, // S_PLAY_DRWN @@ -153,7 +153,7 @@ state_t states[NUMSTATES] = // Knuckles abilities {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE {SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING - {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB + {SPR_PLAY, SPR2_CLMB|FF_MIDDLESTARTCHANCE, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB // Super Sonic {SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND diff --git a/src/p_mobj.c b/src/p_mobj.c index 373326999..61049d9e1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -329,6 +329,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) } } + mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + // Player animations if (st->sprite == SPR_PLAY) { @@ -336,9 +338,9 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) boolean noalt = false; UINT8 spr2 = st->frame & FF_FRAMEMASK; UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; - mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + UINT8 numframes; - while (skin->sprites[spr2].numframes <= 0 + while (skin && ((numframes = skin->sprites[spr2].numframes) <= 0) && spr2 != SPR2_STND) { switch(spr2) @@ -447,17 +449,39 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) break; } + if (!skin) + { + frame = 0; + numframes = 0; + } + if (mobj->sprite != SPR_PLAY) { mobj->sprite = SPR_PLAY; frame = 0; } else if (mobj->sprite2 != spr2) - frame = 0; + { + if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2)) + frame = numframes/2; + else + frame = 0; + } + + if (frame >= numframes) + { + if (st->frame & FF_SPR2ENDSTATE) + { + if (st->var1 == S_NULL) + frame--; // no frame advancement + else + return P_SetPlayerMobjState(mobj, st->var1); + } + else + frame = 0; + } mobj->sprite2 = spr2; - if (!mobj->skin || frame >= ((skin_t *)mobj->skin)->sprites[spr2].numframes) - frame = 0; mobj->frame = frame|(st->frame&~FF_FRAMEMASK); } // Regular sprites @@ -465,6 +489,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) { mobj->sprite = st->sprite; mobj->frame = st->frame; + if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) + mobj->frame += (st->var1)/2; } // Modified handling. @@ -536,18 +562,46 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) // Player animations if (st->sprite == SPR_PLAY) { + skin_t *skin = ((skin_t *)mobj->skin); UINT8 spr2 = st->frame & FF_FRAMEMASK; UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; + UINT8 numframes; + + if (skin) + numframes = skin->sprites[spr2].numframes; + else + { + frame = 0; + numframes = 0; + } + if (mobj->sprite != SPR_PLAY) { mobj->sprite = SPR_PLAY; frame = 0; } else if (mobj->sprite2 != spr2) - frame = 0; + { + if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2)) + frame = numframes/2; + else + frame = 0; + } + + if (frame >= numframes) + { + if (st->frame & FF_SPR2ENDSTATE) + { + if (st->var1 == S_NULL) + frame--; // no frame advancement + else + return P_SetPlayerMobjState(mobj, st->var1); + } + else + frame = 0; + } + mobj->sprite2 = spr2; - if (!mobj->skin || frame >= ((skin_t *)mobj->skin)->sprites[spr2].numframes) - frame = 0; mobj->frame = frame|(st->frame&~FF_FRAMEMASK); } // Regular sprites @@ -555,6 +609,8 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) { mobj->sprite = st->sprite; mobj->frame = st->frame; + if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) + mobj->frame += (st->var1)/2; } // Modified handling. diff --git a/src/p_pspr.h b/src/p_pspr.h index 2fb232e73..4117a53f1 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -35,8 +35,12 @@ #pragma interface #endif -/// \brief Frame flags: only the frame number -#define FF_FRAMEMASK 0x3fff +/// \brief Frame flags: only the frame number - 0 to 127 (Frames and Sprite2) +#define FF_FRAMEMASK 0x7f +/// \brief Frame flags: A change of state at the end of Sprite2 animation +#define FF_SPR2ENDSTATE 0x1000 +/// \brief Frame flags: 50% of starting in middle of animation (Sprite2 and FF_ANIMATE) +#define FF_MIDDLESTARTCHANCE 0x2000 /// \brief Frame flags: Simple stateless animation #define FF_ANIMATE 0x4000 /// \brief Frame flags: frame always appears full bright From 03fe312490ced52b35fa73338e8652119d3ef6bc Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 15 Jul 2016 17:30:52 +0100 Subject: [PATCH 028/100] On MI's reccomendation, a skin flag to disable the effects of FF_MIDDLESTARTCHANCE for specific characters whose animations might not be symmetrical. --- src/d_player.h | 1 + src/p_mobj.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 5097be68d..ef1c1219f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -43,6 +43,7 @@ typedef enum SF_NOJUMPDAMAGE = 1<<8, // Don't damage enemies, etc whilst jumping? SF_STOMPDAMAGE = 1<<9, // Always damage enemies, etc by landing on them, no matter your vunerability? SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc. + SF_NOMIDDLESTART = 1<<10, // Some animations can randomly start you halfway through. Disable this? } skinflags_t; //Primary and secondary skin abilities diff --git a/src/p_mobj.c b/src/p_mobj.c index 61049d9e1..c260391f7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -462,7 +462,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) } else if (mobj->sprite2 != spr2) { - if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2)) + if ((st->frame & FF_MIDDLESTARTCHANCE) && !(player->charflags & SF_NOMIDDLESTART) && numframes && P_RandomChance(FRACUNIT/2)) frame = numframes/2; else frame = 0; @@ -582,7 +582,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) } else if (mobj->sprite2 != spr2) { - if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2)) + if ((st->frame & FF_MIDDLESTARTCHANCE) && !(player->charflags & SF_NOMIDDLESTART) && numframes && P_RandomChance(FRACUNIT/2)) frame = numframes/2; else frame = 0; From 1e648e470901553789f62f9ee08a54332efbb266 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 15 Jul 2016 17:32:29 +0100 Subject: [PATCH 029/100] Woops, forgot SOC parser. --- src/dehacked.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dehacked.c b/src/dehacked.c index cc8bd44a0..3b5e3089d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7104,6 +7104,7 @@ struct { {"SF_NOJUMPDAMAGE",SF_NOJUMPDAMAGE}, {"SF_STOMPDAMAGE",SF_STOMPDAMAGE}, {"SF_MARIODAMAGE",SF_MARIODAMAGE}, + {"SF_NOMIDDLESTART",SF_NOMIDDLESTART}, // Character abilities! // Primary From df8be73787e61565c9ba182f3ce1a1059606c6ca Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 15 Jul 2016 22:13:47 +0100 Subject: [PATCH 030/100] ...fixed this error --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index c260391f7..82809a939 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -582,7 +582,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) } else if (mobj->sprite2 != spr2) { - if ((st->frame & FF_MIDDLESTARTCHANCE) && !(player->charflags & SF_NOMIDDLESTART) && numframes && P_RandomChance(FRACUNIT/2)) + if ((st->frame & FF_MIDDLESTARTCHANCE) && !(skin->flags & SF_NOMIDDLESTART) && numframes && P_RandomChance(FRACUNIT/2)) frame = numframes/2; else frame = 0; From cc35a5e1c10da55dd309b861fe0a2673150f7925 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 16 Jul 2016 13:55:12 +0100 Subject: [PATCH 031/100] Ported CA_HAMMER from new-character-actions in a way that takes advantage of all of the non-hardcodey things I've added in this branch. Also, it's called CA_TWINSPIN because that's more inoccouous. --- src/d_player.h | 3 ++- src/dehacked.c | 4 ++++ src/info.c | 13 +++++++++---- src/info.h | 9 +++++++-- src/p_inter.c | 4 ++-- src/p_map.c | 4 ++-- src/p_mobj.c | 16 ++++++++++------ src/p_user.c | 10 +++++++++- 8 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index ef1c1219f..f2f14e886 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -62,7 +62,8 @@ typedef enum CA_FALLSWITCH, CA_JUMPBOOST, CA_AIRDRILL, - CA_JUMPTHOK + CA_JUMPTHOK, + CA_TWINSPIN } charability_t; //Secondary skin abilities diff --git a/src/dehacked.c b/src/dehacked.c index 3b5e3089d..59d75946a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3793,6 +3793,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PLAY_CLING", "S_PLAY_CLIMB", + // CA_TWINSPIN + "S_PLAY_TWINSPIN", + // SF_SUPERANIMS "S_PLAY_SUPER_STND", "S_PLAY_SUPER_WALK", @@ -7122,6 +7125,7 @@ struct { {"CA_JUMPBOOST",CA_JUMPBOOST}, {"CA_AIRDRILL",CA_AIRDRILL}, {"CA_JUMPTHOK",CA_JUMPTHOK}, + {"CA_TWINSPIN",CA_TWINSPIN}, // Secondary {"CA2_NONE",CA2_NONE}, // now slot 0! {"CA2_SPINDASH",CA2_SPINDASH}, diff --git a/src/info.c b/src/info.c index badc28545..c5ebc8531 100644 --- a/src/info.c +++ b/src/info.c @@ -85,6 +85,8 @@ char spr2names[NUMPLAYERSPRITES][5] = "CLNG", "CLMB", + "TWIN", + "TRNS", "SSTD", "SWLK", @@ -145,17 +147,20 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_EDGE, 12, {NULL}, 0, 0, S_PLAY_EDGE}, // S_PLAY_EDGE {SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE - // Tails abilities + // CA_FLY/CA_SWIM {SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY {SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM {SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED - // Knuckles abilities + // CA_GLIDEANDCLIMB {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE {SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING {SPR_PLAY, SPR2_CLMB|FF_MIDDLESTARTCHANCE, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB - // Super Sonic + // CA_TWINSPIN + {SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN + + // SF_SUPERANIMS {SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND {SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK {SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN @@ -172,7 +177,7 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE {SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT - // Transforming into Super + // SF_SUPER {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2 {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3 diff --git a/src/info.h b/src/info.h index 610839060..809901aa7 100644 --- a/src/info.h +++ b/src/info.h @@ -604,6 +604,8 @@ enum playersprite SPR2_CLNG, SPR2_CLMB, + SPR2_TWIN, // twinspin + SPR2_TRNS, SPR2_SSTD, SPR2_SWLK, @@ -652,13 +654,13 @@ typedef enum state S_PLAY_SPIN, S_PLAY_DASH, S_PLAY_GASP, - S_PLAY_JUMP, // spin jump (todo: make jump separate from spring up for non-spin chars too?) + S_PLAY_JUMP, // spin jump S_PLAY_SPRING, S_PLAY_FALL, S_PLAY_EDGE, S_PLAY_RIDE, - // CA_FLY + // CA_FLY/SWIM S_PLAY_FLY, S_PLAY_SWIM, S_PLAY_FLY_TIRED, @@ -668,6 +670,9 @@ typedef enum state S_PLAY_CLING, S_PLAY_CLIMB, + // CA_TWINSPIN + S_PLAY_TWINSPIN, + // SF_SUPERANIMS S_PLAY_SUPER_STND, S_PLAY_SUPER_WALK, diff --git a/src/p_inter.c b/src/p_inter.c index 9c3b36a7e..eb733a1c6 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -300,7 +300,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE)) + || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) || (player->pflags & (PF_SPINNING|PF_GLIDING)) || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? @@ -345,7 +345,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_DamageMobj(toucher, special, special, 1, 0); } else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) - || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE)) + || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) || (player->pflags & (PF_SPINNING|PF_GLIDING)) || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? diff --git a/src/p_map.c b/src/p_map.c index 447a31b75..05cb03c22 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -939,7 +939,7 @@ static boolean PIT_CheckThing(mobj_t *thing) { if (thing->flags & MF_MONITOR && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) - || ((tmthing->player->pflags & PF_JUMPED) && !(tmthing->player->charflags & SF_NOJUMPDAMAGE)) + || ((tmthing->player->pflags & PF_JUMPED) && !(tmthing->player->charflags & SF_NOJUMPDAMAGE && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) || ((tmthing->player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))) { SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed. @@ -964,7 +964,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // unless it's a CTF team monitor and you're on the wrong team else if (thing->flags & MF_MONITOR && tmthing->player && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) - || ((tmthing->player->pflags & PF_JUMPED) && !(tmthing->player->charflags & SF_NOJUMPDAMAGE)) + || ((tmthing->player->pflags & PF_JUMPED) && !(tmthing->player->charflags & SF_NOJUMPDAMAGE && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) || ((tmthing->player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))) && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2))) ; diff --git a/src/p_mobj.c b/src/p_mobj.c index 82809a939..bff4bb09c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -163,6 +163,10 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) I_Error("P_SetPlayerMobjState used for non-player mobj. Use P_SetMobjState instead!\n(Mobj type: %d, State: %d)", mobj->type, state); #endif + // Catch falling for nojumpspin + if ((state == S_PLAY_JUMP) && (player->charflags & SF_NOJUMPSPIN) && (P_MobjFlip(mobj)*mobj->momz < 0 || player->pflags & PF_THOKKED)) + return P_SetPlayerMobjState(mobj, S_PLAY_FALL); + // Catch state changes for Super Sonic if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS)) { @@ -256,6 +260,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) case S_PLAY_FLY: case S_PLAY_SWIM: case S_PLAY_GLIDE: + case S_PLAY_TWINSPIN: player->panim = PA_ABILITY; break; case S_PLAY_RIDE: @@ -390,6 +395,10 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_CLMB; break; + case SPR2_TWIN: + spr2 = SPR2_SPIN; + break; + // Super sprites fallback to regular sprites case SPR2_SWLK: spr2 = SPR2_WALK; @@ -591,12 +600,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) if (frame >= numframes) { if (st->frame & FF_SPR2ENDSTATE) - { - if (st->var1 == S_NULL) - frame--; // no frame advancement - else - return P_SetPlayerMobjState(mobj, st->var1); - } + return P_SetPlayerMobjState(mobj, st->var1); // Differs from P_SetPlayerMobjState - allows object to be removed via S_NULL else frame = 0; } diff --git a/src/p_user.c b/src/p_user.c index 6f7313db7..f624d3b10 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4175,7 +4175,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags |= PF_THOKKED; } break; - case CA_AIRDRILL: if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY) { @@ -4184,6 +4183,15 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) S_StartSound(player->mo, sfx_spndsh); } break; + case CA_TWINSPIN: + if(!(player->pflags & PF_THOKKED)) + { + player->pflags |= PF_THOKKED; + S_StartSound(player->mo, sfx_s3k42); + player->mo->frame = 0; + P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); + } + break; default: break; } From 226785dcd6e676c91ed80557a9a02dd2c4e00c5e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 16 Jul 2016 14:45:22 +0100 Subject: [PATCH 032/100] Putting the swim animation checks in one place. --- src/p_mobj.c | 6 ++++++ src/p_user.c | 13 +------------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index bff4bb09c..22d06e34d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -167,6 +167,12 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) if ((state == S_PLAY_JUMP) && (player->charflags & SF_NOJUMPSPIN) && (P_MobjFlip(mobj)*mobj->momz < 0 || player->pflags & PF_THOKKED)) return P_SetPlayerMobjState(mobj, S_PLAY_FALL); + // Catch swimming versus flying + if (state == S_PLAY_FLY && player->mo->eflags & MFE_UNDERWATER) + return P_SetPlayerMobjState(player->mo, S_PLAY_SWIM); + else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) + return P_SetPlayerMobjState(player->mo, S_PLAY_FLY); + // Catch state changes for Super Sonic if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS)) { diff --git a/src/p_user.c b/src/p_user.c index f624d3b10..ce6c01d94 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4111,10 +4111,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) ; // Can't do anything if you're a fish out of water! else if (!(player->pflags & PF_THOKKED) && !(player->powers[pw_tailsfly])) { - if (player->mo->eflags & MFE_UNDERWATER) - P_SetPlayerMobjState(player->mo, S_PLAY_SWIM); // Change to the swimming animation - else - P_SetPlayerMobjState(player->mo, S_PLAY_FLY); // Change to the flying animation + P_SetPlayerMobjState(player->mo, S_PLAY_FLY); // Change to the flying animation player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer @@ -6737,14 +6734,6 @@ static void P_MovePlayer(player_t *player) if (player->panim != PA_ABILITY) player->powers[pw_tailsfly] = 0; - if (player->charability == CA_FLY || player->charability == CA_SWIM) // Frustratingly has to remain seperate from the below block. - { - if (player->mo->state-states == S_PLAY_FLY && player->mo->eflags & MFE_UNDERWATER) - P_SetPlayerMobjState(player->mo, S_PLAY_SWIM); // Change to the swimming animation - else if (player->mo->state-states == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) - P_SetPlayerMobjState(player->mo, S_PLAY_FLY); // Change to the flying animation - } - if (player->charability == CA_FLY || (player->charability == CA_SWIM && player->mo->eflags & MFE_UNDERWATER)) { // Fly counter for Tails. From 94490623b5858fbce6946d797d8706c51ff78b48 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 16 Jul 2016 17:11:34 +0100 Subject: [PATCH 033/100] Cleanup of P_CheckUnderwaterAndSpaceTimer's conditional checks for future PF_ROBOT changes, where characters like Metal make electric zaps instead of bubbles. --- src/p_user.c | 96 ++++++++++++++++++++-------------------------------- 1 file changed, 37 insertions(+), 59 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index ce6c01d94..99d2c2fb1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2007,66 +2007,44 @@ static void P_CheckSneakerAndLivesTimer(player_t *player) // static void P_CheckUnderwaterAndSpaceTimer(player_t *player) { - fixed_t height; - mobj_t *numbermobj = NULL; + tic_t timeleft = (player->powers[pw_spacetime]) ? player->powers[pw_spacetime] : player->powers[pw_underwater]; - if (player->mo->eflags & MFE_VERTICALFLIP) - height = player->mo->z - FixedMul(8*FRACUNIT - mobjinfo[MT_DROWNNUMBERS].height, player->mo->scale); - else - height = player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale); + if ((timeleft == 11*TICRATE + 1) // 5 + || (timeleft == 9*TICRATE + 1) // 4 + || (timeleft == 7*TICRATE + 1) // 3 + || (timeleft == 5*TICRATE + 1) // 2 + || (timeleft == 3*TICRATE + 1) // 1 + || (timeleft == 1*TICRATE + 1) // 0 + ) { + fixed_t height = (player->mo->eflags & MFE_VERTICALFLIP) + ? player->mo->z - FixedMul(8*FRACUNIT - mobjinfo[MT_DROWNNUMBERS].height, player->mo->scale) + : player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale); - if (player->powers[pw_underwater] == 11*TICRATE + 1 || player->powers[pw_spacetime] == 11*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+5); - } - else if (player->powers[pw_underwater] == 9*TICRATE + 1 || player->powers[pw_spacetime] == 9*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+4); - } - else if (player->powers[pw_underwater] == 7*TICRATE + 1 || player->powers[pw_spacetime] == 7*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+3); - } - else if (player->powers[pw_underwater] == 5*TICRATE + 1 || player->powers[pw_spacetime] == 5*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+2); - } - else if (player->powers[pw_underwater] == 3*TICRATE + 1 || player->powers[pw_spacetime] == 3*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - P_SetMobjState(numbermobj, numbermobj->info->spawnstate+1); - } - else if (player->powers[pw_underwater] == 1*TICRATE + 1 || player->powers[pw_spacetime] == 1*TICRATE + 1) - { - numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - //P_SetMobjState(numbermobj, numbermobj->info->spawnstate+0); - } - // Underwater timer runs out - else if (player->powers[pw_underwater] == 1) - { - if ((netgame || multiplayer) && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusname, mapmusflags, true); - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED); - } - else if (player->powers[pw_spacetime] == 1) - { - if ((netgame || multiplayer) && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusname, mapmusflags, true); - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN); - } + mobj_t *numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); + + timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be ((timeleft/TICRATE) - 1)/2, but integer division rounds down for us + + S_StartSound(player->mo, sfx_dwnind); + + if (timeleft) // Don't waste time setting the state if the time is 0. + P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft); - if (numbermobj) - { P_SetTarget(&numbermobj->target, player->mo); numbermobj->threshold = 40; - S_StartSound(player->mo, sfx_dwnind); numbermobj->destscale = player->mo->scale; P_SetScale(numbermobj, player->mo->scale); } + // Underwater timer runs out + else if (timeleft == 1) + { + if ((netgame || multiplayer) && P_IsLocalPlayer(player)) + S_ChangeMusic(mapmusname, mapmusflags, true); + + if (player->powers[pw_spacetime] == 1) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN); + else + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED); + } if (!(player->mo->eflags & MFE_UNDERWATER) && player->powers[pw_underwater]) { @@ -2085,19 +2063,19 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) // Underwater audio cues if (P_IsLocalPlayer(player) && !player->bot) { - if (player->powers[pw_underwater] == 11*TICRATE + 1 - && player == &players[consoleplayer]) - { - S_StopMusic(); - S_ChangeMusicInternal("drown", false); - } - if (player->powers[pw_underwater] == 25*TICRATE + 1) S_StartSound(NULL, sfx_wtrdng); else if (player->powers[pw_underwater] == 20*TICRATE + 1) S_StartSound(NULL, sfx_wtrdng); else if (player->powers[pw_underwater] == 15*TICRATE + 1) S_StartSound(NULL, sfx_wtrdng); + + if (player->powers[pw_underwater] == 11*TICRATE + 1 + && player == &players[consoleplayer]) + { + S_StopMusic(); + S_ChangeMusicInternal("drown", false); + } } if (player->exiting) From 21ba204c9e28e47fa6ec04233895c5da71203f63 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 16 Jul 2016 18:34:42 +0100 Subject: [PATCH 034/100] Revert of the FF_MIDDLESTARTCHANCE changes for player states, although the flag still exists internally since there's no reason to remove it. --- src/info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index 3360d5f58..a31307895 100644 --- a/src/info.c +++ b/src/info.c @@ -135,8 +135,8 @@ state_t states[NUMSTATES] = // Player {SPR_PLAY, SPR2_STND, 105, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_STND {SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT - {SPR_PLAY, SPR2_WALK|FF_MIDDLESTARTCHANCE, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK - {SPR_PLAY, SPR2_RUN |FF_MIDDLESTARTCHANCE, 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN + {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK + {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN {SPR_PLAY, SPR2_PEEL, 2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL {SPR_PLAY, SPR2_PAIN, 350, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_PAIN {SPR_PLAY, SPR2_DEAD, 4, {NULL}, 0, 0, S_PLAY_DEAD}, // S_PLAY_DEAD @@ -158,7 +158,7 @@ state_t states[NUMSTATES] = // CA_GLIDEANDCLIMB {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE {SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING - {SPR_PLAY, SPR2_CLMB|FF_MIDDLESTARTCHANCE, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB + {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB // CA_TWINSPIN {SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN From 0f79e9ea3b75e62398dbb7f3c3d41a1706747956 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 16 Jul 2016 18:54:22 +0100 Subject: [PATCH 035/100] On Rob's request, the twinspin can break spikes. (woo) --- src/p_map.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index c534ee137..65a5fefab 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -448,9 +448,12 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - // Dashmode users destroy spikes and monitors. - if ((tmthing->player) && (tmthing->player->charability == CA_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) - && (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE)) + // CA_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users destroy spikes. + if ((tmthing->player) + && (((tmthing->player->charability == CA_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) + && (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE)) + || ((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY) + && (thing->type == MT_SPIKE)))) { if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE))) return true; From 4e064dc335235c3ca7e2348917459e076fccff57 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sat, 16 Jul 2016 16:05:00 -0400 Subject: [PATCH 036/100] whitespace: cleanup --- src/p_user.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 87fe59fb1..06472f771 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4119,14 +4119,14 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) S_StartSound(player->mo, sfx_spndsh); } break; - case CA_TWINSPIN: - if(!(player->pflags & PF_THOKKED)) - { - player->pflags |= PF_THOKKED; + case CA_TWINSPIN: + if(!(player->pflags & PF_THOKKED)) + { + player->pflags |= PF_THOKKED; S_StartSound(player->mo, sfx_s3k42); player->mo->frame = 0; P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); - } + } break; default: break; From f757fb3545955a95439be071b167d8205c590d34 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 16 Jul 2016 22:43:49 +0100 Subject: [PATCH 037/100] SF_MACHINE. Currently only changes drowning, but could do more. * Electric sparks coming off entire body instead of bubbles coming out mouth * Different sounds. * Different icons. These sprites are currently local only, but I'll be doing a lot of asset updating this evening since Rob asked me to so it won't be long until you can get them. --- src/d_player.h | 2 +- src/dehacked.c | 12 ++++++++- src/hardware/hw_light.c | 1 + src/info.c | 54 ++++++++++++++++++++++++++++++++------- src/info.h | 11 ++++++++ src/p_inter.c | 5 +++- src/p_mobj.c | 4 +-- src/p_user.c | 56 ++++++++++++++++++++++++++++------------- 8 files changed, 114 insertions(+), 31 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index b01edc8f5..465bbe3f7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -43,7 +43,7 @@ typedef enum SF_NOJUMPDAMAGE = 1<<8, // Don't damage enemies, etc whilst jumping? SF_STOMPDAMAGE = 1<<9, // Always damage enemies, etc by landing on them, no matter your vunerability? SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc. - SF_NOMIDDLESTART = 1<<10, // Some animations can randomly start you halfway through. Disable this? + SF_MACHINE = 1<<10, // Beep boop. Are you a robot? } skinflags_t; //Primary and secondary skin abilities diff --git a/src/dehacked.c b/src/dehacked.c index fa9674a1e..d174aede1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5552,6 +5552,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_POP1", // Extra Large bubble goes POP! + "S_WATERZAP", + "S_FOG1", "S_FOG2", "S_FOG3", @@ -5593,6 +5595,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FOUR1", "S_FIVE1", + "S_ZERO2", + "S_ONE2", + "S_TWO2", + "S_THREE2", + "S_FOUR2", + "S_FIVE2", + // Tag Sign "S_TTAG1", @@ -6501,6 +6510,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SMALLBUBBLE", // small bubble "MT_MEDIUMBUBBLE", // medium bubble "MT_EXTRALARGEBUBBLE", // extra large bubble + "MT_WATERZAP", "MT_TFOG", "MT_SEED", "MT_PARTICLE", @@ -7146,7 +7156,7 @@ struct { {"SF_NOJUMPDAMAGE",SF_NOJUMPDAMAGE}, {"SF_STOMPDAMAGE",SF_STOMPDAMAGE}, {"SF_MARIODAMAGE",SF_MARIODAMAGE}, - {"SF_NOMIDDLESTART",SF_NOMIDDLESTART}, + {"SF_MACHINE",SF_MACHINE}, // Character abilities! // Primary diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index a93e96dc3..96f79f807 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -387,6 +387,7 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_BUBN &lspr[NOLIGHT], // SPR_BUBM &lspr[NOLIGHT], // SPR_POPP + &lspr[SUPERSPARK_L], // SPR_WZAP &lspr[SUPERSPARK_L], // SPR_TFOG &lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed &lspr[NOLIGHT], // SPR_PRTL diff --git a/src/info.c b/src/info.c index a31307895..2fa4d790e 100644 --- a/src/info.c +++ b/src/info.c @@ -45,15 +45,15 @@ char sprnames[NUMSPRITES + 1][5] = "ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC", "COWZ","RBRD","SPRY","SPRR","SPRB","YSPR","RSPR","SSWY","SSWR","SSWB", "RAIN","SNO1","SPLH","SPLA","SMOK","BUBP","BUBO","BUBN","BUBM","POPP", - "TFOG","SEED","PRTL","SCOR","DRWN","TTAG","GFLG","RRNG","RNGB","RNGR", - "RNGI","RNGA","RNGE","RNGS","RNGG","PIKB","PIKR","PIKA","PIKE","PIKS", - "PIKG","TAUT","TGRE","TSCR","COIN","CPRK","GOOM","BGOM","FFWR","FBLL", - "SHLL","PUMA","HAMM","KOOP","BFLM","MAXE","MUS1","MUS2","TOAD","NDRN", - "SUPE","SUPZ","NDRL","NSPK","NBMP","HOOP","NSCR","NPRU","CAPS","SUPT", - "SPRK","BOM1","BOM2","BOM3","BOM4","ROIA","ROIB","ROIC","ROID","ROIE", - "ROIF","ROIG","ROIH","ROII","ROIJ","ROIK","ROIL","ROIM","ROIN","ROIO", - "ROIP","BBAL","GWLG","GWLR","SRBA","SRBB","SRBC","SRBD","SRBE","SRBF", - "SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", + "WZAP","TFOG","SEED","PRTL","SCOR","DRWN","TTAG","GFLG","RRNG","RNGB", + "RNGR","RNGI","RNGA","RNGE","RNGS","RNGG","PIKB","PIKR","PIKA","PIKE", + "PIKS","PIKG","TAUT","TGRE","TSCR","COIN","CPRK","GOOM","BGOM","FFWR", + "FBLL","SHLL","PUMA","HAMM","KOOP","BFLM","MAXE","MUS1","MUS2","TOAD", + "NDRN","SUPE","SUPZ","NDRL","NSPK","NBMP","HOOP","NSCR","NPRU","CAPS", + "SUPT","SPRK","BOM1","BOM2","BOM3","BOM4","ROIA","ROIB","ROIC","ROID", + "ROIE","ROIF","ROIG","ROIH","ROII","ROIJ","ROIK","ROIL","ROIM","ROIN", + "ROIO","ROIP","BBAL","GWLG","GWLR","SRBA","SRBB","SRBC","SRBD","SRBE", + "SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", }; char spr2names[NUMPLAYERSPRITES][5] = @@ -1936,6 +1936,8 @@ state_t states[NUMSTATES] = // Extra Large Bubble goes POP! {SPR_POPP, 0, 16, {NULL}, 0, 0, S_NULL}, // S_POP1 + {SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_MIDDLESTARTCHANCE, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP + {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1 {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50|1, 2, {NULL}, 0, 0, S_FOG3}, // S_FOG2 {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50|2, 2, {NULL}, 0, 0, S_FOG4}, // S_FOG3 @@ -1978,6 +1980,13 @@ state_t states[NUMSTATES] = {SPR_DRWN, 4, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR1 {SPR_DRWN, 5, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE1 + {SPR_DRWN, 6, 40, {NULL}, 0, 0, S_NULL}, // S_ZERO2 + {SPR_DRWN, 7, 40, {NULL}, 0, 0, S_NULL}, // S_ONE2 + {SPR_DRWN, 8, 40, {NULL}, 0, 0, S_NULL}, // S_TWO2 + {SPR_DRWN, 9, 40, {NULL}, 0, 0, S_NULL}, // S_THREE2 + {SPR_DRWN, 10, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR2 + {SPR_DRWN, 11, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE2 + {SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG1 // CTF Sign @@ -10514,6 +10523,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_WATERZAP + -1, // doomednum + S_WATERZAP, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // 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 + 8, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + { // MT_TFOG -1, // doomednum S_FOG1, // spawnstate diff --git a/src/info.h b/src/info.h index f5e2ce433..ccb223c6c 100644 --- a/src/info.h +++ b/src/info.h @@ -463,6 +463,7 @@ typedef enum sprite SPR_BUBN, // Large bubble SPR_BUBM, // Extra Large (would you like fries with that?) bubble SPR_POPP, // Extra Large bubble goes POP! + SPR_WZAP, SPR_TFOG, // Teleport Fog SPR_SEED, // Sonic CD flower seed SPR_PRTL, // Particle (for fans, etc.) @@ -2434,6 +2435,8 @@ typedef enum state S_POP1, // Extra Large bubble goes POP! + S_WATERZAP, + S_FOG1, S_FOG2, S_FOG3, @@ -2475,6 +2478,13 @@ typedef enum state S_FOUR1, S_FIVE1, + S_ZERO2, + S_ONE2, + S_TWO2, + S_THREE2, + S_FOUR2, + S_FIVE2, + // Tag Sign S_TTAG1, @@ -3401,6 +3411,7 @@ typedef enum mobj_type MT_SMALLBUBBLE, // small bubble MT_MEDIUMBUBBLE, // medium bubble MT_EXTRALARGEBUBBLE, // extra large bubble + MT_WATERZAP, MT_TFOG, MT_SEED, MT_PARTICLE, diff --git a/src/p_inter.c b/src/p_inter.c index 76391705f..26cae304e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2261,7 +2261,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->momx = target->momy = target->momz = 0; if (damagetype == DMG_DROWNED) // drowned { - S_StartSound(target, sfx_drown); + if (target->player->charflags & SF_MACHINE) + S_StartSound(target, sfx_fizzle); + else + S_StartSound(target, sfx_drown); // Don't jump up when drowning } else diff --git a/src/p_mobj.c b/src/p_mobj.c index 7740e5f28..ad19d4423 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -489,7 +489,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) } else if (mobj->sprite2 != spr2) { - if ((st->frame & FF_MIDDLESTARTCHANCE) && !(player->charflags & SF_NOMIDDLESTART) && numframes && P_RandomChance(FRACUNIT/2)) + if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2)) frame = numframes/2; else frame = 0; @@ -609,7 +609,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) } else if (mobj->sprite2 != spr2) { - if ((st->frame & FF_MIDDLESTARTCHANCE) && !(skin->flags & SF_NOMIDDLESTART) && numframes && P_RandomChance(FRACUNIT/2)) + if ((st->frame & FF_MIDDLESTARTCHANCE) && numframes && P_RandomChance(FRACUNIT/2)) frame = numframes/2; else frame = 0; diff --git a/src/p_user.c b/src/p_user.c index 5a3d952a3..89d07e3d2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2018,9 +2018,15 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) mobj_t *numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be ((timeleft/TICRATE) - 1)/2, but integer division rounds down for us + timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be (((timeleft - 1)/TICRATE) - 1)/2, but integer division rounds down for us - S_StartSound(player->mo, sfx_dwnind); + if (player->charflags & SF_MACHINE) + { + S_StartSound(player->mo, sfx_buzz1); + timeleft += 6; + } + else + S_StartSound(player->mo, sfx_dwnind); if (timeleft) // Don't waste time setting the state if the time is 0. P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft); @@ -2059,11 +2065,9 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) // Underwater audio cues if (P_IsLocalPlayer(player) && !player->bot) { - if (player->powers[pw_underwater] == 25*TICRATE + 1) - S_StartSound(NULL, sfx_wtrdng); - else if (player->powers[pw_underwater] == 20*TICRATE + 1) - S_StartSound(NULL, sfx_wtrdng); - else if (player->powers[pw_underwater] == 15*TICRATE + 1) + if ((player->powers[pw_underwater] == 25*TICRATE + 1) + || (player->powers[pw_underwater] == 20*TICRATE + 1) + || (player->powers[pw_underwater] == 15*TICRATE + 1)) S_StartSound(NULL, sfx_wtrdng); if (player->powers[pw_underwater] == 11*TICRATE + 1 @@ -2141,21 +2145,39 @@ static void P_CheckInvincibilityTimer(player_t *player) // static void P_DoBubbleBreath(player_t *player) { - fixed_t zh; + fixed_t x = player->mo->x; + fixed_t y = player->mo->y; + fixed_t z = player->mo->z; mobj_t *bubble = NULL; - if (player->mo->eflags & MFE_VERTICALFLIP) - zh = player->mo->z + player->mo->height - FixedDiv(player->mo->height,5*(FRACUNIT/4)); - else - zh = player->mo->z + FixedDiv(player->mo->height,5*(FRACUNIT/4)); - if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !(player->pflags & PF_NIGHTSMODE)) || player->spectator) return; - if (P_RandomChance(FRACUNIT/16)) - bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_SMALLBUBBLE); - else if (P_RandomChance(3*FRACUNIT/256)) - bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_MEDIUMBUBBLE); + if (player->charflags & SF_MACHINE) + { + if (P_RandomChance((128-(player->powers[pw_underwater]/4))*FRACUNIT/256)) + { + fixed_t rad = player->mo->radius>>FRACBITS; + x += (P_RandomRange(rad, -rad)<mo->height>>FRACBITS)<mo->eflags & MFE_VERTICALFLIP) + z += player->mo->height - FixedDiv(player->mo->height,5*(FRACUNIT/4)); + else + z += FixedDiv(player->mo->height,5*(FRACUNIT/4)); + + if (P_RandomChance(FRACUNIT/16)) + bubble = P_SpawnMobj(x, y, z, MT_SMALLBUBBLE); + else if (P_RandomChance(3*FRACUNIT/256)) + bubble = P_SpawnMobj(x, y, z, MT_MEDIUMBUBBLE); + } + if (bubble) { bubble->threshold = 42; From 898e17a4416e383f3aa373ca31474a469f9da4f6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 16 Jul 2016 23:26:52 +0100 Subject: [PATCH 038/100] SF_MACHINE characters create boss explosions on death. Also, the gravity of drowning characters has been reduced to look more natural. --- src/p_inter.c | 1 + src/p_mobj.c | 17 ++++++++++++++++- src/p_user.c | 6 +++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 26cae304e..e7d98dbe3 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2261,6 +2261,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->momx = target->momy = target->momz = 0; if (damagetype == DMG_DROWNED) // drowned { + target->movedir = damagetype; // we're MOVING the Damage Into anotheR function... Okay, this is a bit of a hack. if (target->player->charflags & SF_MACHINE) S_StartSound(target, sfx_fizzle); else diff --git a/src/p_mobj.c b/src/p_mobj.c index ad19d4423..90d21859b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6908,7 +6908,22 @@ void P_MobjThinker(mobj_t *mobj) } } else // Apply gravity to fall downwards. - P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); + { + if (mobj->player && !(mobj->fuse % 8) && (mobj->player->charflags & SF_MACHINE)) + { + fixed_t r = mobj->radius>>FRACBITS; + mobj_t *explosion = P_SpawnMobj( + mobj->x + (P_RandomRange(r, -r)<y + (P_RandomRange(r, -r)<z + (P_RandomKey(mobj->height>>FRACBITS)<movedir == DMG_DROWNED) + P_SetObjectMomZ(mobj, -FRACUNIT/2, true); // slower fall from drowning + else + P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); + } } break; default: diff --git a/src/p_user.c b/src/p_user.c index 4e761f3bc..a395aa7cd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2157,9 +2157,9 @@ static void P_DoBubbleBreath(player_t *player) { if (P_RandomChance((128-(player->powers[pw_underwater]/4))*FRACUNIT/256)) { - fixed_t rad = player->mo->radius>>FRACBITS; - x += (P_RandomRange(rad, -rad)<mo->radius>>FRACBITS; + x += (P_RandomRange(r, -r)<mo->height>>FRACBITS)< Date: Sun, 17 Jul 2016 01:22:50 +0100 Subject: [PATCH 039/100] Doing stuff for Rob, turns out the anim was designed to go twice as fast. Tally ho! --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 2fa4d790e..4deabefdf 100644 --- a/src/info.c +++ b/src/info.c @@ -161,7 +161,7 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB // CA_TWINSPIN - {SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN + {SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN // SF_SUPERANIMS {SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND From 9557cad235c47a2d2ad079a1fc5329b690b0e132 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 17 Jul 2016 15:56:31 +0100 Subject: [PATCH 040/100] Noticed some bad logic and typos, so correcting. --- src/m_menu.c | 15 +++++++++------ src/m_menu.h | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 7975dd992..095ad4907 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4776,6 +4776,9 @@ static void M_SetupChoosePlayer(INT32 choice) char *name; (void)choice; + if (PlayerMenu[0].status & (IT_DYBIGSPACE)) // Correcting a hack that may be made below. + PlayerMenu[0].status = (IT_DISABLED|(PlayerMenu[0].status & IT_CENTER)); + for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks. { if (PlayerMenu[i].status != IT_DISABLED) // If the character's disabled through SOC, there's nothing we can do for it. @@ -4784,7 +4787,7 @@ static void M_SetupChoosePlayer(INT32 choice) skinnum = R_SkinAvailable(name); if ((skinnum != -1) && (R_SkinUnlock(skinnum))) { - if (PlayerMenu[i].status == (IT_DISABLED|IT_CENTER)) + if (PlayerMenu[i].status & (IT_DISABLED|IT_CENTER)) PlayerMenu[i].status = IT_CALL; if (description[i].picname[0] == '\0') strncpy(description[i].picname, skins[skinnum].charsel, 8); @@ -4801,7 +4804,7 @@ static void M_SetupChoosePlayer(INT32 choice) if (!(availablecount) || (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] != '\0')) { - PlayerMenu[0].status = (IT_CALL|IT_CENTER); // This is a hack to make availablecount not softlock the game. Again, I use IT_CENTER as a dummy flag. + PlayerMenu[0].status = (IT_CALL|IT_DYBIGSPACE|(PlayerMenu[0].status & IT_CENTER)); // This is a hack to make a non-IT_CALL character in slot 0 not softlock the game. IT_DYBIGSPACE is a dummy flag, whilst IT_CENTER is preserved. M_ChoosePlayer(0); // oh for crying out loud just get STARTED, it doesn't matter! return; } @@ -4834,7 +4837,7 @@ static void M_DrawSetupChoosePlayerMenu(void) // Character select profile images!1 M_DrawTextBox(0, my, 16, 20); - i = (itemOn*128 - char_scroll/FRACUNIT); + i = (itemOn*128 - (char_scroll / FRACUNIT)); if (abs(i) > 128) { @@ -4887,7 +4890,7 @@ static void M_DrawSetupChoosePlayerMenu(void) } while (next != i && PlayerMenu[next].status & IT_DISABLED); // Draw prev character if it's visible and its number isn't greater than the current one or there's more than two - if ((o < 32) && !((prev == next) && prev > i)) // (prev != i) was previously a part of this, but we don't need to check again after above. + if (o < 32) // (prev != i) was previously a part of this, but we don't need to check again after above. { patch = W_CachePatchName(description[prev].picname, PU_CACHE); if (SHORT(patch->width) >= 256) @@ -4898,7 +4901,7 @@ static void M_DrawSetupChoosePlayerMenu(void) } // Draw next character if it's visible and its number isn't less than the current one or there's more than two - if ((o < 128) && !((prev == next) && next < i)) // (next != i) was previously a part of this, but it's implicitly true if (prev != i) is true. + if (o < 128) // (next != i) was previously a part of this, but it's implicitly true if (prev != i) is true. { patch = W_CachePatchName(description[next].picname, PU_CACHE); if (SHORT(patch->width) >= 256) @@ -4951,7 +4954,7 @@ static void M_ChoosePlayer(INT32 choice) boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); // skip this if forcecharacter or no characters available - if (!(PlayerMenu[choice].status & IT_CENTER)) + if (!(PlayerMenu[choice].status & IT_DYBIGSPACE)) { // M_SetupChoosePlayer didn't call us directly, that means we've been properly set up. char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu diff --git a/src/m_menu.h b/src/m_menu.h index d578e155e..ed4c3e293 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -79,7 +79,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); #define IT_SUBMENU 6 // go to sub menu #define IT_CVAR 8 // handle as a cvar #define IT_SPACE 10 // no handling -#define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message +#define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message) #define IT_DISPLAY (48+64+128) // 16+32+64+128 #define IT_NOTHING 0 // space From cc9f874c5d78f71e3b46b2b0f6238517fb208c7c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 17 Jul 2016 16:21:46 +0100 Subject: [PATCH 041/100] Further improvements to the character select menu. --- src/m_menu.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 095ad4907..58f431afb 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4839,11 +4839,15 @@ static void M_DrawSetupChoosePlayerMenu(void) i = (itemOn*128 - (char_scroll / FRACUNIT)); - if (abs(i) > 128) + if (!char_notes) { - o = (lastdirection) ? -1 : 1; - char_scroll = (itemOn + o)*128*FRACUNIT; - i = -o*128; + if (i) // turns out this and the preceding check is better then (abs(i) > 128) + { + o = (lastdirection) ? -1 : 1; + char_scroll = (itemOn + o)*128*FRACUNIT; + i = -o*128; + } + char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[itemOn].notes); } if (abs(i) > 1) @@ -4941,8 +4945,6 @@ static void M_DrawSetupChoosePlayerMenu(void) // Character description M_DrawTextBox(136, my, 21, 20); - if (!char_notes) - char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[itemOn].notes); V_DrawString(146, my + 9, V_RETURN8|V_ALLOWLOWERCASE, char_notes); } From df8568642e8ebd5ed79ca684774b343ca12089c4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 17 Jul 2016 16:34:07 +0100 Subject: [PATCH 042/100] Dashmode users can break spinbust blocks when dashing, twinspin users can break both spinbust and Knuckles-only blocks when twinspinning. --- src/p_user.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index a395aa7cd..312465d75 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1717,16 +1717,25 @@ static void P_CheckBustableBlocks(player_t *player) continue; // if it's not an FF_SHATTER, you must be spinning (and not jumping) - // or have Knuckles's abilities (or Super Sonic) - // ...or are drilling in NiGHTS (or Metal Sonic) + // or be super + // or have CA_GLIDEANDCLIMB + // or be in dashmode with CA_DASHMODE + // or be using CA_TWINSPIN + // or are drilling in NiGHTS + // or are recording for Metal Sonic if (!(rover->flags & FF_SHATTER) && !(rover->flags & FF_SPINBUST) && !((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED)) - && (player->charability != CA_GLIDEANDCLIMB && !player->powers[pw_super]) - && !(player->pflags & PF_DRILLING) && !metalrecording) + && !(player->powers[pw_super]) + && !(player->charability == CA_GLIDEANDCLIMB) + && !((player->charability == CA_DASHMODE) && (player->dashmode >= 3*TICRATE)) + && !((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) + && !(player->pflags & PF_DRILLING) + && !metalrecording) continue; - // Only Knuckles can break this rock... - if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX) && !(player->charability == CA_GLIDEANDCLIMB)) + // Only CA_GLIDEANDCLIMB or CA_TWINSPIN users can break this rock... + if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX) + && !(player->charability == CA_GLIDEANDCLIMB || ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)))) continue; // Height checks From 4bd56b82be197365dad44b29d46dda78a6675eaa Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 17 Jul 2016 17:41:44 +0100 Subject: [PATCH 043/100] Better multiability support. * CA_TWINSPIN - you can do it multiple times * CA_DOUBLEJUMP - your jump height is reduced each time, like in Kirby games. The number of extra jumps once you've left the ground that are available is determined by the character's actionspd. --- src/p_user.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 312465d75..3ddbf3c3f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3641,13 +3641,10 @@ void P_DoJump(player_t *player, boolean soundandstate) } } else if (player->charability2 == CA2_MULTIABILITY && - (player->charability == CA_DOUBLEJUMP || player->charability == CA_FLOAT || player->charability == CA_SLOWFALL)) + (player->charability == CA_FLOAT || player->charability == CA_SLOWFALL)) { // Multiability exceptions, since some abilities cannot effectively use it and need a boost. - if (player->charability == CA_DOUBLEJUMP) - player->mo->momz = 23*(FRACUNIT/2); // Increased jump height instead of infinite jumps. - else if (player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) - player->mo->momz = 12*FRACUNIT; // Increased jump height due to ineffective repeat. + player->mo->momz = 12*FRACUNIT; // Increased jump height due to ineffective repeat. } else { @@ -3673,6 +3670,9 @@ void P_DoJump(player_t *player, boolean soundandstate) if (twodlevel || (player->mo->flags2 & MF2_TWOD)) factor += player->jumpfactor / 10; + if (player->charability2 == CA2_MULTIABILITY && player->charability == CA_DOUBLEJUMP) + factor -= max(0, player->secondjump * player->jumpfactor / ((player->actionspd >> FRACBITS) + 1)); // Reduce the jump height each time + P_SetObjectMomZ(player->mo, FixedMul(factor, player->mo->momz), false); // Custom height // set just an eensy above the ground @@ -4111,14 +4111,17 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) } break; case CA_DOUBLEJUMP: // Double-Jump - if (!(player->pflags & PF_THOKKED)) + if (!(player->pflags & PF_THOKKED) || ((player->charability2 == CA2_MULTIABILITY) && (player->secondjump < (player->actionspd >> FRACBITS)))) { - player->pflags &= ~PF_JUMPED; - P_DoJump(player, true); - // Allow infinite double jumping if super. if (!player->powers[pw_super]) player->pflags |= PF_THOKKED; + else + player->secondjump = 0; + + player->pflags &= ~PF_JUMPED; + P_DoJump(player, true); + player->secondjump++; } break; case CA_FLOAT: // Float @@ -4151,7 +4154,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) } break; case CA_TWINSPIN: - if(!(player->pflags & PF_THOKKED)) + if (!(player->pflags & PF_THOKKED) || player->charability2 == CA2_MULTIABILITY) { player->pflags |= PF_THOKKED; S_StartSound(player->mo, sfx_s3k42); From 4168fc02cb17f457f543fe2b9d0ca1126dcc4621 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 17 Jul 2016 18:57:03 +0100 Subject: [PATCH 044/100] Decided the forcing of S_PLAY_FALL when PF_THOKKED was present wasn't that great. --- src/p_mobj.c | 2 +- src/p_user.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 90d21859b..8901622ce 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -164,7 +164,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) #endif // Catch falling for nojumpspin - if ((state == S_PLAY_JUMP) && (player->charflags & SF_NOJUMPSPIN) && (P_MobjFlip(mobj)*mobj->momz < 0 || player->pflags & PF_THOKKED)) + if ((state == S_PLAY_JUMP) && (player->charflags & SF_NOJUMPSPIN) && (P_MobjFlip(mobj)*mobj->momz < 0)) return P_SetPlayerMobjState(mobj, S_PLAY_FALL); // Catch swimming versus flying diff --git a/src/p_user.c b/src/p_user.c index 3ddbf3c3f..abe6816f7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6532,7 +6532,7 @@ static void P_MovePlayer(player_t *player) // If Springing (or nojumpspinning), but travelling DOWNWARD, change back! (nojumpspin also turns to fall once PF_THOKKED is added.) if ((player->panim == PA_SPRING && P_MobjFlip(player->mo)*player->mo->momz < 0) || ((((player->charflags & SF_NOJUMPSPIN) && (player->pflags & PF_JUMPED) && player->panim == PA_JUMP)) - && (P_MobjFlip(player->mo)*player->mo->momz < 0 || player->pflags & PF_THOKKED))) + && (P_MobjFlip(player->mo)*player->mo->momz < 0))) P_SetPlayerMobjState(player->mo, S_PLAY_FALL); // If doing an air animation but on the ground, change back! else if (onground && (player->panim == PA_SPRING || player->panim == PA_FALL || player->panim == PA_RIDE || player->panim == PA_JUMP) && !player->mo->momz) From ac2ff5e386014df2277677297b296908787c3578 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 17 Jul 2016 21:31:15 +0100 Subject: [PATCH 045/100] CA_MELEE. Mostly complete. * When moving slowly, P_InstaThrust at S_SKIN's maxdash forward, and set momz to S_SKIN's mindash upwards. Plays a tok noise (not thok). Hurts enemies/bosses, busts spikes/monitors/all types of bustable blocks. * When moving quickly... doesn't do anything yet, but WILL do a slide. Also, P_DoSpinDash is now renamed to P_DoSpinAbility, and CA_TWINSPIN users can bust all bustable blocks on collision too. --- src/d_player.h | 4 +++- src/dehacked.c | 6 ++++++ src/info.c | 6 ++++++ src/info.h | 8 +++++++- src/lua_hook.h | 2 +- src/p_inter.c | 2 ++ src/p_map.c | 21 +++++++++++++++------ src/p_mobj.c | 25 +++++++++++++++++++++++-- src/p_user.c | 33 ++++++++++++++++++++++++++++----- src/r_things.c | 18 +++++++++--------- 10 files changed, 100 insertions(+), 25 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 465bbe3f7..f57eb90cf 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -72,7 +72,8 @@ typedef enum { CA2_NONE=0, CA2_SPINDASH, - CA2_MULTIABILITY + CA2_MULTIABILITY, + CA2_MELEE } charability2_t; // @@ -178,6 +179,7 @@ typedef enum PA_SPRING, PA_FALL, PA_ABILITY, + PA_ABILITY2, PA_RIDE } panim_t; diff --git a/src/dehacked.c b/src/dehacked.c index d174aede1..8c307569f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3797,6 +3797,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // CA_TWINSPIN "S_PLAY_TWINSPIN", + // CA2_MELEE + "S_PLAY_MELEE", + "S_PLAY_MELEE_FINISH", + // SF_SUPERANIMS "S_PLAY_SUPER_STND", "S_PLAY_SUPER_WALK", @@ -7180,6 +7184,7 @@ struct { {"CA2_NONE",CA2_NONE}, // now slot 0! {"CA2_SPINDASH",CA2_SPINDASH}, {"CA2_MULTIABILITY",CA2_MULTIABILITY}, + {"CA2_MELEE",CA2_MELEE}, // Sound flags {"SF_TOTALLYSINGLE",SF_TOTALLYSINGLE}, @@ -7233,6 +7238,7 @@ struct { {"PA_SPRING",PA_SPRING}, {"PA_FALL",PA_FALL}, {"PA_ABILITY",PA_ABILITY}, + {"PA_ABILITY2",PA_ABILITY2}, {"PA_RIDE",PA_RIDE}, // Current weapon diff --git a/src/info.c b/src/info.c index 4deabefdf..15abd2484 100644 --- a/src/info.c +++ b/src/info.c @@ -88,6 +88,8 @@ char spr2names[NUMPLAYERSPRITES][5] = "TWIN", + "MLEE", + "TRNS", "SSTD", "SWLK", @@ -163,6 +165,10 @@ state_t states[NUMSTATES] = // CA_TWINSPIN {SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN + // CA2_MELEE + {SPR_PLAY, SPR2_MLEE|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_MELEE_FINISH, 0, S_PLAY_MELEE}, // S_PLAY_MELEE + {SPR_PLAY, SPR2_MLEE, 20, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_MELEE_FINISH + // SF_SUPERANIMS {SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND {SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK diff --git a/src/info.h b/src/info.h index ccb223c6c..3c55424be 100644 --- a/src/info.h +++ b/src/info.h @@ -609,7 +609,9 @@ enum playersprite SPR2_CLNG, SPR2_CLMB, - SPR2_TWIN, // twinspin + SPR2_TWIN, + + SPR2_MLEE, SPR2_TRNS, SPR2_SSTD, @@ -680,6 +682,10 @@ typedef enum state // CA_TWINSPIN S_PLAY_TWINSPIN, + // CA2_MELEE + S_PLAY_MELEE, + S_PLAY_MELEE_FINISH, + // SF_SUPERANIMS S_PLAY_SUPER_STND, S_PLAY_SUPER_WALK, diff --git a/src/lua_hook.h b/src/lua_hook.h index 804d99e12..bed32edac 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -69,7 +69,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source); // Ho #define LUAh_MobjRemoved(mo) LUAh_MobjHook(mo, hook_MobjRemoved) // Hook for P_RemoveMobj by mobj type #define LUAh_JumpSpecial(player) LUAh_PlayerHook(player, hook_JumpSpecial) // Hook for P_DoJumpStuff (Any-jumping) #define LUAh_AbilitySpecial(player) LUAh_PlayerHook(player, hook_AbilitySpecial) // Hook for P_DoJumpStuff (Double-jumping) -#define LUAh_SpinSpecial(player) LUAh_PlayerHook(player, hook_SpinSpecial) // Hook for P_DoSpinDash (Spin button effect) +#define LUAh_SpinSpecial(player) LUAh_PlayerHook(player, hook_SpinSpecial) // Hook for P_DoSpinAbility (Spin button effect) #define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air)) boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name diff --git a/src/p_inter.c b/src/p_inter.c index e7d98dbe3..5f538ee8d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -302,6 +302,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) || (player->pflags & (PF_SPINNING|PF_GLIDING)) + || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? { @@ -347,6 +348,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) || (player->pflags & (PF_SPINNING|PF_GLIDING)) + || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) || ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0)) || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? { diff --git a/src/p_map.c b/src/p_map.c index 65a5fefab..18321128c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -448,11 +448,12 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - // CA_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users destroy spikes. + // CA_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. if ((tmthing->player) && (((tmthing->player->charability == CA_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) && (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE)) - || ((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY) + || ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY)) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)) && (thing->type == MT_SPIKE)))) { if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE))) @@ -971,8 +972,12 @@ static boolean PIT_CheckThing(mobj_t *thing) { if (thing->flags & MF_MONITOR && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) - || ((tmthing->player->pflags & PF_JUMPED) && !(tmthing->player->charflags & SF_NOJUMPDAMAGE && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) - || ((tmthing->player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))) + || ((tmthing->player->pflags & PF_JUMPED) + && !(tmthing->player->charflags & SF_NOJUMPDAMAGE + && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) + || ((tmthing->player->charflags & SF_STOMPDAMAGE) + && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))) { SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed. fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;; @@ -996,8 +1001,12 @@ static boolean PIT_CheckThing(mobj_t *thing) // unless it's a CTF team monitor and you're on the wrong team else if (thing->flags & MF_MONITOR && tmthing->player && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) - || ((tmthing->player->pflags & PF_JUMPED) && !(tmthing->player->charflags & SF_NOJUMPDAMAGE && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) - || ((tmthing->player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))) + || ((tmthing->player->pflags & PF_JUMPED) + && !(tmthing->player->charflags & SF_NOJUMPDAMAGE + && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) + || ((tmthing->player->charflags & SF_STOMPDAMAGE) + && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))) && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2))) ; // z checking at last diff --git a/src/p_mobj.c b/src/p_mobj.c index 8901622ce..5e85e4de2 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -173,6 +173,10 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) return P_SetPlayerMobjState(player->mo, S_PLAY_FLY); + // Catch melee into goop + //if (state == S_PLAY_MELEE && player->mo->eflags & MFE_GOOWATER) + //return P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + // Catch state changes for Super Sonic if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS)) { @@ -275,6 +279,10 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) case S_PLAY_TWINSPIN: player->panim = PA_ABILITY; break; + case S_PLAY_MELEE: + case S_PLAY_MELEE_FINISH: + player->panim = PA_ABILITY2; + break; case S_PLAY_RIDE: case S_PLAY_SUPER_RIDE: player->panim = PA_RIDE; @@ -414,6 +422,10 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_SPIN; break; + case SPR2_MLEE: + spr2 = SPR2_TWIN; + break; + // Super sprites fallback to regular sprites case SPR2_SWLK: spr2 = SPR2_WALK; @@ -497,12 +509,16 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) if (frame >= numframes) { - if (st->frame & FF_SPR2ENDSTATE) + if (st->frame & FF_SPR2ENDSTATE) // no frame advancement { if (st->var1 == S_NULL) - frame--; // no frame advancement + frame--; else + { + if (mobj->frame & FF_FRAMEMASK) + mobj->frame--; return P_SetPlayerMobjState(mobj, st->var1); + } } else frame = 0; @@ -3050,6 +3066,11 @@ static void P_PlayerZMovement(mobj_t *mo) mo->player->skidtime = TICRATE; mo->tics = -1; } + else if (mo->player->charability2 == CA2_MELEE && mo->player->panim == PA_ABILITY2) + { + P_InstaThrust(mo, mo->angle, 0); + P_SetPlayerMobjState(mo, S_PLAY_STND); + } else if (mo->player->pflags & PF_JUMPED || (mo->player->pflags & (PF_SPINNING|PF_USEDOWN)) != (PF_SPINNING|PF_USEDOWN) || mo->player->powers[pw_tailsfly] || mo->state-states == S_PLAY_FLY_TIRED) { diff --git a/src/p_user.c b/src/p_user.c index abe6816f7..cacf26a15 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1721,6 +1721,7 @@ static void P_CheckBustableBlocks(player_t *player) // or have CA_GLIDEANDCLIMB // or be in dashmode with CA_DASHMODE // or be using CA_TWINSPIN + // or be using CA2_MELEE // or are drilling in NiGHTS // or are recording for Metal Sonic if (!(rover->flags & FF_SHATTER) && !(rover->flags & FF_SPINBUST) @@ -1729,13 +1730,16 @@ static void P_CheckBustableBlocks(player_t *player) && !(player->charability == CA_GLIDEANDCLIMB) && !((player->charability == CA_DASHMODE) && (player->dashmode >= 3*TICRATE)) && !((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) + && !(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) && !(player->pflags & PF_DRILLING) && !metalrecording) continue; - // Only CA_GLIDEANDCLIMB or CA_TWINSPIN users can break this rock... + // Only players with CA_GLIDEANDCLIMB, or CA_TWINSPIN/CA2_MELEE users can break this rock... if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX) - && !(player->charability == CA_GLIDEANDCLIMB || ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)))) + && !(player->charability == CA_GLIDEANDCLIMB + || ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) + || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))) continue; // Height checks @@ -3706,11 +3710,11 @@ void P_DoJump(player_t *player, boolean soundandstate) } // -// P_DoSpinDash +// P_DoSpinAbility // // Player spindash handling // -static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) +static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) { if (player->pflags & PF_STASIS) return; @@ -3828,6 +3832,25 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) P_SetPlayerMobjState(player->mo, S_PLAY_DASH); else if (onground && player->pflags & PF_SPINNING && !(player->panim == PA_ROLL)) P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + + // Melee attack + if ((player->charability2 == CA2_MELEE) && !(player->panim == PA_ABILITY2) && !player->exiting + && !P_PlayerInPain(player) && (cmd->buttons & BT_USE) && player->speed < FixedMul(10<mo->scale) + && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) +#ifdef ESLOPE + && (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) +#endif + ) + { + player->mo->z += P_MobjFlip(player->mo); + player->mo->momx = player->cmomx = 0; + player->mo->momy = player->cmomy = 0; + P_SetObjectMomZ(player->mo, player->mindash, false); + P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->maxdash, player->mo->scale)); + P_SetPlayerMobjState(player->mo, S_PLAY_MELEE); + player->pflags |= PF_USEDOWN; + S_StartSound(player->mo, sfx_s3k8b); + } } // @@ -6796,7 +6819,7 @@ static void P_MovePlayer(player_t *player) && !(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) P_ElementalFireTrail(player); - P_DoSpinDash(player, cmd); + P_DoSpinAbility(player, cmd); // jumping P_DoJumpStuff(player, cmd); diff --git a/src/r_things.c b/src/r_things.c index a059df7c6..e15bb7d38 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2620,15 +2620,15 @@ void R_AddSkins(UINT16 wadnum) FULLPROCESS(revitem) #undef FULLPROCESS -#define GETSPEED(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<field = atoi(value)<field = atoi(value); From cfcd25f2cd1adcfe1d7bbb17451505f61b207c3c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 19 Jul 2016 01:03:40 +0100 Subject: [PATCH 046/100] Fixing a bug which could be caused by tapping up/down on the character select at high speeds by ensuring that o is never negative instead of assuming the one circumstance it may have been negative under. --- src/m_menu.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 58f431afb..10f990275 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4856,22 +4856,27 @@ static void M_DrawSetupChoosePlayerMenu(void) char_scroll = itemOn*128*FRACUNIT; // just be exact now. o = ((char_scroll / FRACUNIT) + 16); - if (lastdirection) - o += 128; // This one-directional hack is to prevent visual glitches when going from the (currentMenu->numitems)nd character to the 1st character. - i = (o / 128); - o = (o % 128); - // subtract 1 from i to counteract the +128 from the prior hack, if we made it happen - if (lastdirection) + if (o < 0) // This hack is to prevent visual glitches when looping from the last character to the 1st character. { + o += 128; + + i = (o / 128); + o = (o % 128); + j = i; - do + do // subtract 1 from i to counteract the +128 from the prior hack { i--; if (i < 0) i = (currentMenu->numitems - 1); } while (i != j && PlayerMenu[i].status & IT_DISABLED); } + else // Regular circumstances + { + i = (o / 128); + o = (o % 128); + } // Get prev character... prev = i; From 46e50a523f2d6075a70813844940a212dee8f16b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 19 Jul 2016 01:19:03 +0100 Subject: [PATCH 047/100] Let's be consistent with how other parts of the code handle this same issue of conditional operations surrounding non-conditional operations. --- src/m_menu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 10f990275..16f63231e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4829,6 +4829,7 @@ static void M_DrawSetupChoosePlayerMenu(void) const INT32 my = 24; patch_t *patch; INT32 i, o, j, prev, next; + boolean loophack = false; // Black BG V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); @@ -4858,12 +4859,16 @@ static void M_DrawSetupChoosePlayerMenu(void) o = ((char_scroll / FRACUNIT) + 16); if (o < 0) // This hack is to prevent visual glitches when looping from the last character to the 1st character. - { + loophack = true; + + if (loophack) o += 128; - i = (o / 128); - o = (o % 128); + i = (o / 128); + o = (o % 128); + if (loophack) + { j = i; do // subtract 1 from i to counteract the +128 from the prior hack { @@ -4872,11 +4877,6 @@ static void M_DrawSetupChoosePlayerMenu(void) i = (currentMenu->numitems - 1); } while (i != j && PlayerMenu[i].status & IT_DISABLED); } - else // Regular circumstances - { - i = (o / 128); - o = (o % 128); - } // Get prev character... prev = i; From f1311c515db33e7adf2179d89559140356bf12f9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 19 Jul 2016 13:45:31 +0100 Subject: [PATCH 048/100] Making FF_MIDDLESTARTCHANCE more useful for FF_ANIMATE animations. --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5e85e4de2..eec959b62 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -533,7 +533,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) mobj->sprite = st->sprite; mobj->frame = st->frame; if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) - mobj->frame += (st->var1)/2; + mobj->frame += P_RandomKey(st->var1); } // Modified handling. @@ -648,7 +648,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) mobj->sprite = st->sprite; mobj->frame = st->frame; if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) - mobj->frame += (st->var1)/2; + mobj->frame += P_RandomKey(st->var1); } // Modified handling. From 4435815c354151e7ab6d7074028ea4a7385d2121 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 20 Jul 2016 15:48:24 +0100 Subject: [PATCH 049/100] "prefoppositecolor" - exists solely for metal so he can have his sonic 4 peridot-background end sign when using skincolor_blue. not updating player.dta yet though. --- src/p_enemy.c | 29 +++++++++++++++++++++++++---- src/r_draw.c | 10 +++++++--- src/r_things.c | 9 +++++++-- src/r_things.h | 2 ++ 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 4e11dc494..aa38c9818 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3949,6 +3949,7 @@ void A_UnsetSolidSteam(mobj_t *actor) void A_SignPlayer(mobj_t *actor) { mobj_t *ov; + skin_t *skin; #ifdef HAVE_BLUA if (LUA_CallAction("A_SignPlayer", actor)) return; @@ -3959,15 +3960,35 @@ void A_SignPlayer(mobj_t *actor) if (!actor->target->player) return; - // Set the sign to be an appropriate background color for this player's skincolor. - actor->color = Color_Opposite[actor->target->player->skincolor*2]; - actor->frame += Color_Opposite[actor->target->player->skincolor*2+1]; + skin = &skins[actor->target->player->skin]; + + if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? + { + actor->color = skin->prefoppositecolor; + /* + If you're here from the comment above Color_Opposite, + the following line is the one which is dependent on the + array being symmetrical. It gets the opposite of the + opposite of your desired colour just so it can get the + brightness frame for the End Sign. It's not a great + design choice, but it's constant time array access and + the idea that the colours should be OPPOSITES is kind + of in the name. If you have a better idea, feel free + to let me know. ~toast 2016/07/20 + */ + actor->frame += Color_Opposite[Color_Opposite[skin->prefoppositecolor*2]*2+1]; + } + else // Set the sign to be an appropriate background color for this player's skincolor. + { + actor->color = Color_Opposite[actor->target->player->skincolor*2]; + actor->frame += Color_Opposite[actor->target->player->skincolor*2+1]; + } // spawn an overlay of the player's face. ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); P_SetTarget(&ov->target, actor); ov->color = actor->target->player->skincolor; - ov->skin = &skins[actor->target->player->skin]; + ov->skin = skin; P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN } diff --git a/src/r_draw.c b/src/r_draw.c index d6a1ee7ae..c56888e0d 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -166,9 +166,13 @@ const char *Color_Names[MAXSKINCOLORS] = "Lavender", // SKINCOLOR_LAVENDER "Magenta", // SKINCOLOR_MAGENTA "Pink", // SKINCOLOR_PINK - "Rosy" // SKINCOLOR_ROSY + "Rosy" // SKINCOLOR_ROSY }; +/* +A word of warning: If the following array is non-symmetrical, +A_SignPlayer's prefoppositecolor behaviour will break. +*/ const UINT8 Color_Opposite[MAXSKINCOLORS*2] = { SKINCOLOR_NONE,8, // SKINCOLOR_NONE @@ -183,7 +187,7 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] = SKINCOLOR_CYAN,8, // SKINCOLOR_CRIMSON - ditto SKINCOLOR_BLUE,12, // SKINCOLOR_ORANGE SKINCOLOR_TAN,8, // SKINCOLOR_RUST - ditto - SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD - ditto + SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD - ditto SKINCOLOR_TEAL,8, // SKINCOLOR_YELLOW - ditto SKINCOLOR_RUST,8, // SKINCOLOR_TAN - ditto SKINCOLOR_MAGENTA,3, // SKINCOLOR_MOSS @@ -200,7 +204,7 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] = SKINCOLOR_GOLD,8, // SKINCOLOR_LAVENDER - ditto SKINCOLOR_MOSS,8, // SKINCOLOR_MAGENTA - ditto SKINCOLOR_AZURE,8, // SKINCOLOR_PINK - ditto - SKINCOLOR_AQUA,8 // SKINCOLOR_ROSY - ditto + SKINCOLOR_AQUA,8 // SKINCOLOR_ROSY - ditto }; CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; diff --git a/src/r_things.c b/src/r_things.c index e15bb7d38..7b63edfcb 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2288,6 +2288,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->starttranscolor = 96; skin->prefcolor = SKINCOLOR_GREEN; + skin->prefoppositecolor = 0; // use tables skin->normalspeed = 36<runspeed = 28<field = atoi(value)<starttranscolor = atoi(value); - else if (!stricmp(stoken, "prefcolor")) - skin->prefcolor = R_GetColorByName(value); +#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value); + GETSKINCOLOR(prefcolor) + GETSKINCOLOR(prefoppositecolor) +#undef GETSKINCOLOR #define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value)); GETFLOAT(jumpfactor) diff --git a/src/r_things.h b/src/r_things.h index 430cdd639..15f9eb774 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -102,6 +102,8 @@ typedef struct // Definable color translation table UINT8 starttranscolor; UINT8 prefcolor; + UINT8 prefoppositecolor; // if 0 use tables instead + fixed_t highresscale; // scale of highres, default is 0.5 // specific sounds per skin From d0cd1d951fd2c2a4b2c4e332df372bb7787d1d44 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 20 Jul 2016 15:53:08 +0100 Subject: [PATCH 050/100] Add prefoppositecolor to Lua. --- src/lua_skinlib.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 2d1caef04..91735337d 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -50,6 +50,7 @@ enum skin { skin_shieldscale, skin_starttranscolor, skin_prefcolor, + skin_prefoppositecolor, skin_highresscale, skin_soundsid, skin_availability @@ -85,6 +86,7 @@ static const char *const skin_opt[] = { "shieldscale", "starttranscolor", "prefcolor", + "prefoppositecolor", "highresscale", "soundsid", "availability", @@ -201,6 +203,9 @@ static int skin_get(lua_State *L) case skin_prefcolor: lua_pushinteger(L, skin->prefcolor); break; + case skin_prefoppositecolor: + lua_pushinteger(L, skin->prefoppositecolor); + break; case skin_highresscale: lua_pushinteger(L, skin->highresscale); break; From fe5b8c58afb65c8545dfafce6d0109935f2af442 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 31 Jul 2016 20:51:39 +0100 Subject: [PATCH 051/100] Add basic support for animated sky textures --- src/hardware/hw_main.c | 6 +++--- src/r_plane.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a83960177..e3d9bc218 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5325,7 +5325,7 @@ static void HWR_DrawSkyBackground(player_t *player) // 0--1 (void)player; - HWR_GetTexture(skytexture); + HWR_GetTexture(texturetranslation[skytexture]); //Hurdler: the sky is the only texture who need 4.0f instead of 1.0 // because it's called just after clearing the screen @@ -5345,7 +5345,7 @@ static void HWR_DrawSkyBackground(player_t *player) angle = (dup_viewangle + gr_xtoviewangle[0]); - dimensionmultiply = ((float)textures[skytexture]->width/256.0f); + dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); v[0].sow = v[3].sow = ((float) angle / ((ANGLE_90-1)*dimensionmultiply)); v[2].sow = v[1].sow = (-1.0f/dimensionmultiply)+((float) angle / ((ANGLE_90-1)*dimensionmultiply)); @@ -5354,7 +5354,7 @@ static void HWR_DrawSkyBackground(player_t *player) angle = aimingangle; aspectratio = (float)vid.width/(float)vid.height; - dimensionmultiply = ((float)textures[skytexture]->height/(128.0f*aspectratio)); + dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio)); angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply; // Middle of the sky should always be at angle 0 diff --git a/src/r_plane.c b/src/r_plane.c index 19007d88f..ad30f4247 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -711,7 +711,7 @@ void R_DrawPlanes(void) angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; dc_x = x; dc_source = - R_GetColumn(skytexture, + R_GetColumn(texturetranslation[skytexture], angle); wallcolfunc(); } From 1ac1f27e4c8a7cdf1726577293443cddab5d629c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 1 Aug 2016 17:17:25 +0100 Subject: [PATCH 052/100] Preparation for the SPR2_ freeslot branch's merger. *crosses fingers it happens soon* --- src/p_pspr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_pspr.h b/src/p_pspr.h index 4117a53f1..9420796ff 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -35,8 +35,8 @@ #pragma interface #endif -/// \brief Frame flags: only the frame number - 0 to 127 (Frames and Sprite2) -#define FF_FRAMEMASK 0x7f +/// \brief Frame flags: only the frame number - 0 to 511 (Frames from 0 to 63, Sprite2 number uses full range) +#define FF_FRAMEMASK 0x1ff /// \brief Frame flags: A change of state at the end of Sprite2 animation #define FF_SPR2ENDSTATE 0x1000 /// \brief Frame flags: 50% of starting in middle of animation (Sprite2 and FF_ANIMATE) From 9d870ea31dc4015d45bc88ee3240ff7c26f94323 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 6 Aug 2016 13:53:16 +0100 Subject: [PATCH 053/100] Enabling patch.dta, and also upping the number of SPR2_ slots (not just freeslots) to be equivalent to FF_FRAMEMASK. --- src/doomdef.h | 2 +- src/info.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 4428ef617..a7a722b42 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -158,7 +158,7 @@ extern FILE *logstream; // Does this version require an added patch file? // Comment or uncomment this as necessary. -//#define USE_PATCH_DTA +#define USE_PATCH_DTA // Modification options // If you want to take advantage of the Master Server's ability to force clients to update diff --git a/src/info.h b/src/info.h index 690f6bbee..beb08a55c 100644 --- a/src/info.h +++ b/src/info.h @@ -632,7 +632,7 @@ enum playersprite SPR2_SFLT, SPR2_FIRSTFREESLOT, - SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, + SPR2_LASTFREESLOT = 0x1ff, // FF_FRAMEMASK (cannot use #define'd constants as enum value...) - previously set to SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, NUMPLAYERSPRITES }; From 5e35d629f23b612d3510ae9e3643673747916b0a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 6 Aug 2016 21:22:38 +0100 Subject: [PATCH 054/100] A clearer understanding of freeslots and their relation to FF_FRAMEMASK, explained via comment. --- src/info.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/info.h b/src/info.h index beb08a55c..7a99d8b07 100644 --- a/src/info.h +++ b/src/info.h @@ -579,6 +579,9 @@ typedef enum sprite NUMSPRITES } spritenum_t; +// Make sure to be conscious of FF_FRAMEMASK whenever you change this table. +// Currently, FF_FRAMEMASK is 0x1ff, or 511 - and NUMSPRITEFREESLOTS is 256. +// Since this is zero-based, there can be at most 256 different SPR2_'s without changing that. enum playersprite { SPR2_STND = 0, @@ -632,7 +635,7 @@ enum playersprite SPR2_SFLT, SPR2_FIRSTFREESLOT, - SPR2_LASTFREESLOT = 0x1ff, // FF_FRAMEMASK (cannot use #define'd constants as enum value...) - previously set to SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, + SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, NUMPLAYERSPRITES }; From 029fd156a8bf910939a96814b4644140492bfa17 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 6 Aug 2016 22:41:25 +0100 Subject: [PATCH 055/100] Some nice optimisations to the new character select menu - no need to iterate up to 3 times a tic at the expense of ((32*2 + 2)*UINT8 - 3*INT32) memory. --- src/m_menu.c | 127 +++++++++++++++++++++++++-------------------------- src/m_menu.h | 2 + 2 files changed, 65 insertions(+), 64 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 16f63231e..35495ec55 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -110,38 +110,38 @@ const char *quitmsg[NUM_QUITMESSAGES]; // Stuff for customizing the player select screen Tails 09-22-2003 description_t description[32] = { - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0}, - {"???", "", "", 0} + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0}, + {"???", "", "", 0, 0, 0} }; static char *char_notes = NULL; static fixed_t char_scroll = 0; @@ -4771,8 +4771,10 @@ void M_ForceSaveSlotSelected(INT32 sslot) static void M_SetupChoosePlayer(INT32 choice) { - INT32 availablecount = 0; - INT32 i, skinnum; + INT32 skinnum; + UINT8 i; + UINT8 firstvalid = 255; + UINT8 lastvalid = 0; char *name; (void)choice; @@ -4787,6 +4789,17 @@ static void M_SetupChoosePlayer(INT32 choice) skinnum = R_SkinAvailable(name); if ((skinnum != -1) && (R_SkinUnlock(skinnum))) { + // Handling order. + if (firstvalid == 255) + firstvalid = i; + else + { + description[i].prev = lastvalid; + description[lastvalid].next = i; + } + lastvalid = i; + + // Handling visibility. if (PlayerMenu[i].status & (IT_DISABLED|IT_CENTER)) PlayerMenu[i].status = IT_CALL; if (description[i].picname[0] == '\0') @@ -4795,17 +4808,22 @@ static void M_SetupChoosePlayer(INT32 choice) else // Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. PlayerMenu[i].status = (IT_DISABLED|IT_CENTER); Z_Free(name); - - if (!(PlayerMenu[i].status & IT_DISABLED)) // If this character is available at all... - availablecount++; } } - if (!(availablecount) - || (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] != '\0')) + if ((firstvalid != 255) + && !(mapheaderinfo[startmap-1] + && (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0') + ) + ) + { // One last bit of order we can't do in the iteration above. + description[firstvalid].prev = lastvalid; + description[lastvalid].next = firstvalid; + } + else // We're being forced into a specific character, so might as well. { PlayerMenu[0].status = (IT_CALL|IT_DYBIGSPACE|(PlayerMenu[0].status & IT_CENTER)); // This is a hack to make a non-IT_CALL character in slot 0 not softlock the game. IT_DYBIGSPACE is a dummy flag, whilst IT_CENTER is preserved. - M_ChoosePlayer(0); // oh for crying out loud just get STARTED, it doesn't matter! + M_ChoosePlayer(0); return; } @@ -4828,7 +4846,8 @@ static void M_DrawSetupChoosePlayerMenu(void) { const INT32 my = 24; patch_t *patch; - INT32 i, o, j, prev, next; + INT32 i, o; + UINT8 prev, next; boolean loophack = false; // Black BG @@ -4868,35 +4887,15 @@ static void M_DrawSetupChoosePlayerMenu(void) o = (o % 128); if (loophack) - { - j = i; - do // subtract 1 from i to counteract the +128 from the prior hack - { - i--; - if (i < 0) - i = (currentMenu->numitems - 1); - } while (i != j && PlayerMenu[i].status & IT_DISABLED); - } + i = description[i].prev; // Get prev character... - prev = i; - do - { - prev--; - if (prev < 0) - prev = (currentMenu->numitems - 1); - } while (prev != i && PlayerMenu[prev].status & IT_DISABLED); + prev = description[i].prev; if (prev != i) // If there's more than one character available... { // Let's get the next character now. - next = i; - do - { - next++; - if (next >= currentMenu->numitems) - next = 0; - } while (next != i && PlayerMenu[next].status & IT_DISABLED); + next = description[i].next; // Draw prev character if it's visible and its number isn't greater than the current one or there's more than two if (o < 32) // (prev != i) was previously a part of this, but we don't need to check again after above. diff --git a/src/m_menu.h b/src/m_menu.h index ed4c3e293..9cac52ed5 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -178,6 +178,8 @@ typedef struct char picname[8]; char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 UINT16 wadnum; // for duplicate characters + UINT8 prev; + UINT8 next; } description_t; // mode descriptions for video mode menu From c678220857a718117aeb1df218e509f14bff2ab9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 6 Aug 2016 23:18:37 +0100 Subject: [PATCH 056/100] New S_SKIN attribute - "camerascale", another float. Acts as a scale modifier to t_cam_dist and t_cam_height. --- src/lua_skinlib.c | 5 +++++ src/p_user.c | 8 ++++---- src/r_things.c | 2 ++ src/r_things.h | 1 + 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 91735337d..7ff21151c 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -48,6 +48,7 @@ enum skin { skin_height, skin_spinheight, skin_shieldscale, + skin_camerascale, skin_starttranscolor, skin_prefcolor, skin_prefoppositecolor, @@ -84,6 +85,7 @@ static const char *const skin_opt[] = { "height", "spinheight", "shieldscale", + "camerascale", "starttranscolor", "prefcolor", "prefoppositecolor", @@ -197,6 +199,9 @@ static int skin_get(lua_State *L) case skin_shieldscale: lua_pushfixed(L, skin->shieldscale); break; + case skin_camerascale: + lua_pushfixed(L, skin->camerascale); + break; case skin_starttranscolor: lua_pushinteger(L, skin->starttranscolor); break; diff --git a/src/p_user.c b/src/p_user.c index cacf26a15..b85e83d78 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8002,16 +8002,16 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camspeed = cv_cam_speed.value; camstill = cv_cam_still.value; camrotate = cv_cam_rotate.value; - camdist = FixedMul(cv_cam_dist.value, mo->scale); - camheight = FixedMul(cv_cam_height.value, mo->scale); + camdist = FixedMul(cv_cam_dist.value, FixedMul(skins[player->skin].camerascale, mo->scale)); + camheight = FixedMul(cv_cam_height.value, FixedMul(skins[player->skin].camerascale, mo->scale)); } else // Camera 2 { camspeed = cv_cam2_speed.value; camstill = cv_cam2_still.value; camrotate = cv_cam2_rotate.value; - camdist = FixedMul(cv_cam2_dist.value, mo->scale); - camheight = FixedMul(cv_cam2_height.value, mo->scale); + camdist = FixedMul(cv_cam2_dist.value, FixedMul(skins[player->skin].camerascale, mo->scale)); + camheight = FixedMul(cv_cam2_height.value, FixedMul(skins[player->skin].camerascale, mo->scale)); } #ifdef REDSANALOG diff --git a/src/r_things.c b/src/r_things.c index dd0cf34ef..c3a7ac271 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2308,6 +2308,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->spinheight = FixedMul(skin->height, 2*FRACUNIT/3); skin->shieldscale = FRACUNIT; + skin->camerascale = FRACUNIT; skin->thokitem = -1; skin->spinitem = -1; @@ -2662,6 +2663,7 @@ void R_AddSkins(UINT16 wadnum) GETFLOAT(jumpfactor) GETFLOAT(highresscale) GETFLOAT(shieldscale) + GETFLOAT(camerascale) #undef GETFLOAT else // let's check if it's a sound, otherwise error out diff --git a/src/r_things.h b/src/r_things.h index 15f9eb774..651950f05 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -98,6 +98,7 @@ typedef struct fixed_t spinheight; fixed_t shieldscale; // no change to bounding box, but helps set the shield's sprite size + fixed_t camerascale; // Definable color translation table UINT8 starttranscolor; From 6a865abb93ac71486348b39aa171f46b23bd607c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 6 Aug 2016 23:54:38 +0100 Subject: [PATCH 057/100] Bugfix for spike sound playing when attempting to attack non-solid spikes with CA_DASHMODE/CA_TWINSPIN/CA2_MELEE. --- src/p_map.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 8f6bd3577..b8123fc0c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -443,7 +443,8 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // underneath if (thing->type == MT_SPIKE) { - S_StartSound(tmthing, thing->info->deathsound); + if (thing->flags & MF_SOLID) + S_StartSound(tmthing, thing->info->deathsound); for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext) if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(thing, tmthing, tmthing, 0); @@ -476,7 +477,8 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // underneath if (thing->type == MT_SPIKE) { - S_StartSound(tmthing, thing->info->deathsound); + if (thing->flags & MF_SOLID) + S_StartSound(tmthing, thing->info->deathsound); for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext) if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(thing, tmthing, tmthing, 0); From f46ec64958a66b7cde9df55e98eb10cc62dba2ba Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 8 Aug 2016 21:17:51 +0100 Subject: [PATCH 058/100] each SF_ flag can be set by their own parameters again, does not replace "flags" but is an alternative to it e.g.: super = 1 for SF_SUPER, noskid = 1 for SF_NOSKID, machine = 1 for SF_MACHINE --- src/r_things.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/r_things.c b/src/r_things.c index c3a7ac271..942f6b66e 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2666,6 +2666,27 @@ void R_AddSkins(UINT16 wadnum) GETFLOAT(camerascale) #undef GETFLOAT +#define GETFLAG(field, flag) else if (!stricmp(stoken, #field)) { \ + if (atoi(value) == 1) \ + skin->flags |= flag; \ + else \ + skin->flags &= ~flag; \ +} + // parameters for individual character flags + GETFLAG(super, SF_SUPER) + GETFLAG(superanims, SF_SUPERANIMS) + GETFLAG(superspin, SF_SUPERSPIN) + GETFLAG(hires, SF_HIRES) + GETFLAG(noskid, SF_NOSKID) + GETFLAG(nospeedadjust, SF_NOSPEEDADJUST) + GETFLAG(runonwater, SF_RUNONWATER) + GETFLAG(nojumpspin, SF_NOJUMPSPIN) + GETFLAG(nojumpdamage, SF_NOJUMPDAMAGE) + GETFLAG(stompdamage, SF_STOMPDAMAGE) + GETFLAG(mariodamage, SF_MARIODAMAGE) + GETFLAG(machine, SF_MACHINE) +#undef GETFLAG + else // let's check if it's a sound, otherwise error out { boolean found = false; From 841ee6eca00a7e23f0f58aa9b282557475a14dba Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 8 Aug 2016 22:34:47 +0100 Subject: [PATCH 059/100] Reduced GETFLAG macro args to just one as requested, true/yes are also valid now like with level header flags params (everything else is considered 'off') --- src/r_things.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 942f6b66e..7d7f7f093 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2666,25 +2666,28 @@ void R_AddSkins(UINT16 wadnum) GETFLOAT(camerascale) #undef GETFLOAT -#define GETFLAG(field, flag) else if (!stricmp(stoken, #field)) { \ - if (atoi(value) == 1) \ - skin->flags |= flag; \ +#define GETFLAG(field) else if (!stricmp(stoken, #field)) { \ + strupr(value); \ + if (atoi(value) || value[0] == 'T' || value[0] == 'Y') \ + skin->flags |= (SF_##field); \ else \ - skin->flags &= ~flag; \ + skin->flags &= ~(SF_##field); \ } // parameters for individual character flags - GETFLAG(super, SF_SUPER) - GETFLAG(superanims, SF_SUPERANIMS) - GETFLAG(superspin, SF_SUPERSPIN) - GETFLAG(hires, SF_HIRES) - GETFLAG(noskid, SF_NOSKID) - GETFLAG(nospeedadjust, SF_NOSPEEDADJUST) - GETFLAG(runonwater, SF_RUNONWATER) - GETFLAG(nojumpspin, SF_NOJUMPSPIN) - GETFLAG(nojumpdamage, SF_NOJUMPDAMAGE) - GETFLAG(stompdamage, SF_STOMPDAMAGE) - GETFLAG(mariodamage, SF_MARIODAMAGE) - GETFLAG(machine, SF_MACHINE) + // these are uppercase so they can be concatenated with SF_ + // 1, true, yes are all valid values + GETFLAG(SUPER) + GETFLAG(SUPERANIMS) + GETFLAG(SUPERSPIN) + GETFLAG(HIRES) + GETFLAG(NOSKID) + GETFLAG(NOSPEEDADJUST) + GETFLAG(RUNONWATER) + GETFLAG(NOJUMPSPIN) + GETFLAG(NOJUMPDAMAGE) + GETFLAG(STOMPDAMAGE) + GETFLAG(MARIODAMAGE) + GETFLAG(MACHINE) #undef GETFLAG else // let's check if it's a sound, otherwise error out From bc7389327a82d88926e6d773f862b85a7e2e27ad Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 9 Aug 2016 13:59:31 +0100 Subject: [PATCH 060/100] Mario invincibility colours now span solely the saturated colours (no white to black, no peach, no brown) --- src/g_game.c | 2 +- src/p_user.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index b92ad8dd4..70b963912 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4350,7 +4350,7 @@ void G_GhostTicker(void) g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); break; case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) - g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS); + g->mo->color = (UINT8)(SKINCOLOR_RED + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RED))); // Passes through all saturated colours break; default: break; diff --git a/src/p_user.c b/src/p_user.c index b85e83d78..89ef6a3ad 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2111,7 +2111,7 @@ static void P_CheckInvincibilityTimer(player_t *player) return; if (mariomode && !player->powers[pw_super]) - player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); + player->mo->color = (UINT8)(SKINCOLOR_RED + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RED))); // Passes through all saturated colours else if (leveltime % (TICRATE/7) == 0) { mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); From 810e1ec041c3c341fcb97190784788bde41e2c84 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 10 Aug 2016 19:48:20 +0100 Subject: [PATCH 061/100] SUPERCOLOR BONANZA COMMIT. * Several new supercolours. - SKINCOLOR_SUPERSILVER1-5 (for fun) - "Silver" - SKINCOLOR_SUPERPERIDOT1-5 (nyeheheh) - "Peridot" - SKINCOLOR_SUPERCYAN1-5 (for fun) - "Cyan" - SKINCOLOR_SUPERPURPLE1-5 (for fun) - "Purple" - SKINCOLOR_SUPERRUST1-5 (mecha/metal sonic) - "Rust" - SKINCOLOR_SUPERTAN1-5 (shadow/silver the hedgehog) - "Tan" * SKINCOLOR_SUPER1-5 renamed to SKINCOLOR_SUPERGOLD1-5, one index for darkest is changed - "Gold" * SKINCOLOR_TSUPER1-5 renamed to SKINCOLOR_SUPERORANGE1-5, ported properly to the new palette - "Orange" * SKINCOLOR_KSUPER1-5 renamed to SKINCOLOR_SUPERRED1-5, ported properly to the new palette - "Red" * new S_SKIN attribute - supercolor - uses an entirely different function to get the names (R_GetSuperColorByName instead of R_GetColorByName) * a fun little secret - typing "god on" in the console whilst super makes the player hyper (visual only, no sparkles - just rainbow flash) - can be removed if no fun is allowed --- src/dehacked.c | 71 ++++-- src/doomdata.h | 2 +- src/doomdef.h | 75 +++++-- src/g_game.c | 10 +- src/hardware/hw_md2.c | 149 +++++++++++-- src/p_user.c | 11 +- src/r_draw.c | 509 +++++++++++++++++++++++++++++++++++++++--- src/r_draw.h | 1 + src/r_things.c | 3 + src/r_things.h | 1 + src/st_stuff.c | 4 +- 11 files changed, 736 insertions(+), 100 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c0bf96cc7..b1ec86055 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6895,24 +6895,61 @@ static const char *COLOR_ENUMS[] = { "MAGENTA", // SKINCOLOR_MAGENTA "PINK", // SKINCOLOR_PINK "ROSY", // SKINCOLOR_ROSY + // Super special awesome Super flashing colors! - "SUPER1", // SKINCOLOR_SUPER1 - "SUPER2", // SKINCOLOR_SUPER2, - "SUPER3", // SKINCOLOR_SUPER3, - "SUPER4", // SKINCOLOR_SUPER4, - "SUPER5", // SKINCOLOR_SUPER5, - // Super Tails - "TSUPER1", // SKINCOLOR_TSUPER1, - "TSUPER2", // SKINCOLOR_TSUPER2, - "TSUPER3", // SKINCOLOR_TSUPER3, - "TSUPER4", // SKINCOLOR_TSUPER4, - "TSUPER5", // SKINCOLOR_TSUPER5, - // Super Knuckles - "KSUPER1", // SKINCOLOR_KSUPER1, - "KSUPER2", // SKINCOLOR_KSUPER2, - "KSUPER3", // SKINCOLOR_KSUPER3, - "KSUPER4", // SKINCOLOR_KSUPER4, - "KSUPER5" // SKINCOLOR_KSUPER5, + "SUPERSILVER1", // SKINCOLOR_SUPERSILVER1 + "SUPERSILVER2", // SKINCOLOR_SUPERSILVER2, + "SUPERSILVER3", // SKINCOLOR_SUPERSILVER3, + "SUPERSILVER4", // SKINCOLOR_SUPERSILVER4, + "SUPERSILVER5", // SKINCOLOR_SUPERSILVER5, + + "SUPERRED1", // SKINCOLOR_SUPERRED1 + "SUPERRED2", // SKINCOLOR_SUPERRED2, + "SUPERRED3", // SKINCOLOR_SUPERRED3, + "SUPERRED4", // SKINCOLOR_SUPERRED4, + "SUPERRED5", // SKINCOLOR_SUPERRED5, + + "SUPERORANGE1", // SKINCOLOR_SUPERORANGE1 + "SUPERORANGE2", // SKINCOLOR_SUPERORANGE2, + "SUPERORANGE3", // SKINCOLOR_SUPERORANGE3, + "SUPERORANGE4", // SKINCOLOR_SUPERORANGE4, + "SUPERORANGE5", // SKINCOLOR_SUPERORANGE5, + + "SUPERGOLD1", // SKINCOLOR_SUPERGOLD1 + "SUPERGOLD2", // SKINCOLOR_SUPERGOLD2, + "SUPERGOLD3", // SKINCOLOR_SUPERGOLD3, + "SUPERGOLD4", // SKINCOLOR_SUPERGOLD4, + "SUPERGOLD5", // SKINCOLOR_SUPERGOLD5, + + "SUPERPERIDOT1", // SKINCOLOR_SUPERPERIDOT1 + "SUPERPERIDOT2", // SKINCOLOR_SUPERPERIDOT2, + "SUPERPERIDOT3", // SKINCOLOR_SUPERPERIDOT3, + "SUPERPERIDOT4", // SKINCOLOR_SUPERPERIDOT4, + "SUPERPERIDOT5", // SKINCOLOR_SUPERPERIDOT5, + + "SUPERCYAN1", // SKINCOLOR_SUPERCYAN1 + "SUPERCYAN2", // SKINCOLOR_SUPERCYAN2, + "SUPERCYAN3", // SKINCOLOR_SUPERCYAN3, + "SUPERCYAN4", // SKINCOLOR_SUPERCYAN4, + "SUPERCYAN5", // SKINCOLOR_SUPERCYAN5, + + "SUPERPURPLE1", // SKINCOLOR_SUPERPURPLE1, + "SUPERPURPLE2", // SKINCOLOR_SUPERPURPLE2, + "SUPERPURPLE3", // SKINCOLOR_SUPERPURPLE3, + "SUPERPURPLE4", // SKINCOLOR_SUPERPURPLE4, + "SUPERPURPLE5", // SKINCOLOR_SUPERPURPLE5, + + "SUPERRUST1", // SKINCOLOR_SUPERRUST1 + "SUPERRUST2", // SKINCOLOR_SUPERRUST2, + "SUPERRUST3", // SKINCOLOR_SUPERRUST3, + "SUPERRUST4", // SKINCOLOR_SUPERRUST4, + "SUPERRUST5", // SKINCOLOR_SUPERRUST5, + + "SUPERTAN1", // SKINCOLOR_SUPERTAN1 + "SUPERTAN2", // SKINCOLOR_SUPERTAN2, + "SUPERTAN3", // SKINCOLOR_SUPERTAN3, + "SUPERTAN4", // SKINCOLOR_SUPERTAN4, + "SUPERTAN5" // SKINCOLOR_SUPERTAN5, }; static const char *const POWERS_LIST[] = { diff --git a/src/doomdata.h b/src/doomdata.h index e916a151f..033cc71b3 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -207,7 +207,7 @@ typedef struct #define ZSHIFT 4 -extern const char *Color_Names[MAXSKINCOLORS]; +extern const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS]; extern const UINT8 Color_Opposite[MAXSKINCOLORS*2]; #define NUMMAPS 1035 diff --git a/src/doomdef.h b/src/doomdef.h index a7a722b42..4de83fda1 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -257,32 +257,69 @@ typedef enum SKINCOLOR_MAGENTA, SKINCOLOR_PINK, SKINCOLOR_ROSY, + //SKINCOLOR_? + //SKINCOLOR_? - // Careful! MAXSKINCOLORS cannot be greater than 0x20! + // Careful! MAXSKINCOLORS cannot be greater than 0x20! Two slots left... MAXSKINCOLORS, // Super special awesome Super flashing colors! - SKINCOLOR_SUPER1 = MAXSKINCOLORS, - SKINCOLOR_SUPER2, - SKINCOLOR_SUPER3, - SKINCOLOR_SUPER4, - SKINCOLOR_SUPER5, + SKINCOLOR_SUPERSILVER1 = MAXSKINCOLORS, + SKINCOLOR_SUPERSILVER2, + SKINCOLOR_SUPERSILVER3, + SKINCOLOR_SUPERSILVER4, + SKINCOLOR_SUPERSILVER5, - // Super Tails - SKINCOLOR_TSUPER1, - SKINCOLOR_TSUPER2, - SKINCOLOR_TSUPER3, - SKINCOLOR_TSUPER4, - SKINCOLOR_TSUPER5, + SKINCOLOR_SUPERRED1, + SKINCOLOR_SUPERRED2, + SKINCOLOR_SUPERRED3, + SKINCOLOR_SUPERRED4, + SKINCOLOR_SUPERRED5, - // Super Knuckles - SKINCOLOR_KSUPER1, - SKINCOLOR_KSUPER2, - SKINCOLOR_KSUPER3, - SKINCOLOR_KSUPER4, - SKINCOLOR_KSUPER5, + SKINCOLOR_SUPERORANGE1, + SKINCOLOR_SUPERORANGE2, + SKINCOLOR_SUPERORANGE3, + SKINCOLOR_SUPERORANGE4, + SKINCOLOR_SUPERORANGE5, - MAXTRANSLATIONS + SKINCOLOR_SUPERGOLD1, + SKINCOLOR_SUPERGOLD2, + SKINCOLOR_SUPERGOLD3, + SKINCOLOR_SUPERGOLD4, + SKINCOLOR_SUPERGOLD5, + + SKINCOLOR_SUPERPERIDOT1, + SKINCOLOR_SUPERPERIDOT2, + SKINCOLOR_SUPERPERIDOT3, + SKINCOLOR_SUPERPERIDOT4, + SKINCOLOR_SUPERPERIDOT5, + + SKINCOLOR_SUPERCYAN1, + SKINCOLOR_SUPERCYAN2, + SKINCOLOR_SUPERCYAN3, + SKINCOLOR_SUPERCYAN4, + SKINCOLOR_SUPERCYAN5, + + SKINCOLOR_SUPERPURPLE1, + SKINCOLOR_SUPERPURPLE2, + SKINCOLOR_SUPERPURPLE3, + SKINCOLOR_SUPERPURPLE4, + SKINCOLOR_SUPERPURPLE5, + + SKINCOLOR_SUPERRUST1, + SKINCOLOR_SUPERRUST2, + SKINCOLOR_SUPERRUST3, + SKINCOLOR_SUPERRUST4, + SKINCOLOR_SUPERRUST5, + + SKINCOLOR_SUPERTAN1, + SKINCOLOR_SUPERTAN2, + SKINCOLOR_SUPERTAN3, + SKINCOLOR_SUPERTAN4, + SKINCOLOR_SUPERTAN5, + + MAXTRANSLATIONS, + NUMSUPERCOLORS = ((MAXTRANSLATIONS - MAXSKINCOLORS)/5) } skincolors_t; // State updates, number of tics / second. diff --git a/src/g_game.c b/src/g_game.c index 70b963912..c12d3b25d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4345,8 +4345,14 @@ void G_GhostTicker(void) // Tick ghost colors (Super and Mario Invincibility flashing) switch(g->color) { - case GHC_SUPER: // Super Sonic (P_DoSuperStuff) - g->mo->color = SKINCOLOR_SUPER1; + case GHC_SUPER: // Super (P_DoSuperStuff) + if (g->mo->skin) + { + skin_t *skin = (skin_t *)g->mo->skin; + g->mo->color = skin->supercolor; + } + else + g->mo->color = SKINCOLOR_SUPERGOLD1; g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); break; case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 6628d1317..f602794c9 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1035,32 +1035,151 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, case SKINCOLOR_ROSY: blendcolor = V_GetColor(202); break; - case SKINCOLOR_SUPER1: + + case SKINCOLOR_SUPERSILVER1: // Super white + blendcolor = V_GetColor(0); + break; + case SKINCOLOR_SUPERSILVER2: + blendcolor = V_GetColor(2); + break; + case SKINCOLOR_SUPERSILVER3: + blendcolor = V_GetColor(4); + break; + case SKINCOLOR_SUPERSILVER4: + blendcolor = V_GetColor(7); + break; + case SKINCOLOR_SUPERSILVER5: + blendcolor = V_GetColor(10); + break; + + case SKINCOLOR_SUPERRED1: // Super red + blendcolor = V_GetColor(208); + break; + case SKINCOLOR_SUPERRED2: + blendcolor = V_GetColor(210); + break; + case SKINCOLOR_SUPERRED3: + blendcolor = V_GetColor(32); + break; + case SKINCOLOR_SUPERRED4: + blendcolor = V_GetColor(33); + break; + case SKINCOLOR_SUPERRED5: + blendcolor = V_GetColor(35); + break; + + case SKINCOLOR_SUPERORANGE1: // Super orange + blendcolor = V_GetColor(208); + break; + case SKINCOLOR_SUPERORANGE2: + blendcolor = V_GetColor(48); + break; + case SKINCOLOR_SUPERORANGE3: + blendcolor = V_GetColor(50); + break; + case SKINCOLOR_SUPERORANGE4: + blendcolor = V_GetColor(54); + break; + case SKINCOLOR_SUPERORANGE5: + blendcolor = V_GetColor(58); + break; + + case SKINCOLOR_SUPERGOLD1: // Super gold blendcolor = V_GetColor(80); break; - case SKINCOLOR_SUPER2: + case SKINCOLOR_SUPERGOLD2: blendcolor = V_GetColor(83); break; - case SKINCOLOR_SUPER3: + case SKINCOLOR_SUPERGOLD3: blendcolor = V_GetColor(73); break; - case SKINCOLOR_SUPER4: + case SKINCOLOR_SUPERGOLD4: blendcolor = V_GetColor(64); break; - case SKINCOLOR_SUPER5: + case SKINCOLOR_SUPERGOLD5: blendcolor = V_GetColor(67); break; - case SKINCOLOR_TSUPER1: - case SKINCOLOR_TSUPER2: - case SKINCOLOR_TSUPER3: - case SKINCOLOR_TSUPER4: - case SKINCOLOR_TSUPER5: - case SKINCOLOR_KSUPER1: - case SKINCOLOR_KSUPER2: - case SKINCOLOR_KSUPER3: - case SKINCOLOR_KSUPER4: - case SKINCOLOR_KSUPER5: + case SKINCOLOR_SUPERPERIDOT1: // Super peridot + blendcolor = V_GetColor(88); + break; + case SKINCOLOR_SUPERPERIDOT2: + blendcolor = V_GetColor(188); + break; + case SKINCOLOR_SUPERPERIDOT3: + blendcolor = V_GetColor(189); + break; + case SKINCOLOR_SUPERPERIDOT4: + blendcolor = V_GetColor(190); + break; + case SKINCOLOR_SUPERPERIDOT5: + blendcolor = V_GetColor(191); + break; + + case SKINCOLOR_SUPERCYAN1: // Super cyan + blendcolor = V_GetColor(128); + break; + case SKINCOLOR_SUPERCYAN2: + blendcolor = V_GetColor(131); + break; + case SKINCOLOR_SUPERCYAN3: + blendcolor = V_GetColor(133); + break; + case SKINCOLOR_SUPERCYAN4: + blendcolor = V_GetColor(134); + break; + case SKINCOLOR_SUPERCYAN5: + blendcolor = V_GetColor(136); + break; + + case SKINCOLOR_SUPERPURPLE1: // Super purple + blendcolor = V_GetColor(144); + break; + case SKINCOLOR_SUPERPURPLE2: + blendcolor = V_GetColor(162); + break; + case SKINCOLOR_SUPERPURPLE3: + blendcolor = V_GetColor(164); + break; + case SKINCOLOR_SUPERPURPLE4: + blendcolor = V_GetColor(166); + break; + case SKINCOLOR_SUPERPURPLE5: + blendcolor = V_GetColor(168); + break; + + case SKINCOLOR_SUPERRUST1: // Super rust + blendcolor = V_GetColor(51); + break; + case SKINCOLOR_SUPERRUST2: + blendcolor = V_GetColor(54); + break; + case SKINCOLOR_SUPERRUST3: + blendcolor = V_GetColor(68); + break; + case SKINCOLOR_SUPERRUST4: + blendcolor = V_GetColor(70); + break; + case SKINCOLOR_SUPERRUST5: + blendcolor = V_GetColor(234); + break; + + case SKINCOLOR_SUPERTAN1: // Super tan + blendcolor = V_GetColor(80); + break; + case SKINCOLOR_SUPERTAN2: + blendcolor = V_GetColor(82); + break; + case SKINCOLOR_SUPERTAN3: + blendcolor = V_GetColor(84); + break; + case SKINCOLOR_SUPERTAN4: + blendcolor = V_GetColor(87); + break; + case SKINCOLOR_SUPERTAN5: + blendcolor = V_GetColor(247); + break; + default: blendcolor = V_GetColor(255); break; diff --git a/src/p_user.c b/src/p_user.c index 89ef6a3ad..6ce9b8f48 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3415,14 +3415,9 @@ static void P_DoSuperStuff(player_t *player) player->mo->health--; } - // future todo: a skin option for this, and possibly more colors - switch (player->skin) - { - case 1: /* Tails */ player->mo->color = SKINCOLOR_TSUPER1; break; - case 2: /* Knux */ player->mo->color = SKINCOLOR_KSUPER1; break; - default: /* everyone */ player->mo->color = SKINCOLOR_SUPER1; break; - } - player->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); + player->mo->color = (player->pflags & PF_GODMODE) + ? (SKINCOLOR_SUPERSILVER1 + 5*((leveltime >> 1) % 7)) // A wholesome easter egg. + : skins[player->skin].supercolor + (unsigned)abs( ( (signed)(leveltime >> 1) % 9) - 4); // This is where super flashing is handled. if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN)) && !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy)) diff --git a/src/r_draw.c b/src/r_draw.c index c56888e0d..47688db03 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -135,7 +135,7 @@ static UINT8** translationtablecache[MAXSKINS + 4] = {NULL}; // See also the enum skincolors_t // TODO Callum: Can this be translated? -const char *Color_Names[MAXSKINCOLORS] = +const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] = { "None", // SKINCOLOR_NONE "White", // SKINCOLOR_WHITE @@ -166,7 +166,17 @@ const char *Color_Names[MAXSKINCOLORS] = "Lavender", // SKINCOLOR_LAVENDER "Magenta", // SKINCOLOR_MAGENTA "Pink", // SKINCOLOR_PINK - "Rosy" // SKINCOLOR_ROSY + "Rosy", // SKINCOLOR_ROSY + // Super behaves by different rules (one name per 5 colours), and will be accessed exclusively via R_GetSuperColorByName instead of R_GetColorByName. + "Silver", // SKINCOLOR_SUPERSILVER1 + "Red", // SKINCOLOR_SUPERRED1 + "Orange", // SKINCOLOR_SUPERORANGE1 + "Gold", // SKINCOLOR_SUPERGOLD1 + "Peridot", // SKINCOLOR_SUPERPERIDOT1 + "Cyan", // SKINCOLOR_SUPERCYAN1 + "Purple", // SKINCOLOR_SUPERPURPLE1 + "Rust", // SKINCOLOR_SUPERRUST1 + "Tan" // SKINCOLOR_SUPERTAN1 }; /* @@ -573,49 +583,186 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U break; // Super colors, from lightest to darkest! - case SKINCOLOR_SUPER1: - // Super White + + // Super silvers. + case SKINCOLOR_SUPERSILVER1: + for (i = 0; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 14; i++) + dest_colormap[starttranscolor + i] = (UINT8)1; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(i-12); + break; + + case SKINCOLOR_SUPERSILVER2: + for (i = 0; i < 3; i++) + dest_colormap[starttranscolor + i] = (UINT8)(i); + dest_colormap[starttranscolor + (i++)] = (UINT8)2; + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)3; + for (; i < 14; i++) + dest_colormap[starttranscolor + i] = (UINT8)4; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(i-9); + break; + + case SKINCOLOR_SUPERSILVER3: + dest_colormap[starttranscolor] = (UINT8)1; + for (i = 1; i < 3; i++) + dest_colormap[starttranscolor + i] = (UINT8)2; + for (; i < 6; i++) + dest_colormap[starttranscolor + i] = (UINT8)3; + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)4; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-12)*2)); + break; + + case SKINCOLOR_SUPERSILVER4: + dest_colormap[starttranscolor] = (UINT8)2; + for (i = 1; i < 3; i++) + dest_colormap[starttranscolor + i] = (UINT8)3; + for (; i < 9; i++) + dest_colormap[starttranscolor + i] = (UINT8)4; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-9)*2)); + break; + + case SKINCOLOR_SUPERSILVER5: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)3; + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)4; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-8)*2)); + break; + + // Super reds. + case SKINCOLOR_SUPERRED1: + for (i = 0; i < 10; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-10) >> 1)); + break; + + case SKINCOLOR_SUPERRED2: + for (i = 0; i < 3; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-3) / 3)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-12) >> 1)); + break; + + case SKINCOLOR_SUPERRED3: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-2) >> 1)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-8) >> 1)); + break; + + case SKINCOLOR_SUPERRED4: + dest_colormap[starttranscolor] = (UINT8)0; + for (i = 1; i < 6; i++) + dest_colormap[starttranscolor + i] = (UINT8)(208 + (i >> 1)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-6) >> 1)); + break; + + case SKINCOLOR_SUPERRED5: + dest_colormap[starttranscolor] = (UINT8)208; + for (i = 1; i < 4; i++) + dest_colormap[starttranscolor + i] = (UINT8)(209 + (i >> 1)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-4) >> 1)); + break; + + // Super oranges. + case SKINCOLOR_SUPERORANGE1: + for (i = 0; i < 10; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + dest_colormap[starttranscolor + (i++)] = (UINT8)208; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-11)); + break; + + case SKINCOLOR_SUPERORANGE2: + for (i = 0; i < 4; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 6; i++) + dest_colormap[starttranscolor + i] = (UINT8)208; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(48 + ((i-6) >> 1)); + break; + + case SKINCOLOR_SUPERORANGE3: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 4; i++) + dest_colormap[starttranscolor + i] = (UINT8)208; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(48 + ((i-4) >> 1)); + break; + + case SKINCOLOR_SUPERORANGE4: + dest_colormap[starttranscolor] = (UINT8)0; + dest_colormap[starttranscolor + 1] = (UINT8)208; + for (i = 2; i < 13; i++) + dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-2)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-13)); + break; + + case SKINCOLOR_SUPERORANGE5: + dest_colormap[starttranscolor] = (UINT8)208; + for (i = 1; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-1)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-12)); + break; + + // Super golds. + case SKINCOLOR_SUPERGOLD1: for (i = 0; i < 10; i++) dest_colormap[starttranscolor + i] = (UINT8)0; // True white for (; i < 12; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)(80); + dest_colormap[starttranscolor + i] = (UINT8)80; for (; i < 15; i++) // White-yellow fade dest_colormap[starttranscolor + i] = (UINT8)(81 + (i-12)); - dest_colormap[starttranscolor + 15] = (UINT8)(72); + dest_colormap[starttranscolor + 15] = (UINT8)72; break; - case SKINCOLOR_SUPER2: - // Super Bright + case SKINCOLOR_SUPERGOLD2: dest_colormap[starttranscolor] = (UINT8)(0); for (i = 1; i < 4; i++) // White-yellow fade dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1)); for (; i < 6; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(83); + dest_colormap[starttranscolor + i] = (UINT8)83; for (; i < 8; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(72); + dest_colormap[starttranscolor + i] = (UINT8)72; for (; i < 14; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(73); + dest_colormap[starttranscolor + i] = (UINT8)73; for (; i < 16; i++) // With a fine golden finish! :3 dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-14)); break; - case SKINCOLOR_SUPER3: - // Super Yellow + case SKINCOLOR_SUPERGOLD3: for (i = 0; i < 2; i++) // White-yellow fade dest_colormap[starttranscolor + i] = (UINT8)(81 + i); for (; i < 4; i++) - dest_colormap[starttranscolor + i] = (UINT8)(83); + dest_colormap[starttranscolor + i] = (UINT8)83; for (; i < 6; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(72); + dest_colormap[starttranscolor + i] = (UINT8)72; for (; i < 12; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(73); + dest_colormap[starttranscolor + i] = (UINT8)73; for (; i < 16; i++) // With a fine golden finish! :3 dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-12)); break; - case SKINCOLOR_SUPER4: - // "The SSNTails" - dest_colormap[starttranscolor] = 83; // Golden shine + case SKINCOLOR_SUPERGOLD4: // "The SSNTails" + dest_colormap[starttranscolor] = (UINT8)83; // Golden shine for (i = 1; i < 3; i++) // Yellow dest_colormap[starttranscolor + i] = (UINT8)(72); for (; i < 9; i++) // Yellow @@ -624,30 +771,309 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-9)); break; - case SKINCOLOR_SUPER5: - // Golden Delicious + case SKINCOLOR_SUPERGOLD5: // Golden Delicious for (i = 0; i < 2; i++) // Yellow dest_colormap[starttranscolor + i] = (UINT8)(72); for (; i < 8; i++) // Yellow dest_colormap[starttranscolor + i] = (UINT8)(73); - for (; i < 15; i++) // With a fine golden finish! :3 + for (; i < 16; i++) // With a fine golden finish! :3 dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-8)); - dest_colormap[starttranscolor + 15] = (UINT8)63; break; - // Super Tails and Knuckles, who really should be dummied out by now - case SKINCOLOR_TSUPER1: - case SKINCOLOR_TSUPER2: - case SKINCOLOR_TSUPER3: - case SKINCOLOR_TSUPER4: - case SKINCOLOR_TSUPER5: - case SKINCOLOR_KSUPER1: - case SKINCOLOR_KSUPER2: - case SKINCOLOR_KSUPER3: - case SKINCOLOR_KSUPER4: - case SKINCOLOR_KSUPER5: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = 0xFF; + // Super peridots. (nyeheheheh) + case SKINCOLOR_SUPERPERIDOT1: + for (i = 0; i < 10; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 13; i++) + dest_colormap[starttranscolor + i] = (UINT8)88; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)188; + break; + + case SKINCOLOR_SUPERPERIDOT2: + dest_colormap[starttranscolor] = (UINT8)(0); + for (i = 1; i < 4; i++) + dest_colormap[starttranscolor + i] = (UINT8)88; + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)188; + for (; i < 14; i++) + dest_colormap[starttranscolor + i] = (UINT8)189; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)190; + break; + + case SKINCOLOR_SUPERPERIDOT3: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)88; + for (; i < 6; i++) + dest_colormap[starttranscolor + i] = (UINT8)188; + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)189; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-12) >> 1)); + break; + + case SKINCOLOR_SUPERPERIDOT4: + dest_colormap[starttranscolor] = (UINT8)88; + for (i = 1; i < 3; i++) + dest_colormap[starttranscolor + i] = (UINT8)188; + for (; i < 9; i++) + dest_colormap[starttranscolor + i] = (UINT8)189; + for (; i < 13; i++) + dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-9) >> 1)); + for (; i < 15; i++) + dest_colormap[starttranscolor + i] = (UINT8)94; + dest_colormap[starttranscolor + i] = (UINT8)95; + break; + + case SKINCOLOR_SUPERPERIDOT5: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)188; + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)189; + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-8) >> 1)); + for (; i < 14; i++) + dest_colormap[starttranscolor + i] = (UINT8)94; + dest_colormap[starttranscolor + (i++)] = (UINT8)95; + dest_colormap[starttranscolor + i] = (UINT8)119; + break; + + // Super cyans. + case SKINCOLOR_SUPERCYAN1: + for (i = 0; i < 10; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)128; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(129 + (i-12)); + break; + + case SKINCOLOR_SUPERCYAN2: + dest_colormap[starttranscolor] = (UINT8)0; + for (i = 1; i < 4; i++) + dest_colormap[starttranscolor + i] = (UINT8)(128 + (i-1)); + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)(131 + ((i-4) >> 1)); + for (; i < 14; i++) + dest_colormap[starttranscolor + i] = (UINT8)133; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)134; + break; + + case SKINCOLOR_SUPERCYAN3: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)(129 + i); + for (; i < 6; i++) + dest_colormap[starttranscolor + i] = (UINT8)(131 + ((i-2) >> 1)); + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)133; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-12) >> 1)); + break; + + case SKINCOLOR_SUPERCYAN4: + dest_colormap[starttranscolor] = (UINT8)131; + for (i = 1; i < 3; i++) + dest_colormap[starttranscolor + i] = (UINT8)132; + for (; i < 9; i++) + dest_colormap[starttranscolor + i] = (UINT8)133; + for (; i < 13; i++) + dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-9) >> 1)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(136 + (i-13)); + break; + + case SKINCOLOR_SUPERCYAN5: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)132; + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)133; + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-8) >> 1)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(136 + (i-12)); + break; + + // Super purples. + case SKINCOLOR_SUPERPURPLE1: + for (i = 0; i < 10; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)144; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(160 + (i-12)); + break; + + case SKINCOLOR_SUPERPURPLE2: + dest_colormap[starttranscolor] = (UINT8)0; + dest_colormap[starttranscolor + 1] = (UINT8)144; + for (i = 2; i < 4; i++) + dest_colormap[starttranscolor + i] = (UINT8)(160 + (i-2)); + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)(162 + ((i-4) >> 1)); + for (; i < 14; i++) + dest_colormap[starttranscolor + i] = (UINT8)164; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)165; + break; + + case SKINCOLOR_SUPERPURPLE3: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)(160 + i); + for (; i < 6; i++) + dest_colormap[starttranscolor + i] = (UINT8)(162 + ((i-2) >> 1)); + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)164; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-12) >> 1)); + break; + + case SKINCOLOR_SUPERPURPLE4: + dest_colormap[starttranscolor] = (UINT8)162; + for (i = 1; i < 3; i++) + dest_colormap[starttranscolor + i] = (UINT8)163; + for (; i < 9; i++) + dest_colormap[starttranscolor + i] = (UINT8)164; + for (; i < 13; i++) + dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-9) >> 1)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(167 + (i-13)); + break; + + case SKINCOLOR_SUPERPURPLE5: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)163; + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)164; + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-8) >> 1)); + for (; i < 15; i++) + dest_colormap[starttranscolor + i] = (UINT8)(167 + (i-12)); + dest_colormap[starttranscolor + i] = (UINT8)253; + break; + + // Super rusts. + case SKINCOLOR_SUPERRUST1: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 5; i++) + dest_colormap[starttranscolor + i] = (UINT8)208; + for (; i < 7; i++) + dest_colormap[starttranscolor + i] = (UINT8)48; + for (; i < 10; i++) + dest_colormap[starttranscolor + i] = (UINT8)(49 + (i-7)); + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)(55 + ((i-10)*3)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-11)); + break; + + case SKINCOLOR_SUPERRUST2: + for (i = 0; i < 4; i++) + dest_colormap[starttranscolor + i] = (UINT8)48; + for (; i < 9; i++) + dest_colormap[starttranscolor + i] = (UINT8)(49 + (i-4)); + for (; i < 11; i++) + dest_colormap[starttranscolor + i] = (UINT8)(56 + ((i-9)*2)); + for (; i < 15; i++) + dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-11)); + dest_colormap[starttranscolor + i] = (UINT8)71; + break; + + case SKINCOLOR_SUPERRUST3: + dest_colormap[starttranscolor] = (UINT8)49; + for (i = 1; i < 3; i++) + dest_colormap[starttranscolor + i] = (UINT8)50; + for (; i < 5; i++) + dest_colormap[starttranscolor + i] = (UINT8)(51 + (i-3)); + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)(54 + (i-5)); + dest_colormap[starttranscolor + (i++)] = (UINT8)58; + for (; i < 15; i++) + dest_colormap[starttranscolor + i] = (UINT8)(68 + ((i-7) >> 1)); + dest_colormap[starttranscolor + i] = (UINT8)46; + break; + + case SKINCOLOR_SUPERRUST4: + dest_colormap[starttranscolor] = (UINT8)83; + dest_colormap[starttranscolor + 1] = (UINT8)72; + for (i = 2; i < 6; i++) + dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-2)); + for (; i < 14; i++) + dest_colormap[starttranscolor + i] = (UINT8)(68 + ((i-6) >> 1)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)46; + break; + + case SKINCOLOR_SUPERRUST5: + for (i = 0; i < 3; i++) + dest_colormap[starttranscolor + i] = (UINT8)(64 + i); + for (; i < 7; i++) + dest_colormap[starttranscolor + i] = (UINT8)(67 + ((i-3) >> 1)); + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)(233 + (i-7)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(238 + ((i-12) >> 1)); + break; + + case SKINCOLOR_SUPERTAN1: + for (i = 0; i < 10; i++) + dest_colormap[starttranscolor + i] = (UINT8)0; + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-10) >> 1)); + break; + + case SKINCOLOR_SUPERTAN2: + dest_colormap[starttranscolor] = (UINT8)0; + for (i = 1; i < 7; i++) + dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-1) >> 1)); + dest_colormap[starttranscolor + (i++)] = (UINT8)82; + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)84; + for (; i < 15; i++) + dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-12)); + dest_colormap[starttranscolor + i] = (UINT8)245; + break; + + case SKINCOLOR_SUPERTAN3: + dest_colormap[starttranscolor] = (UINT8)80; + for (i = 1; i < 5; i++) + dest_colormap[starttranscolor + i] = (UINT8)(81 + ((i-1) >> 1)); + dest_colormap[starttranscolor + (i++)] = (UINT8)82; + for (; i < 10; i++) + dest_colormap[starttranscolor + i] = (UINT8)84; + for (; i < 13; i++) + dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-10)); + for (; i < 16; i++) + dest_colormap[starttranscolor + i] = (UINT8)(245 + ((i-13)*2)); + break; + + case SKINCOLOR_SUPERTAN4: + dest_colormap[starttranscolor] = (UINT8)81; + for (i = 1; i < 5; i++) + dest_colormap[starttranscolor + i] = (UINT8)82; + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)84; + for (; i < 11; i++) + dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-8)); + for (; i < 15; i++) + dest_colormap[starttranscolor + i] = (UINT8)(245 + ((i-11)*2)); + dest_colormap[starttranscolor + i] = (UINT8)237; + break; + + case SKINCOLOR_SUPERTAN5: + for (i = 0; i < 2; i++) + dest_colormap[starttranscolor + i] = (UINT8)82; + for (; i < 5; i++) + dest_colormap[starttranscolor + i] = (UINT8)84; + for (; i < 8; i++) + dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-5)); + for (; i < 12; i++) + dest_colormap[starttranscolor + i] = (UINT8)(245 + (i-8)); + for (; i < 15; i++) + dest_colormap[starttranscolor + i] = (UINT8)(237 + (i-12)); + dest_colormap[starttranscolor + i] = (UINT8)239; break; default: @@ -731,6 +1157,17 @@ UINT8 R_GetColorByName(const char *name) return 0; } +UINT8 R_GetSuperColorByName(const char *name) +{ + UINT8 color = (UINT8)atoi(name); + if (color > MAXSKINCOLORS && color < MAXTRANSLATIONS) + return color; + for (color = 0; color < NUMSUPERCOLORS; color++) + if (!stricmp(Color_Names[color + MAXSKINCOLORS], name)) + return ((color*5) + MAXSKINCOLORS); + return 0; +} + // ========================================================================== // COMMON DRAWER FOR 8 AND 16 BIT COLOR MODES // ========================================================================== diff --git a/src/r_draw.h b/src/r_draw.h index 6d85bd6a5..60c3c9db6 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -111,6 +111,7 @@ void R_InitTranslationTables(void); UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags); void R_FlushTranslationColormapCache(void); UINT8 R_GetColorByName(const char *name); +UINT8 R_GetSuperColorByName(const char *name); // Custom player skin translation void R_InitViewBuffer(INT32 width, INT32 height); diff --git a/src/r_things.c b/src/r_things.c index 7d7f7f093..9e63f0304 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2288,6 +2288,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->starttranscolor = 96; skin->prefcolor = SKINCOLOR_GREEN; + skin->supercolor = SKINCOLOR_SUPERGOLD1; skin->prefoppositecolor = 0; // use tables skin->normalspeed = 36<supercolor = R_GetSuperColorByName(value); #define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value)); GETFLOAT(jumpfactor) diff --git a/src/r_things.h b/src/r_things.h index 651950f05..d4944734c 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -103,6 +103,7 @@ typedef struct // Definable color translation table UINT8 starttranscolor; UINT8 prefcolor; + UINT8 supercolor; UINT8 prefoppositecolor; // if 0 use tables instead fixed_t highresscale; // scale of highres, default is 0.5 diff --git a/src/st_stuff.c b/src/st_stuff.c index b37a173e3..2a1c4956a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -893,7 +893,7 @@ static void ST_drawFirstPersonHUD(void) // [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold static skincolors_t linkColor[14] = {SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, - SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPER4, SKINCOLOR_PINK, SKINCOLOR_RED, + SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED, SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD}; static void ST_drawNightsRecords(void) @@ -1299,7 +1299,7 @@ static void ST_drawNiGHTSHUD(void) nightsnum, SKINCOLOR_RED); else ST_DrawNightsOverlayNum(160 + numbersize, STRINGY(12), SPLITFLAGS(V_SNAPTOTOP), realnightstime, - nightsnum, SKINCOLOR_SUPER4); + nightsnum, SKINCOLOR_SUPERGOLD4); // Show exact time in debug if (cv_debug & DBG_NIGHTSBASIC) From b3b6d5c4f9b633a39e309fc6ce2b58c6769d1d16 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 10 Aug 2016 19:54:07 +0100 Subject: [PATCH 062/100] woops, renamed superwhite to supersilver during writing and forgot to change this comment --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index f602794c9..fa4699810 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1036,7 +1036,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, blendcolor = V_GetColor(202); break; - case SKINCOLOR_SUPERSILVER1: // Super white + case SKINCOLOR_SUPERSILVER1: // Super silver blendcolor = V_GetColor(0); break; case SKINCOLOR_SUPERSILVER2: From 8f5258fc22130727864d97a739c5a454a3757092 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 10 Aug 2016 20:31:18 +0100 Subject: [PATCH 063/100] Two changes to the supercolor stuff. * Don't allow arbitrary numbers to be used for a skin's supercolor, only strings. * Devmode is no fun allowed mode, so turn off the god hyper flash there. --- src/p_user.c | 2 +- src/r_draw.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 6ce9b8f48..e694d08a1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3415,7 +3415,7 @@ static void P_DoSuperStuff(player_t *player) player->mo->health--; } - player->mo->color = (player->pflags & PF_GODMODE) + player->mo->color = (player->pflags & PF_GODMODE && cv_debug == 0) ? (SKINCOLOR_SUPERSILVER1 + 5*((leveltime >> 1) % 7)) // A wholesome easter egg. : skins[player->skin].supercolor + (unsigned)abs( ( (signed)(leveltime >> 1) % 9) - 4); // This is where super flashing is handled. diff --git a/src/r_draw.c b/src/r_draw.c index 47688db03..b96afad98 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -1159,9 +1159,9 @@ UINT8 R_GetColorByName(const char *name) UINT8 R_GetSuperColorByName(const char *name) { - UINT8 color = (UINT8)atoi(name); - if (color > MAXSKINCOLORS && color < MAXTRANSLATIONS) - return color; + UINT8 color; /* = (UINT8)atoi(name); -- This isn't relevant to S_SKIN, which is the only way it's accessible right now. Let's simplify things. + if (color > MAXSKINCOLORS && color < MAXTRANSLATIONS && !((color - MAXSKINCOLORS) % 5)) + return color;*/ for (color = 0; color < NUMSUPERCOLORS; color++) if (!stricmp(Color_Names[color + MAXSKINCOLORS], name)) return ((color*5) + MAXSKINCOLORS); From 8b333f5933d477d02cce876bb8cecb8dbc1885fe Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 10 Aug 2016 22:47:42 +0100 Subject: [PATCH 064/100] Forgot a comment. --- src/r_draw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/r_draw.c b/src/r_draw.c index b96afad98..9188e082e 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -1017,6 +1017,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U dest_colormap[starttranscolor + i] = (UINT8)(238 + ((i-12) >> 1)); break; + // Super tans. case SKINCOLOR_SUPERTAN1: for (i = 0; i < 10; i++) dest_colormap[starttranscolor + i] = (UINT8)0; From a6f4178023a0d899c7ad06b0adc102bf2a7a16e2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 10 Aug 2016 23:51:35 +0100 Subject: [PATCH 065/100] Rob requested new NiGHTS link colours, his wish is my command. (This is only vaguely appropriate for this branch, but the boat sailed on a specific Reduced_Palette branch a while ago.) --- src/st_stuff.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 2a1c4956a..f19467bb5 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -890,11 +890,19 @@ static void ST_drawFirstPersonHUD(void) V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, p); } -// [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold -static skincolors_t linkColor[14] = +// 2.0-1: [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold +/*#define NUMLINKCOLORS 14 +static skincolors_t linkColor[NUMLINKCOLORS] = {SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED, - SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD}; + SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/ + +// 2.2+: (unix time 1470866042) Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot +#define NUMLINKCOLORS 13 +static skincolors_t linkColor[NUMLINKCOLORS] = +{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL, + SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, + SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}; static void ST_drawNightsRecords(void) { @@ -994,7 +1002,7 @@ static void ST_drawNiGHTSHUD(void) #endif stplyr->linkcount > minlink) { - skincolors_t colornum = linkColor[((stplyr->linkcount-1) / 5) % (sizeof(linkColor) / sizeof(skincolors_t))]; + skincolors_t colornum = linkColor[((stplyr->linkcount-1) / 5) % NUMLINKCOLORS]; if (stplyr->powers[pw_nights_linkfreeze]) colornum = SKINCOLOR_WHITE; From 0c3256fa141834e46f03229c831a0ca1fd137b3c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 12 Aug 2016 02:57:37 +0100 Subject: [PATCH 066/100] NiGHTS is now spr2-ised. i'll upload the relevant files and etc to the ftp * if you can turn SF_SUPER, flash your skin's supercolor, otherwise be your normal color * if your skin doesn't have a SPR2_NGT0 (horizontal fly), use Sonic's (this will hopefully be replaced by 2.2 with sprites of NiGHTS themselves) * MT_NIGHTSCHAR made irrelevant, everything follows actor->target instead of actor->target->tracer now * emerald is now player->mo->tracer instead of player->mo->tracer->target * nightopian helpers flash for the 35 tics before they disappear * nights capsule makes boss explosions/noises now (i can change it back i just like it better) * drill off into the sky instead of fly up in floating pose (but no noise yet) ALSO: * default maxdash is now 70 * forgot to add supercolor to lua, it is there now * SPR2_SMSL renamed to SPR2_SSTN (stun) * any player with a skincolor that's in the super range is set to FF_FULLBRIGHT at state-set time, so no need to keep super players non-fullbright just because they use spin stuff --- src/dehacked.c | 142 +++++++++------------------- src/info.c | 226 ++++++++++++++++++-------------------------- src/info.h | 233 +++++++++++++++++++++------------------------- src/lua_skinlib.c | 5 + src/p_enemy.c | 15 ++- src/p_inter.c | 10 +- src/p_mobj.c | 83 ++++++++++++++++- src/p_user.c | 204 ++++++++++++++++------------------------ src/r_things.c | 2 +- 9 files changed, 424 insertions(+), 496 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b1ec86055..a512e1029 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3859,6 +3859,50 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Level end sign (uses player sprite) "S_PLAY_SIGN", + // NiGHTS character (uses player sprite) + "S_PLAY_NIGHTS_TRANS", + "S_PLAY_NIGHTS_TRANS2", + "S_PLAY_NIGHTS_TRANS3", + "S_PLAY_NIGHTS_TRANS4", + "S_PLAY_NIGHTS_TRANS5", + "S_PLAY_NIGHTS_TRANS6", + "S_PLAY_NIGHTS_TRANS7", + "S_PLAY_NIGHTS_TRANS8", + "S_PLAY_NIGHTS_TRANS9", + + "S_PLAY_NIGHTS_STAND", + "S_PLAY_NIGHTS_FLOAT", + "S_PLAY_NIGHTS_PAIN", + "S_PLAY_NIGHTS_PULL", + "S_PLAY_NIGHTS_ATTACK", + + "S_PLAY_NIGHTS_FLY0", + "S_PLAY_NIGHTS_DRILL0", + "S_PLAY_NIGHTS_FLY1", + "S_PLAY_NIGHTS_DRILL1", + "S_PLAY_NIGHTS_FLY2", + "S_PLAY_NIGHTS_DRILL2", + "S_PLAY_NIGHTS_FLY3", + "S_PLAY_NIGHTS_DRILL3", + "S_PLAY_NIGHTS_FLY4", + "S_PLAY_NIGHTS_DRILL4", + "S_PLAY_NIGHTS_FLY5", + "S_PLAY_NIGHTS_DRILL5", + "S_PLAY_NIGHTS_FLY6", + "S_PLAY_NIGHTS_DRILL6", + "S_PLAY_NIGHTS_FLY7", + "S_PLAY_NIGHTS_DRILL7", + "S_PLAY_NIGHTS_FLY8", + "S_PLAY_NIGHTS_DRILL8", + "S_PLAY_NIGHTS_FLY9", + "S_PLAY_NIGHTS_DRILL9", + "S_PLAY_NIGHTS_FLYA", + "S_PLAY_NIGHTS_DRILLA", + "S_PLAY_NIGHTS_FLYB", + "S_PLAY_NIGHTS_DRILLB", + "S_PLAY_NIGHTS_FLYC", + "S_PLAY_NIGHTS_DRILLC", + // Blue Crawla "S_POSS_STND", "S_POSS_RUN1", @@ -5854,93 +5898,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_NIGHTSGOAL3", "S_NIGHTSGOAL4", - "S_NIGHTSFLY1A", - "S_NIGHTSFLY1B", - "S_NIGHTSDRILL1A", - "S_NIGHTSDRILL1B", - "S_NIGHTSDRILL1C", - "S_NIGHTSDRILL1D", - "S_NIGHTSFLY2A", - "S_NIGHTSFLY2B", - "S_NIGHTSDRILL2A", - "S_NIGHTSDRILL2B", - "S_NIGHTSDRILL2C", - "S_NIGHTSDRILL2D", - "S_NIGHTSFLY3A", - "S_NIGHTSFLY3B", - "S_NIGHTSDRILL3A", - "S_NIGHTSDRILL3B", - "S_NIGHTSDRILL3C", - "S_NIGHTSDRILL3D", - "S_NIGHTSFLY4A", - "S_NIGHTSFLY4B", - "S_NIGHTSDRILL4A", - "S_NIGHTSDRILL4B", - "S_NIGHTSDRILL4C", - "S_NIGHTSDRILL4D", - "S_NIGHTSFLY5A", - "S_NIGHTSFLY5B", - "S_NIGHTSDRILL5A", - "S_NIGHTSDRILL5B", - "S_NIGHTSDRILL5C", - "S_NIGHTSDRILL5D", - "S_NIGHTSFLY6A", - "S_NIGHTSFLY6B", - "S_NIGHTSDRILL6A", - "S_NIGHTSDRILL6B", - "S_NIGHTSDRILL6C", - "S_NIGHTSDRILL6D", - "S_NIGHTSFLY7A", - "S_NIGHTSFLY7B", - "S_NIGHTSDRILL7A", - "S_NIGHTSDRILL7B", - "S_NIGHTSDRILL7C", - "S_NIGHTSDRILL7D", - "S_NIGHTSFLY8A", - "S_NIGHTSFLY8B", - "S_NIGHTSDRILL8A", - "S_NIGHTSDRILL8B", - "S_NIGHTSDRILL8C", - "S_NIGHTSDRILL8D", - "S_NIGHTSFLY9A", - "S_NIGHTSFLY9B", - "S_NIGHTSDRILL9A", - "S_NIGHTSDRILL9B", - "S_NIGHTSDRILL9C", - "S_NIGHTSDRILL9D", - "S_NIGHTSHURT1", - "S_NIGHTSHURT2", - "S_NIGHTSHURT3", - "S_NIGHTSHURT4", - "S_NIGHTSHURT5", - "S_NIGHTSHURT6", - "S_NIGHTSHURT7", - "S_NIGHTSHURT8", - "S_NIGHTSHURT9", - "S_NIGHTSHURT10", - "S_NIGHTSHURT11", - "S_NIGHTSHURT12", - "S_NIGHTSHURT13", - "S_NIGHTSHURT14", - "S_NIGHTSHURT15", - "S_NIGHTSHURT16", - "S_NIGHTSHURT17", - "S_NIGHTSHURT18", - "S_NIGHTSHURT19", - "S_NIGHTSHURT20", - "S_NIGHTSHURT21", - "S_NIGHTSHURT22", - "S_NIGHTSHURT23", - "S_NIGHTSHURT24", - "S_NIGHTSHURT25", - "S_NIGHTSHURT26", - "S_NIGHTSHURT27", - "S_NIGHTSHURT28", - "S_NIGHTSHURT29", - "S_NIGHTSHURT30", - "S_NIGHTSHURT31", - "S_NIGHTSHURT32", - "S_NIGHTSPARKLE1", "S_NIGHTSPARKLE2", "S_NIGHTSPARKLE3", @@ -6037,16 +5994,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_CRUMBLE1", "S_CRUMBLE2", - "S_SUPERTRANS1", - "S_SUPERTRANS2", - "S_SUPERTRANS3", - "S_SUPERTRANS4", - "S_SUPERTRANS5", - "S_SUPERTRANS6", - "S_SUPERTRANS7", - "S_SUPERTRANS8", - "S_SUPERTRANS9", - // Spark "S_SPRK1", "S_SPRK2", @@ -6603,7 +6550,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_AXISTRANSFERLINE", "MT_NIGHTSDRONE", "MT_NIGHTSGOAL", - "MT_NIGHTSCHAR", "MT_NIGHTSPARKLE", "MT_NIGHTSLOOPHELPER", "MT_NIGHTSBUMPER", // NiGHTS Bumper diff --git a/src/info.c b/src/info.c index 51b25e4b7..aeba7dcab 100644 --- a/src/info.c +++ b/src/info.c @@ -96,7 +96,7 @@ char spr2names[NUMPLAYERSPRITES][5] = "SRUN", "SPEE", "SPAN", - "SMSL", + "SSTN", "SDTH", "SDRN", "SSPN", @@ -106,7 +106,42 @@ char spr2names[NUMPLAYERSPRITES][5] = "SFAL", "SEDG", "SRID", - "SFLT" + "SFLT", + + "NTRN", + "NSTD", + "NFLT", + "NPAN", + "NPUL", + "NATK", + + "NGT0", + "NGT1", + "NGT2", + "NGT3", + "NGT4", + "NGT5", + "NGT6", + "NGT7", + "NGT8", + "NGT9", + "NGTA", + "NGTB", + "NGTC", + + "DRL0", + "DRL1", + "DRL2", + "DRL3", + "DRL4", + "DRL5", + "DRL6", + "DRL7", + "DRL8", + "DRL9", + "DRLA", + "DRLB", + "DRLC" }; enum playersprite free_spr2 = SPR2_FIRSTFREESLOT; @@ -176,7 +211,7 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN {SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL {SPR_PLAY, SPR2_SPAN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN - {SPR_PLAY, SPR2_SMSL, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN + {SPR_PLAY, SPR2_SSTN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN {SPR_PLAY, SPR2_SDTH, 4, {NULL}, 0, 0, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD {SPR_PLAY, SPR2_SDRN, 4, {NULL}, 0, 0, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN {SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN @@ -192,12 +227,12 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2 {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3 - {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4 - {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5 - {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6 - {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7 - {SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8 - {SPR_PLAY, SPR2_TRNS, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8 + {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9 {SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY @@ -211,6 +246,52 @@ state_t states[NUMSTATES] = // Level end sign (uses player sprite) {SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN + // NiGHTS Player, transforming + {SPR_PLAY, SPR2_NTRN, 4, {A_Scream}, 0, 0, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS + {SPR_PLAY, SPR2_NTRN, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS3}, // S_PLAY_NIGHTS_TRANS2 + {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS4}, // S_PLAY_NIGHTS_TRANS3 + {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS5}, // S_PLAY_NIGHTS_TRANS4 + {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5 + {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS7}, // S_PLAY_NIGHTS_TRANS6 + {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS8}, // S_PLAY_NIGHTS_TRANS7 + {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS9}, // S_PLAY_NIGHTS_TRANS8 + {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS9 + + // NiGHTS Player, Stand, Floating, Pain, Pull and Attack + {SPR_PLAY, SPR2_NSTD, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_STAND}, // S_PLAY_NIGHTS_STAND + {SPR_PLAY, SPR2_NFLT, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_FLOAT + {SPR_PLAY, SPR2_NPAN, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_PAIN}, // S_PLAY_NIGHTS_PAIN + {SPR_PLAY, SPR2_NPUL, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_PULL}, // S_PLAY_NIGHTS_PULL + {SPR_PLAY, SPR2_NATK, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_ATTACK}, // S_PLAY_NIGHTS_ATTACK + + // NiGHTS Player, Flying and Drilling + {SPR_PLAY, SPR2_NGT0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY0}, // S_PLAY_NIGHTS_FLY0 + {SPR_PLAY, SPR2_DRL0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL0}, // S_PLAY_NIGHTS_DRILL0 + {SPR_PLAY, SPR2_NGT1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY1}, // S_PLAY_NIGHTS_FLY1 + {SPR_PLAY, SPR2_DRL1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL1}, // S_PLAY_NIGHTS_DRILL1 + {SPR_PLAY, SPR2_NGT2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY2}, // S_PLAY_NIGHTS_FLY2 + {SPR_PLAY, SPR2_DRL2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL2}, // S_PLAY_NIGHTS_DRILL2 + {SPR_PLAY, SPR2_NGT3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY3}, // S_PLAY_NIGHTS_FLY3 + {SPR_PLAY, SPR2_DRL3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL3}, // S_PLAY_NIGHTS_DRILL3 + {SPR_PLAY, SPR2_NGT4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY4}, // S_PLAY_NIGHTS_FLY4 + {SPR_PLAY, SPR2_DRL4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL4}, // S_PLAY_NIGHTS_DRILL4 + {SPR_PLAY, SPR2_NGT5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY5}, // S_PLAY_NIGHTS_FLY5 + {SPR_PLAY, SPR2_DRL5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL5}, // S_PLAY_NIGHTS_DRILL5 + {SPR_PLAY, SPR2_NGT6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY6}, // S_PLAY_NIGHTS_FLY6 + {SPR_PLAY, SPR2_DRL6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL6}, // S_PLAY_NIGHTS_DRILL6 + {SPR_PLAY, SPR2_NGT7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY7}, // S_PLAY_NIGHTS_FLY7 + {SPR_PLAY, SPR2_DRL7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL7}, // S_PLAY_NIGHTS_DRILL7 + {SPR_PLAY, SPR2_NGT8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY8}, // S_PLAY_NIGHTS_FLY8 + {SPR_PLAY, SPR2_DRL8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL8}, // S_PLAY_NIGHTS_DRILL8 + {SPR_PLAY, SPR2_NGT9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY9}, // S_PLAY_NIGHTS_FLY9 + {SPR_PLAY, SPR2_DRL9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL9}, // S_PLAY_NIGHTS_DRILL9 + {SPR_PLAY, SPR2_NGTA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYA}, // S_PLAY_NIGHTS_FLYA + {SPR_PLAY, SPR2_DRLA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLA}, // S_PLAY_NIGHTS_DRILLA + {SPR_PLAY, SPR2_NGTB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYB}, // S_PLAY_NIGHTS_FLYB + {SPR_PLAY, SPR2_DRLB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLB}, // S_PLAY_NIGHTS_DRILLB + {SPR_PLAY, SPR2_NGTC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYC}, // S_PLAY_NIGHTS_FLYC + {SPR_PLAY, SPR2_DRLC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLC}, // S_PLAY_NIGHTS_DRILLC + // Blue Crawla {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND {SPR_POSS, 0, 3, {A_Chase}, 0, 0, S_POSS_RUN2}, // S_POSS_RUN1 @@ -2266,96 +2347,6 @@ state_t states[NUMSTATES] = {SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSGOAL4}, // S_NIGHTSGOAL3 {SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSGOAL1}, // S_NIGHTSGOAL4 - // Nights Player, Flying and Drilling - {SPR_SUPE, 0, 1, {NULL}, 0, 0, S_NIGHTSFLY1B}, // S_NIGHTSFLY1A - {SPR_SUPE, 1, 1, {NULL}, 0, 0, S_NIGHTSFLY1A}, // S_NIGHTSFLY1B - {SPR_NDRL, 0, 2, {NULL}, 0, 0, S_NIGHTSDRILL1B}, // S_NIGHTSDRILL1A - {SPR_NDRL, 1, 2, {NULL}, 0, 0, S_NIGHTSDRILL1C}, // S_NIGHTSDRILL1B - {SPR_NDRL, 2, 2, {NULL}, 0, 0, S_NIGHTSDRILL1D}, // S_NIGHTSDRILL1C - {SPR_NDRL, 3, 2, {NULL}, 0, 0, S_NIGHTSDRILL1A}, // S_NIGHTSDRILL1D - {SPR_SUPE, 2, 1, {NULL}, 0, 0, S_NIGHTSFLY2B}, // S_NIGHTSFLY2A - {SPR_SUPE, 3, 1, {NULL}, 0, 0, S_NIGHTSFLY2A}, // S_NIGHTSFLY2B - {SPR_NDRL, 4, 2, {NULL}, 0, 0, S_NIGHTSDRILL2B}, // S_NIGHTSDRILL2A - {SPR_NDRL, 5, 2, {NULL}, 0, 0, S_NIGHTSDRILL2C}, // S_NIGHTSDRILL2B - {SPR_NDRL, 6, 2, {NULL}, 0, 0, S_NIGHTSDRILL2D}, // S_NIGHTSDRILL2C - {SPR_NDRL, 7, 2, {NULL}, 0, 0, S_NIGHTSDRILL2A}, // S_NIGHTSDRILL2D - {SPR_SUPE, 4, 1, {NULL}, 0, 0, S_NIGHTSFLY3B}, // S_NIGHTSFLY3A - {SPR_SUPE, 5, 1, {NULL}, 0, 0, S_NIGHTSFLY3A}, // S_NIGHTSFLY3B - {SPR_NDRL, 8, 2, {NULL}, 0, 0, S_NIGHTSDRILL3B}, // S_NIGHTSDRILL3A - {SPR_NDRL, 9, 2, {NULL}, 0, 0, S_NIGHTSDRILL3C}, // S_NIGHTSDRILL3B - {SPR_NDRL, 10, 2, {NULL}, 0, 0, S_NIGHTSDRILL3D}, // S_NIGHTSDRILL3C - {SPR_NDRL, 11, 2, {NULL}, 0, 0, S_NIGHTSDRILL3A}, // S_NIGHTSDRILL3D - {SPR_SUPE, 6, 1, {NULL}, 0, 0, S_NIGHTSFLY4B}, // S_NIGHTSFLY4A - {SPR_SUPE, 7, 1, {NULL}, 0, 0, S_NIGHTSFLY4A}, // S_NIGHTSFLY4B - {SPR_NDRL, 12, 2, {NULL}, 0, 0, S_NIGHTSDRILL4B}, // S_NIGHTSDRILL4A - {SPR_NDRL, 13, 2, {NULL}, 0, 0, S_NIGHTSDRILL4C}, // S_NIGHTSDRILL4B - {SPR_NDRL, 14, 2, {NULL}, 0, 0, S_NIGHTSDRILL4D}, // S_NIGHTSDRILL4C - {SPR_NDRL, 15, 2, {NULL}, 0, 0, S_NIGHTSDRILL4A}, // S_NIGHTSDRILL4D - {SPR_SUPE, 8, 1, {NULL}, 0, 0, S_NIGHTSFLY5B}, // S_NIGHTSFLY5A - {SPR_SUPE, 9, 1, {NULL}, 0, 0, S_NIGHTSFLY5A}, // S_NIGHTSFLY5B - {SPR_NDRL, 16, 2, {NULL}, 0, 0, S_NIGHTSDRILL5B}, // S_NIGHTSDRILL5A - {SPR_NDRL, 17, 2, {NULL}, 0, 0, S_NIGHTSDRILL5C}, // S_NIGHTSDRILL5B - {SPR_NDRL, 18, 2, {NULL}, 0, 0, S_NIGHTSDRILL5D}, // S_NIGHTSDRILL5C - {SPR_NDRL, 19, 2, {NULL}, 0, 0, S_NIGHTSDRILL5A}, // S_NIGHTSDRILL5D - {SPR_SUPE, 10, 1, {NULL}, 0, 0, S_NIGHTSFLY6B}, // S_NIGHTSFLY6A - {SPR_SUPE, 11, 1, {NULL}, 0, 0, S_NIGHTSFLY6A}, // S_NIGHTSFLY6B - {SPR_NDRL, 20, 2, {NULL}, 0, 0, S_NIGHTSDRILL6B}, // S_NIGHTSDRILL6A - {SPR_NDRL, 21, 2, {NULL}, 0, 0, S_NIGHTSDRILL6C}, // S_NIGHTSDRILL6B - {SPR_NDRL, 22, 2, {NULL}, 0, 0, S_NIGHTSDRILL6D}, // S_NIGHTSDRILL6C - {SPR_NDRL, 23, 2, {NULL}, 0, 0, S_NIGHTSDRILL6A}, // S_NIGHTSDRILL6D - {SPR_SUPE, 12, 1, {NULL}, 0, 0, S_NIGHTSFLY7B}, // S_NIGHTSFLY7A - {SPR_SUPE, 13, 1, {NULL}, 0, 0, S_NIGHTSFLY7A}, // S_NIGHTSFLY7B - {SPR_NDRL, 24, 2, {NULL}, 0, 0, S_NIGHTSDRILL7B}, // S_NIGHTSDRILL7A - {SPR_NDRL, 25, 2, {NULL}, 0, 0, S_NIGHTSDRILL7C}, // S_NIGHTSDRILL7B - {SPR_NDRL, 26, 2, {NULL}, 0, 0, S_NIGHTSDRILL7D}, // S_NIGHTSDRILL7C - {SPR_NDRL, 27, 2, {NULL}, 0, 0, S_NIGHTSDRILL7A}, // S_NIGHTSDRILL7D - {SPR_SUPE, 14, 1, {NULL}, 0, 0, S_NIGHTSFLY8B}, // S_NIGHTSFLY8A - {SPR_SUPE, 15, 1, {NULL}, 0, 0, S_NIGHTSFLY8A}, // S_NIGHTSFLY8B - {SPR_NDRL, 28, 2, {NULL}, 0, 0, S_NIGHTSDRILL8B}, // S_NIGHTSDRILL8A - {SPR_NDRL, 29, 2, {NULL}, 0, 0, S_NIGHTSDRILL8C}, // S_NIGHTSDRILL8B - {SPR_NDRL, 30, 2, {NULL}, 0, 0, S_NIGHTSDRILL8D}, // S_NIGHTSDRILL8C - {SPR_NDRL, 31, 2, {NULL}, 0, 0, S_NIGHTSDRILL8A}, // S_NIGHTSDRILL8D - {SPR_SUPE, 16, 1, {NULL}, 0, 0, S_NIGHTSFLY9B}, // S_NIGHTSFLY9A - {SPR_SUPE, 17, 1, {NULL}, 0, 0, S_NIGHTSFLY9A}, // S_NIGHTSFLY9B - {SPR_NDRL, 32, 2, {NULL}, 0, 0, S_NIGHTSDRILL9B}, // S_NIGHTSDRILL9A - {SPR_NDRL, 33, 2, {NULL}, 0, 0, S_NIGHTSDRILL9C}, // S_NIGHTSDRILL9B - {SPR_NDRL, 34, 2, {NULL}, 0, 0, S_NIGHTSDRILL9D}, // S_NIGHTSDRILL9C - {SPR_NDRL, 35, 2, {NULL}, 0, 0, S_NIGHTSDRILL9A}, // S_NIGHTSDRILL9D - - // Nights Player, Falling - {SPR_SUPZ, 0, 1, {NULL}, 0, 0, S_NIGHTSHURT2}, // S_NIGHTSHURT1 - {SPR_SUPZ, 1, 1, {NULL}, 0, 0, S_NIGHTSHURT3}, // S_NIGHTSHURT2 - {SPR_SUPZ, 2, 1, {NULL}, 0, 0, S_NIGHTSHURT4}, // S_NIGHTSHURT3 - {SPR_SUPZ, 3, 1, {NULL}, 0, 0, S_NIGHTSHURT5}, // S_NIGHTSHURT4 - {SPR_SUPZ, 4, 1, {NULL}, 0, 0, S_NIGHTSHURT6}, // S_NIGHTSHURT5 - {SPR_SUPZ, 5, 1, {NULL}, 0, 0, S_NIGHTSHURT7}, // S_NIGHTSHURT6 - {SPR_SUPZ, 6, 1, {NULL}, 0, 0, S_NIGHTSHURT8}, // S_NIGHTSHURT7 - {SPR_SUPZ, 7, 1, {NULL}, 0, 0, S_NIGHTSHURT9}, // S_NIGHTSHURT8 - {SPR_SUPZ, 8, 1, {NULL}, 0, 0, S_NIGHTSHURT10}, // S_NIGHTSHURT9 - {SPR_SUPZ, 9, 1, {NULL}, 0, 0, S_NIGHTSHURT11}, // S_NIGHTSHURT10 - {SPR_SUPZ, 10, 1, {NULL}, 0, 0, S_NIGHTSHURT12}, // S_NIGHTSHURT11 - {SPR_SUPZ, 11, 1, {NULL}, 0, 0, S_NIGHTSHURT13}, // S_NIGHTSHURT12 - {SPR_SUPZ, 12, 1, {NULL}, 0, 0, S_NIGHTSHURT14}, // S_NIGHTSHURT13 - {SPR_SUPZ, 13, 1, {NULL}, 0, 0, S_NIGHTSHURT15}, // S_NIGHTSHURT14 - {SPR_SUPZ, 14, 1, {NULL}, 0, 0, S_NIGHTSHURT16}, // S_NIGHTSHURT15 - {SPR_SUPZ, 15, 1, {NULL}, 0, 0, S_NIGHTSHURT17}, // S_NIGHTSHURT16 - {SPR_SUPZ, 0, 1, {NULL}, 0, 0, S_NIGHTSHURT18}, // S_NIGHTSHURT17 - {SPR_SUPZ, 1, 1, {NULL}, 0, 0, S_NIGHTSHURT19}, // S_NIGHTSHURT18 - {SPR_SUPZ, 2, 1, {NULL}, 0, 0, S_NIGHTSHURT20}, // S_NIGHTSHURT19 - {SPR_SUPZ, 3, 1, {NULL}, 0, 0, S_NIGHTSHURT21}, // S_NIGHTSHURT20 - {SPR_SUPZ, 4, 1, {NULL}, 0, 0, S_NIGHTSHURT22}, // S_NIGHTSHURT21 - {SPR_SUPZ, 5, 1, {NULL}, 0, 0, S_NIGHTSHURT23}, // S_NIGHTSHURT22 - {SPR_SUPZ, 6, 1, {NULL}, 0, 0, S_NIGHTSHURT24}, // S_NIGHTSHURT23 - {SPR_SUPZ, 7, 1, {NULL}, 0, 0, S_NIGHTSHURT25}, // S_NIGHTSHURT24 - {SPR_SUPZ, 8, 1, {NULL}, 0, 0, S_NIGHTSHURT26}, // S_NIGHTSHURT25 - {SPR_SUPZ, 9, 1, {NULL}, 0, 0, S_NIGHTSHURT27}, // S_NIGHTSHURT26 - {SPR_SUPZ, 10, 1, {NULL}, 0, 0, S_NIGHTSHURT28}, // S_NIGHTSHURT27 - {SPR_SUPZ, 11, 1, {NULL}, 0, 0, S_NIGHTSHURT29}, // S_NIGHTSHURT28 - {SPR_SUPZ, 12, 1, {NULL}, 0, 0, S_NIGHTSHURT30}, // S_NIGHTSHURT29 - {SPR_SUPZ, 13, 1, {NULL}, 0, 0, S_NIGHTSHURT31}, // S_NIGHTSHURT30 - {SPR_SUPZ, 14, 1, {NULL}, 0, 0, S_NIGHTSHURT32}, // S_NIGHTSHURT31 - {SPR_SUPZ, 15, 1, {NULL}, 0, 0, S_NIGHTSFLY1A}, // S_NIGHTSHURT32 - // Nights Sparkle {SPR_NSPK, FF_FULLBRIGHT, 140, {NULL}, 0, 0, S_NIGHTSPARKLE2}, // S_NIGHTSPARKLE1 {SPR_NSPK, FF_FULLBRIGHT|1, 7, {NULL}, 0, 0, S_NIGHTSPARKLE3}, // S_NIGHTSPARKLE2 @@ -2458,16 +2449,6 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 35, {NULL}, 0, 0, S_CRUMBLE2}, // S_CRUMBLE1 {SPR_NULL, 0, 105, {A_Scream}, 0, 0, S_NULL}, // S_CRUMBLE2 - {SPR_SUPT, 0, 4, {A_Scream}, 0, 0, S_SUPERTRANS2}, // S_SUPERTRANS1 - {SPR_SUPT, 1, 4, {NULL}, 0, 0, S_SUPERTRANS3}, // S_SUPERTRANS2 - {SPR_SUPT, FF_FULLBRIGHT|2, 4, {NULL}, 0, 0, S_SUPERTRANS4}, // S_SUPERTRANS3 - {SPR_SUPT, 3, 3, {NULL}, 0, 0, S_SUPERTRANS5}, // S_SUPERTRANS4 - {SPR_SUPT, 4, 3, {NULL}, 0, 0, S_SUPERTRANS6}, // S_SUPERTRANS5 - {SPR_SUPT, 5, 3, {NULL}, 0, 0, S_SUPERTRANS7}, // S_SUPERTRANS6 - {SPR_SUPT, 6, 3, {NULL}, 0, 0, S_SUPERTRANS8}, // S_SUPERTRANS7 - {SPR_SUPT, 7, 3, {NULL}, 0, 0, S_SUPERTRANS9}, // S_SUPERTRANS8 - {SPR_SUPT, 8, 16, {NULL}, 0, 0, S_NIGHTSDRONE1}, // S_SUPERTRANS9 - // Spark {SPR_SPRK, FF_TRANS40 , 1, {NULL}, 0, 0, S_SPRK2}, // S_SPRK1 {SPR_SPRK, FF_TRANS50|1, 1, {NULL}, 0, 0, S_SPRK3}, // S_SPRK2 @@ -12185,33 +12166,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_NIGHTSCHAR - -1, // doomednum - S_NIGHTSFLY1A, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 0, // reactiontime - sfx_None, // attacksound - S_NIGHTSFLY1A, // painstate - 255, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NIGHTSFLY1A, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 48*FRACUNIT, // height - 0, // display offset - 1000, // mass - 0, // damage - sfx_None, // activesound - MF_NOCLIP|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - { // MT_NIGHTSPARKLE -1, // doomednum S_NIGHTSPARKLE1,// spawnstate diff --git a/src/info.h b/src/info.h index 7a99d8b07..a700ad24e 100644 --- a/src/info.h +++ b/src/info.h @@ -591,9 +591,9 @@ enum playersprite SPR2_PEEL, SPR2_PAIN, SPR2_DEAD, - SPR2_DRWN, + SPR2_DRWN, // drown SPR2_SPIN, - SPR2_DASH, + SPR2_DASH, // spindash charge SPR2_GASP, SPR2_JUMP, SPR2_SPNG, // spring @@ -601,38 +601,75 @@ enum playersprite SPR2_EDGE, SPR2_RIDE, - SPR2_SIGN, - SPR2_LIFE, + SPR2_SIGN, // end sign head + SPR2_LIFE, // life monitor icon SPR2_FLY , SPR2_SWIM, - SPR2_TIRE, + SPR2_TIRE, // tired - SPR2_GLID, - SPR2_CLNG, - SPR2_CLMB, + SPR2_GLID, // glide + SPR2_CLNG, // cling + SPR2_CLMB, // climb - SPR2_TWIN, + SPR2_TWIN, // twinspin - SPR2_MLEE, + SPR2_MLEE, // melee - SPR2_TRNS, - SPR2_SSTD, - SPR2_SWLK, - SPR2_SRUN, - SPR2_SPEE, - SPR2_SPAN, - SPR2_SMSL, - SPR2_SDTH, - SPR2_SDRN, - SPR2_SSPN, - SPR2_SGSP, - SPR2_SJMP, - SPR2_SSPG, - SPR2_SFAL, - SPR2_SEDG, - SPR2_SRID, - SPR2_SFLT, + SPR2_TRNS, // super transformation + SPR2_SSTD, // super stand + SPR2_SWLK, // super walk + SPR2_SRUN, // super run + SPR2_SPEE, // super peelout + SPR2_SPAN, // super pain + SPR2_SSTN, // super stun + SPR2_SDTH, // super death + SPR2_SDRN, // super drown + SPR2_SSPN, // super spin + SPR2_SGSP, // super gasp + SPR2_SJMP, // super jump + SPR2_SSPG, // super spring + SPR2_SFAL, // super fall + SPR2_SEDG, // super edge + SPR2_SRID, // super ride + SPR2_SFLT, // super float + + SPR2_NTRN, // NiGHTS transformation + SPR2_NSTD, // NiGHTS stand + SPR2_NFLT, // NiGHTS float + SPR2_NPAN, // NiGHTS pain + SPR2_NPUL, // NiGHTS pull + SPR2_NATK, // NiGHTS attack + + // NiGHTS flight. + SPR2_NGT0, + SPR2_NGT1, + SPR2_NGT2, + SPR2_NGT3, + SPR2_NGT4, + SPR2_NGT5, + SPR2_NGT6, + SPR2_NGT7, + SPR2_NGT8, + SPR2_NGT9, + SPR2_NGTA, + SPR2_NGTB, + SPR2_NGTC, + + // NiGHTS drill. + SPR2_DRL0, + SPR2_DRL1, + SPR2_DRL2, + SPR2_DRL3, + SPR2_DRL4, + SPR2_DRL5, + SPR2_DRL6, + SPR2_DRL7, + SPR2_DRL8, + SPR2_DRL9, + SPR2_DRLA, + SPR2_DRLB, + SPR2_DRLC, SPR2_FIRSTFREESLOT, SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, @@ -733,6 +770,50 @@ typedef enum state // Level end sign overlay (uses player sprite) S_PLAY_SIGN, + // NiGHTS character (uses player sprite) + S_PLAY_NIGHTS_TRANS, + S_PLAY_NIGHTS_TRANS2, + S_PLAY_NIGHTS_TRANS3, + S_PLAY_NIGHTS_TRANS4, + S_PLAY_NIGHTS_TRANS5, + S_PLAY_NIGHTS_TRANS6, + S_PLAY_NIGHTS_TRANS7, + S_PLAY_NIGHTS_TRANS8, + S_PLAY_NIGHTS_TRANS9, + + S_PLAY_NIGHTS_STAND, + S_PLAY_NIGHTS_FLOAT, + S_PLAY_NIGHTS_PAIN, + S_PLAY_NIGHTS_PULL, + S_PLAY_NIGHTS_ATTACK, + + S_PLAY_NIGHTS_FLY0, + S_PLAY_NIGHTS_DRILL0, + S_PLAY_NIGHTS_FLY1, + S_PLAY_NIGHTS_DRILL1, + S_PLAY_NIGHTS_FLY2, + S_PLAY_NIGHTS_DRILL2, + S_PLAY_NIGHTS_FLY3, + S_PLAY_NIGHTS_DRILL3, + S_PLAY_NIGHTS_FLY4, + S_PLAY_NIGHTS_DRILL4, + S_PLAY_NIGHTS_FLY5, + S_PLAY_NIGHTS_DRILL5, + S_PLAY_NIGHTS_FLY6, + S_PLAY_NIGHTS_DRILL6, + S_PLAY_NIGHTS_FLY7, + S_PLAY_NIGHTS_DRILL7, + S_PLAY_NIGHTS_FLY8, + S_PLAY_NIGHTS_DRILL8, + S_PLAY_NIGHTS_FLY9, + S_PLAY_NIGHTS_DRILL9, + S_PLAY_NIGHTS_FLYA, + S_PLAY_NIGHTS_DRILLA, + S_PLAY_NIGHTS_FLYB, + S_PLAY_NIGHTS_DRILLB, + S_PLAY_NIGHTS_FLYC, + S_PLAY_NIGHTS_DRILLC, + // Blue Crawla S_POSS_STND, S_POSS_RUN1, @@ -2728,93 +2809,6 @@ typedef enum state S_NIGHTSGOAL3, S_NIGHTSGOAL4, - S_NIGHTSFLY1A, - S_NIGHTSFLY1B, - S_NIGHTSDRILL1A, - S_NIGHTSDRILL1B, - S_NIGHTSDRILL1C, - S_NIGHTSDRILL1D, - S_NIGHTSFLY2A, - S_NIGHTSFLY2B, - S_NIGHTSDRILL2A, - S_NIGHTSDRILL2B, - S_NIGHTSDRILL2C, - S_NIGHTSDRILL2D, - S_NIGHTSFLY3A, - S_NIGHTSFLY3B, - S_NIGHTSDRILL3A, - S_NIGHTSDRILL3B, - S_NIGHTSDRILL3C, - S_NIGHTSDRILL3D, - S_NIGHTSFLY4A, - S_NIGHTSFLY4B, - S_NIGHTSDRILL4A, - S_NIGHTSDRILL4B, - S_NIGHTSDRILL4C, - S_NIGHTSDRILL4D, - S_NIGHTSFLY5A, - S_NIGHTSFLY5B, - S_NIGHTSDRILL5A, - S_NIGHTSDRILL5B, - S_NIGHTSDRILL5C, - S_NIGHTSDRILL5D, - S_NIGHTSFLY6A, - S_NIGHTSFLY6B, - S_NIGHTSDRILL6A, - S_NIGHTSDRILL6B, - S_NIGHTSDRILL6C, - S_NIGHTSDRILL6D, - S_NIGHTSFLY7A, - S_NIGHTSFLY7B, - S_NIGHTSDRILL7A, - S_NIGHTSDRILL7B, - S_NIGHTSDRILL7C, - S_NIGHTSDRILL7D, - S_NIGHTSFLY8A, - S_NIGHTSFLY8B, - S_NIGHTSDRILL8A, - S_NIGHTSDRILL8B, - S_NIGHTSDRILL8C, - S_NIGHTSDRILL8D, - S_NIGHTSFLY9A, - S_NIGHTSFLY9B, - S_NIGHTSDRILL9A, - S_NIGHTSDRILL9B, - S_NIGHTSDRILL9C, - S_NIGHTSDRILL9D, - S_NIGHTSHURT1, - S_NIGHTSHURT2, - S_NIGHTSHURT3, - S_NIGHTSHURT4, - S_NIGHTSHURT5, - S_NIGHTSHURT6, - S_NIGHTSHURT7, - S_NIGHTSHURT8, - S_NIGHTSHURT9, - S_NIGHTSHURT10, - S_NIGHTSHURT11, - S_NIGHTSHURT12, - S_NIGHTSHURT13, - S_NIGHTSHURT14, - S_NIGHTSHURT15, - S_NIGHTSHURT16, - S_NIGHTSHURT17, - S_NIGHTSHURT18, - S_NIGHTSHURT19, - S_NIGHTSHURT20, - S_NIGHTSHURT21, - S_NIGHTSHURT22, - S_NIGHTSHURT23, - S_NIGHTSHURT24, - S_NIGHTSHURT25, - S_NIGHTSHURT26, - S_NIGHTSHURT27, - S_NIGHTSHURT28, - S_NIGHTSHURT29, - S_NIGHTSHURT30, - S_NIGHTSHURT31, - S_NIGHTSHURT32, - S_NIGHTSPARKLE1, S_NIGHTSPARKLE2, S_NIGHTSPARKLE3, @@ -2911,16 +2905,6 @@ typedef enum state S_CRUMBLE1, S_CRUMBLE2, - S_SUPERTRANS1, - S_SUPERTRANS2, - S_SUPERTRANS3, - S_SUPERTRANS4, - S_SUPERTRANS5, - S_SUPERTRANS6, - S_SUPERTRANS7, - S_SUPERTRANS8, - S_SUPERTRANS9, - // Spark S_SPRK1, S_SPRK2, @@ -3496,7 +3480,6 @@ typedef enum mobj_type MT_AXISTRANSFERLINE, MT_NIGHTSDRONE, MT_NIGHTSGOAL, - MT_NIGHTSCHAR, MT_NIGHTSPARKLE, MT_NIGHTSLOOPHELPER, MT_NIGHTSBUMPER, // NiGHTS Bumper diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 7ff21151c..f93513c49 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -51,6 +51,7 @@ enum skin { skin_camerascale, skin_starttranscolor, skin_prefcolor, + skin_supercolor, skin_prefoppositecolor, skin_highresscale, skin_soundsid, @@ -88,6 +89,7 @@ static const char *const skin_opt[] = { "camerascale", "starttranscolor", "prefcolor", + "supercolor", "prefoppositecolor", "highresscale", "soundsid", @@ -208,6 +210,9 @@ static int skin_get(lua_State *L) case skin_prefcolor: lua_pushinteger(L, skin->prefcolor); break; + case skin_supercolor: + lua_pushinteger(L, skin->supercolor); + break; case skin_prefoppositecolor: lua_pushinteger(L, skin->prefoppositecolor); break; diff --git a/src/p_enemy.c b/src/p_enemy.c index aa38c9818..07246d69b 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8039,7 +8039,7 @@ void A_OrbitNights(mobj_t* actor) #endif if (!actor->target || !actor->target->player || - !actor->target->tracer || !actor->target->player->nightstime + !(actor->target->player->pflags & PF_NIGHTSMODE) || !actor->target->player->nightstime // Also remove this object if they no longer have a NiGHTS helper || (ishelper && !actor->target->player->powers[pw_nights_helper])) { @@ -8058,14 +8058,21 @@ void A_OrbitNights(mobj_t* actor) const fixed_t fh = FixedMul(FINECOSINE(ofa),FixedMul(20*FRACUNIT, actor->scale)); const fixed_t fs = FixedMul(FINESINE(fa),FixedMul(32*FRACUNIT, actor->scale)); - actor->x = actor->target->tracer->x + fc; - actor->y = actor->target->tracer->y + fs; - actor->z = actor->target->tracer->z + fh + FixedMul(16*FRACUNIT, actor->scale); + actor->x = actor->target->x + fc; + actor->y = actor->target->y + fs; + actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale); // Semi-lazy hack actor->angle = (angle_t)actor->extravalue1 + ANGLE_90; } P_SetThingPosition(actor); + + if (ishelper // Flash a helper that's about to be removed. + && (actor->target->player->powers[pw_nights_helper] < TICRATE) + && (actor->target->player->powers[pw_nights_helper] & 1)) + actor->flags2 |= MF2_DONTDRAW; + else + actor->flags2 &= ~MF2_DONTDRAW; } } diff --git a/src/p_inter.c b/src/p_inter.c index 5f538ee8d..936747ce6 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -652,16 +652,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (G_IsSpecialStage(gamemap)) //After-mare bonus time/emerald reward in special stages. { // only allow the player with the emerald in-hand to leave. - if (toucher->tracer && toucher->tracer->target - && toucher->tracer->target->type == MT_GOTEMERALD) + if (toucher->tracer + && toucher->tracer->type == MT_GOTEMERALD) { } else // Make sure that SOMEONE has the emerald, at least! { for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].playerstate == PST_LIVE - && players[i].mo->tracer && players[i].mo->tracer->target - && players[i].mo->tracer->target->type == MT_GOTEMERALD) + && players[i].mo->tracer + && players[i].mo->tracer->type == MT_GOTEMERALD) return; // Well no one has an emerald, so exit anyway! } @@ -2487,7 +2487,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) } player->powers[pw_flashing] = flashingtics; - P_SetMobjState(target->tracer, S_NIGHTSHURT1); + P_SetPlayerMobjState(target, S_PLAY_NIGHTS_PAIN); S_StartSound(target, sfx_nghurt); if (oldnightstime > 10*TICRATE diff --git a/src/p_mobj.c b/src/p_mobj.c index f006cb53d..730af9003 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -173,10 +173,6 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) return P_SetPlayerMobjState(player->mo, S_PLAY_FLY); - // Catch melee into goop - //if (state == S_PLAY_MELEE && player->mo->eflags & MFE_GOOWATER) - //return P_SetPlayerMobjState(player->mo, S_PLAY_FALL); - // Catch state changes for Super Sonic if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS)) { @@ -439,7 +435,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) case SPR2_SPAN: spr2 = SPR2_PAIN; break; - case SPR2_SMSL: + case SPR2_SSTN: spr2 = SPR2_SPAN; break; case SPR2_SDTH: @@ -473,6 +469,81 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_SWLK; break; + // NiGHTS sprites. + case SPR2_NTRN: + spr2 = SPR2_TRNS; + break; + case SPR2_NSTD: + spr2 = SPR2_SSTD; + break; + case SPR2_NFLT: + spr2 = (skin->flags & SF_SUPERANIMS) ? SPR2_SFLT : SPR2_FALL; // This is skin-exclusive so the default NiGHTS skin changing system plays nice. + break; + case SPR2_NPUL: + spr2 = SPR2_NFLT; + break; + case SPR2_NPAN: + spr2 = SPR2_NPUL; + break; + case SPR2_NATK: + spr2 = SPR2_SSPN; + break; + /*case SPR2_NGT0: + spr2 = SPR2_STND; + break;*/ + case SPR2_NGT1: + case SPR2_NGT7: + case SPR2_DRL0: + spr2 = SPR2_NGT0; + break; + case SPR2_NGT2: + case SPR2_DRL1: + spr2 = SPR2_NGT1; + break; + case SPR2_NGT3: + case SPR2_DRL2: + spr2 = SPR2_NGT2; + break; + case SPR2_NGT4: + case SPR2_DRL3: + spr2 = SPR2_NGT3; + break; + case SPR2_NGT5: + case SPR2_DRL4: + spr2 = SPR2_NGT4; + break; + case SPR2_NGT6: + case SPR2_DRL5: + spr2 = SPR2_NGT5; + break; + case SPR2_DRL6: + spr2 = SPR2_NGT6; + break; + case SPR2_NGT8: + case SPR2_DRL7: + spr2 = SPR2_NGT7; + break; + case SPR2_NGT9: + case SPR2_DRL8: + spr2 = SPR2_NGT8; + break; + case SPR2_NGTA: + case SPR2_DRL9: + spr2 = SPR2_NGT9; + break; + case SPR2_NGTB: + case SPR2_DRLA: + spr2 = SPR2_NGTA; + break; + case SPR2_NGTC: + case SPR2_DRLB: + spr2 = SPR2_NGTB; + break; + case SPR2_DRLC: + spr2 = SPR2_NGTC; + break; + + // Sprites for non-player objects? There's nothing we can do. case SPR2_SIGN: case SPR2_LIFE: @@ -526,6 +597,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) mobj->sprite2 = spr2; mobj->frame = frame|(st->frame&~FF_FRAMEMASK); + if (mobj->color > MAXSKINCOLORS) // Super colours? Super bright! + mobj->frame |= FF_FULLBRIGHT; } // Regular sprites else diff --git a/src/p_user.c b/src/p_user.c index e694d08a1..cf265b645 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -576,9 +576,6 @@ static void P_DeNightserizePlayer(player_t *player) player->pflags &= ~PF_NIGHTSMODE; - //if (player->mo->tracer) - //P_RemoveMobj(player->mo->tracer); - player->powers[pw_underwater] = 0; player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST); player->secondjump = 0; @@ -592,7 +589,8 @@ static void P_DeNightserizePlayer(player_t *player) player->mo->flags &= ~MF_NOGRAVITY; - player->mo->flags2 &= ~MF2_DONTDRAW; + player->mo->skin = &skins[player->skin]; + player->mo->color = player->skincolor; // Restore aiming angle if (player == &players[consoleplayer]) @@ -603,8 +601,6 @@ static void P_DeNightserizePlayer(player_t *player) // If you screwed up, kiss your score goodbye. player->marescore = 0; - if (player->mo->tracer) - P_RemoveMobj(player->mo->tracer); P_SetPlayerMobjState(player->mo, S_PLAY_FALL); player->pflags |= PF_NIGHTSFALL; @@ -638,6 +634,9 @@ static void P_DeNightserizePlayer(player_t *player) // Restore from drowning music P_RestoreMusic(player); } + +#define DEFAULTNIGHTSSKIN 0 + // // P_NightserizePlayer // @@ -652,11 +651,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) if (!(player->pflags & PF_NIGHTSMODE)) { - P_SetTarget(&player->mo->tracer, P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NIGHTSCHAR)); - player->mo->tracer->destscale = player->mo->scale; - P_SetScale(player->mo->tracer, player->mo->scale); - player->mo->tracer->eflags = (player->mo->tracer->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); - player->mo->height = player->mo->tracer->height; + player->mo->radius = 16*FRACUNIT; + player->mo->height = 48*FRACUNIT; } player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_THOKKED|PF_SPINNING|PF_DRILLING); @@ -670,13 +666,17 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->mo->flags |= MF_NOGRAVITY; - player->mo->flags2 |= MF2_DONTDRAW; + if (skins[player->skin].sprites[SPR2_NGT0].numframes == 0) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. + { + player->mo->skin = &skins[DEFAULTNIGHTSSKIN]; + player->mo->color = ((skin_t *)(player->mo->skin))->prefcolor; + } player->nightstime = player->startedtime = nighttime*TICRATE; player->bonustime = false; P_RestoreMusic(player); - P_SetMobjState(player->mo->tracer, S_SUPERTRANS1); + P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_TRANS); if (gametype == GT_RACE || gametype == GT_COMPETITION) { @@ -772,6 +772,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->pflags |= PF_NIGHTSMODE; } +#undef DEFAULTNIGHTSSKIN + // // P_PlayerInPain // @@ -4999,13 +5001,13 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad return; // You're welcome, Rob. (Now with slightly less horrendous hacking -Red - player->mo->tracer->flags &= ~MF_NOCLIP; + /*player->mo->tracer->flags &= ~MF_NOCLIP; player->mo->tracer->z = player->mo->z; if (!P_TryMove(player->mo->tracer, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, true)) { player->mo->tracer->flags |= MF_NOCLIP; return; } - player->mo->tracer->flags |= MF_NOCLIP; + player->mo->tracer->flags |= MF_NOCLIP;*/ { const INT32 sequence = player->mo->target->threshold; mobj_t *transfer1 = NULL; @@ -5395,10 +5397,6 @@ static void P_DoNiGHTSCapsule(player_t *player) { INT32 i; - if ((player->pflags & PF_NIGHTSMODE) && (player->mo->tracer->state < &states[S_NIGHTSHURT1] - || player->mo->tracer->state > &states[S_NIGHTSHURT32])) - P_SetMobjState(player->mo->tracer, S_NIGHTSHURT1); - if (abs(player->mo->x-player->capsule->x) <= 2*FRACUNIT) { P_UnsetThingPosition(player->mo); @@ -5436,6 +5434,20 @@ static void P_DoNiGHTSCapsule(player_t *player) else if (player->mo->z < player->capsule->z+(player->capsule->height/3)) player->mo->momz = 2*FRACUNIT; + if (player->pflags & PF_NIGHTSMODE) + { + if (player->mo->momx || player->mo->momy || player->mo->momz) + { + if (player->mo->state != &states[S_PLAY_NIGHTS_PULL]) + P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_PULL); + } + else if (player->mo->state != &states[S_PLAY_NIGHTS_ATTACK]) + { + S_StartSound(player->mo, sfx_spin); + P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_ATTACK); + } + } + if (G_IsSpecialStage(gamemap)) { // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here! for (i = 0; i < MAXPLAYERS; i++) @@ -5465,7 +5477,7 @@ static void P_DoNiGHTSCapsule(player_t *player) S_StartSound(P_SpawnMobj(player->capsule->x + ((P_SignedRandom()/2)<capsule->y + ((P_SignedRandom()/2)<capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<capsule->health <= 0) { @@ -5503,13 +5515,13 @@ static void P_DoNiGHTSCapsule(player_t *player) P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); }*/ - if (player->mo->tracer) + if (player->pflags & PF_NIGHTSMODE) { // Only give it to ONE person, and THAT player has to get to the goal! emmo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->info->height, MT_GOTEMERALD); P_SetTarget(&emmo->target, player->mo); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); - P_SetTarget(&player->mo->tracer->target, emmo); + P_SetTarget(&player->mo->tracer, emmo); } // Okay, we're doing this down here because we're handling time weirdly for co-op special stages @@ -5568,7 +5580,8 @@ static void P_NiGHTSMovement(player_t *player) ticcmd_t *cmd = &player->cmd; INT32 thrustfactor; INT32 i; - statenum_t flystate = S_NIGHTSFLY1A; + statenum_t flystate; + UINT16 visangle; player->pflags &= ~PF_DRILLING; @@ -5587,7 +5600,7 @@ static void P_NiGHTSMovement(player_t *player) player->drillmeter = TICRATE/10; } - if (!player->mo->tracer) + if (!(player->pflags & PF_NIGHTSMODE)) { P_DeNightserizePlayer(player); return; @@ -5602,13 +5615,14 @@ static void P_NiGHTSMovement(player_t *player) && (players[i].capsule && players[i].capsule->reactiontime)) capsule = true; if (!capsule - && !(player->mo->tracer->state >= &states[S_SUPERTRANS1] - && player->mo->tracer->state <= &states[S_SUPERTRANS9]) + && !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS] + && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9]) && !player->exiting) player->nightstime--; } else if (gametype != GT_RACE && gametype != GT_COMPETITION - && !(player->mo->tracer->state >= &states[S_SUPERTRANS1] && player->mo->tracer->state <= &states[S_SUPERTRANS9]) + && !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS] + && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9]) && !(player->capsule && player->capsule->reactiontime) && !player->exiting) player->nightstime--; @@ -5693,8 +5707,6 @@ static void P_NiGHTSMovement(player_t *player) radius = player->mo->target->radius; player->mo->flags |= MF_NOGRAVITY; - player->mo->flags2 |= MF2_DONTDRAW; - P_SetScale(player->mo->tracer, player->mo->scale); if (player->mo->eflags & MFE_VERTICALFLIP) cmd->forwardmove = (SINT8)(-cmd->forwardmove); @@ -5749,8 +5761,8 @@ static void P_NiGHTSMovement(player_t *player) return; } - if (player->mo->tracer->state >= &states[S_SUPERTRANS1] - && player->mo->tracer->state <= &states[S_SUPERTRANS9]) + if (player->mo->state >= &states[S_PLAY_NIGHTS_TRANS] + && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9]) { player->mo->momx = player->mo->momy = player->mo->momz = 0; return; @@ -5761,16 +5773,13 @@ static void P_NiGHTSMovement(player_t *player) player->mo->momx = player->mo->momy = 0; if (gametype != GT_RACE && gametype != GT_COMPETITION) - P_SetObjectMomZ(player->mo, 30*FRACUNIT, false); + P_SetObjectMomZ(player->mo, FRACUNIT/2, true); - player->mo->tracer->angle += ANGLE_11hh; + if (player->mo->state != &states[S_PLAY_NIGHTS_DRILL6]) + P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_DRILL6); - if (!(player->mo->tracer->state >= &states[S_NIGHTSDRONE1] - && player->mo->tracer->state <= &states[S_NIGHTSDRONE2])) - P_SetMobjState(player->mo->tracer, S_NIGHTSDRONE1); - - player->mo->tracer->flags |= MF_NOCLIPHEIGHT; player->mo->flags |= MF_NOCLIPHEIGHT; + return; } @@ -6036,74 +6045,41 @@ static void P_NiGHTSMovement(player_t *player) // NiGHTS flying state // Yep, I just ripped out almost 1000 lines of code. - if ((player->anotherflyangle >= 12 && player->anotherflyangle <= 33) // +x +y - || (player->anotherflyangle >= 147 && player->anotherflyangle <= 168)) // -x +y - flystate = S_NIGHTSFLY2A; - else if ((player->anotherflyangle >= 34 && player->anotherflyangle <= 56) // +x +y - || (player->anotherflyangle >= 124 && player->anotherflyangle <= 146)) // -x +y - flystate = S_NIGHTSFLY3A; - else if ((player->anotherflyangle >= 57 && player->anotherflyangle <= 79) // +x +y - || (player->anotherflyangle >= 102 && player->anotherflyangle <= 123)) // -x +y - flystate = S_NIGHTSFLY4A; - else if (player->anotherflyangle >= 80 && player->anotherflyangle <= 101) - flystate = S_NIGHTSFLY5A; - else if ((player->anotherflyangle >= 192 && player->anotherflyangle <= 213) // -x -y - || (player->anotherflyangle >= 327 && player->anotherflyangle <= 348)) // +x -y - flystate = S_NIGHTSFLY6A; - else if ((player->anotherflyangle >= 214 && player->anotherflyangle <= 236) // -x -y - || (player->anotherflyangle >= 305 && player->anotherflyangle <= 326)) // +x -y - flystate = S_NIGHTSFLY7A; - else if ((player->anotherflyangle >= 237 && player->anotherflyangle <= 258) // -x -y - || (player->anotherflyangle >= 282 && player->anotherflyangle <= 304)) // +x -y - flystate = S_NIGHTSFLY8A; - else if (player->anotherflyangle >= 259 && player->anotherflyangle <= 281) - flystate = S_NIGHTSFLY9A; + // (and then toast revamped the entire thing again to be better, but not by much) + if (still) + flystate = (P_IsObjectOnGround(player->mo)) ? S_PLAY_NIGHTS_STAND : S_PLAY_NIGHTS_FLOAT; else - flystate = S_NIGHTSFLY1A; - - if (player->mo->eflags & MFE_VERTICALFLIP) { - if (flystate >= S_NIGHTSFLY2A && flystate <= S_NIGHTSFLY5A) - flystate += 24; // shift to S_NIGHTSFLY6A - else if (flystate >= S_NIGHTSFLY6A && flystate <= S_NIGHTSFLY9A) - flystate -= 24; // shift to S_NIGHTSFLY2A - } + visangle = ((player->anotherflyangle + 7) % 360)/15; + if (visangle > 18) // Over 270 degrees. + visangle = 30 - visangle; + else if (visangle > 12) // Over 180 degrees. + visangle -= 6; + else if (visangle > 6) // Over 90 degrees. + visangle = 12 - visangle; - if (player->pflags & PF_DRILLING) - { - const statenum_t drillstate = flystate + 2; - - if (!(player->mo->tracer->state >= &states[drillstate] - && player->mo->tracer->state <= &states[drillstate+4])) + if (player->mo->eflags & MFE_VERTICALFLIP && visangle) // S_PLAY_NIGHTS_FLY0 stays the same, even in reverse gravity { - if (!(player->mo->tracer->state >= &states[S_NIGHTSFLY1A] - && player->mo->tracer->state <= &states[S_NIGHTSFLY9B])) - { - const INT32 framenum = player->mo->tracer->state->frame & 3; - - if (framenum == 3) // Drilld special case - P_SetMobjStateNF(player->mo->tracer, drillstate); - else - P_SetMobjStateNF(player->mo->tracer, drillstate+framenum+1); - } + if (visangle > 6) + visangle -= 6; // shift to S_PLAY_NIGHTS_FLY1-6 else - P_SetMobjStateNF(player->mo->tracer, drillstate); + visangle += 6; // shift to S_PLAY_NIGHTS_FLY7-C } + + flystate = S_PLAY_NIGHTS_FLY0 + (visangle*2); // S_PLAY_FLY0-C - the *2 is to skip over drill states + + if (player->pflags & PF_DRILLING) + flystate++; // shift to S_PLAY_NIGHTS_DRILL0-C } - else - P_SetMobjStateNF(player->mo->tracer, leveltime & 1 ? flystate : flystate+1); + + if (player->mo->state != &states[flystate]) + P_SetPlayerMobjState(player->mo, flystate); if (player == &players[consoleplayer]) localangle = player->mo->angle; else if (player == &players[secondarydisplayplayer]) localangle2 = player->mo->angle; - if (still) - { - P_SetMobjStateNF(player->mo->tracer, S_NIGHTSDRONE1); - player->mo->tracer->angle = player->mo->angle; - } - // Check for crushing in our new location if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) && !(player->mo->flags & MF_NOCLIP)) @@ -6127,8 +6103,6 @@ static void P_NiGHTSMovement(player_t *player) else if (player == &players[secondarydisplayplayer]) localaiming2 = movingangle; - player->mo->tracer->angle = player->mo->angle; - if ((player->pflags & PF_DRILLING) && !player->bumpertime) { if (firstdrill) @@ -6433,6 +6407,15 @@ static void P_MovePlayer(player_t *player) // Locate the capsule for this mare. else if (maptol & TOL_NIGHTS) { + if ((player->pflags & PF_NIGHTSMODE) + && !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS] + && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9] + && !(player->exiting))) + { + skin_t *skin = ((skin_t *)(player->mo->skin)); + player->mo->color = (skin->flags & SF_SUPER) ? skin->supercolor + (unsigned)abs(((signed)(leveltime >> 1) % 9) - 4) : player->mo->color; // This is where super flashing is handled. + } + if (!player->capsule && !player->bonustime) { thinker_t *th; @@ -9063,19 +9046,6 @@ void P_PlayerThink(player_t *player) else player->pflags &= ~PF_USEDOWN; } - else if (player->mo->tracer) // match tracer's position with yours when NiGHTS - { - P_UnsetThingPosition(player->mo->tracer); - player->mo->tracer->x = player->mo->x; - player->mo->tracer->y = player->mo->y; - if (player->mo->eflags & MFE_VERTICALFLIP) - player->mo->tracer->z = player->mo->z + player->mo->height - player->mo->tracer->height; - else - player->mo->tracer->z = player->mo->z; - player->mo->tracer->floorz = player->mo->floorz; - player->mo->tracer->ceilingz = player->mo->ceilingz; - P_SetThingPosition(player->mo->tracer); - } // Counters, time dependent power ups. // Time Bonus & Ring Bonus count settings @@ -9172,20 +9142,10 @@ void P_PlayerThink(player_t *player) player->losstime--; // Flash player after being hit. - if (!(player->pflags & PF_NIGHTSMODE)) - { - if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1)) - player->mo->flags2 |= MF2_DONTDRAW; - else - player->mo->flags2 &= ~MF2_DONTDRAW; - } - else if (player->mo->tracer) - { - if (player->powers[pw_flashing] & 1) - player->mo->tracer->flags2 |= MF2_DONTDRAW; - else - player->mo->tracer->flags2 &= ~MF2_DONTDRAW; - } + if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1)) + player->mo->flags2 |= MF2_DONTDRAW; + else + player->mo->flags2 &= ~MF2_DONTDRAW; player->pflags &= ~PF_SLIDING; diff --git a/src/r_things.c b/src/r_things.c index 4ef67f18f..783304868 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2357,7 +2357,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->jumpfactor = FRACUNIT; skin->actionspd = 30<mindash = 15<maxdash = 90<maxdash = 70<radius = mobjinfo[MT_PLAYER].radius; skin->height = mobjinfo[MT_PLAYER].height; From 9c02c810954e2daec88c04309e47e9fddc8fc33f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 12 Aug 2016 14:42:22 +0100 Subject: [PATCH 067/100] Now that it's not 3am, here's some fixes to what I pushed last night. * That hacky anti-NiGHTS-deaxisment code I commented out because I thought it was visual only? Reimplemented in a way that is both more and less hacky. It's identical in result to the original code, but takes a roundabout method to get there. * Sprite references for SUPE, SUPZ and NDRL are removed because they are now unused. * Helper's flashing conditional is restructured to do less flag swapping. * The check for super setting FF_FULLBRIGHT is limited to MAXTRANSLATIONS now, and also correctly takes into account MAXSKINCOLORS == SKINCOLOR_SUPERSILVER1. * NiGHTS collision bounds aren't hardcoded anymore. * NiGHTS link will never display when leaving stage. * Slightly tweaked rules for the supercolor setting when doing a NiGHTS transformation, but only meaningful for setting FF_FULLBRIGHT. --- src/hardware/hw_light.c | 4 -- src/info.c | 22 ++++----- src/info.h | 4 -- src/p_enemy.c | 14 +++--- src/p_mobj.c | 2 +- src/p_user.c | 105 ++++++++++++++++++++++------------------ 6 files changed, 79 insertions(+), 72 deletions(-) diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 96f79f807..0145c88fe 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -438,16 +438,12 @@ light_t *t_lspr[NUMSPRITES] = // NiGHTS Stuff &lspr[SUPERSONIC_L], // SPR_NDRN // NiGHTS drone - &lspr[SUPERSONIC_L], // SPR_SUPE // NiGHTS character flying - &lspr[SUPERSONIC_L], // SPR_SUPZ // NiGHTS hurt - &lspr[SUPERSONIC_L], // SPR_NDRL // NiGHTS character drilling &lspr[NOLIGHT], // SPR_NSPK &lspr[NOLIGHT], // SPR_NBMP &lspr[NOLIGHT], // SPR_HOOP &lspr[NOLIGHT], // SPR_HSCR &lspr[NOLIGHT], // SPR_NPRU &lspr[NOLIGHT], // SPR_CAPS - &lspr[SUPERSONIC_L], // SPR_SUPT // Debris &lspr[RINGSPARK_L], // SPR_SPRK diff --git a/src/info.c b/src/info.c index aeba7dcab..9d9f02d67 100644 --- a/src/info.c +++ b/src/info.c @@ -49,11 +49,11 @@ char sprnames[NUMSPRITES + 1][5] = "RNGR","RNGI","RNGA","RNGE","RNGS","RNGG","PIKB","PIKR","PIKA","PIKE", "PIKS","PIKG","TAUT","TGRE","TSCR","COIN","CPRK","GOOM","BGOM","FFWR", "FBLL","SHLL","PUMA","HAMM","KOOP","BFLM","MAXE","MUS1","MUS2","TOAD", - "NDRN","SUPE","SUPZ","NDRL","NSPK","NBMP","HOOP","NSCR","NPRU","CAPS", - "SUPT","SPRK","BOM1","BOM2","BOM3","BOM4","ROIA","ROIB","ROIC","ROID", - "ROIE","ROIF","ROIG","ROIH","ROII","ROIJ","ROIK","ROIL","ROIM","ROIN", - "ROIO","ROIP","BBAL","GWLG","GWLR","SRBA","SRBB","SRBC","SRBD","SRBE", - "SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", + "NDRN","NSPK","NBMP","HOOP","NSCR","NPRU","CAPS","SPRK","BOM1","BOM2", + "BOM3","BOM4","ROIA","ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH", + "ROII","ROIJ","ROIK","ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG", + "GWLR","SRBA","SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI", + "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", }; char spr2names[NUMPLAYERSPRITES][5] = @@ -250,12 +250,12 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_NTRN, 4, {A_Scream}, 0, 0, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS {SPR_PLAY, SPR2_NTRN, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS3}, // S_PLAY_NIGHTS_TRANS2 {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS4}, // S_PLAY_NIGHTS_TRANS3 - {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS5}, // S_PLAY_NIGHTS_TRANS4 - {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5 - {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS7}, // S_PLAY_NIGHTS_TRANS6 - {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS8}, // S_PLAY_NIGHTS_TRANS7 - {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS9}, // S_PLAY_NIGHTS_TRANS8 - {SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS9 + {SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS5}, // S_PLAY_NIGHTS_TRANS4 + {SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5 + {SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS7}, // S_PLAY_NIGHTS_TRANS6 + {SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS8}, // S_PLAY_NIGHTS_TRANS7 + {SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS9}, // S_PLAY_NIGHTS_TRANS8 + {SPR_PLAY, SPR2_NTRN, 16, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS9 // NiGHTS Player, Stand, Floating, Pain, Pull and Attack {SPR_PLAY, SPR2_NSTD, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_STAND}, // S_PLAY_NIGHTS_STAND diff --git a/src/info.h b/src/info.h index a700ad24e..f1366c441 100644 --- a/src/info.h +++ b/src/info.h @@ -514,16 +514,12 @@ typedef enum sprite // NiGHTS Stuff SPR_NDRN, // NiGHTS drone - SPR_SUPE, // NiGHTS character flying - SPR_SUPZ, // NiGHTS hurt - SPR_NDRL, // NiGHTS character drilling SPR_NSPK, // NiGHTS sparkle SPR_NBMP, // NiGHTS Bumper SPR_HOOP, // NiGHTS hoop sprite SPR_NSCR, // NiGHTS score sprite SPR_NPRU, // Nights Powerups SPR_CAPS, // Capsule thingy for NiGHTS - SPR_SUPT, // Super Sonic Transformation (NiGHTS) // Debris SPR_SPRK, // spark diff --git a/src/p_enemy.c b/src/p_enemy.c index 07246d69b..3790633ea 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8067,12 +8067,14 @@ void A_OrbitNights(mobj_t* actor) } P_SetThingPosition(actor); - if (ishelper // Flash a helper that's about to be removed. - && (actor->target->player->powers[pw_nights_helper] < TICRATE) - && (actor->target->player->powers[pw_nights_helper] & 1)) - actor->flags2 |= MF2_DONTDRAW; - else - actor->flags2 &= ~MF2_DONTDRAW; + if (ishelper) // Flash a helper that's about to be removed. + { + if ((actor->target->player->powers[pw_nights_helper] < TICRATE) + && (actor->target->player->powers[pw_nights_helper] & 1)) + actor->flags2 |= MF2_DONTDRAW; + else + actor->flags2 &= ~MF2_DONTDRAW; + } } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 730af9003..8de79fe92 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -597,7 +597,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) mobj->sprite2 = spr2; mobj->frame = frame|(st->frame&~FF_FRAMEMASK); - if (mobj->color > MAXSKINCOLORS) // Super colours? Super bright! + if (mobj->color >= MAXSKINCOLORS && mobj->color < MAXTRANSLATIONS) // Super colours? Super bright! mobj->frame |= FF_FULLBRIGHT; } // Regular sprites diff --git a/src/p_user.c b/src/p_user.c index cf265b645..6cc32c89a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -56,6 +56,39 @@ static void P_NukeAllPlayers(player_t *player); #endif +// +// P_GetPlayerRadius +// +// Returns the radius +// of the player. +// +fixed_t P_GetPlayerRadius(player_t *player) +{ + return FixedMul(skins[player->skin].radius, player->mo->scale); +} + +// +// P_GetPlayerHeight +// +// Returns the height +// of the player. +// +fixed_t P_GetPlayerHeight(player_t *player) +{ + return FixedMul(skins[player->skin].height, player->mo->scale); +} + +// +// P_GetPlayerSpinHeight +// +// Returns the 'spin height' +// of the player. +// +fixed_t P_GetPlayerSpinHeight(player_t *player) +{ + return FixedMul(skins[player->skin].spinheight, player->mo->scale); +} + // // Movement. // @@ -650,10 +683,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) return; if (!(player->pflags & PF_NIGHTSMODE)) - { - player->mo->radius = 16*FRACUNIT; - player->mo->height = 48*FRACUNIT; - } + player->mo->height = P_GetPlayerHeight(player); // Just to make sure jumping into the drone doesn't result in a squashed hitbox. player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_THOKKED|PF_SPINNING|PF_DRILLING); player->homing = 0; @@ -1298,39 +1328,6 @@ void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative) mo->momz = value; } -// -// P_GetPlayerRadius -// -// Returns the radius -// of the player. -// -fixed_t P_GetPlayerRadius(player_t *player) -{ - return FixedMul(skins[player->skin].radius, player->mo->scale); -} - -// -// P_GetPlayerHeight -// -// Returns the height -// of the player. -// -fixed_t P_GetPlayerHeight(player_t *player) -{ - return FixedMul(skins[player->skin].height, player->mo->scale); -} - -// -// P_GetPlayerSpinHeight -// -// Returns the 'spin height' -// of the player. -// -fixed_t P_GetPlayerSpinHeight(player_t *player) -{ - return FixedMul(skins[player->skin].spinheight, player->mo->scale); -} - // // P_IsLocalPlayer // @@ -5000,14 +4997,30 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad if (player->exiting) return; - // You're welcome, Rob. (Now with slightly less horrendous hacking -Red - /*player->mo->tracer->flags &= ~MF_NOCLIP; - player->mo->tracer->z = player->mo->z; - if (!P_TryMove(player->mo->tracer, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, true)) { - player->mo->tracer->flags |= MF_NOCLIP; - return; + /* + In some ways worse, in some ways better. + I did the following this way because the player object has to deal with touchspecials too, not just solids. + There were all sorts of fun bugs when the player got to touch the goal a frame earlier than it should've. + We could've applied MF_NOCLIPTHING, but then we'd lose out on clipping against MF_SOLIDs. Which is bad. + Instead, the object TEMPORARILY LOSES ITS PLAYER STATUS. Is that nuts? It's probably a little nuts. I know + we probably could've kept around MT_NIGHTSCHAR in some fashion, having an invisible hitbox following the + player around... but I'd already removed all its references, restructured the way the chaos emerald follows + the player around to fill the player->mo->tracer gap left behind, and NiGHTS is a lag magnet (lagnet?) + enough as it is... so whatever. You're welcome to tell me I'm terrible, but at least it works. + ~toast + */ + { + fixed_t prevx = player->mo->x; + fixed_t prevy = player->mo->y; + boolean notallowed; + player->mo->player = NULL; // YIKES + notallowed = (!(P_TryMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, true))); + P_TeleportMove(player->mo, prevx, prevy, player->mo->z); + player->mo->player = player; // unyikes + if (notallowed) + return; } - player->mo->tracer->flags |= MF_NOCLIP;*/ + { const INT32 sequence = player->mo->target->threshold; mobj_t *transfer1 = NULL; @@ -5768,7 +5781,7 @@ static void P_NiGHTSMovement(player_t *player) return; } - if (player->exiting > 0 && player->exiting < 2*TICRATE) + if (player->exiting > 0) //&& player->exiting < 2*TICRATE) { player->mo->momx = player->mo->momy = 0; @@ -6409,7 +6422,7 @@ static void P_MovePlayer(player_t *player) { if ((player->pflags & PF_NIGHTSMODE) && !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS] - && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9] + && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6] // NOT 9 - it's 6 when the player turns their supercolor. && !(player->exiting))) { skin_t *skin = ((skin_t *)(player->mo->skin)); From 8b519631f8f5581985d325b1155e65089610eb94 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 12 Aug 2016 15:40:17 +0100 Subject: [PATCH 068/100] * Keep the camera still when ending a NiGHTS map. http://gfycat.com/ComplicatedComposedAoudad * Correcting an earlier oversight with the SPR2_ defaulting system for super forms. --- src/p_mobj.c | 2 +- src/p_user.c | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 8de79fe92..4eb989a2d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -451,7 +451,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_GASP; break; case SPR2_SJMP: - spr2 = SPR2_JUMP; + spr2 = (player->charflags & SF_NOJUMPSPIN) ? SPR2_SSPG : SPR2_SSPN; break; case SPR2_SSPG: spr2 = SPR2_SPNG; diff --git a/src/p_user.c b/src/p_user.c index 6cc32c89a..583d2bb4d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5781,7 +5781,7 @@ static void P_NiGHTSMovement(player_t *player) return; } - if (player->exiting > 0) //&& player->exiting < 2*TICRATE) + if (player->exiting > 0) // && player->exiting < 2*TICRATE) { player->mo->momx = player->mo->momy = 0; @@ -8158,10 +8158,15 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall pviewheight = FixedMul(cv_viewheight.value<scale); - if (mo->eflags & MFE_VERTICALFLIP) - z = mo->z + mo->height - pviewheight - camheight; + if (!(player->pflags & PF_NIGHTSMODE && player->exiting)) // I never liked how the camera moved with the player. + { + if (mo->eflags & MFE_VERTICALFLIP) + z = mo->z + mo->height - pviewheight - camheight; + else + z = mo->z + pviewheight + camheight; + } else - z = mo->z + pviewheight + camheight; + z = thiscam->z; // move camera down to move under lower ceilings newsubsec = R_IsPointInSubsector(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1)); @@ -8418,12 +8423,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall f2 = viewpointy-thiscam->y; dist = FixedHypot(f1, f2); - if (mo->eflags & MFE_VERTICALFLIP) - angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player)); + if (!(player->pflags & PF_NIGHTSMODE && player->exiting)) // Ditto. + { + if (mo->eflags & MFE_VERTICALFLIP) + angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player)); + else + angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player)); + if (player->playerstate != PST_DEAD) + angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;' + } else - angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player)); - if (player->playerstate != PST_DEAD && !(player->pflags & PF_NIGHTSMODE && player->exiting)) - angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;' + angle = 0; if (twodlevel || (mo->flags2 & MF2_TWOD) || !camstill) // Keep the view still... { From de77dc4413a7c8eef7974da1cb7cf23a0b7a0d3c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 12 Aug 2016 19:18:50 +0100 Subject: [PATCH 069/100] Fixed a bug where NiGHTS form didn't properly account for changing skins mid-flight (devmode, maybe mp if standing on ground - haven't checked there) Also as a consequence, DEFAULTNIGHTSSKIN is #defined in r_things.h instead of p_user.c. --- src/p_user.c | 4 ---- src/r_things.c | 17 ++++++++++++----- src/r_things.h | 2 ++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 583d2bb4d..992a47d40 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -668,8 +668,6 @@ static void P_DeNightserizePlayer(player_t *player) P_RestoreMusic(player); } -#define DEFAULTNIGHTSSKIN 0 - // // P_NightserizePlayer // @@ -802,8 +800,6 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->pflags |= PF_NIGHTSMODE; } -#undef DEFAULTNIGHTSSKIN - // // P_PlayerInPain // diff --git a/src/r_things.c b/src/r_things.c index 783304868..39afabd64 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2452,13 +2452,12 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) { player_t *player = &players[playernum]; skin_t *skin = &skins[skinnum]; + UINT8 newcolor = 0; if ((skinnum >= 0 && skinnum < numskins) // Make sure it exists! && (!P_IsLocalPlayer(player) || R_SkinUnlock(skinnum))) // ...but is it allowed? We must always allow external players to change skin. The server should vet that... { player->skin = skinnum; - if (player->mo) - player->mo->skin = skin; player->charability = (UINT8)skin->ability; player->charability2 = (UINT8)skin->ability2; @@ -2487,13 +2486,21 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) CV_StealthSetValue(&cv_playercolor, skin->prefcolor); else if (playernum == secondarydisplayplayer) CV_StealthSetValue(&cv_playercolor2, skin->prefcolor); - player->skincolor = skin->prefcolor; - if (player->mo) - player->mo->color = player->skincolor; + player->skincolor = newcolor = skin->prefcolor; } if (player->mo) + { + if ((player->pflags & PF_NIGHTSMODE) && (skin->sprites[SPR2_NGT0].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. + { + skin = &skins[DEFAULTNIGHTSSKIN]; + newcolor = ((skin->flags & SF_SUPER) ? skin->supercolor : skin->prefcolor); + } + player->mo->skin = skin; + if (newcolor) + player->mo->color = newcolor; P_SetScale(player->mo, player->mo->scale); + } return; } else if (skinnum >= 0 && skinnum < numskins) diff --git a/src/r_things.h b/src/r_things.h index 671477c49..ffe34e293 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -29,6 +29,8 @@ #define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS) #define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1) +#define DEFAULTNIGHTSSKIN 0 + // Constant arrays used for psprite clipping // and initializing clipping. extern INT16 negonearray[MAXVIDWIDTH]; From 9e38f44f342e9a6bd0f825b0bb6975eb5daea30b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 12 Aug 2016 21:24:17 +0100 Subject: [PATCH 070/100] Rob requested a reversion of the NiGHTS camera changes on exiting the level, so here we go. --- src/p_user.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 992a47d40..5c3476b45 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8154,15 +8154,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall pviewheight = FixedMul(cv_viewheight.value<scale); - if (!(player->pflags & PF_NIGHTSMODE && player->exiting)) // I never liked how the camera moved with the player. - { - if (mo->eflags & MFE_VERTICALFLIP) - z = mo->z + mo->height - pviewheight - camheight; - else - z = mo->z + pviewheight + camheight; - } + if (mo->eflags & MFE_VERTICALFLIP) + z = mo->z + mo->height - pviewheight - camheight; else - z = thiscam->z; + z = mo->z + pviewheight + camheight; // move camera down to move under lower ceilings newsubsec = R_IsPointInSubsector(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1)); @@ -8419,17 +8414,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall f2 = viewpointy-thiscam->y; dist = FixedHypot(f1, f2); - if (!(player->pflags & PF_NIGHTSMODE && player->exiting)) // Ditto. - { - if (mo->eflags & MFE_VERTICALFLIP) - angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player)); - else - angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player)); - if (player->playerstate != PST_DEAD) - angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;' - } + if (mo->eflags & MFE_VERTICALFLIP) + angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player)); else - angle = 0; + angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player)); + if (player->playerstate != PST_DEAD) + angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;' if (twodlevel || (mo->flags2 & MF2_TWOD) || !camstill) // Keep the view still... { From 67f8a1295ecd2ca4ed8a31099a0867f348686987 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 16 Aug 2016 17:49:20 +0100 Subject: [PATCH 071/100] Couldn't justify my hack in the long run, so it's back to adding and removing MF_NOCLIPTHING instead of the player pointer. I DID make some steps towards re-implementing PIT_CheckThing for solids only in order to replace the hack long-term and hopefully use less CPU, but is currently disabled via #if 0 since I'm not comfortable changing the function signature of P_CheckPosition right now. --- src/p_map.c | 284 ++++++++++++++++++++++++++++++++++----------------- src/p_user.c | 11 +- 2 files changed, 196 insertions(+), 99 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index b8123fc0c..7bdbcdc23 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -378,6 +378,195 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) } } +// +// P_ConsiderSolids (moved out of PIT_CheckThing in order to have additional flexibility) +// + +static boolean P_ConsiderSolids(mobj_t *thing) +{ + // Monitors are not treated as solid to players who are jumping, spinning or gliding, + // unless it's a CTF team monitor and you're on the wrong team + if (thing->flags & MF_MONITOR && tmthing->player + && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) + || ((tmthing->player->pflags & PF_JUMPED) + && !(tmthing->player->charflags & SF_NOJUMPDAMAGE + && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) + || ((tmthing->player->charflags & SF_STOMPDAMAGE) + && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))) + && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2))) + ; + // z checking at last + // Treat noclip things as non-solid! + else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID + && (tmthing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID) + { + fixed_t topz, tmtopz; + + if (tmthing->eflags & MFE_VERTICALFLIP) + { + // pass under + tmtopz = tmthing->z; + + if (tmtopz > thing->z + thing->height) + { + if (thing->z + thing->height > tmfloorz) + { + tmfloorz = thing->z + thing->height; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + } + return true; + } + + topz = thing->z - FixedMul(FRACUNIT, thing->scale); + + // block only when jumping not high enough, + // (dont climb max. 24units while already in air) + // if not in air, let P_TryMove() decide if it's not too high + if (tmthing->player && tmthing->z + tmthing->height > topz + && tmthing->z + tmthing->height < tmthing->ceilingz) + return false; // block while in air + + if (thing->flags & MF_SPRING) + ; + else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) + { + tmceilingz = topz; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + tmfloorthing = thing; // thing we may stand on + } + } + else + { + // pass under + tmtopz = tmthing->z + tmthing->height; + + if (tmtopz < thing->z) + { + if (thing->z < tmceilingz) + { + tmceilingz = thing->z; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + } + return true; + } + + topz = thing->z + thing->height + FixedMul(FRACUNIT, thing->scale); + + // block only when jumping not high enough, + // (dont climb max. 24units while already in air) + // if not in air, let P_TryMove() decide if it's not too high + if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz) + return false; // block while in air + + if (thing->flags & MF_SPRING) + ; + else if (topz > tmfloorz && tmthing->z >= thing->z) + { + tmfloorz = topz; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + tmfloorthing = thing; // thing we may stand on + } + } + } + + // not solid not blocked + return true; +} + +#if 0 +// +// PIT_CheckSolid (PIT_CheckThing, but for solids only, and guaranteed no side effects) +// +static boolean PIT_CheckSolid(mobj_t *thing) +{ + fixed_t blockdist; + + // don't clip against self + if (thing == tmthing) + return true; + + // Ignore... things. + if (!tmthing || !thing || P_MobjWasRemoved(thing)) + return true; + + I_Assert(!P_MobjWasRemoved(tmthing)); + I_Assert(!P_MobjWasRemoved(thing)); + + if (!(thing->flags & MF_SOLID)) + return true; + + // Ignore spectators + if ((tmthing->player && tmthing->player->spectator) + || (thing->player && thing->player->spectator)) + return true; + + // Metal Sonic destroys tiny baby objects. + if (tmthing->type == MT_METALSONIC_RACE + && (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) || thing->type == MT_SPIKE)) + return true; + + // CA_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. + if ((tmthing->player) + && (((tmthing->player->charability == CA_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) + && (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE)) + || ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY)) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)) + && (thing->type == MT_SPIKE)))) + return true; + + // Don't collide with your buddies while NiGHTS-flying. + if (tmthing->player && thing->player && (maptol & TOL_NIGHTS) + && ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE))) + return true; + + blockdist = thing->radius + tmthing->radius; + + if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) + return true; // didn't hit it + + // Force solid players in hide and seek to avoid corner stacking. + if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK) + { + if (tmthing->player && thing->player) + return true; + } + + if (tmthing->player) // Is the moving/interacting object the player? + { + if (!tmthing->health) + return true; + + // Are you touching the side of the object you're interacting with? + else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height + && thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z) + { + if (thing->flags & MF_MONITOR + && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) + || ((tmthing->player->pflags & PF_JUMPED) + && !(tmthing->player->charflags & SF_NOJUMPDAMAGE + && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) + || ((tmthing->player->charflags & SF_STOMPDAMAGE) + && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))) + { + return false; + } + } + } + + return P_ConsiderSolids(thing); +} +#endif + // // PIT_CheckThing // @@ -1007,99 +1196,8 @@ static boolean PIT_CheckThing(mobj_t *thing) if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now... return false; // "cancel" P_TryMove via blocking so you keep your current position } - // Monitors are not treated as solid to players who are jumping, spinning or gliding, - // unless it's a CTF team monitor and you're on the wrong team - else if (thing->flags & MF_MONITOR && tmthing->player - && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) - || ((tmthing->player->pflags & PF_JUMPED) - && !(tmthing->player->charflags & SF_NOJUMPDAMAGE - && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) - || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) - || ((tmthing->player->charflags & SF_STOMPDAMAGE) - && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))) - && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2))) - ; - // z checking at last - // Treat noclip things as non-solid! - else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID - && (tmthing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID) - { - fixed_t topz, tmtopz; - - if (tmthing->eflags & MFE_VERTICALFLIP) - { - // pass under - tmtopz = tmthing->z; - - if (tmtopz > thing->z + thing->height) - { - if (thing->z + thing->height > tmfloorz) - { - tmfloorz = thing->z + thing->height; -#ifdef ESLOPE - tmfloorslope = NULL; -#endif - } - return true; - } - - topz = thing->z - FixedMul(FRACUNIT, thing->scale); - - // block only when jumping not high enough, - // (dont climb max. 24units while already in air) - // if not in air, let P_TryMove() decide if it's not too high - if (tmthing->player && tmthing->z + tmthing->height > topz - && tmthing->z + tmthing->height < tmthing->ceilingz) - return false; // block while in air - - if (thing->flags & MF_SPRING) - ; - else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) - { - tmceilingz = topz; -#ifdef ESLOPE - tmceilingslope = NULL; -#endif - tmfloorthing = thing; // thing we may stand on - } - } - else - { - // pass under - tmtopz = tmthing->z + tmthing->height; - - if (tmtopz < thing->z) - { - if (thing->z < tmceilingz) - { - tmceilingz = thing->z; -#ifdef ESLOPE - tmceilingslope = NULL; -#endif - } - return true; - } - - topz = thing->z + thing->height + FixedMul(FRACUNIT, thing->scale); - - // block only when jumping not high enough, - // (dont climb max. 24units while already in air) - // if not in air, let P_TryMove() decide if it's not too high - if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz) - return false; // block while in air - - if (thing->flags & MF_SPRING) - ; - else if (topz > tmfloorz && tmthing->z >= thing->z) - { - tmfloorz = topz; -#ifdef ESLOPE - tmfloorslope = NULL; -#endif - tmfloorthing = thing; // thing we may stand on - } - } - } + else + return P_ConsiderSolids(thing); // not solid not blocked return true; diff --git a/src/p_user.c b/src/p_user.c index 5c3476b45..1d0fb38c9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4997,22 +4997,21 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad In some ways worse, in some ways better. I did the following this way because the player object has to deal with touchspecials too, not just solids. There were all sorts of fun bugs when the player got to touch the goal a frame earlier than it should've. - We could've applied MF_NOCLIPTHING, but then we'd lose out on clipping against MF_SOLIDs. Which is bad. - Instead, the object TEMPORARILY LOSES ITS PLAYER STATUS. Is that nuts? It's probably a little nuts. I know - we probably could've kept around MT_NIGHTSCHAR in some fashion, having an invisible hitbox following the + Technically, we lose out on being blocked by MF_SOLID objects, but official stages don't use them on the track. + I know we probably could've kept around MT_NIGHTSCHAR in some fashion, having an invisible hitbox following the player around... but I'd already removed all its references, restructured the way the chaos emerald follows the player around to fill the player->mo->tracer gap left behind, and NiGHTS is a lag magnet (lagnet?) - enough as it is... so whatever. You're welcome to tell me I'm terrible, but at least it works. + enough as it is... so whatever. ~toast */ { fixed_t prevx = player->mo->x; fixed_t prevy = player->mo->y; boolean notallowed; - player->mo->player = NULL; // YIKES + player->mo->flags |= MF_NOCLIPTHING; // player = NULL; // YIKES notallowed = (!(P_TryMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, true))); P_TeleportMove(player->mo, prevx, prevy, player->mo->z); - player->mo->player = player; // unyikes + player->mo->flags &= ~MF_NOCLIPTHING; // player = player; // unyikes if (notallowed) return; } From cc593a6ac709d505157a640d62d8476d049e106e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 30 Aug 2016 14:50:03 +0100 Subject: [PATCH 072/100] Did a few things with spindashing: * Fixed bug where being pushed off a platform whilst charging a spindash would leave you in your charging frames instead of your rolling ones when you hit the ground (http://gfycat.com/MassiveThreadbareItalianbrownbear) * Fixed bug where spindashing on top of a bubble spawnpoint led to you being able to move around in spindash frames (no gif since obvious desired behaviour is obvious) * Spindash animation speeds up the faster you'll shoot off. * The spin charging mechanism is now scale-independent, and only multiplies by scale when shooting off - less FixedMul calls, and potentially deals with weird quirks of changing scale whilst spindashing that nobody's discovered because there's no place to find that in the main game! Also: * Climbing animation defaults to rolling instead of walking, because what. --- src/p_mobj.c | 61 ++++++++++++++++++++++++++++++++-------------------- src/p_user.c | 26 ++++++++++++---------- 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4f9807cf6..4aff6d2f9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -253,7 +253,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) player->panim = PA_PAIN; break; case S_PLAY_SPIN: - case S_PLAY_DASH: + //case S_PLAY_DASH: -- everyone can ROLL thanks to zoom tubes... case S_PLAY_SUPER_SPIN: player->panim = PA_ROLL; break; @@ -275,6 +275,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) case S_PLAY_TWINSPIN: player->panim = PA_ABILITY; break; + case S_PLAY_DASH: // ...but the act of SPINDASHING is charability2 specific. case S_PLAY_MELEE: case S_PLAY_MELEE_FINISH: player->panim = PA_ABILITY2; @@ -309,15 +310,8 @@ 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); - if (player->panim == PA_ROLL || player->panim == PA_JUMP) - { - if (speed > 16<tics = 1; - else - mobj->tics = 2; - } - else if (player->panim == PA_FALL) + fixed_t speed;// = FixedDiv(player->speed, mobj->scale); + if (player->panim == PA_FALL) { speed = FixedDiv(abs(mobj->momz), mobj->scale); if (speed < 10<tics = 1; } - else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying. + else if (player->panim == PA_ABILITY2 && player->charability2 == CA2_SPINDASH) { - if (player->panim == PA_WALK) + speed = player->maxdash/3; // We're using dashspeed as the variable to check against, but reusing speed to reduce the number of calculations done. + if (player->dashspeed > 2*speed) + mobj->tics = 1; + else if (player->dashspeed > speed) + mobj->tics = 2; + else + mobj->tics = 3; + } + else + { + speed = FixedDiv(player->speed, mobj->scale); + if (player->panim == PA_ROLL || player->panim == PA_JUMP) { - if (speed > 12<tics = 2; - else if (speed > 6<tics = 3; - else - mobj->tics = 4; - } - else if ((player->panim == PA_RUN) || (player->panim == PA_PEEL)) - { - if (speed > 52< 16<tics = 1; else mobj->tics = 2; } + else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying. + { + if (player->panim == PA_WALK) + { + if (speed > 12<tics = 2; + else if (speed > 6<tics = 3; + else + mobj->tics = 4; + } + else if ((player->panim == PA_RUN) || (player->panim == PA_PEEL)) + { + if (speed > 52<tics = 1; + else + mobj->tics = 2; + } + } } } @@ -408,7 +423,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_FLY; break; case SPR2_CLMB: - spr2 = SPR2_WALK; + spr2 = SPR2_SPIN; break; case SPR2_CLNG: spr2 = SPR2_CLMB; diff --git a/src/p_user.c b/src/p_user.c index 0a1686f25..b6b5f15e6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -900,7 +900,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) // Useful when you want to kill everything the player is doing. void P_ResetPlayer(player_t *player) { - player->pflags &= ~(PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN|PF_SPINNING|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CARRIED); + player->pflags &= ~(PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN|PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CARRIED); player->jumping = 0; player->secondjump = 0; player->glidetime = 0; @@ -3727,18 +3727,18 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->momx = player->cmomx; player->mo->momy = player->cmomy; player->pflags |= PF_STARTDASH|PF_SPINNING; - player->dashspeed = FixedMul(FRACUNIT, player->mo->scale); + player->dashspeed = FRACUNIT; player->dashtime = 0; P_SetPlayerMobjState(player->mo, S_PLAY_DASH); player->pflags |= PF_USEDOWN; } else if ((cmd->buttons & BT_USE) && (player->pflags & PF_STARTDASH)) { - player->dashspeed += FixedMul(FRACUNIT, player->mo->scale); + player->dashspeed += FRACUNIT; if (!(player->dashtime++ % 5)) { - if (!player->spectator && player->dashspeed < FixedMul(player->maxdash, player->mo->scale)) + if (!player->spectator && player->dashspeed < player->maxdash) S_StartSound(player->mo, sfx_spndsh); // Make the rev sound! // Now spawn the color thok circle. @@ -3800,7 +3800,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (player->dashspeed) { P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); - P_InstaThrust(player->mo, player->mo->angle, player->dashspeed); // catapult forward ho!! + P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->dashspeed, player->mo->scale)); // catapult forward ho!! } else { @@ -3815,8 +3815,11 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->dashspeed = 0; } - if (onground && player->pflags & PF_STARTDASH && player->mo->state-states != S_PLAY_DASH) - P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + if (onground && player->pflags & PF_STARTDASH) + { + if (player->mo->state-states != S_PLAY_DASH) + P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + } else if (onground && player->pflags & PF_SPINNING && !(player->panim == PA_ROLL)) P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); @@ -3829,6 +3832,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) #endif ) { + P_ResetPlayer(player); player->mo->z += P_MobjFlip(player->mo); player->mo->momx = player->cmomx = 0; player->mo->momy = player->cmomy = 0; @@ -6566,10 +6570,10 @@ static void P_MovePlayer(player_t *player) // Cap the speed limit on a spindash // Up the 60*FRACUNIT number to boost faster, you speed demon you! - if (player->dashspeed > FixedMul(player->maxdash, player->mo->scale)) - player->dashspeed = FixedMul(player->maxdash, player->mo->scale); - else if (player->dashspeed > 0 && player->dashspeed < FixedMul(player->mindash, player->mo->scale)) - player->dashspeed = FixedMul(player->mindash, player->mo->scale); + if (player->dashspeed > player->maxdash) + player->dashspeed = player->maxdash; + else if (player->dashspeed > 0 && player->dashspeed < player->mindash) + player->dashspeed = player->mindash; if (!(player->charability == CA_GLIDEANDCLIMB) || player->gotflag) // If you can't glide, then why the heck would you be gliding? { From 42d527a955b3ee6a95ba20e96125f6a480e5dc41 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 30 Aug 2016 15:00:01 +0100 Subject: [PATCH 073/100] Did a few things with spindashing: * Fixed bug where being pushed off a platform whilst charging a spindash would leave you in your charging frames instead of your rolling ones when you hit the ground (http://gfycat.com/MassiveThreadbareItalianbrownbear for how it works now, http://gfycat.com/MarvelousEnlightenedAuk is how it used to work) * Fixed bug where spindashing on top of a bubble spawnpoint led to you being able to move around in spindash frames (no gif since obvious desired behaviour is obvious) * Spindash animation speeds up the faster you'll shoot off. * The spin charging mechanism is now scale-independent, and only multiplies by scale when shooting off - less FixedMul calls, and potentially deals with weird quirks of changing scale whilst spindashing that nobody's discovered because there's no place to find that in the main game! Also: * Climbing animation defaults to rolling instead of walking, because what. --- src/p_mobj.c | 61 ++++++++++++++++++++++++++++++++-------------------- src/p_user.c | 26 ++++++++++++---------- 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4f9807cf6..4aff6d2f9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -253,7 +253,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) player->panim = PA_PAIN; break; case S_PLAY_SPIN: - case S_PLAY_DASH: + //case S_PLAY_DASH: -- everyone can ROLL thanks to zoom tubes... case S_PLAY_SUPER_SPIN: player->panim = PA_ROLL; break; @@ -275,6 +275,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) case S_PLAY_TWINSPIN: player->panim = PA_ABILITY; break; + case S_PLAY_DASH: // ...but the act of SPINDASHING is charability2 specific. case S_PLAY_MELEE: case S_PLAY_MELEE_FINISH: player->panim = PA_ABILITY2; @@ -309,15 +310,8 @@ 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); - if (player->panim == PA_ROLL || player->panim == PA_JUMP) - { - if (speed > 16<tics = 1; - else - mobj->tics = 2; - } - else if (player->panim == PA_FALL) + fixed_t speed;// = FixedDiv(player->speed, mobj->scale); + if (player->panim == PA_FALL) { speed = FixedDiv(abs(mobj->momz), mobj->scale); if (speed < 10<tics = 1; } - else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying. + else if (player->panim == PA_ABILITY2 && player->charability2 == CA2_SPINDASH) { - if (player->panim == PA_WALK) + speed = player->maxdash/3; // We're using dashspeed as the variable to check against, but reusing speed to reduce the number of calculations done. + if (player->dashspeed > 2*speed) + mobj->tics = 1; + else if (player->dashspeed > speed) + mobj->tics = 2; + else + mobj->tics = 3; + } + else + { + speed = FixedDiv(player->speed, mobj->scale); + if (player->panim == PA_ROLL || player->panim == PA_JUMP) { - if (speed > 12<tics = 2; - else if (speed > 6<tics = 3; - else - mobj->tics = 4; - } - else if ((player->panim == PA_RUN) || (player->panim == PA_PEEL)) - { - if (speed > 52< 16<tics = 1; else mobj->tics = 2; } + else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying. + { + if (player->panim == PA_WALK) + { + if (speed > 12<tics = 2; + else if (speed > 6<tics = 3; + else + mobj->tics = 4; + } + else if ((player->panim == PA_RUN) || (player->panim == PA_PEEL)) + { + if (speed > 52<tics = 1; + else + mobj->tics = 2; + } + } } } @@ -408,7 +423,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_FLY; break; case SPR2_CLMB: - spr2 = SPR2_WALK; + spr2 = SPR2_SPIN; break; case SPR2_CLNG: spr2 = SPR2_CLMB; diff --git a/src/p_user.c b/src/p_user.c index 0a1686f25..b6b5f15e6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -900,7 +900,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) // Useful when you want to kill everything the player is doing. void P_ResetPlayer(player_t *player) { - player->pflags &= ~(PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN|PF_SPINNING|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CARRIED); + player->pflags &= ~(PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN|PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CARRIED); player->jumping = 0; player->secondjump = 0; player->glidetime = 0; @@ -3727,18 +3727,18 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->momx = player->cmomx; player->mo->momy = player->cmomy; player->pflags |= PF_STARTDASH|PF_SPINNING; - player->dashspeed = FixedMul(FRACUNIT, player->mo->scale); + player->dashspeed = FRACUNIT; player->dashtime = 0; P_SetPlayerMobjState(player->mo, S_PLAY_DASH); player->pflags |= PF_USEDOWN; } else if ((cmd->buttons & BT_USE) && (player->pflags & PF_STARTDASH)) { - player->dashspeed += FixedMul(FRACUNIT, player->mo->scale); + player->dashspeed += FRACUNIT; if (!(player->dashtime++ % 5)) { - if (!player->spectator && player->dashspeed < FixedMul(player->maxdash, player->mo->scale)) + if (!player->spectator && player->dashspeed < player->maxdash) S_StartSound(player->mo, sfx_spndsh); // Make the rev sound! // Now spawn the color thok circle. @@ -3800,7 +3800,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (player->dashspeed) { P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); - P_InstaThrust(player->mo, player->mo->angle, player->dashspeed); // catapult forward ho!! + P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->dashspeed, player->mo->scale)); // catapult forward ho!! } else { @@ -3815,8 +3815,11 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->dashspeed = 0; } - if (onground && player->pflags & PF_STARTDASH && player->mo->state-states != S_PLAY_DASH) - P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + if (onground && player->pflags & PF_STARTDASH) + { + if (player->mo->state-states != S_PLAY_DASH) + P_SetPlayerMobjState(player->mo, S_PLAY_DASH); + } else if (onground && player->pflags & PF_SPINNING && !(player->panim == PA_ROLL)) P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); @@ -3829,6 +3832,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) #endif ) { + P_ResetPlayer(player); player->mo->z += P_MobjFlip(player->mo); player->mo->momx = player->cmomx = 0; player->mo->momy = player->cmomy = 0; @@ -6566,10 +6570,10 @@ static void P_MovePlayer(player_t *player) // Cap the speed limit on a spindash // Up the 60*FRACUNIT number to boost faster, you speed demon you! - if (player->dashspeed > FixedMul(player->maxdash, player->mo->scale)) - player->dashspeed = FixedMul(player->maxdash, player->mo->scale); - else if (player->dashspeed > 0 && player->dashspeed < FixedMul(player->mindash, player->mo->scale)) - player->dashspeed = FixedMul(player->mindash, player->mo->scale); + if (player->dashspeed > player->maxdash) + player->dashspeed = player->maxdash; + else if (player->dashspeed > 0 && player->dashspeed < player->mindash) + player->dashspeed = player->mindash; if (!(player->charability == CA_GLIDEANDCLIMB) || player->gotflag) // If you can't glide, then why the heck would you be gliding? { From c07f273af0107ef7e38addec1e888579b63e883d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 30 Aug 2016 16:41:00 +0100 Subject: [PATCH 074/100] Fixed some oversights with the spindash dashspeed changes --- src/p_mobj.c | 1 - src/st_stuff.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4aff6d2f9..6b12bdca6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6198,7 +6198,6 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale) { G_GhostAddScale(newscale); player->viewheight = FixedMul(FixedDiv(player->viewheight, oldscale), newscale); // Nonono don't calculate viewheight elsewhere, this is the best place for it! - player->dashspeed = FixedMul(FixedDiv(player->dashspeed, oldscale), newscale); // Prevents the player from having to re-charge up spindash if the player grew in size } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 2f569e1ce..340f8a2b2 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -565,7 +565,7 @@ static void ST_drawDebugInfo(void) { V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield])); V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT)); - V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, FixedMul(stplyr->maxdash,stplyr->mo->scale)>>FRACBITS)); + V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, stplyr->maxdash>>FRACBITS)); V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); // Flags From 73843764de9df4096cbcf85b99e72d9f16041c21 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 2 Sep 2016 17:27:39 +0100 Subject: [PATCH 075/100] Some more spindash changes. NOTE that this temporarily breaks the charging aura; if we want to, we can either kill that entirely or re-enable it - but none of the main characters are using it, and Lua makes having a dedicated charging aura irrelevant if the main characters don't use it... * Spindash sound only plays six times during the charge, equally spaced up until you finish charging. * Spindash animation speed increase rebalanced. --- src/p_mobj.c | 7 ++++--- src/p_user.c | 13 ++++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 6b12bdca6..9f95f012b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -325,10 +325,11 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) } else if (player->panim == PA_ABILITY2 && player->charability2 == CA2_SPINDASH) { - speed = player->maxdash/3; // We're using dashspeed as the variable to check against, but reusing speed to reduce the number of calculations done. - if (player->dashspeed > 2*speed) + fixed_t step = (player->maxdash - player->mindash)/4; + speed = (player->dashspeed - player->mindash); + if (speed > 3*step) mobj->tics = 1; - else if (player->dashspeed > speed) + else if (speed > step) mobj->tics = 2; else mobj->tics = 3; diff --git a/src/p_user.c b/src/p_user.c index b6b5f15e6..73f68e60e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3731,15 +3731,22 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->dashtime = 0; P_SetPlayerMobjState(player->mo, S_PLAY_DASH); player->pflags |= PF_USEDOWN; + if (!player->spectator) + S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. } else if ((cmd->buttons & BT_USE) && (player->pflags & PF_STARTDASH)) { +#define chargecalculation (6*(player->dashspeed - player->mindash))/(player->maxdash - player->mindash) + fixed_t soundcalculation = chargecalculation; player->dashspeed += FRACUNIT; + if (!player->spectator && soundcalculation != chargecalculation) + S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. +#undef chargecalculation - if (!(player->dashtime++ % 5)) + /*if (!(player->dashtime++ % 5)) { if (!player->spectator && player->dashspeed < player->maxdash) - S_StartSound(player->mo, sfx_spndsh); // Make the rev sound! + S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. // Now spawn the color thok circle. if (player->revitem) @@ -3748,7 +3755,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (demorecording) G_GhostAddRev(); } - } + }*/ } // If not moving up or down, and travelling faster than a speed of four while not holding // down the spin button and not spinning. From 0852a20014adb914ba7e56d6872a7eebc830664e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 2 Sep 2016 18:12:46 +0100 Subject: [PATCH 076/100] Revitem is saved by tying it to leveltime instead of dashtime, whilst dashtime is now dead. --- src/d_clisrv.c | 2 -- src/d_clisrv.h | 1 - src/d_player.h | 1 - src/lua_playerlib.c | 4 ---- src/p_saveg.c | 2 -- src/p_user.c | 20 ++++++-------------- 6 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e49f37e2a..f4caf66e6 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -550,7 +550,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->maxlink = LONG(players[i].maxlink); rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed); - rsp->dashtime = LONG(players[i].dashtime); rsp->angle_pos = (angle_t)LONG(players[i].angle_pos); rsp->old_angle_pos = (angle_t)LONG(players[i].old_angle_pos); rsp->bumpertime = (tic_t)LONG(players[i].bumpertime); @@ -677,7 +676,6 @@ static void resynch_read_player(resynch_pak *rsp) players[i].maxlink = LONG(rsp->maxlink); players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed); - players[i].dashtime = LONG(rsp->dashtime); players[i].angle_pos = (angle_t)LONG(rsp->angle_pos); players[i].old_angle_pos = (angle_t)LONG(rsp->old_angle_pos); players[i].bumpertime = (tic_t)LONG(rsp->bumpertime); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index f9e33dc4c..9d130618b 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -210,7 +210,6 @@ typedef struct INT32 maxlink; fixed_t dashspeed; - INT32 dashtime; angle_t angle_pos; angle_t old_angle_pos; tic_t bumpertime; diff --git a/src/d_player.h b/src/d_player.h index f57eb90cf..59875b4cc 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -319,7 +319,6 @@ typedef struct player_s UINT32 score; // player score fixed_t dashspeed; // dashing speed - INT32 dashtime; // tics dashing, used for rev sound fixed_t normalspeed; // Normal ground fixed_t runspeed; // Speed you break into the run animation diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 60119deae..c83aa8811 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -142,8 +142,6 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->score); else if (fastcmp(field,"dashspeed")) lua_pushfixed(L, plr->dashspeed); - else if (fastcmp(field,"dashtime")) - lua_pushinteger(L, plr->dashtime); else if (fastcmp(field,"normalspeed")) lua_pushfixed(L, plr->normalspeed); else if (fastcmp(field,"runspeed")) @@ -401,8 +399,6 @@ static int player_set(lua_State *L) plr->score = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"dashspeed")) plr->dashspeed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"dashtime")) - plr->dashtime = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"normalspeed")) plr->normalspeed = luaL_checkfixed(L, 3); else if (fastcmp(field,"runspeed")) diff --git a/src/p_saveg.c b/src/p_saveg.c index 964e8b774..768949b3c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -147,7 +147,6 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].score); WRITEFIXED(save_p, players[i].dashspeed); - WRITEINT32(save_p, players[i].dashtime); WRITESINT8(save_p, players[i].lives); WRITESINT8(save_p, players[i].continues); WRITESINT8(save_p, players[i].xtralife); @@ -323,7 +322,6 @@ static void P_NetUnArchivePlayers(void) players[i].score = READUINT32(save_p); players[i].dashspeed = READFIXED(save_p); // dashing speed - players[i].dashtime = READINT32(save_p); // dashing speed players[i].lives = READSINT8(save_p); players[i].continues = READSINT8(save_p); // continues that player has acquired players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter diff --git a/src/p_user.c b/src/p_user.c index 73f68e60e..b165560f4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3728,7 +3728,6 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->momy = player->cmomy; player->pflags |= PF_STARTDASH|PF_SPINNING; player->dashspeed = FRACUNIT; - player->dashtime = 0; P_SetPlayerMobjState(player->mo, S_PLAY_DASH); player->pflags |= PF_USEDOWN; if (!player->spectator) @@ -3742,21 +3741,14 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (!player->spectator && soundcalculation != chargecalculation) S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. #undef chargecalculation - - /*if (!(player->dashtime++ % 5)) + if (player->revitem && !(leveltime % 5)) // Now spawn the color thok circle. { - if (!player->spectator && player->dashspeed < player->maxdash) - S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. - - // Now spawn the color thok circle. - if (player->revitem) - { - P_SpawnSpinMobj(player, player->revitem); - if (demorecording) - G_GhostAddRev(); - } - }*/ + P_SpawnSpinMobj(player, player->revitem); + if (demorecording) + G_GhostAddRev(); + } } + // If not moving up or down, and travelling faster than a speed of four while not holding // down the spin button and not spinning. // AKA Just go into a spin on the ground, you idiot. ;) From 58f815ddbce985a5dc9442e0521c52fb1c87ba6e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Sep 2016 15:51:38 +0100 Subject: [PATCH 077/100] Revert "Revitem is saved by tying it to leveltime instead of dashtime, whilst dashtime is now dead." This reverts commit 0852a20014adb914ba7e56d6872a7eebc830664e. --- src/d_clisrv.c | 2 ++ src/d_clisrv.h | 1 + src/d_player.h | 1 + src/lua_playerlib.c | 4 ++++ src/p_saveg.c | 2 ++ src/p_user.c | 22 +++++++++++++++------- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f4caf66e6..e49f37e2a 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -550,6 +550,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->maxlink = LONG(players[i].maxlink); rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed); + rsp->dashtime = LONG(players[i].dashtime); rsp->angle_pos = (angle_t)LONG(players[i].angle_pos); rsp->old_angle_pos = (angle_t)LONG(players[i].old_angle_pos); rsp->bumpertime = (tic_t)LONG(players[i].bumpertime); @@ -676,6 +677,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].maxlink = LONG(rsp->maxlink); players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed); + players[i].dashtime = LONG(rsp->dashtime); players[i].angle_pos = (angle_t)LONG(rsp->angle_pos); players[i].old_angle_pos = (angle_t)LONG(rsp->old_angle_pos); players[i].bumpertime = (tic_t)LONG(rsp->bumpertime); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 9d130618b..f9e33dc4c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -210,6 +210,7 @@ typedef struct INT32 maxlink; fixed_t dashspeed; + INT32 dashtime; angle_t angle_pos; angle_t old_angle_pos; tic_t bumpertime; diff --git a/src/d_player.h b/src/d_player.h index 59875b4cc..f57eb90cf 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -319,6 +319,7 @@ typedef struct player_s UINT32 score; // player score fixed_t dashspeed; // dashing speed + INT32 dashtime; // tics dashing, used for rev sound fixed_t normalspeed; // Normal ground fixed_t runspeed; // Speed you break into the run animation diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index c83aa8811..60119deae 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -142,6 +142,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->score); else if (fastcmp(field,"dashspeed")) lua_pushfixed(L, plr->dashspeed); + else if (fastcmp(field,"dashtime")) + lua_pushinteger(L, plr->dashtime); else if (fastcmp(field,"normalspeed")) lua_pushfixed(L, plr->normalspeed); else if (fastcmp(field,"runspeed")) @@ -399,6 +401,8 @@ static int player_set(lua_State *L) plr->score = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"dashspeed")) plr->dashspeed = luaL_checkfixed(L, 3); + else if (fastcmp(field,"dashtime")) + plr->dashtime = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"normalspeed")) plr->normalspeed = luaL_checkfixed(L, 3); else if (fastcmp(field,"runspeed")) diff --git a/src/p_saveg.c b/src/p_saveg.c index 768949b3c..964e8b774 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -147,6 +147,7 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].score); WRITEFIXED(save_p, players[i].dashspeed); + WRITEINT32(save_p, players[i].dashtime); WRITESINT8(save_p, players[i].lives); WRITESINT8(save_p, players[i].continues); WRITESINT8(save_p, players[i].xtralife); @@ -322,6 +323,7 @@ static void P_NetUnArchivePlayers(void) players[i].score = READUINT32(save_p); players[i].dashspeed = READFIXED(save_p); // dashing speed + players[i].dashtime = READINT32(save_p); // dashing speed players[i].lives = READSINT8(save_p); players[i].continues = READSINT8(save_p); // continues that player has acquired players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter diff --git a/src/p_user.c b/src/p_user.c index b165560f4..73f68e60e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3728,6 +3728,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->momy = player->cmomy; player->pflags |= PF_STARTDASH|PF_SPINNING; player->dashspeed = FRACUNIT; + player->dashtime = 0; P_SetPlayerMobjState(player->mo, S_PLAY_DASH); player->pflags |= PF_USEDOWN; if (!player->spectator) @@ -3741,14 +3742,21 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (!player->spectator && soundcalculation != chargecalculation) S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. #undef chargecalculation - if (player->revitem && !(leveltime % 5)) // Now spawn the color thok circle. - { - P_SpawnSpinMobj(player, player->revitem); - if (demorecording) - G_GhostAddRev(); - } - } + /*if (!(player->dashtime++ % 5)) + { + if (!player->spectator && player->dashspeed < player->maxdash) + S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. + + // Now spawn the color thok circle. + if (player->revitem) + { + P_SpawnSpinMobj(player, player->revitem); + if (demorecording) + G_GhostAddRev(); + } + }*/ + } // If not moving up or down, and travelling faster than a speed of four while not holding // down the spin button and not spinning. // AKA Just go into a spin on the ground, you idiot. ;) From 2cee8c1a8d26e8f898dd8fe54beb2a031f363776 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Sep 2016 16:05:58 +0100 Subject: [PATCH 078/100] SORRY, I SHOULDN'T HAVE PUSHED THE PREVIOUS THING Revert "Revert "Revitem is saved by tying it to leveltime instead of dashtime, whilst dashtime is now dead."" This reverts commit 58f815ddbce985a5dc9442e0521c52fb1c87ba6e. --- src/d_clisrv.c | 2 -- src/d_clisrv.h | 1 - src/d_player.h | 1 - src/lua_playerlib.c | 4 ---- src/p_saveg.c | 2 -- src/p_user.c | 20 ++++++-------------- 6 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e49f37e2a..f4caf66e6 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -550,7 +550,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->maxlink = LONG(players[i].maxlink); rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed); - rsp->dashtime = LONG(players[i].dashtime); rsp->angle_pos = (angle_t)LONG(players[i].angle_pos); rsp->old_angle_pos = (angle_t)LONG(players[i].old_angle_pos); rsp->bumpertime = (tic_t)LONG(players[i].bumpertime); @@ -677,7 +676,6 @@ static void resynch_read_player(resynch_pak *rsp) players[i].maxlink = LONG(rsp->maxlink); players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed); - players[i].dashtime = LONG(rsp->dashtime); players[i].angle_pos = (angle_t)LONG(rsp->angle_pos); players[i].old_angle_pos = (angle_t)LONG(rsp->old_angle_pos); players[i].bumpertime = (tic_t)LONG(rsp->bumpertime); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index f9e33dc4c..9d130618b 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -210,7 +210,6 @@ typedef struct INT32 maxlink; fixed_t dashspeed; - INT32 dashtime; angle_t angle_pos; angle_t old_angle_pos; tic_t bumpertime; diff --git a/src/d_player.h b/src/d_player.h index f57eb90cf..59875b4cc 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -319,7 +319,6 @@ typedef struct player_s UINT32 score; // player score fixed_t dashspeed; // dashing speed - INT32 dashtime; // tics dashing, used for rev sound fixed_t normalspeed; // Normal ground fixed_t runspeed; // Speed you break into the run animation diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 60119deae..c83aa8811 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -142,8 +142,6 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->score); else if (fastcmp(field,"dashspeed")) lua_pushfixed(L, plr->dashspeed); - else if (fastcmp(field,"dashtime")) - lua_pushinteger(L, plr->dashtime); else if (fastcmp(field,"normalspeed")) lua_pushfixed(L, plr->normalspeed); else if (fastcmp(field,"runspeed")) @@ -401,8 +399,6 @@ static int player_set(lua_State *L) plr->score = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"dashspeed")) plr->dashspeed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"dashtime")) - plr->dashtime = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"normalspeed")) plr->normalspeed = luaL_checkfixed(L, 3); else if (fastcmp(field,"runspeed")) diff --git a/src/p_saveg.c b/src/p_saveg.c index 964e8b774..768949b3c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -147,7 +147,6 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].score); WRITEFIXED(save_p, players[i].dashspeed); - WRITEINT32(save_p, players[i].dashtime); WRITESINT8(save_p, players[i].lives); WRITESINT8(save_p, players[i].continues); WRITESINT8(save_p, players[i].xtralife); @@ -323,7 +322,6 @@ static void P_NetUnArchivePlayers(void) players[i].score = READUINT32(save_p); players[i].dashspeed = READFIXED(save_p); // dashing speed - players[i].dashtime = READINT32(save_p); // dashing speed players[i].lives = READSINT8(save_p); players[i].continues = READSINT8(save_p); // continues that player has acquired players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter diff --git a/src/p_user.c b/src/p_user.c index 73f68e60e..b165560f4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3728,7 +3728,6 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->momy = player->cmomy; player->pflags |= PF_STARTDASH|PF_SPINNING; player->dashspeed = FRACUNIT; - player->dashtime = 0; P_SetPlayerMobjState(player->mo, S_PLAY_DASH); player->pflags |= PF_USEDOWN; if (!player->spectator) @@ -3742,21 +3741,14 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (!player->spectator && soundcalculation != chargecalculation) S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. #undef chargecalculation - - /*if (!(player->dashtime++ % 5)) + if (player->revitem && !(leveltime % 5)) // Now spawn the color thok circle. { - if (!player->spectator && player->dashspeed < player->maxdash) - S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. - - // Now spawn the color thok circle. - if (player->revitem) - { - P_SpawnSpinMobj(player, player->revitem); - if (demorecording) - G_GhostAddRev(); - } - }*/ + P_SpawnSpinMobj(player, player->revitem); + if (demorecording) + G_GhostAddRev(); + } } + // If not moving up or down, and travelling faster than a speed of four while not holding // down the spin button and not spinning. // AKA Just go into a spin on the ground, you idiot. ;) From c11d8da3a34d9f356e8b2871798838612bbce99e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Sep 2016 16:20:04 +0100 Subject: [PATCH 079/100] No need to check for under/overflow outside of the spindash code, let's just start at the mindash and not add power if you're over instead. --- src/p_user.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index b165560f4..003fe9c87 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3727,7 +3727,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->momx = player->cmomx; player->mo->momy = player->cmomy; player->pflags |= PF_STARTDASH|PF_SPINNING; - player->dashspeed = FRACUNIT; + player->dashspeed = player->mindash; P_SetPlayerMobjState(player->mo, S_PLAY_DASH); player->pflags |= PF_USEDOWN; if (!player->spectator) @@ -3735,12 +3735,15 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) } else if ((cmd->buttons & BT_USE) && (player->pflags & PF_STARTDASH)) { + if (player->dashspeed < player->maxdash) + { #define chargecalculation (6*(player->dashspeed - player->mindash))/(player->maxdash - player->mindash) - fixed_t soundcalculation = chargecalculation; - player->dashspeed += FRACUNIT; - if (!player->spectator && soundcalculation != chargecalculation) - S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. + fixed_t soundcalculation = chargecalculation; + player->dashspeed += FRACUNIT; + if (!player->spectator && soundcalculation != chargecalculation) + S_StartSound(player->mo, sfx_s3kab); // Make the rev sound! Previously sfx_spndsh. #undef chargecalculation + } if (player->revitem && !(leveltime % 5)) // Now spawn the color thok circle. { P_SpawnSpinMobj(player, player->revitem); @@ -6567,13 +6570,6 @@ static void P_MovePlayer(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_STND); } - // Cap the speed limit on a spindash - // Up the 60*FRACUNIT number to boost faster, you speed demon you! - if (player->dashspeed > player->maxdash) - player->dashspeed = player->maxdash; - else if (player->dashspeed > 0 && player->dashspeed < player->mindash) - player->dashspeed = player->mindash; - if (!(player->charability == CA_GLIDEANDCLIMB) || player->gotflag) // If you can't glide, then why the heck would you be gliding? { if (player->pflags & PF_GLIDING || player->climbing) From 0333c9db94b3735aa3a6e590fefa7102b2d4747d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 3 Sep 2016 20:00:29 +0100 Subject: [PATCH 080/100] P_MobjCheckWater now properly accounts for changing heights (skin non-spin height for players, mobj height otherwise) instead of mobj info height. Also, the particles made via spindashing in shallow water are now located behind the player. This does move the running particles too, but that's okay. --- src/p_mobj.c | 43 +++++++++++++++++++++---------------------- src/p_user.c | 2 +- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 9f95f012b..9fb0063d9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3481,10 +3481,11 @@ void P_MobjCheckWater(mobj_t *mobj) boolean waterwasnotset = (mobj->watertop == INT32_MAX); boolean wasinwater = (mobj->eflags & MFE_UNDERWATER) == MFE_UNDERWATER; boolean wasingoo = (mobj->eflags & MFE_GOOWATER) == MFE_GOOWATER; - fixed_t thingtop = mobj->z + mobj->height; // especially for players, infotable height does not neccessarily match actual height + fixed_t thingtop = mobj->z + mobj->height; sector_t *sector = mobj->subsector->sector; ffloor_t *rover; player_t *p = mobj->player; // Will just be null if not a player. + fixed_t height = (p ? P_GetPlayerHeight(p) : mobj->height); // for players, calculation height does not necessarily match actual height for gameplay reasons (spin, etc) // Default if no water exists. mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT; @@ -3513,14 +3514,14 @@ void P_MobjCheckWater(mobj_t *mobj) if (mobj->eflags & MFE_VERTICALFLIP) { - if (topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale)) + if (topheight < (thingtop - (height>>1)) || bottomheight > thingtop) continue; } else { if (topheight < mobj->z - || bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale))) + || bottomheight > (mobj->z + (height>>1))) continue; } @@ -3529,16 +3530,16 @@ void P_MobjCheckWater(mobj_t *mobj) mobj->waterbottom = bottomheight; // Just touching the water? - if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < bottomheight) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight)) + if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - height < bottomheight) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + height > topheight)) { mobj->eflags |= MFE_TOUCHWATER; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) mobj->eflags |= MFE_GOOWATER; } // Actually in the water? - if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > bottomheight) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < topheight)) + if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - (height>>1) > bottomheight) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + (height>>1) < topheight)) { mobj->eflags |= MFE_UNDERWATER; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) @@ -3546,6 +3547,10 @@ void P_MobjCheckWater(mobj_t *mobj) } } + // Spectators and dead players don't get to do any of the things after this. + if (p && (p->spectator || p->playerstate != PST_LIVE)) + return; + // Specific things for underwater players if (p && (mobj->eflags & MFE_UNDERWATER) == MFE_UNDERWATER) { @@ -3578,10 +3583,6 @@ void P_MobjCheckWater(mobj_t *mobj) if (waterwasnotset || !!(mobj->eflags & MFE_UNDERWATER) == wasinwater) return; - // Spectators and dead players also don't count. - if (p && (p->spectator || p->playerstate != PST_LIVE)) - return; - if ((p) // Players || (mobj->flags & MF_PUSHABLE) // Pushables || ((mobj->info->flags & MF_PUSHABLE) && mobj->fuse) // Previously pushable, might be moving still @@ -3589,10 +3590,8 @@ void P_MobjCheckWater(mobj_t *mobj) { // Check to make sure you didn't just cross into a sector to jump out of // that has shallower water than the block you were originally in. - if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->watertop-mobj->floorz <= FixedMul(mobj->info->height, mobj->scale)>>1) - return; - - if ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= FixedMul(mobj->info->height, mobj->scale)>>1) + if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->watertop-mobj->floorz <= height>>1) + || ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= height>>1)) return; if ((mobj->eflags & MFE_GOOWATER || wasingoo)) { // Decide what happens to your momentum when you enter/leave goopy water. @@ -3604,8 +3603,8 @@ void P_MobjCheckWater(mobj_t *mobj) if (P_MobjFlip(mobj)*mobj->momz < 0) { - if ((mobj->eflags & MFE_VERTICALFLIP && thingtop-(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz <= mobj->waterbottom) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz >= mobj->watertop)) + if ((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz <= mobj->waterbottom) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz >= mobj->watertop)) { // Spawn a splash mobj_t *splish; @@ -3638,8 +3637,8 @@ void P_MobjCheckWater(mobj_t *mobj) } else if (P_MobjFlip(mobj)*mobj->momz > 0) { - if (((mobj->eflags & MFE_VERTICALFLIP && thingtop-(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz > mobj->waterbottom) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(FixedMul(mobj->info->height, mobj->scale)>>1)-mobj->momz < mobj->watertop)) + if (((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz > mobj->waterbottom) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz < mobj->watertop)) && !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side { // Spawn a splash @@ -3744,10 +3743,10 @@ static void P_SceneryCheckWater(mobj_t *mobj) #endif if (topheight <= mobj->z - || bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale))) + || bottomheight > (mobj->z + (mobj->height>>1))) continue; - if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight) + if (mobj->z + mobj->height > topheight) mobj->eflags |= MFE_TOUCHWATER; else mobj->eflags &= ~MFE_TOUCHWATER; @@ -3756,7 +3755,7 @@ static void P_SceneryCheckWater(mobj_t *mobj) mobj->watertop = topheight; mobj->waterbottom = bottomheight; - if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < topheight) + if (mobj->z + (mobj->height>>1) < topheight) mobj->eflags |= MFE_UNDERWATER; else mobj->eflags &= ~MFE_UNDERWATER; diff --git a/src/p_user.c b/src/p_user.c index 003fe9c87..5149f8d73 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6671,7 +6671,7 @@ static void P_MovePlayer(player_t *player) && (player->speed > runspd || (player->pflags & PF_STARTDASH)) && leveltime % (TICRATE/7) == 0 && player->mo->momz == 0 && !(player->pflags & PF_SLIDING) && !player->spectator) { - mobj_t *water = P_SpawnMobj(player->mo->x, player->mo->y, + mobj_t *water = P_SpawnMobj(player->mo->x - P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius), player->mo->y - P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius), ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_SPLISH].height, player->mo->scale) : player->mo->watertop), MT_SPLISH); if (player->mo->eflags & MFE_GOOWATER) S_StartSound(water, sfx_ghit); From df7b375f05f146e1656d7af7dd727f74982b221a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 8 Sep 2016 13:57:43 +0100 Subject: [PATCH 081/100] Corrected an oversight for horizontal springs the introduction of PA_JUMP caused. --- src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index c8ae4089f..0b4987c49 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -211,7 +211,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) P_SetPlayerMobjState(object, S_PLAY_FALL); else // horizontal spring { - if (pflags & (PF_JUMPED|PF_SPINNING) && object->player->panim == PA_ROLL) + if (pflags & (PF_JUMPED|PF_SPINNING) && (object->player->panim == PA_ROLL || object->player->panim == PA_JUMP || object->player->panim == PA_FALL)) object->player->pflags = pflags; else P_SetPlayerMobjState(object, S_PLAY_WALK); From 941bf8eb03174cd1c7fca04ad9bd5ab5f3effe22 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 8 Sep 2016 14:38:57 +0100 Subject: [PATCH 082/100] Corrected multiple oversights with swimming players dropping their friends when they shouldn't. --- src/p_map.c | 5 ++++- src/p_user.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 0b4987c49..48946a4ba 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -307,7 +307,10 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) if ((sonic->pflags & PF_CARRIED) && sonic->mo->tracer == tails->mo) return; - if (!tails->powers[pw_tailsfly] && !(tails->charability == CA_FLY && tails->mo->state-states == S_PLAY_FLY_TIRED)) + if (tails->charability != CA_FLY && tails->charability != CA_SWIM) + return; + + if (!tails->powers[pw_tailsfly] && tails->mo->state-states != S_PLAY_FLY_TIRED) return; if (tails->bot == 1) diff --git a/src/p_user.c b/src/p_user.c index 5149f8d73..2934bc2ae 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9405,7 +9405,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT)); if (player->mo->tracer->player - && player->mo->tracer->state-states != S_PLAY_FLY + && !player->mo->tracer->player->powers[pw_tailsfly] && player->mo->tracer->state-states != S_PLAY_FLY_TIRED) player->pflags &= ~PF_CARRIED; From fb377ad44fb3d38515748b6b7a22143a612e5cfe Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 8 Sep 2016 17:48:54 +0100 Subject: [PATCH 083/100] Minor tweaks to animations and endsigns. --- src/p_user.c | 2 +- src/r_draw.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 2934bc2ae..8c58838d1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6857,7 +6857,7 @@ static void P_MovePlayer(player_t *player) } // Otherwise, face the direction you're travelling. else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_PEEL || player->panim == PA_ROLL || player->panim == PA_JUMP - || (player->mo->state-states == S_PLAY_FLY || player->mo->state-states == S_PLAY_FLY_TIRED)) + || (player->panim == PA_ABILITY && player->mo->state-states == S_PLAY_GLIDE)) player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy); // Update the local angle control. diff --git a/src/r_draw.c b/src/r_draw.c index 9188e082e..2c1f18826 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -210,11 +210,11 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] = SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE SKINCOLOR_PINK,8, // SKINCOLOR_AZURE - ditto SKINCOLOR_EMERALD,8, // SKINCOLOR_PASTEL - ditto - SKINCOLOR_PERIDOT,8, // SKINCOLOR_PURPLE - ditto + SKINCOLOR_PERIDOT,10, // SKINCOLOR_PURPLE - ditto SKINCOLOR_GOLD,8, // SKINCOLOR_LAVENDER - ditto SKINCOLOR_MOSS,8, // SKINCOLOR_MAGENTA - ditto SKINCOLOR_AZURE,8, // SKINCOLOR_PINK - ditto - SKINCOLOR_AQUA,8 // SKINCOLOR_ROSY - ditto + SKINCOLOR_AQUA,14 // SKINCOLOR_ROSY - ditto }; CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; From f844fb34606ee0b04156fb6aa8197097ee938691 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 10 Sep 2016 21:00:57 +0100 Subject: [PATCH 084/100] More strenous checking of ability for these animations in preparation for something I wanna try... --- src/p_mobj.c | 4 ++-- src/p_user.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 9fb0063d9..808ff6355 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3169,7 +3169,7 @@ static void P_PlayerZMovement(mobj_t *mo) { if (mo->player->cmomx || mo->player->cmomy) { - if (mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL) + if (mo->player->charability == CA_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL) P_SetPlayerMobjState(mo, S_PLAY_PEEL); else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN) P_SetPlayerMobjState(mo, S_PLAY_RUN); @@ -3180,7 +3180,7 @@ static void P_PlayerZMovement(mobj_t *mo) } else { - if (mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL) + if (mo->player->charability == CA_DASHMODE && mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL) P_SetPlayerMobjState(mo, S_PLAY_PEEL); if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN) P_SetPlayerMobjState(mo, S_PLAY_RUN); diff --git a/src/p_user.c b/src/p_user.c index 8c58838d1..4db4197b8 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6528,7 +6528,7 @@ static void P_MovePlayer(player_t *player) // If your peelout animation is playing, and you're // going too slow, switch back to the run. - if (player->panim == PA_PEEL && player->dashmode < 3*TICRATE) + if (player->charability == CA_DASHMODE && player->panim == PA_PEEL && player->dashmode < 3*TICRATE) P_SetPlayerMobjState(player->mo, S_PLAY_RUN); // If your running animation is playing, and you're From cd0c2347df333d5f0e86770bb55656807cb468a6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 10 Sep 2016 21:13:51 +0100 Subject: [PATCH 085/100] Ditto with regards to glideandclimb. --- src/p_user.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 4db4197b8..24b547786 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6570,17 +6570,15 @@ static void P_MovePlayer(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_STND); } - if (!(player->charability == CA_GLIDEANDCLIMB) || player->gotflag) // If you can't glide, then why the heck would you be gliding? + if ((!(player->charability == CA_GLIDEANDCLIMB) || player->gotflag) // If you can't glide, then why the heck would you be gliding? + && (player->pflags & PF_GLIDING || player->climbing)) { - if (player->pflags & PF_GLIDING || player->climbing) + if (onground) + P_SetPlayerMobjState(player->mo, S_PLAY_WALK); + else { - if (onground) - P_SetPlayerMobjState(player->mo, S_PLAY_WALK); - else - { - player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); - } + player->pflags |= PF_JUMPED; + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } player->pflags &= ~PF_GLIDING; player->glidetime = 0; From ba78dda27692ea2e291b5503904521e8e277152f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 10 Sep 2016 22:44:28 +0100 Subject: [PATCH 086/100] Just noticed when poking around in dashmodecode that it didn't actually get stopped from running when you were playing in CTF! --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 24b547786..90f021377 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9153,7 +9153,7 @@ void P_PlayerThink(player_t *player) #define dashmode player->dashmode // Dash mode ability for Metal Sonic - if ((player->charability == CA_DASHMODE) && !(maptol & TOL_NIGHTS)) // woo, dashmode! no nights tho. + if ((player->charability == CA_DASHMODE) && !(player->gotflag) && !(maptol & TOL_NIGHTS)) // woo, dashmode! no nights tho. { if (player->speed >= FixedMul(player->runspeed, player->mo->scale) || (player->pflags & PF_STARTDASH)) { From e16648a72bf63dd85ac94f8fcf415858da2d3356 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 23 Sep 2016 23:48:48 +0100 Subject: [PATCH 087/100] Introducing player->powers[pw_carry]! Also, I made rope hangs a lot smoother. * PF_ITEMHANG -> CR_GENERIC * PF_CARRIED -> CR_PLAYER * (mo->tracer == MT_TUBEWAYPOINT) -> CR_ZOOMTUBE * PF_ROPEHANG -> CR_ROPEHANG * PF_MACESPIN -> CR_MACESPIN --- src/b_bot.c | 12 +- src/d_player.h | 51 ++++---- src/dehacked.c | 21 ++-- src/p_enemy.c | 32 +++-- src/p_inter.c | 14 ++- src/p_map.c | 310 +++++++++++++++++-------------------------------- src/p_mobj.c | 29 ++--- src/p_spec.c | 15 ++- src/p_telept.c | 4 +- src/p_user.c | 98 +++++++++------- 10 files changed, 254 insertions(+), 332 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index c59c084e9..0f2c80d55 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -41,12 +41,13 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm return; #endif - if (tails->player->pflags & (PF_MACESPIN|PF_ITEMHANG)) + if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC) { + boolean isrelevant = (sonic->player->powers[pw_carry] == CR_MACESPIN || sonic->player->powers[pw_carry] == CR_GENERIC); dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y); - if (sonic->player->cmd.buttons & BT_JUMP && sonic->player->pflags & (PF_JUMPED|PF_MACESPIN|PF_ITEMHANG)) + if (sonic->player->cmd.buttons & BT_JUMP && (sonic->player->pflags & PF_JUMPED) && isrelevant) cmd->buttons |= BT_JUMP; - if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG)) + if (isrelevant) { cmd->forwardmove = sonic->player->cmd.forwardmove; cmd->angleturn = abs((signed)(tails->angle - sonic->angle))>>16; @@ -211,8 +212,9 @@ boolean B_CheckRespawn(player_t *player) // Check if Sonic is busy first. // If he's doing any of these things, he probably doesn't want to see us. - if (sonic->player->pflags & (PF_ROPEHANG|PF_GLIDING|PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_NIGHTSMODE) - || (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK)) + if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_NIGHTSMODE) + || (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK) + || (sonic->player->powers[pw_carry])) return false; // Low ceiling, do not want! diff --git a/src/d_player.h b/src/d_player.h index 59875b4cc..f1d4d4395 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -44,6 +44,7 @@ typedef enum SF_STOMPDAMAGE = 1<<9, // Always damage enemies, etc by landing on them, no matter your vunerability? SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc. SF_MACHINE = 1<<10, // Beep boop. Are you a robot? + // free up to and including 1<<31 } skinflags_t; //Primary and secondary skin abilities @@ -128,40 +129,28 @@ typedef enum // Are you gliding? PF_GLIDING = 1<<16, - // Tails pickup! - PF_CARRIED = 1<<17, - // Sliding (usually in water) like Labyrinth/Oil Ocean - PF_SLIDING = 1<<18, - - // Hanging on a rope - PF_ROPEHANG = 1<<19, - - // Hanging on an item of some kind - zipline, chain, etc. (->tracer) - PF_ITEMHANG = 1<<20, - - // On the mace chain spinning around (->tracer) - PF_MACESPIN = 1<<21, + PF_SLIDING = 1<<17, /*** NIGHTS STUFF ***/ // Is the player in NiGHTS mode? - PF_NIGHTSMODE = 1<<22, - PF_TRANSFERTOCLOSEST = 1<<23, + PF_NIGHTSMODE = 1<<18, + PF_TRANSFERTOCLOSEST = 1<<19, // Spill rings after falling - PF_NIGHTSFALL = 1<<24, - PF_DRILLING = 1<<25, - PF_SKIDDOWN = 1<<26, + PF_NIGHTSFALL = 1<<20, + PF_DRILLING = 1<<21, + PF_SKIDDOWN = 1<<22, /*** TAG STUFF ***/ - PF_TAGGED = 1<<27, // Player has been tagged and awaits the next round in hide and seek. - PF_TAGIT = 1<<28, // The player is it! For Tag Mode + PF_TAGGED = 1<<23, // Player has been tagged and awaits the next round in hide and seek. + PF_TAGIT = 1<<24, // The player is it! For Tag Mode /*** misc ***/ - PF_FORCESTRAFE = 1<<29, // Turning inputs are translated into strafing inputs - PF_ANALOGMODE = 1<<30, // Analog mode? + PF_FORCESTRAFE = 1<<25, // Turning inputs are translated into strafing inputs + PF_ANALOGMODE = 1<<26, // Analog mode? - // free: 1<<30 and 1<<31 + // free up to and including 1<<31 } pflags_t; typedef enum @@ -204,7 +193,20 @@ typedef enum SH_STACK = SH_FIREFLOWER, SH_NOSTACK = ~SH_STACK -} shieldtype_t; +} shieldtype_t; // pw_shield + +typedef enum +{ + CR_NONE = 0, + // The generic case is suitable for most objects. + CR_GENERIC, + // Tails carry. + CR_PLAYER, + // Specific level gimmicks. + CR_ZOOMTUBE, + CR_ROPEHANG, + CR_MACESPIN +} carrytype_t; // pw_carry // Player powers. (don't edit this comment) typedef enum @@ -213,6 +215,7 @@ typedef enum pw_sneakers, pw_flashing, pw_shield, + pw_carry, pw_tailsfly, // tails flying pw_underwater, // underwater timer pw_spacetime, // In space, no one can hear you spin! diff --git a/src/dehacked.c b/src/dehacked.c index a512e1029..b4cc8f519 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6750,21 +6750,9 @@ static const char *const PLAYERFLAG_LIST[] = { // Are you gliding? "GLIDING", - // Tails pickup! - "CARRIED", - // Sliding (usually in water) like Labyrinth/Oil Ocean "SLIDING", - // Hanging on a rope - "ROPEHANG", - - // Hanging on an item of some kind - zipline, chain, etc. (->tracer) - "ITEMHANG", - - // On the mace chain spinning around (->tracer) - "MACESPIN", - /*** NIGHTS STUFF ***/ // Is the player in NiGHTS mode? "NIGHTSMODE", @@ -6903,6 +6891,7 @@ static const char *const POWERS_LIST[] = { "SNEAKERS", "FLASHING", "SHIELD", + "CARRY", "TAILSFLY", // tails flying "UNDERWATER", // underwater timer "SPACETIME", // In space, no one can hear you spin! @@ -7138,6 +7127,14 @@ struct { {"SH_STACK",SH_STACK}, {"SH_NOSTACK",SH_NOSTACK}, + // Carrying + {"CR_NONE",CR_NONE}, + {"CR_GENERIC",CR_GENERIC}, + {"CR_PLAYER",CR_PLAYER}, + {"CR_ZOOMTUBE",CR_ZOOMTUBE}, + {"CR_ROPEHANG",CR_ROPEHANG}, + {"CR_MACESPIN",CR_MACESPIN}, + // Ring weapons (ringweapons_t) // Useful for A_GiveWeapon {"RW_AUTO",RW_AUTO}, diff --git a/src/p_enemy.c b/src/p_enemy.c index 3790633ea..73ec2a79d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5428,8 +5428,8 @@ void A_MixUp(mobj_t *actor) // Zoom tube stuff mobj_t *tempthing = NULL; //tracer - pflags_t flags1,flags2; //player pflags - INT32 transspeed; //player speed + UINT16 carry1,carry2; //carry + INT32 transspeed; //player speed // Starpost stuff INT16 starpostx, starposty, starpostz; @@ -5466,8 +5466,8 @@ void A_MixUp(mobj_t *actor) players[two].speed = transspeed; //set flags variables now but DON'T set them. - flags1 = (players[one].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); - flags2 = (players[two].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); + carry1 = (players[one].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[one].powers[pw_carry]); + carry2 = (players[two].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[two].powers[pw_carry]); x = players[one].mo->x; y = players[one].mo->y; @@ -5492,12 +5492,10 @@ void A_MixUp(mobj_t *actor) starpostnum, starposttime, starpostangle, mflags2); - //flags set after mixup. Stupid P_ResetPlayer() takes away some of the flags we look for... - //but not all of them! So we need to make sure they aren't set wrong or anything. - players[one].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG); - players[one].pflags |= flags2; - players[two].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG); - players[two].pflags |= flags1; + //carry set after mixup. Stupid P_ResetPlayer() takes away some of the stuff we look for... + //but not all of it! So we need to make sure they aren't set wrong or anything. + players[one].powers[pw_carry] = carry2; + players[two].powers[pw_carry] = carry1; teleported[one] = true; teleported[two] = true; @@ -5509,8 +5507,9 @@ void A_MixUp(mobj_t *actor) INT32 pindex[MAXPLAYERS], counter = 0, teleportfrom = 0; // Zoom tube stuff - mobj_t *transtracer[MAXPLAYERS]; //tracer - pflags_t transflag[MAXPLAYERS]; //player pflags + mobj_t *transtracer[MAXPLAYERS]; //tracer + //pflags_t transflag[MAXPLAYERS]; //cyan pink white pink cyan + UINT16 transcarry[MAXPLAYERS]; //player carry INT32 transspeed[MAXPLAYERS]; //player speed // Star post stuff @@ -5544,7 +5543,7 @@ void A_MixUp(mobj_t *actor) players[i].rmomx = players[i].rmomy = 1; players[i].cmomx = players[i].cmomy = 0; - transflag[counter] = (players[i].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); + transcarry[counter] = (players[i].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[i].powers[pw_carry]); transspeed[counter] = players[i].speed; transtracer[counter] = players[i].mo->tracer; @@ -5596,9 +5595,8 @@ void A_MixUp(mobj_t *actor) starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom], flags2[teleportfrom]); - //...flags after. same reasoning. - players[i].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG); - players[i].pflags |= transflag[teleportfrom]; + //...carry after. same reasoning. + players[i].powers[pw_carry] = transcarry[teleportfrom]; teleported[i] = true; counter++; @@ -6165,7 +6163,7 @@ void A_Boss7Chase(mobj_t *actor) if (actor->health <= actor->info->damage && actor->target && actor->target->player - && (actor->target->player->pflags & PF_ITEMHANG)) + && (actor->target->player->powers[pw_carry] == CR_GENERIC)) { A_FaceTarget(actor); P_SetMobjState(actor, S_BLACKEGG_SHOOT1); diff --git a/src/p_inter.c b/src/p_inter.c index 936747ce6..4349be579 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1249,10 +1249,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) player->powers[pw_ingoop] = 2; - if (player->pflags & PF_ITEMHANG) + if (player->powers[pw_carry] == CR_GENERIC) { P_SetTarget(&toucher->tracer, NULL); - player->pflags &= ~PF_ITEMHANG; + player->powers[pw_carry] = CR_NONE; } P_ResetPlayer(player); @@ -1337,7 +1337,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_BIGMACECHAIN: // Is this the last link in the chain? if (toucher->momz > 0 || !(special->flags & MF_AMBUSH) - || (player->pflags & PF_ITEMHANG) || (player->pflags & PF_MACESPIN)) + || (player->powers[pw_carry])) return; if (toucher->z > special->z + special->height/2) @@ -1354,12 +1354,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->target && (special->target->type == MT_SPINMACEPOINT || special->target->type == MT_HIDDEN_SLING)) { - player->pflags |= PF_MACESPIN; + player->powers[pw_carry] = CR_MACESPIN; S_StartSound(toucher, sfx_spin); P_SetPlayerMobjState(toucher, S_PLAY_SPIN); } else - player->pflags |= PF_ITEMHANG; + player->powers[pw_carry] = CR_GENERIC; // Can't jump first frame player->pflags |= PF_JUMPSTASIS; @@ -2623,7 +2623,9 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) { - player->pflags &= ~(PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG|PF_NIGHTSMODE); + player->pflags &= ~(PF_SLIDING|PF_NIGHTSMODE); + + player->powers[pw_carry] = CR_NONE; // Burst weapons and emeralds in Match/CTF only if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)) diff --git a/src/p_map.c b/src/p_map.c index 6d4acf1a2..92ed14f57 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -302,9 +302,9 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) INT32 p; fixed_t zdist; // z distance between the two players' bottoms - if ((tails->pflags & PF_CARRIED) && tails->mo->tracer == sonic->mo) + if (tails->powers[pw_carry] == CR_PLAYER)// && tails->mo->tracer == sonic->mo) <-- why was this here? return; - if ((sonic->pflags & PF_CARRIED) && sonic->mo->tracer == tails->mo) + if (sonic->powers[pw_carry] == CR_PLAYER && sonic->mo->tracer == tails->mo) return; if (tails->charability != CA_FLY && tails->charability != CA_SWIM) @@ -319,8 +319,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) if (sonic->pflags & PF_NIGHTSMODE) return; - if (sonic->mo->tracer && sonic->mo->tracer->type == MT_TUBEWAYPOINT - && !(sonic->pflags & PF_ROPEHANG)) + if (sonic->mo->tracer && sonic->powers[pw_carry] == CR_ZOOMTUBE) return; // don't steal players from zoomtubes! if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP)) @@ -337,7 +336,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) // Search in case another player is already being carried by this fox. for (p = 0; p < MAXPLAYERS; p++) if (playeringame[p] && players[p].mo - && players[p].pflags & PF_CARRIED && players[p].mo->tracer == tails->mo) + && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == tails->mo) return; if (tails->mo->eflags & MFE_VERTICALFLIP) @@ -357,16 +356,16 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) || (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT))) || (gametype == GT_MATCH) || (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam)) - sonic->pflags &= ~PF_CARRIED; */ + sonic->powers[pw_carry] = CR_NONE; */ if (tails->spectator || sonic->spectator) - sonic->pflags &= ~PF_CARRIED; + sonic->powers[pw_carry] = CR_NONE; else { if (sonic-players == consoleplayer && botingame) CV_SetValue(&cv_analog2, false); P_ResetPlayer(sonic); P_SetTarget(&sonic->mo->tracer, tails->mo); - sonic->pflags |= PF_CARRIED; + sonic->powers[pw_carry] = CR_PLAYER; S_StartSound(sonic->mo, sfx_s3k4a); P_UnsetThingPosition(sonic->mo); sonic->mo->x = tails->mo->x; @@ -377,199 +376,10 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) else { if (sonic-players == consoleplayer && botingame) CV_SetValue(&cv_analog2, true); - sonic->pflags &= ~PF_CARRIED; + sonic->powers[pw_carry] = CR_NONE; } } -// -// P_ConsiderSolids (moved out of PIT_CheckThing in order to have additional flexibility) -// - -static boolean P_ConsiderSolids(mobj_t *thing) -{ - // Monitors are not treated as solid to players who are jumping, spinning or gliding, - // unless it's a CTF team monitor and you're on the wrong team - if (thing->flags & MF_MONITOR && tmthing->player - && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) - || ((tmthing->player->pflags & PF_JUMPED) - && !(tmthing->player->charflags & SF_NOJUMPDAMAGE - && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) - || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) - || ((tmthing->player->charflags & SF_STOMPDAMAGE) - && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))) - && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2))) - ; - // z checking at last - // Treat noclip things as non-solid! - else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID - && (tmthing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID) - { - fixed_t topz, tmtopz; - - if (tmthing->eflags & MFE_VERTICALFLIP) - { - // pass under - tmtopz = tmthing->z; - - if (tmtopz > thing->z + thing->height) - { - if (thing->z + thing->height > tmfloorz) - { - tmfloorz = thing->z + thing->height; -#ifdef ESLOPE - tmfloorslope = NULL; -#endif - } - return true; - } - - topz = thing->z - FixedMul(FRACUNIT, thing->scale); - - // block only when jumping not high enough, - // (dont climb max. 24units while already in air) - // if not in air, let P_TryMove() decide if it's not too high - if (tmthing->player && tmthing->z + tmthing->height > topz - && tmthing->z + tmthing->height < tmthing->ceilingz) - return false; // block while in air - - if (thing->flags & MF_SPRING) - ; - else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) - { - tmceilingz = topz; -#ifdef ESLOPE - tmceilingslope = NULL; -#endif - tmfloorthing = thing; // thing we may stand on - } - } - else - { - // pass under - tmtopz = tmthing->z + tmthing->height; - - if (tmtopz < thing->z) - { - if (thing->z < tmceilingz) - { - tmceilingz = thing->z; -#ifdef ESLOPE - tmceilingslope = NULL; -#endif - } - return true; - } - - topz = thing->z + thing->height + FixedMul(FRACUNIT, thing->scale); - - // block only when jumping not high enough, - // (dont climb max. 24units while already in air) - // if not in air, let P_TryMove() decide if it's not too high - if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz) - return false; // block while in air - - if (thing->flags & MF_SPRING) - ; - else if (topz > tmfloorz && tmthing->z >= thing->z) - { - tmfloorz = topz; -#ifdef ESLOPE - tmfloorslope = NULL; -#endif - tmfloorthing = thing; // thing we may stand on - } - } - } - - // not solid not blocked - return true; -} - -#if 0 -// -// PIT_CheckSolid (PIT_CheckThing, but for solids only, and guaranteed no side effects) -// -static boolean PIT_CheckSolid(mobj_t *thing) -{ - fixed_t blockdist; - - // don't clip against self - if (thing == tmthing) - return true; - - // Ignore... things. - if (!tmthing || !thing || P_MobjWasRemoved(thing)) - return true; - - I_Assert(!P_MobjWasRemoved(tmthing)); - I_Assert(!P_MobjWasRemoved(thing)); - - if (!(thing->flags & MF_SOLID)) - return true; - - // Ignore spectators - if ((tmthing->player && tmthing->player->spectator) - || (thing->player && thing->player->spectator)) - return true; - - // Metal Sonic destroys tiny baby objects. - if (tmthing->type == MT_METALSONIC_RACE - && (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) || thing->type == MT_SPIKE)) - return true; - - // CA_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. - if ((tmthing->player) - && (((tmthing->player->charability == CA_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) - && (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE)) - || ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY)) - || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)) - && (thing->type == MT_SPIKE)))) - return true; - - // Don't collide with your buddies while NiGHTS-flying. - if (tmthing->player && thing->player && (maptol & TOL_NIGHTS) - && ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE))) - return true; - - blockdist = thing->radius + tmthing->radius; - - if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) - return true; // didn't hit it - - // Force solid players in hide and seek to avoid corner stacking. - if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK) - { - if (tmthing->player && thing->player) - return true; - } - - if (tmthing->player) // Is the moving/interacting object the player? - { - if (!tmthing->health) - return true; - - // Are you touching the side of the object you're interacting with? - else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height - && thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z) - { - if (thing->flags & MF_MONITOR - && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) - || ((tmthing->player->pflags & PF_JUMPED) - && !(tmthing->player->charflags & SF_NOJUMPDAMAGE - && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) - || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) - || ((tmthing->player->charflags & SF_STOMPDAMAGE) - && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))) - { - return false; - } - } - } - - return P_ConsiderSolids(thing); -} -#endif - // // PIT_CheckThing // @@ -858,7 +668,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->flags & MF_MISSILE && thing->player && tmthing->target && tmthing->target->player && thing->player->ctfteam == tmthing->target->player->ctfteam - && thing->player->pflags & PF_CARRIED && thing->tracer == tmthing->target) + && thing->player->powers[pw_carry] == CR_PLAYER && thing->tracer == tmthing->target) return true; // Don't give rings to your carry player by accident. if (thing->type == MT_EGGSHIELD) @@ -901,7 +711,7 @@ static boolean PIT_CheckThing(mobj_t *thing) && tmthing->target != thing) { // Hop on the missile for a ride! - thing->player->pflags |= PF_ITEMHANG; + thing->player->powers[pw_carry] = CR_GENERIC; thing->player->pflags &= ~PF_JUMPED; P_SetTarget(&thing->tracer, tmthing); P_SetTarget(&tmthing->target, thing); // Set owner to the player @@ -920,7 +730,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && ((thing->player->pflags & PF_ITEMHANG) || (thing->player->pflags & PF_JUMPED))) + else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && ((thing->player->powers[pw_carry] == CR_GENERIC) || (thing->player->pflags & PF_JUMPED))) { // Ignore } @@ -1121,7 +931,8 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (thing->player) { if (thing->player-players == consoleplayer && botingame) CV_SetValue(&cv_analog2, true); - thing->player->pflags &= ~PF_CARRIED; + if (thing->player->powers[pw_carry] == CR_PLAYER) + thing->player->powers[pw_carry] = CR_NONE; } if (thing->player) @@ -1199,8 +1010,99 @@ static boolean PIT_CheckThing(mobj_t *thing) if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now... return false; // "cancel" P_TryMove via blocking so you keep your current position } - else - return P_ConsiderSolids(thing); + // Monitors are not treated as solid to players who are jumping, spinning or gliding, + // unless it's a CTF team monitor and you're on the wrong team + else if (thing->flags & MF_MONITOR && tmthing->player + && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING) + || ((tmthing->player->pflags & PF_JUMPED) + && !(tmthing->player->charflags & SF_NOJUMPDAMAGE + && !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) + || ((tmthing->player->charflags & SF_STOMPDAMAGE) + && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))) + && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2))) + ; + // z checking at last + // Treat noclip things as non-solid! + else if ((thing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID + && (tmthing->flags & (MF_SOLID|MF_NOCLIP)) == MF_SOLID) + { + fixed_t topz, tmtopz; + + if (tmthing->eflags & MFE_VERTICALFLIP) + { + // pass under + tmtopz = tmthing->z; + + if (tmtopz > thing->z + thing->height) + { + if (thing->z + thing->height > tmfloorz) + { + tmfloorz = thing->z + thing->height; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + } + return true; + } + + topz = thing->z - FixedMul(FRACUNIT, thing->scale); + + // block only when jumping not high enough, + // (dont climb max. 24units while already in air) + // if not in air, let P_TryMove() decide if it's not too high + if (tmthing->player && tmthing->z + tmthing->height > topz + && tmthing->z + tmthing->height < tmthing->ceilingz) + return false; // block while in air + + if (thing->flags & MF_SPRING) + ; + else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) + { + tmceilingz = topz; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + tmfloorthing = thing; // thing we may stand on + } + } + else + { + // pass under + tmtopz = tmthing->z + tmthing->height; + + if (tmtopz < thing->z) + { + if (thing->z < tmceilingz) + { + tmceilingz = thing->z; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + } + return true; + } + + topz = thing->z + thing->height + FixedMul(FRACUNIT, thing->scale); + + // block only when jumping not high enough, + // (dont climb max. 24units while already in air) + // if not in air, let P_TryMove() decide if it's not too high + if (tmthing->player && tmthing->z < topz && tmthing->z > tmthing->floorz) + return false; // block while in air + + if (thing->flags & MF_SPRING) + ; + else if (topz > tmfloorz && tmthing->z >= thing->z) + { + tmfloorz = topz; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + tmfloorthing = thing; // thing we may stand on + } + } + } // not solid not blocked return true; diff --git a/src/p_mobj.c b/src/p_mobj.c index 7d9c32451..c156581c0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3998,20 +3998,23 @@ static void P_PlayerMobjThinker(mobj_t *mobj) mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; // Zoom tube - if (mobj->tracer && mobj->tracer->type == MT_TUBEWAYPOINT) + if (mobj->tracer) { - P_UnsetThingPosition(mobj); - mobj->x += mobj->momx; - mobj->y += mobj->momy; - mobj->z += mobj->momz; - P_SetThingPosition(mobj); - P_CheckPosition(mobj, mobj->x, mobj->y); - goto animonly; - } - else if (mobj->player->pflags & PF_MACESPIN && mobj->tracer) - { - P_CheckPosition(mobj, mobj->x, mobj->y); - goto animonly; + if (mobj->player->powers[pw_carry] == CR_ZOOMTUBE) + { + P_UnsetThingPosition(mobj); + mobj->x += mobj->momx; + mobj->y += mobj->momy; + mobj->z += mobj->momz; + P_SetThingPosition(mobj); + P_CheckPosition(mobj, mobj->x, mobj->y); + goto animonly; + } + else if (mobj->player->powers[pw_carry] == CR_MACESPIN) + { + P_CheckPosition(mobj, mobj->x, mobj->y); + goto animonly; + } } // Needed for gravity boots diff --git a/src/p_spec.c b/src/p_spec.c index a3d6cecfa..ed8a12a5d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3889,7 +3889,7 @@ DoneSection2: mobj_t *mo2; angle_t an; - if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) + if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) break; // Find line #3 tagged to this sector @@ -3938,6 +3938,7 @@ DoneSection2: break; // behind back P_SetTarget(&player->mo->tracer, waypoint); + player->powers[pw_carry] = CR_ZOOMTUBE; player->speed = speed; player->pflags |= PF_SPINNING; player->pflags &= ~PF_JUMPED; @@ -3962,7 +3963,7 @@ DoneSection2: mobj_t *mo2; angle_t an; - if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) + if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) break; // Find line #3 tagged to this sector @@ -4012,6 +4013,7 @@ DoneSection2: break; // behind back P_SetTarget(&player->mo->tracer, waypoint); + player->powers[pw_carry] = CR_ZOOMTUBE; player->speed = speed; player->pflags |= PF_SPINNING; player->pflags &= ~PF_JUMPED; @@ -4084,7 +4086,7 @@ DoneSection2: vertex_t v1, v2, resulthigh, resultlow; mobj_t *highest = NULL; - if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) + if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ROPEHANG) break; if (player->mo->momz > 0) @@ -4305,6 +4307,7 @@ DoneSection2: } P_SetTarget(&player->mo->tracer, closest); + player->powers[pw_carry] = CR_ROPEHANG; // Option for static ropes. if (lines[lineindex].flags & ML_NOCLIMB) @@ -4312,7 +4315,7 @@ DoneSection2: else player->speed = speed; - player->pflags |= PF_ROPEHANG; + player->powers[pw_carry] = CR_ROPEHANG; S_StartSound(player->mo, sfx_s3k4a); @@ -7165,7 +7168,7 @@ static inline boolean PIT_PushThing(mobj_t *thing) if (thing->eflags & MFE_PUSHED) return false; - if (thing->player && thing->player->pflags & PF_ROPEHANG) + if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG) return false; // Allow this to affect pushable objects at some point? @@ -7398,7 +7401,7 @@ void T_Pusher(pusher_t *p) if (thing->eflags & MFE_PUSHED) continue; - if (thing->player && thing->player->pflags & PF_ROPEHANG) + if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG) continue; if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics)) diff --git a/src/p_telept.c b/src/p_telept.c index 4921040b4..671accb0f 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -160,9 +160,9 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle INT32 p; // Search for any players you might be carrying, so you can get them off before they end up being taken with you! for (p = 0; p < MAXPLAYERS; p++) - if (playeringame[p] && players[p].mo && players[p].pflags & PF_CARRIED && players[p].mo->tracer == thing) + if (playeringame[p] && players[p].mo && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == thing) { - players[p].pflags &= ~PF_CARRIED; + players[p].powers[pw_carry] = CR_NONE; break; } thing->player->cmomx = thing->player->cmomy = 0; diff --git a/src/p_user.c b/src/p_user.c index f6e9270ec..4f8a96de0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -873,7 +873,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) P_InstaThrust(player->mo, ang, fallbackspeed); - if (player->pflags & PF_ROPEHANG) + if (player->powers[pw_carry] == CR_ROPEHANG) P_SetTarget(&player->mo->tracer, NULL); // Point penalty for hitting a hazard during tag. @@ -900,7 +900,8 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) // Useful when you want to kill everything the player is doing. void P_ResetPlayer(player_t *player) { - player->pflags &= ~(PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN|PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CARRIED); + player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED); + player->powers[pw_carry] = CR_NONE; player->jumping = 0; player->secondjump = 0; player->glidetime = 0; @@ -3415,7 +3416,7 @@ static void P_DoSuperStuff(player_t *player) ? (SKINCOLOR_SUPERSILVER1 + 5*((leveltime >> 1) % 7)) // A wholesome easter egg. : skins[player->skin].supercolor + (unsigned)abs( ( (signed)(leveltime >> 1) % 9) - 4); // This is where super flashing is handled. - if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN)) + if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->powers[pw_carry]) && !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy)) { spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK); @@ -3583,22 +3584,22 @@ void P_DoJump(player_t *player, boolean soundandstate) return; // Jump this high. - if (player->pflags & PF_CARRIED) + if (player->powers[pw_carry] == CR_PLAYER) { player->mo->momz = 9*FRACUNIT; - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; if (player-players == consoleplayer && botingame) CV_SetValue(&cv_analog2, true); } - else if (player->pflags & PF_ITEMHANG) + else if (player->powers[pw_carry] == CR_GENERIC) { player->mo->momz = 9*FRACUNIT; - player->pflags &= ~PF_ITEMHANG; + player->powers[pw_carry] = CR_NONE; } - else if (player->pflags & PF_ROPEHANG) + else if (player->powers[pw_carry] == CR_ROPEHANG) { player->mo->momz = 12*FRACUNIT; - player->pflags &= ~PF_ROPEHANG; + player->powers[pw_carry] = CR_NONE; P_SetTarget(&player->mo->tracer, NULL); } else if (player->mo->eflags & MFE_GOOWATER) @@ -3935,9 +3936,9 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (cmd->buttons & BT_USE && !(player->pflags & PF_JUMPDOWN) && !player->exiting && !P_PlayerInPain(player)) { - if (onground || player->climbing || player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG)) + if (player->mo->tracer && player->powers[pw_carry] == CR_MACESPIN) {} - else if (player->pflags & PF_MACESPIN && player->mo->tracer) + else if (onground || player->climbing || (player->mo->tracer && player->powers[pw_carry])) {} else if (!(player->pflags & PF_SLIDING) && ((gametype != GT_CTF) || (!player->gotflag))) { @@ -4010,19 +4011,19 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->secondjump = 0; player->pflags &= ~PF_THOKKED; } + else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer) + { + player->powers[pw_carry] = CR_NONE; + player->powers[pw_flashing] = TICRATE/4; + } else // can't jump while in air, can't jump while jumping - if (onground || player->climbing || player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG)) + if (onground || player->climbing || player->powers[pw_carry]) { P_DoJump(player, true); player->secondjump = 0; player->pflags &= ~PF_THOKKED; } - else if (player->pflags & PF_MACESPIN && player->mo->tracer) - { - player->pflags &= ~PF_MACESPIN; - player->powers[pw_flashing] = TICRATE/4; - } else if (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag)) ; else if (P_SuperReady(player)) @@ -6973,7 +6974,7 @@ static void P_MovePlayer(player_t *player) // Check for teeter! if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER) - && player->panim == PA_IDLE && !(player->pflags & (PF_CARRIED|PF_ITEMHANG|PF_ROPEHANG))) + && player->panim == PA_IDLE && !(player->powers[pw_carry])) P_DoTeeter(player); // Toss a flag @@ -7244,6 +7245,7 @@ static void P_DoZoomTube(player_t *player) else { P_SetTarget(&player->mo->tracer, NULL); // Else, we just let him fly. + player->powers[pw_carry] = CR_NONE; CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n"); } @@ -7291,7 +7293,7 @@ static void P_DoRopeHang(player_t *player) P_SetTarget(&player->mo->tracer, NULL); player->pflags |= PF_JUMPED; - player->pflags &= ~PF_ROPEHANG; + player->powers[pw_carry] = CR_NONE; if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) && !(player->panim == PA_JUMP)) @@ -7309,6 +7311,10 @@ static void P_DoRopeHang(player_t *player) sequence = player->mo->tracer->threshold; + // If not allowed to move, we're done here. + if (!speed) + return; + // change slope dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); @@ -7319,22 +7325,28 @@ static void P_DoRopeHang(player_t *player) speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); speedz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); - // If not allowed to move, we're done here. - if (!speed) - return; - // Calculate the distance between the player and the waypoint // 'dist' already equals this. - // Will the player be FURTHER away if the momx/momy/momz is added to - // his current coordinates, or closer? (shift down to fracunits to avoid approximation errors) - if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - playerz - speedz)>>FRACBITS) + // Will the player go past the waypoint? + if ( + ((speedx || speedy) + && (R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y) + - R_PointToAngle2(player->mo->x + speedx, player->mo->y + speedy, player->mo->tracer->x, player->mo->tracer->y)) > ANG1) + || ((speedz) + && ((playerz - player->mo->tracer->z) > 0) != ((playerz + speedz - player->mo->tracer->z) > 0)) + ) { + if (speed > dist) + speed -= dist; + else + speed = 0; // If further away, set XYZ of player to waypoint location P_UnsetThingPosition(player->mo); player->mo->x = player->mo->tracer->x; player->mo->y = player->mo->tracer->y; player->mo->z = player->mo->tracer->z - player->mo->height; + playerz = player->mo->tracer->z; P_SetThingPosition(player->mo); CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n"); @@ -7390,6 +7402,8 @@ static void P_DoRopeHang(player_t *player) { CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health); + P_SetTarget(&player->mo->tracer, waypoint); + // calculate MOMX/MOMY/MOMZ for next waypoint // change slope dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); @@ -7400,15 +7414,12 @@ static void P_DoRopeHang(player_t *player) player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); - - P_SetTarget(&player->mo->tracer, waypoint); } else { if (player->mo->tracer->flags & MF_SLIDEME) { player->pflags |= PF_JUMPED; - player->pflags &= ~PF_ROPEHANG; if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) && !(player->panim == PA_JUMP)) @@ -7416,6 +7427,7 @@ static void P_DoRopeHang(player_t *player) } P_SetTarget(&player->mo->tracer, NULL); + player->powers[pw_carry] = CR_NONE; CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found!\n"); } @@ -8109,7 +8121,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall { dist = camdist; - if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->pflags & (PF_MACESPIN|PF_ITEMHANG|PF_ROPEHANG))) + if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->powers[pw_carry] && player->powers[pw_carry] != CR_PLAYER)) dist <<= 1; } @@ -8979,9 +8991,9 @@ void P_PlayerThink(player_t *player) // for a bit after a teleport. if (player->mo->reactiontime) player->mo->reactiontime--; - else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) + else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_ZOOMTUBE)) { - if (player->pflags & PF_ROPEHANG) + if (player->powers[pw_carry] == CR_ROPEHANG) { if (!P_AnalogMove(player)) player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); @@ -8994,7 +9006,7 @@ void P_PlayerThink(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); P_DoJumpStuff(player, &player->cmd); } - else + else if (player->powers[pw_carry] == CR_ZOOMTUBE) { P_DoZoomTube(player); if (!(player->panim == PA_ROLL)) @@ -9406,14 +9418,14 @@ void P_PlayerAfterThink(player_t *player) && !(player->charflags & SF_NOJUMPSPIN)) P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); - if (player->pflags & PF_CARRIED && player->mo->tracer) + if (player->powers[pw_carry] == CR_PLAYER && player->mo->tracer) { player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT)); if (player->mo->tracer->player && !player->mo->tracer->player->powers[pw_tailsfly] && player->mo->tracer->state-states != S_PLAY_FLY_TIRED) - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; if (player->mo->eflags & MFE_VERTICALFLIP) { @@ -9421,7 +9433,7 @@ void P_PlayerAfterThink(player_t *player) && (player->mo->tracer->eflags & MFE_VERTICALFLIP)) // Reverse gravity check for the carrier - Flame player->mo->z = player->mo->tracer->z + player->mo->tracer->height + FixedMul(FRACUNIT, player->mo->scale); else - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; } else { @@ -9429,11 +9441,11 @@ void P_PlayerAfterThink(player_t *player) && !(player->mo->tracer->eflags & MFE_VERTICALFLIP)) // Correct gravity check for the carrier - Flame player->mo->z = player->mo->tracer->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale); else - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; } if (player->mo->tracer->health <= 0) - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; else { P_TryMove(player->mo, player->mo->tracer->x, player->mo->tracer->y, true); @@ -9456,14 +9468,14 @@ void P_PlayerAfterThink(player_t *player) } if (P_AproxDistance(player->mo->x - player->mo->tracer->x, player->mo->y - player->mo->tracer->y) > player->mo->radius) - player->pflags &= ~PF_CARRIED; + player->powers[pw_carry] = CR_NONE; P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); if (player-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, !(player->pflags & PF_CARRIED)); + CV_SetValue(&cv_analog2, (player->powers[pw_carry] != CR_PLAYER)); } - else if (player->pflags & PF_ITEMHANG && player->mo->tracer) + else if (player->powers[pw_carry] == CR_GENERIC && player->mo->tracer) { // tracer is what you're hanging onto P_UnsetThingPosition(player->mo); @@ -9491,12 +9503,12 @@ void P_PlayerAfterThink(player_t *player) if (player->mo->z <= player->mo->floorz || player->mo->tracer->health <= 0) { - player->pflags &= ~PF_ITEMHANG; + player->powers[pw_carry] = CR_NONE; P_SetTarget(&player->mo->tracer, NULL); } } } - else if (player->pflags & PF_MACESPIN && player->mo->tracer && player->mo->tracer->target) + else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer && player->mo->tracer->target) { player->mo->height = P_GetPlayerSpinHeight(player); // tracer is what you're hanging onto.... From 1de32b3dac257eebdfb8bea68278fc5e89aa553e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 24 Sep 2016 00:37:18 +0100 Subject: [PATCH 088/100] Fixed my mistake with static rope hangs. Also, the same smoothness changes have been ported over to zoom tubes! --- src/p_mobj.c | 2 +- src/p_spec.c | 2 -- src/p_user.c | 40 +++++++++++++++++++--------------------- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index c156581c0..86001388b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4000,7 +4000,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) // Zoom tube if (mobj->tracer) { - if (mobj->player->powers[pw_carry] == CR_ZOOMTUBE) + if (mobj->player->powers[pw_carry] == CR_ZOOMTUBE || mobj->player->powers[pw_carry] == CR_ROPEHANG) { P_UnsetThingPosition(mobj); mobj->x += mobj->momx; diff --git a/src/p_spec.c b/src/p_spec.c index ed8a12a5d..9fc20b83f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4315,8 +4315,6 @@ DoneSection2: else player->speed = speed; - player->powers[pw_carry] = CR_ROPEHANG; - S_StartSound(player->mo, sfx_s3k4a); player->pflags &= ~PF_JUMPED; diff --git a/src/p_user.c b/src/p_user.c index 4f8a96de0..ae8ded5b4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7178,10 +7178,19 @@ static void P_DoZoomTube(player_t *player) // Calculate the distance between the player and the waypoint // 'dist' already equals this. - // Will the player be FURTHER away if the momx/momy/momz is added to - // his current coordinates, or closer? (shift down to fracunits to avoid approximation errors) - if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x - speedx, player->mo->tracer->y - player->mo->y - speedy), player->mo->tracer->z - player->mo->z - speedz)>>FRACBITS) + // Will the player go past the waypoint? + if (speed && ( + ((speedx || speedy) + && (R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y) + - R_PointToAngle2(player->mo->x + speedx, player->mo->y + speedy, player->mo->tracer->x, player->mo->tracer->y)) > ANG1) + || ((speedz) + && ((player->mo->z - player->mo->tracer->z) > 0) != ((player->mo->z + speedz - player->mo->tracer->z) > 0)) + )) { + if (speed > dist) + speed -= dist; + else + speed = 0; // If further away, set XYZ of player to waypoint location P_UnsetThingPosition(player->mo); player->mo->x = player->mo->tracer->x; @@ -7221,6 +7230,8 @@ static void P_DoZoomTube(player_t *player) { CONS_Debug(DBG_GAMELOGIC, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health); + P_SetTarget(&player->mo->tracer, waypoint); + // calculate MOMX/MOMY/MOMZ for next waypoint // change angle player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y); @@ -7239,8 +7250,6 @@ static void P_DoZoomTube(player_t *player) player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed)); - - P_SetTarget(&player->mo->tracer, waypoint); } else { @@ -7256,17 +7265,6 @@ static void P_DoZoomTube(player_t *player) player->mo->momy = speedy; player->mo->momz = speedz; } - - // change angle - if (player->mo->tracer) - { - player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y); - - if (player == &players[consoleplayer]) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; - } } // @@ -7311,10 +7309,6 @@ static void P_DoRopeHang(player_t *player) sequence = player->mo->tracer->threshold; - // If not allowed to move, we're done here. - if (!speed) - return; - // change slope dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); @@ -7325,6 +7319,10 @@ static void P_DoRopeHang(player_t *player) speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); speedz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); + // If not allowed to move, we're done here. + if (!speed) + return; + // Calculate the distance between the player and the waypoint // 'dist' already equals this. @@ -9006,7 +9004,7 @@ void P_PlayerThink(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); P_DoJumpStuff(player, &player->cmd); } - else if (player->powers[pw_carry] == CR_ZOOMTUBE) + else //if (player->powers[pw_carry] == CR_ZOOMTUBE) { P_DoZoomTube(player); if (!(player->panim == PA_ROLL)) From 41b4d9c565c0836d7dfce322e54b4ad9b7f120c7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 24 Sep 2016 12:06:00 +0100 Subject: [PATCH 089/100] Fixed carry bug that I introduced a while ago. --- src/p_user.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index ae8ded5b4..53c59d072 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9421,7 +9421,9 @@ void P_PlayerAfterThink(player_t *player) player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT)); if (player->mo->tracer->player - && !player->mo->tracer->player->powers[pw_tailsfly] + // && !player->mo->tracer->player->powers[pw_tailsfly] -- race hazard - pw_tailsfly gets set to 0 a tic before the state switch to S_PLAY_FLY_TIRED... + && player->mo->tracer->state-states != S_PLAY_FLY + && player->mo->tracer->state-states != S_PLAY_SWIM && player->mo->tracer->state-states != S_PLAY_FLY_TIRED) player->powers[pw_carry] = CR_NONE; From eb64e4ccd9d196bde0fd1b9da65c940b355d38fa Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 24 Sep 2016 12:38:37 +0100 Subject: [PATCH 090/100] Tightened some restrictions on Tails carry because right now the looseness leads to edge case noise spam when trying to pick up a player off a rope hang, for example. --- src/p_map.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 92ed14f57..63ba258f9 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -302,9 +302,9 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) INT32 p; fixed_t zdist; // z distance between the two players' bottoms - if (tails->powers[pw_carry] == CR_PLAYER)// && tails->mo->tracer == sonic->mo) <-- why was this here? + if (tails->powers[pw_carry])// && tails->mo->tracer == sonic->mo) <-- why was this here? return; - if (sonic->powers[pw_carry] == CR_PLAYER && sonic->mo->tracer == tails->mo) + if (sonic->powers[pw_carry]) return; if (tails->charability != CA_FLY && tails->charability != CA_SWIM) @@ -319,9 +319,6 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) if (sonic->pflags & PF_NIGHTSMODE) return; - if (sonic->mo->tracer && sonic->powers[pw_carry] == CR_ZOOMTUBE) - return; // don't steal players from zoomtubes! - if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP)) return; // Both should be in same gravity From f933210c03af311fa0b46714f76e160af905caa7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 24 Sep 2016 13:18:08 +0100 Subject: [PATCH 091/100] Let's simplify a lot of stuff. PF_CANCARRY instead of a horrible assortment of checks. --- src/d_player.h | 3 +++ src/p_map.c | 54 ++++++++++++++++++++++++-------------------------- src/p_mobj.c | 3 +-- src/p_spec.c | 9 +++------ src/p_user.c | 12 ++++------- 5 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index f1d4d4395..620b698c7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -150,6 +150,9 @@ typedef enum PF_FORCESTRAFE = 1<<25, // Turning inputs are translated into strafing inputs PF_ANALOGMODE = 1<<26, // Analog mode? + // Can carry another player? + PF_CANCARRY = 1<<27 + // free up to and including 1<<31 } pflags_t; diff --git a/src/p_map.c b/src/p_map.c index 63ba258f9..765f88a7d 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -302,15 +302,17 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) INT32 p; fixed_t zdist; // z distance between the two players' bottoms - if (tails->powers[pw_carry])// && tails->mo->tracer == sonic->mo) <-- why was this here? + if (tails->powers[pw_carry]) return; if (sonic->powers[pw_carry]) return; - if (tails->charability != CA_FLY && tails->charability != CA_SWIM) + if (tails->spectator) + return; + if (sonic->spectator) return; - if (!tails->powers[pw_tailsfly] && tails->mo->state-states != S_PLAY_FLY_TIRED) + if (!(tails->pflags & PF_CANCARRY)) return; if (tails->bot == 1) @@ -336,39 +338,35 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == tails->mo) return; + // Why block opposing teams from tailsflying each other? + // Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows. + /* + if (gametype == GT_RACE || gametype == GT_COMPETITION + || (netgame && (tails->spectator || sonic->spectator)) + || (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT))) + || (gametype == GT_MATCH) + || (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam)) + return; */ + if (tails->mo->eflags & MFE_VERTICALFLIP) zdist = (sonic->mo->z + sonic->mo->height) - (tails->mo->z + tails->mo->height); else zdist = tails->mo->z - sonic->mo->z; - if (zdist <= sonic->mo->height + FixedMul(FRACUNIT, sonic->mo->scale) + if (zdist <= sonic->mo->height + sonic->mo->scale // FixedMul(FRACUNIT, sonic->mo->scale), but scale == FRACUNIT by default && zdist > sonic->mo->height*2/3 && P_MobjFlip(tails->mo)*sonic->mo->momz <= 0) { - // Why block opposing teams from tailsflying each other? - // Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows. - /* - if (gametype == GT_RACE || gametype == GT_COMPETITION - || (netgame && (tails->spectator || sonic->spectator)) - || (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT))) - || (gametype == GT_MATCH) - || (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam)) - sonic->powers[pw_carry] = CR_NONE; */ - if (tails->spectator || sonic->spectator) - sonic->powers[pw_carry] = CR_NONE; - else - { - if (sonic-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, false); - P_ResetPlayer(sonic); - P_SetTarget(&sonic->mo->tracer, tails->mo); - sonic->powers[pw_carry] = CR_PLAYER; - S_StartSound(sonic->mo, sfx_s3k4a); - P_UnsetThingPosition(sonic->mo); - sonic->mo->x = tails->mo->x; - sonic->mo->y = tails->mo->y; - P_SetThingPosition(sonic->mo); - } + if (sonic-players == consoleplayer && botingame) + CV_SetValue(&cv_analog2, false); + P_ResetPlayer(sonic); + P_SetTarget(&sonic->mo->tracer, tails->mo); + sonic->powers[pw_carry] = CR_PLAYER; + S_StartSound(sonic->mo, sfx_s3k4a); + P_UnsetThingPosition(sonic->mo); + sonic->mo->x = tails->mo->x; + sonic->mo->y = tails->mo->y; + P_SetThingPosition(sonic->mo); } else { if (sonic-players == consoleplayer && botingame) diff --git a/src/p_mobj.c b/src/p_mobj.c index 86001388b..f2ef4dc0d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3188,8 +3188,7 @@ static void P_PlayerZMovement(mobj_t *mo) if (!(mo->player->pflags & PF_GLIDING)) mo->player->pflags &= ~PF_JUMPED; - mo->player->pflags &= ~PF_THOKKED; - //mo->player->pflags &= ~PF_GLIDING; + mo->player->pflags &= ~(PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/); mo->player->jumping = 0; mo->player->secondjump = 0; mo->player->glidetime = 0; diff --git a/src/p_spec.c b/src/p_spec.c index 9fc20b83f..ed2ff055c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3941,8 +3941,7 @@ DoneSection2: player->powers[pw_carry] = CR_ZOOMTUBE; player->speed = speed; player->pflags |= PF_SPINNING; - player->pflags &= ~PF_JUMPED; - player->pflags &= ~PF_GLIDING; + player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY); player->climbing = 0; if (player->mo->state-states != S_PLAY_SPIN) @@ -4016,7 +4015,7 @@ DoneSection2: player->powers[pw_carry] = CR_ZOOMTUBE; player->speed = speed; player->pflags |= PF_SPINNING; - player->pflags &= ~PF_JUMPED; + player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY); if (player->mo->state-states != S_PLAY_SPIN) { @@ -4317,9 +4316,7 @@ DoneSection2: S_StartSound(player->mo, sfx_s3k4a); - player->pflags &= ~PF_JUMPED; - player->pflags &= ~PF_GLIDING; - player->pflags &= ~PF_SLIDING; + player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY); player->climbing = 0; P_SetThingPosition(player->mo); P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); diff --git a/src/p_user.c b/src/p_user.c index 53c59d072..0b653b24c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -900,7 +900,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) // Useful when you want to kill everything the player is doing. void P_ResetPlayer(player_t *player) { - player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED); + player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CANCARRY); player->powers[pw_carry] = CR_NONE; player->jumping = 0; player->secondjump = 0; @@ -4107,7 +4107,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer player->pflags &= ~(PF_JUMPED|PF_SPINNING|PF_STARTDASH); - player->pflags |= PF_THOKKED; + player->pflags |= PF_THOKKED|PF_CANCARRY; } break; case CA_GLIDEANDCLIMB: @@ -7253,7 +7253,7 @@ static void P_DoZoomTube(player_t *player) } else { - P_SetTarget(&player->mo->tracer, NULL); // Else, we just let him fly. + P_SetTarget(&player->mo->tracer, NULL); // Else, we just let them fly. player->powers[pw_carry] = CR_NONE; CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n"); @@ -9420,11 +9420,7 @@ void P_PlayerAfterThink(player_t *player) { player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT)); - if (player->mo->tracer->player - // && !player->mo->tracer->player->powers[pw_tailsfly] -- race hazard - pw_tailsfly gets set to 0 a tic before the state switch to S_PLAY_FLY_TIRED... - && player->mo->tracer->state-states != S_PLAY_FLY - && player->mo->tracer->state-states != S_PLAY_SWIM - && player->mo->tracer->state-states != S_PLAY_FLY_TIRED) + if (player->mo->tracer->player && !(player->mo->tracer->player->pflags & PF_CANCARRY)) player->powers[pw_carry] = CR_NONE; if (player->mo->eflags & MFE_VERTICALFLIP) From da1db42b1402d3bb258fb236c1374117f4f38a7f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 24 Sep 2016 13:39:04 +0100 Subject: [PATCH 092/100] Forgot some compilers would complain about this. --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 0b653b24c..f155f7486 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4107,7 +4107,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer player->pflags &= ~(PF_JUMPED|PF_SPINNING|PF_STARTDASH); - player->pflags |= PF_THOKKED|PF_CANCARRY; + player->pflags |= (PF_THOKKED|PF_CANCARRY); } break; case CA_GLIDEANDCLIMB: From 50a44d96b16ef8f32ea0119bfd8d7c8e907440b0 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 24 Sep 2016 17:15:42 +0100 Subject: [PATCH 093/100] Changes to bubbles for new DSZ + bubble sprites (needs new patch.dta). --- src/dehacked.c | 7 +++--- src/hardware/hw_light.c | 8 ++----- src/info.c | 47 +++++++++++++++++++++-------------------- src/info.h | 15 ++++++------- 4 files changed, 36 insertions(+), 41 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b4cc8f519..e06e9752f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4753,6 +4753,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Bubble Source "S_BUBBLES1", "S_BUBBLES2", + "S_BUBBLES3", + "S_BUBBLES4", // Level End Sign "S_SIGN1", @@ -5608,10 +5610,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Bubbles "S_SMALLBUBBLE", - "S_SMALLBUBBLE1", "S_MEDIUMBUBBLE", - "S_MEDIUMBUBBLE1", - "S_LARGEBUBBLE", + "S_LARGEBUBBLE1", + "S_LARGEBUBBLE2", "S_EXTRALARGEBUBBLE", // breathable "S_POP1", // Extra Large bubble goes POP! diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 0145c88fe..7dfc6f624 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -237,7 +237,7 @@ light_t *t_lspr[NUMSPRITES] = // Interactive Objects &lspr[NOLIGHT], // SPR_FANS - &lspr[NOLIGHT], // SPR_BUBL + &lspr[NOLIGHT], // SPR_BBLS &lspr[NOLIGHT], // SPR_SIGN &lspr[NOLIGHT], // SPR_STEM &lspr[NOLIGHT], // SPR_SPIK @@ -382,11 +382,7 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_SPLH &lspr[NOLIGHT], // SPR_SPLA &lspr[NOLIGHT], // SPR_SMOK - &lspr[NOLIGHT], // SPR_BUBP - &lspr[NOLIGHT], // SPR_BUBO - &lspr[NOLIGHT], // SPR_BUBN - &lspr[NOLIGHT], // SPR_BUBM - &lspr[NOLIGHT], // SPR_POPP + &lspr[NOLIGHT], // SPR_BUBL &lspr[SUPERSPARK_L], // SPR_WZAP &lspr[SUPERSPARK_L], // SPR_TFOG &lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed diff --git a/src/info.c b/src/info.c index 9d9f02d67..04a28e7ca 100644 --- a/src/info.c +++ b/src/info.c @@ -33,7 +33,7 @@ char sprnames[NUMSPRITES + 1][5] = "BBUZ","JETF","EGGM","EGGN","TNKA","TNKB","SPNK","GOOP","EGGO","PRPL", "FAKE","EGGP","EFIR","EGGQ","EGGR","BRAK","BGOO","BMSL","EGGT","RCKT", "ELEC","TARG","NPLM","MNPL","METL","MSCF","MSCB","RING","TRNG","EMMY", - "TOKE","RFLG","BFLG","NWNG","EMBM","CEMG","EMER","FANS","BUBL","SIGN", + "TOKE","RFLG","BFLG","NWNG","EMBM","CEMG","EMER","FANS","BBLS","SIGN", "STEM","SPIK","SFLM","USPK","STPT","BMNE","SRBX","RRBX","BRBX","SHTV", "PINV","YLTV","BLTV","BKTV","WHTV","GRTV","ELTV","EGGB","MIXU","RECY", "QUES","GBTV","PRUP","PTTV","MTEX","MISL","TORP","ENRG","MINE","JBUL", @@ -44,16 +44,16 @@ char sprnames[NUMSPRITES + 1][5] = "BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN", "ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC", "COWZ","RBRD","SPRY","SPRR","SPRB","YSPR","RSPR","SSWY","SSWR","SSWB", - "RAIN","SNO1","SPLH","SPLA","SMOK","BUBP","BUBO","BUBN","BUBM","POPP", - "WZAP","TFOG","SEED","PRTL","SCOR","DRWN","TTAG","GFLG","RRNG","RNGB", - "RNGR","RNGI","RNGA","RNGE","RNGS","RNGG","PIKB","PIKR","PIKA","PIKE", - "PIKS","PIKG","TAUT","TGRE","TSCR","COIN","CPRK","GOOM","BGOM","FFWR", - "FBLL","SHLL","PUMA","HAMM","KOOP","BFLM","MAXE","MUS1","MUS2","TOAD", - "NDRN","NSPK","NBMP","HOOP","NSCR","NPRU","CAPS","SPRK","BOM1","BOM2", - "BOM3","BOM4","ROIA","ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH", - "ROII","ROIJ","ROIK","ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG", - "GWLR","SRBA","SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI", - "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", + "RAIN","SNO1","SPLH","SPLA","SMOK","BUBL","WZAP","TFOG","SEED","PRTL", + "SCOR","DRWN","TTAG","GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE", + "RNGS","RNGG","PIKB","PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE", + "TSCR","COIN","CPRK","GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM", + "KOOP","BFLM","MAXE","MUS1","MUS2","TOAD","NDRN","NSPK","NBMP","HOOP", + "NSCR","NPRU","CAPS","SPRK","BOM1","BOM2","BOM3","BOM4","ROIA","ROIB", + "ROIC","ROID","ROIE","ROIF","ROIG","ROIH","ROII","ROIJ","ROIK","ROIL", + "ROIM","ROIN","ROIO","ROIP","BBAL","GWLG","GWLR","SRBA","SRBB","SRBC", + "SRBD","SRBE","SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL","SRBM", + "SRBN","SRBO", }; char spr2names[NUMPLAYERSPRITES][5] = @@ -1144,8 +1144,10 @@ state_t states[NUMSTATES] = {SPR_FANS, 4, 1, {A_FanBubbleSpawn}, 512, 0, S_FAN}, // S_FAN5 // Bubble Source - {SPR_BUBL, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1 - {SPR_BUBL, 1, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES2 + {SPR_BBLS, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1 + {SPR_BBLS, 1, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES3}, // S_BUBBLES2 + {SPR_BBLS, 2, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES4}, // S_BUBBLES3 + {SPR_BBLS, 3, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES4 // Level End Sign {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN2}, // S_SIGN1 @@ -2012,17 +2014,16 @@ state_t states[NUMSTATES] = {SPR_SMOK, FF_TRANS50|4, 8, {NULL}, 0, 0, S_NULL}, // S_SMOKE5 // Bubbles - {SPR_BUBP, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE1}, // S_SMALLBUBBLE - {SPR_BUBP, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE}, // S_SMALLBUBBLE1 - {SPR_BUBO, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE1}, // S_MEDIUMBUBBLE - {SPR_BUBO, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE}, // S_MEDIUMBUBBLE1 + {SPR_BUBL, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE}, // S_SMALLBUBBLE + {SPR_BUBL, FF_TRANS50|1, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE}, // S_MEDIUMBUBBLE // Extra Large Bubble (breathable) - {SPR_BUBN, FF_TRANS50|FF_FULLBRIGHT, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_LARGEBUBBLE - {SPR_BUBM, FF_TRANS50|FF_FULLBRIGHT, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_EXTRALARGEBUBBLE + {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|2, 8, {A_BubbleRise}, 0, 1024, S_LARGEBUBBLE2}, // S_LARGEBUBBLE1 + {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|3, 8, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_LARGEBUBBLE2 + {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|4, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_EXTRALARGEBUBBLE // Extra Large Bubble goes POP! - {SPR_POPP, 0, 16, {NULL}, 0, 0, S_NULL}, // S_POP1 + {SPR_BUBL, 5, 16, {NULL}, 0, 0, S_NULL}, // S_POP1 {SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_MIDDLESTARTCHANCE, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP @@ -10486,7 +10487,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_EXTRALARGEBUBBLE -1, // doomednum - S_LARGEBUBBLE, // spawnstate + S_LARGEBUBBLE1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -10501,8 +10502,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_gasp, // deathsound 8, // speed - 8*FRACUNIT, // radius - 12*FRACUNIT, // height + 23*FRACUNIT, // radius + 43*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage diff --git a/src/info.h b/src/info.h index f1366c441..23278aa13 100644 --- a/src/info.h +++ b/src/info.h @@ -314,7 +314,7 @@ typedef enum sprite // Interactive Objects SPR_FANS, - SPR_BUBL, // water bubble source + SPR_BBLS, // water bubble source SPR_SIGN, // Level end sign SPR_STEM, // Steam riser SPR_SPIK, // Spike Ball @@ -458,11 +458,7 @@ typedef enum sprite SPR_SPLH, // Water Splish SPR_SPLA, // Water Splash SPR_SMOK, - SPR_BUBP, // Small bubble - SPR_BUBO, // Medium bubble - SPR_BUBN, // Large bubble - SPR_BUBM, // Extra Large (would you like fries with that?) bubble - SPR_POPP, // Extra Large bubble goes POP! + SPR_BUBL, // Bubble SPR_WZAP, SPR_TFOG, // Teleport Fog SPR_SEED, // Sonic CD flower seed @@ -1660,6 +1656,8 @@ typedef enum state // Bubble Source S_BUBBLES1, S_BUBBLES2, + S_BUBBLES3, + S_BUBBLES4, // Level End Sign S_SIGN1, @@ -2515,10 +2513,9 @@ typedef enum state // Bubbles S_SMALLBUBBLE, - S_SMALLBUBBLE1, S_MEDIUMBUBBLE, - S_MEDIUMBUBBLE1, - S_LARGEBUBBLE, + S_LARGEBUBBLE1, + S_LARGEBUBBLE2, S_EXTRALARGEBUBBLE, // breathable S_POP1, // Extra Large bubble goes POP! From 9f69850c058005dcabea9c60052655f300dd20f6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 25 Sep 2016 15:07:00 +0100 Subject: [PATCH 094/100] Basically seriously un-fucked the rope hang and zoom tube code from my experimentations (i just wanted to compare speed and distance and got carried away...) --- src/p_user.c | 78 ++++++++++++++++------------------------------------ 1 file changed, 23 insertions(+), 55 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index f155f7486..eb163283f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7150,7 +7150,6 @@ static void P_DoZoomTube(player_t *player) mobj_t *waypoint = NULL; fixed_t dist; boolean reverse; - fixed_t speedx,speedy,speedz; player->mo->height = P_GetPlayerSpinHeight(player); @@ -7171,26 +7170,17 @@ static void P_DoZoomTube(player_t *player) if (dist < 1) dist = 1; - speedx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); - speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); - speedz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed)); + player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); + player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); + player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - player->mo->z, dist), (speed)); // Calculate the distance between the player and the waypoint // 'dist' already equals this. // Will the player go past the waypoint? - if (speed && ( - ((speedx || speedy) - && (R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y) - - R_PointToAngle2(player->mo->x + speedx, player->mo->y + speedy, player->mo->tracer->x, player->mo->tracer->y)) > ANG1) - || ((speedz) - && ((player->mo->z - player->mo->tracer->z) > 0) != ((player->mo->z + speedz - player->mo->tracer->z) > 0)) - )) + if (speed > dist) { - if (speed > dist) - speed -= dist; - else - speed = 0; + speed -= dist; // If further away, set XYZ of player to waypoint location P_UnsetThingPosition(player->mo); player->mo->x = player->mo->tracer->x; @@ -7259,12 +7249,6 @@ static void P_DoZoomTube(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n"); } } - else - { - player->mo->momx = speedx; - player->mo->momy = speedy; - player->mo->momz = speedz; - } } // @@ -7281,24 +7265,10 @@ static void P_DoRopeHang(player_t *player) mobj_t *mo2; mobj_t *waypoint = NULL; fixed_t dist; - fixed_t speedx,speedy,speedz; fixed_t playerz; player->mo->height = P_GetPlayerHeight(player); - if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope - { - P_SetTarget(&player->mo->tracer, NULL); - - player->pflags |= PF_JUMPED; - player->powers[pw_carry] = CR_NONE; - - if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) - && !(player->panim == PA_JUMP)) - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); - return; - } - // Play the 'clink' sound only if the player is moving. if (!(leveltime & 7) && player->speed) S_StartSound(player->mo, sfx_s3k55); @@ -7315,9 +7285,22 @@ static void P_DoRopeHang(player_t *player) if (dist < 1) dist = 1; - speedx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); - speedy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); - speedz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); + player->mo->momx = FixedMul(FixedDiv(player->mo->tracer->x - player->mo->x, dist), (speed)); + player->mo->momy = FixedMul(FixedDiv(player->mo->tracer->y - player->mo->y, dist), (speed)); + player->mo->momz = FixedMul(FixedDiv(player->mo->tracer->z - playerz, dist), (speed)); + + if (player->cmd.buttons & BT_USE && !(player->pflags & PF_STASIS)) // Drop off of the rope + { + P_SetTarget(&player->mo->tracer, NULL); + + player->pflags |= PF_JUMPED; + player->powers[pw_carry] = CR_NONE; + + if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) + && !(player->panim == PA_JUMP)) + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + return; + } // If not allowed to move, we're done here. if (!speed) @@ -7327,18 +7310,9 @@ static void P_DoRopeHang(player_t *player) // 'dist' already equals this. // Will the player go past the waypoint? - if ( - ((speedx || speedy) - && (R_PointToAngle2(player->mo->x, player->mo->y, player->mo->tracer->x, player->mo->tracer->y) - - R_PointToAngle2(player->mo->x + speedx, player->mo->y + speedy, player->mo->tracer->x, player->mo->tracer->y)) > ANG1) - || ((speedz) - && ((playerz - player->mo->tracer->z) > 0) != ((playerz + speedz - player->mo->tracer->z) > 0)) - ) + if (speed > dist) { - if (speed > dist) - speed -= dist; - else - speed = 0; + speed -= dist; // If further away, set XYZ of player to waypoint location P_UnsetThingPosition(player->mo); player->mo->x = player->mo->tracer->x; @@ -7430,12 +7404,6 @@ static void P_DoRopeHang(player_t *player) CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found!\n"); } } - else - { - player->mo->momx = speedx; - player->mo->momy = speedy; - player->mo->momz = speedz; - } } #if 0 From 64a9a946043f7cb734c80782369ba1a37b7144cd Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 25 Sep 2016 15:23:22 +0100 Subject: [PATCH 095/100] GETSPEED -> GETFRACBITS completion. woops --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 8618093a3..ab155bd4d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2696,7 +2696,7 @@ void R_AddSkins(UINT16 wadnum) GETFRACBITS(radius) GETFRACBITS(height) GETFRACBITS(spinheight) -#undef GETSPEED +#undef GETFRACBITS #define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value); GETINT(thrustfactor) From be0e898bae59eab676ef02145d55af2bde2570bd Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 25 Sep 2016 18:21:52 +0100 Subject: [PATCH 096/100] * Skin-controlled radius is no longer set each tic, only on skin change and player spawn. * Camerascale, shieldscale, height and spinheight are now player attributes which are set to the skin attribute on skin change, not read directly from the skin. * P_GetPlayerHeight and P_GetPlayerSpinHeight are now macros instead of functions. * Extra protection against switching to a locked skin. --- src/d_clisrv.c | 8 ++++++++ src/d_clisrv.h | 4 ++++ src/d_player.h | 5 +++++ src/g_game.c | 26 +++++++++++++++++++++++++- src/lua_playerlib.c | 16 ++++++++++++++++ src/p_local.h | 6 +++--- src/p_mobj.c | 2 +- src/p_saveg.c | 10 ++++++++++ src/p_user.c | 42 ++++-------------------------------------- src/r_things.c | 9 ++++++++- 10 files changed, 84 insertions(+), 44 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f4caf66e6..734173f8d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -506,6 +506,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->skin = LONG(players[i].skin); // Just in case Lua does something like // modify these at runtime + rsp->camerascale = (fixed_t)LONG(players[i].camerascale); + rsp->shieldscale = (fixed_t)LONG(players[i].shieldscale); rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed); rsp->runspeed = (fixed_t)LONG(players[i].runspeed); rsp->thrustfactor = players[i].thrustfactor; @@ -521,6 +523,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->mindash = (fixed_t)LONG(players[i].mindash); rsp->maxdash = (fixed_t)LONG(players[i].maxdash); rsp->jumpfactor = (fixed_t)LONG(players[i].jumpfactor); + rsp->playerheight = (fixed_t)LONG(players[i].height); + rsp->playerspinheight = (fixed_t)LONG(players[i].spinheight); rsp->speed = (fixed_t)LONG(players[i].speed); rsp->jumping = players[i].jumping; @@ -632,6 +636,8 @@ static void resynch_read_player(resynch_pak *rsp) players[i].skin = LONG(rsp->skin); // Just in case Lua does something like // modify these at runtime + players[i].camerascale = (fixed_t)LONG(rsp->camerascale); + players[i].shieldscale = (fixed_t)LONG(rsp->shieldscale); players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed); players[i].runspeed = (fixed_t)LONG(rsp->runspeed); players[i].thrustfactor = rsp->thrustfactor; @@ -647,6 +653,8 @@ static void resynch_read_player(resynch_pak *rsp) players[i].mindash = (fixed_t)LONG(rsp->mindash); players[i].maxdash = (fixed_t)LONG(rsp->maxdash); players[i].jumpfactor = (fixed_t)LONG(rsp->jumpfactor); + players[i].height = (fixed_t)LONG(rsp->playerheight); + players[i].spinheight = (fixed_t)LONG(rsp->playerspinheight); players[i].speed = (fixed_t)LONG(rsp->speed); players[i].jumping = rsp->jumping; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 9d130618b..f86c09b45 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -166,6 +166,8 @@ typedef struct INT32 skin; // Just in case Lua does something like // modify these at runtime + fixed_t camerascale; + fixed_t shieldscale; fixed_t normalspeed; fixed_t runspeed; UINT8 thrustfactor; @@ -181,6 +183,8 @@ typedef struct fixed_t mindash; fixed_t maxdash; fixed_t jumpfactor; + fixed_t playerheight; + fixed_t playerspinheight; fixed_t speed; UINT8 jumping; diff --git a/src/d_player.h b/src/d_player.h index 620b698c7..bd553d9fa 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -282,6 +282,8 @@ typedef struct player_s playerstate_t playerstate; // Determine POV, including viewpoint bobbing during movement. + fixed_t camerascale; + fixed_t shieldscale; // Focal origin above r.z fixed_t viewz; // Base height above floor for viewz. @@ -349,6 +351,9 @@ typedef struct player_s fixed_t jumpfactor; // How high can the player jump? + fixed_t height; // Bounding box changes. + fixed_t spinheight; + SINT8 lives; SINT8 continues; // continues that player has acquired diff --git a/src/g_game.c b/src/g_game.c index 76229347e..2f60b79c3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2047,6 +2047,8 @@ void G_PlayerReborn(INT32 player) INT32 score; INT32 lives; INT32 continues; + fixed_t camerascale; + fixed_t shieldscale; UINT8 charability; UINT8 charability2; fixed_t normalspeed; @@ -2070,6 +2072,8 @@ void G_PlayerReborn(INT32 player) INT32 starpostnum; INT32 starpostangle; fixed_t jumpfactor; + fixed_t height; + fixed_t spinheight; INT32 exiting; INT16 numboxes; INT16 totalring; @@ -2101,6 +2105,8 @@ void G_PlayerReborn(INT32 player) skincolor = players[player].skincolor; skin = players[player].skin; + camerascale = players[player].camerascale; + shieldscale = players[player].shieldscale; charability = players[player].charability; charability2 = players[player].charability2; normalspeed = players[player].normalspeed; @@ -2117,6 +2123,8 @@ void G_PlayerReborn(INT32 player) starpostnum = players[player].starpostnum; starpostangle = players[player].starpostangle; jumpfactor = players[player].jumpfactor; + height = players[player].height; + spinheight = players[player].spinheight; thokitem = players[player].thokitem; spinitem = players[player].spinitem; revitem = players[player].revitem; @@ -2142,6 +2150,8 @@ void G_PlayerReborn(INT32 player) // save player config truth reborn p->skincolor = skincolor; p->skin = skin; + p->camerascale = camerascale; + p->shieldscale = shieldscale; p->charability = charability; p->charability2 = charability2; p->normalspeed = normalspeed; @@ -2164,6 +2174,8 @@ void G_PlayerReborn(INT32 player) p->starpostnum = starpostnum; p->starpostangle = starpostangle; p->jumpfactor = jumpfactor; + p->height = height; + p->spinheight = spinheight; p->exiting = exiting; p->numboxes = numboxes; @@ -4696,6 +4708,8 @@ void G_BeginRecording(void) demo_p += 16; // Stats + WRITEUINT8(demo_p,player->camerascale>>FRACBITS); + WRITEUINT8(demo_p,player->shieldscale>>FRACBITS); WRITEUINT8(demo_p,player->charability); WRITEUINT8(demo_p,player->charability2); WRITEUINT8(demo_p,player->actionspd>>FRACBITS); @@ -4706,6 +4720,8 @@ void G_BeginRecording(void) WRITEUINT8(demo_p,player->thrustfactor); WRITEUINT8(demo_p,player->accelstart); WRITEUINT8(demo_p,player->acceleration); + WRITEUINT8(demo_p,player->height>>FRACBITS); + WRITEUINT8(demo_p,player->spinheight>>FRACBITS); // Trying to convert it back to % causes demo desync due to precision loss. // Don't do it. @@ -4936,7 +4952,7 @@ void G_DoPlayDemo(char *defdemoname) char skin[17],color[17],*n,*pdemoname; UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration; UINT32 randseed; - fixed_t actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor; + fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight; char msg[1024]; skin[16] = '\0'; @@ -5072,6 +5088,8 @@ void G_DoPlayDemo(char *defdemoname) M_Memcpy(color,demo_p,16); demo_p += 16; + camerascale = (fixed_t)READUINT8(demo_p)<cmd, META_TICCMD); else if (fastcmp(field,"playerstate")) lua_pushinteger(L, plr->playerstate); + else if (fastcmp(field,"camerascale")) + lua_pushfixed(L, plr->camerascale); + else if (fastcmp(field,"shieldscale")) + lua_pushfixed(L, plr->shieldscale); else if (fastcmp(field,"viewz")) lua_pushfixed(L, plr->viewz); else if (fastcmp(field,"viewheight")) @@ -172,6 +176,10 @@ static int player_get(lua_State *L) lua_pushfixed(L, plr->maxdash); else if (fastcmp(field,"jumpfactor")) lua_pushfixed(L, plr->jumpfactor); + else if (fastcmp(field,"height")) + lua_pushfixed(L, plr->height); + else if (fastcmp(field,"spinheight")) + lua_pushfixed(L, plr->spinheight); else if (fastcmp(field,"lives")) lua_pushinteger(L, plr->lives); else if (fastcmp(field,"continues")) @@ -355,6 +363,10 @@ static int player_set(lua_State *L) return NOSET; else if (fastcmp(field,"playerstate")) plr->playerstate = luaL_checkinteger(L, 3); + else if (fastcmp(field,"camerascale")) + plr->camerascale = luaL_checkfixed(L, 3); + else if (fastcmp(field,"shieldscale")) + plr->shieldscale = luaL_checkfixed(L, 3); else if (fastcmp(field,"viewz")) plr->viewz = luaL_checkfixed(L, 3); else if (fastcmp(field,"viewheight")) @@ -429,6 +441,10 @@ static int player_set(lua_State *L) plr->maxdash = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"jumpfactor")) plr->jumpfactor = (INT32)luaL_checkinteger(L, 3); + else if (fastcmp(field,"height")) + plr->height = luaL_checkfixed(L, 3); + else if (fastcmp(field,"spinheight")) + plr->spinheight = luaL_checkfixed(L, 3); else if (fastcmp(field,"lives")) plr->lives = (SINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"continues")) diff --git a/src/p_local.h b/src/p_local.h index 8a451566f..a1cf4892a 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -62,6 +62,9 @@ #define mariomode (maptol & TOL_MARIO) #define twodlevel (maptol & TOL_2D) +#define P_GetPlayerHeight(player) FixedMul(player->height, player->mo->scale) +#define P_GetPlayerSpinHeight(player) FixedMul(player->spinheight, player->mo->scale) + // // P_TICK // @@ -119,9 +122,6 @@ extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed; extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate; extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate; -fixed_t P_GetPlayerRadius(player_t *player); -fixed_t P_GetPlayerHeight(player_t *player); -fixed_t P_GetPlayerSpinHeight(player_t *player); INT32 P_GetPlayerControlDirection(player_t *player); void P_AddPlayerScore(player_t *player, UINT32 amount); void P_ResetCamera(player_t *player, camera_t *thiscam); diff --git a/src/p_mobj.c b/src/p_mobj.c index f2ef4dc0d..72f6098aa 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6301,7 +6301,7 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) thing->flags |= MF_NOCLIPHEIGHT; thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP); - P_SetScale(thing, FixedMul(thing->target->scale, skins[thing->target->player->skin].shieldscale)); + P_SetScale(thing, FixedMul(thing->target->scale, thing->target->player->shieldscale)); P_UnsetThingPosition(thing); thing->x = thing->target->x; thing->y = thing->target->y; diff --git a/src/p_saveg.c b/src/p_saveg.c index 768949b3c..b086b076e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -259,6 +259,9 @@ static void P_NetArchivePlayers(void) if (flags & AWAYVIEW) WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum); + WRITEFIXED(save_p, players[i].camerascale); + WRITEFIXED(save_p, players[i].shieldscale); + WRITEUINT8(save_p, players[i].charability); WRITEUINT8(save_p, players[i].charability2); WRITEUINT32(save_p, players[i].charflags); @@ -274,6 +277,8 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].accelstart); WRITEUINT8(save_p, players[i].acceleration); WRITEFIXED(save_p, players[i].jumpfactor); + WRITEFIXED(save_p, players[i].height); + WRITEFIXED(save_p, players[i].spinheight); } } @@ -424,6 +429,9 @@ static void P_NetUnArchivePlayers(void) players[i].viewheight = cv_viewheight.value<skin].radius, player->mo->scale); -} - -// -// P_GetPlayerHeight -// -// Returns the height -// of the player. -// -fixed_t P_GetPlayerHeight(player_t *player) -{ - return FixedMul(skins[player->skin].height, player->mo->scale); -} - -// -// P_GetPlayerSpinHeight -// -// Returns the 'spin height' -// of the player. -// -fixed_t P_GetPlayerSpinHeight(player_t *player) -{ - return FixedMul(skins[player->skin].spinheight, player->mo->scale); -} - // // Movement. // @@ -7002,7 +6969,6 @@ static void P_MovePlayer(player_t *player) player->mo->height = P_GetPlayerSpinHeight(player); else player->mo->height = P_GetPlayerHeight(player); - player->mo->radius = P_GetPlayerRadius(player); if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling player->mo->z -= player->mo->height - oldheight; @@ -7968,16 +7934,16 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camspeed = cv_cam_speed.value; camstill = cv_cam_still.value; camrotate = cv_cam_rotate.value; - camdist = FixedMul(cv_cam_dist.value, FixedMul(skins[player->skin].camerascale, mo->scale)); - camheight = FixedMul(cv_cam_height.value, FixedMul(skins[player->skin].camerascale, mo->scale)); + camdist = FixedMul(cv_cam_dist.value, FixedMul(player->camerascale, mo->scale)); + camheight = FixedMul(cv_cam_height.value, FixedMul(player->camerascale, mo->scale)); } else // Camera 2 { camspeed = cv_cam2_speed.value; camstill = cv_cam2_still.value; camrotate = cv_cam2_rotate.value; - camdist = FixedMul(cv_cam2_dist.value, FixedMul(skins[player->skin].camerascale, mo->scale)); - camheight = FixedMul(cv_cam2_height.value, FixedMul(skins[player->skin].camerascale, mo->scale)); + camdist = FixedMul(cv_cam2_dist.value, FixedMul(player->camerascale, mo->scale)); + camheight = FixedMul(cv_cam2_height.value, FixedMul(player->camerascale, mo->scale)); } #ifdef REDSANALOG diff --git a/src/r_things.c b/src/r_things.c index ab155bd4d..f9f0f756c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2432,7 +2432,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname) INT32 i = R_SkinAvailable(skinname); player_t *player = &players[playernum]; - if (i != -1) + if ((i != -1) && (!P_IsLocalPlayer(player) || R_SkinUnlock(i))) { SetPlayerSkinByNum(playernum, i); return; @@ -2459,6 +2459,9 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) { player->skin = skinnum; + player->camerascale = skin->camerascale; + player->shieldscale = skin->shieldscale; + player->charability = (UINT8)skin->ability; player->charability2 = (UINT8)skin->ability2; @@ -2480,6 +2483,9 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) player->jumpfactor = skin->jumpfactor; + player->height = skin->height; + player->spinheight = skin->spinheight; + if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) { if (playernum == consoleplayer) @@ -2500,6 +2506,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) if (newcolor) player->mo->color = newcolor; P_SetScale(player->mo, player->mo->scale); + player->mo->radius = FixedMul(skin->radius, player->mo->scale); } return; } From 28f5e7d1bc5cd9730f248cd78c4006b11457f63d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 26 Sep 2016 12:25:10 +0100 Subject: [PATCH 097/100] Did I not commit this fix? Woops. --- src/p_mobj.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 72f6098aa..a28fb6a0d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8834,6 +8834,8 @@ void P_AfterPlayerSpawn(INT32 playernum) player_t *p = &players[playernum]; mobj_t *mobj = p->mo; + mobj->radius = skins[p->skin].radius; + if (playernum == consoleplayer) localangle = mobj->angle; else if (playernum == secondarydisplayplayer) From cf9ea19d11f591d2951b35b998e2b145254954c2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 27 Sep 2016 11:32:34 +0100 Subject: [PATCH 098/100] Tweaked P_SetScale so it allows radii and heights set by Lua (and the skin's radius) to be kept, and tweaked the contents of the last commit to match. --- src/p_mobj.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a28fb6a0d..81551c6a0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6181,8 +6181,8 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale) mobj->scale = newscale; - mobj->radius = FixedMul(mobj->info->radius, newscale); - mobj->height = FixedMul(mobj->info->height, newscale); + mobj->radius = FixedMul(FixedDiv(mobj->radius, oldscale), newscale); + mobj->height = FixedMul(FixedDiv(mobj->height, oldscale), newscale); player = mobj->player; @@ -8811,6 +8811,8 @@ void P_SpawnPlayer(INT32 playernum) // the dead body mobj retains the skin through the 'spritedef' override). mobj->skin = &skins[p->skin]; + mobj->radius = FixedMul(skins[p->skin].radius, mobj->destscale); + mobj->health = p->health; p->playerstate = PST_LIVE; @@ -8834,8 +8836,6 @@ void P_AfterPlayerSpawn(INT32 playernum) player_t *p = &players[playernum]; mobj_t *mobj = p->mo; - mobj->radius = skins[p->skin].radius; - if (playernum == consoleplayer) localangle = mobj->angle; else if (playernum == secondarydisplayplayer) From e801c581d34208bf517b2fe890b5539deb03a2cd Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 27 Sep 2016 11:50:48 +0100 Subject: [PATCH 099/100] Fixed off-by-one error with the relationship between FF_ANIMATE's var1/number of frames, FF_MIDDLESTARTCHANCE, and P_RandomKey. --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 81551c6a0..44a701ee9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -622,7 +622,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) mobj->sprite = st->sprite; mobj->frame = st->frame; if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) - mobj->frame += P_RandomKey(st->var1); + mobj->frame += P_RandomKey(st->var1+1); } // Modified handling. @@ -737,7 +737,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) mobj->sprite = st->sprite; mobj->frame = st->frame; if ((st->frame & (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) == (FF_ANIMATE|FF_MIDDLESTARTCHANCE)) - mobj->frame += P_RandomKey(st->var1); + mobj->frame += P_RandomKey(st->var1+1); } // Modified handling. From 55d8b419e2dfca1b67affc6547115f1f630bb05f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 27 Sep 2016 17:51:17 +0100 Subject: [PATCH 100/100] MI's last few reccomendations fixed. --- src/p_mobj.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 44a701ee9..db80851f3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8811,8 +8811,6 @@ void P_SpawnPlayer(INT32 playernum) // the dead body mobj retains the skin through the 'spritedef' override). mobj->skin = &skins[p->skin]; - mobj->radius = FixedMul(skins[p->skin].radius, mobj->destscale); - mobj->health = p->health; p->playerstate = PST_LIVE; @@ -8827,6 +8825,10 @@ void P_SpawnPlayer(INT32 playernum) P_SetScale(mobj, mobj->destscale); P_FlashPal(p, 0, 0); // Resets + // Set bounds accurately. + mobj->radius = FixedMul(skins[p->skin].radius, mobj->scale); + mobj->height = P_GetPlayerHeight(p); + // Spawn with a pity shield if necessary. P_DoPityCheck(p); }