diff --git a/src/dehacked.c b/src/dehacked.c index acf68a58..bbc78d15 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -877,38 +877,32 @@ static void readfollower(MYFILE *f) } strcpy(followers[numfollowers].skinname, testname); + strcpy(dname, followers[numfollowers].skinname); // display name, just used for printing succesful stuff or errors later down the line. - // get ready to print the name... - strcpy(dname, followers[numfollowers].skinname); + // now that the skin name is ready, post process the actual name to turn the underscores into spaces! + for (INT32 i = 0; followers[numfollowers].name[i]; i++) + { + if (followers[numfollowers].name[i] == '_') + followers[numfollowers].name[i] = ' '; + } - if (followers[numfollowers].dist < 0) - followers[numfollowers].dist = 0; + // fallbacks for variables + // Print a warning if the variable is on a weird value and set it back to the minimum available if that's the case. +#define FALLBACK(field, field2, threshold, set) \ +if (followers[numfollowers].field < threshold) \ +{ \ + followers[numfollowers].field = set; \ + deh_warning("Follower '%s': Value for '%s' is too low! Minimum should be %d. Value was overwritten to %d.", dname, field2, set, set); \ +} \ - if (followers[numfollowers].zoffs < 0) - followers[numfollowers].zoffs = 0; - - // HORZLAG and VERTLAG must ABSOLUTELY be higher than 0. If 0, the game crashes, if negative, weird shit happens! - if (followers[numfollowers].horzlag <= 0) - followers[numfollowers].horzlag = 1; - - if (followers[numfollowers].vertlag <= 0) - followers[numfollowers].vertlag = 1; - - // scale must be positive for obvious reasons, and so must both of the bob related variables - if (followers[numfollowers].scale <= 0) - followers[numfollowers].scale = 1; - - // Bob amplitude can totally be 0 - if (followers[numfollowers].bobamp < 0) - followers[numfollowers].bobamp = 1; - - // so can bob speed - if (followers[numfollowers].bobspeed < 0) - followers[numfollowers].bobspeed = 1; - - // hit confirm time must be > 0 - if (followers[numfollowers].hitconfirmtime < 1) - followers[numfollowers].hitconfirmtime = 1; + FALLBACK(dist, "DIST", 0, 0); + FALLBACK(zoffs, "ZOFFS", 0, 0); + FALLBACK(horzlag, "HORZLAG", 1, 1); + FALLBACK(vertlag, "VERTLAG", 1, 1); + FALLBACK(bobamp, "BOBAMP", 0, 0); + FALLBACK(bobspeed, "BOBSPEED", 0, 0); + FALLBACK(hitconfirmtime, "HITCONFIRMTIME", 1, 1); +#undef FALLBACK // also check if we forgot states. If we did, we will set any missing state to the follower's idlestate. // Print a warning in case we don't have a fallback and set the state to S_INVISIBLE (rather than S_NULL) if unavailable. @@ -918,15 +912,15 @@ if (!followers[numfollowers].field) \ { \ followers[numfollowers].field = fallbackstate ? fallbackstate : S_INVISIBLE; \ if (!fallbackstate) \ - deh_warning("Follower %s is missing state definition for %s, no idlestate fallback was found", dname, field2); \ + deh_warning("Follower '%s' is missing state definition for '%s', no idlestate fallback was found", dname, field2); \ } \ - NOSTATE(idlestate, "idlestate"); - NOSTATE(followstate, "followstate"); - NOSTATE(hurtstate, "hurtstate"); - NOSTATE(losestate, "losestate"); - NOSTATE(winstate, "winstate"); - NOSTATE(hitconfirmstate, "hitconfirmstate"); + NOSTATE(idlestate, "IDLESTATE"); + NOSTATE(followstate, "FOLLOWSTATE"); + NOSTATE(hurtstate, "HURTSTATE"); + NOSTATE(losestate, "LOSESTATE"); + NOSTATE(winstate, "WINSTATE"); + NOSTATE(hitconfirmstate, "HITCONFIRMSTATE"); #undef NOSTATE CONS_Printf("Added follower '%s'\n", dname); diff --git a/src/p_mobj.c b/src/p_mobj.c index fd42a1d7..461f50aa 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6556,6 +6556,13 @@ void P_MobjThinker(mobj_t *mobj) #endif switch (mobj->type) { + case MT_FOLLOWER: + // small thinker for follower: + // We cleanse ourselves from existence if our target player doesn't exist for whatever reason. (generally players leaving) + if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->player || mobj->target->player->spectator || mobj->target->player->followerskin < 0) + P_RemoveMobj(mobj); + + return; case MT_HOOP: if (mobj->fuse > 1) P_MoveHoop(mobj); @@ -10962,6 +10969,8 @@ void P_SpawnPlayer(INT32 playernum) //awayview stuff p->awayviewmobj = NULL; p->awayviewtics = 0; + + p->follower = NULL; // cleanse follower from existence // set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't. if (cv_kartdebugshrink.value && !modeattacking && !p->bot) diff --git a/src/p_setup.c b/src/p_setup.c index 1acfb7a3..7334ba78 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2356,6 +2356,9 @@ static void P_LevelInitStuff(void) // and this stupid flag as a result players[i].pflags &= ~PF_TRANSFERTOCLOSEST; + + // Wipe follower from existence to avoid crashes + players[i].follower = NULL; } // SRB2Kart: map load variables diff --git a/src/p_user.c b/src/p_user.c index f062a461..5b187d71 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8960,7 +8960,7 @@ static void P_HandleFollower(player_t *player) // How about making sure our follower exists and is added before trying to spawn it n' all? if (player->followerskin > numfollowers-1 || player->followerskin < -1) { - CONS_Printf("Follower skin invlaid. Setting to -1.\n"); + //CONS_Printf("Follower skin invlaid. Setting to -1.\n"); player->followerskin = -1; return; } @@ -8970,7 +8970,6 @@ static void P_HandleFollower(player_t *player) return; if (player->followerskin < 0) return; - // Before we do anything, let's be sure of where we're supposed to be fl = followers[player->followerskin]; @@ -9029,12 +9028,17 @@ static void P_HandleFollower(player_t *player) P_SetScale(player->follower, FixedMul(fl.scale, player->mo->scale)); K_MatchGenericExtraFlags(player->follower, player->mo); + // For comeback in battle. + player->follower->flags2 = (player->follower->flags2 & ~MF2_SHADOW)|(player->mo->flags2 & MF2_SHADOW); + // Make the follower invisible if we no contest'd rather than removing it. No one will notice the diff seriously. if (player->pflags & PF_TIMEOVER) // there is more to it than that to check for a full no contest but this isn't used for anything else. player->follower->flags2 &= MF2_DONTDRAW; - + if (player->speed) + player->follower->angle = R_PointToAngle2(0, 0, player->follower->momx, player->follower->momy); + // if we're moving let's make the angle the direction we're moving towards. This is to avoid drifting / reverse looking awkward. // handle follower animations. Yes, it looks like very bad kiddie script so what, do you have any better idea genius? Go get a life instead of criticizing my unpaid work!!!!!! // hurt or dead @@ -9061,8 +9065,6 @@ static void P_HandleFollower(player_t *player) } else if (player->speed > 10*player->mo->scale) // animation for moving fast enough { - // if we're moving fast enough, let's make the angle the direction we're moving towards. This is to avoid drifting looking awkward. - player->follower->angle = R_PointToAngle2(0, 0, player->follower->momx, player->follower->momy); if (player->follower->extravalue1 != 1) {