mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2025-01-23 09:40:56 +00:00
Add more customization options & fix some dumb things
This commit is contained in:
parent
707e3d20e2
commit
eaff7617a5
5 changed files with 89 additions and 26 deletions
|
@ -716,7 +716,15 @@ static void readfollower(MYFILE *f)
|
||||||
|
|
||||||
s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||||
|
|
||||||
CONS_Printf("Adding follower...\n");
|
// Ready the default variables for followers. We will overwrite them as we go! We won't set the name or states RIGHT HERE as this is handled down instead.
|
||||||
|
followers[numfollowers].scale = FRACUNIT;
|
||||||
|
followers[numfollowers].atangle = 230;
|
||||||
|
followers[numfollowers].dist = 16;
|
||||||
|
followers[numfollowers].zoffs = 32;
|
||||||
|
followers[numfollowers].horzlag = 2;
|
||||||
|
followers[numfollowers].vertlag = 4;
|
||||||
|
followers[numfollowers].bobspeed = TICRATE*2;
|
||||||
|
followers[numfollowers].bobamp = 4;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -751,11 +759,36 @@ static void readfollower(MYFILE *f)
|
||||||
strcpy(followers[numfollowers].name, word2);
|
strcpy(followers[numfollowers].name, word2);
|
||||||
nameset = true;
|
nameset = true;
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(word, "SCALE"))
|
||||||
|
{
|
||||||
|
DEH_WriteUndoline(word, va("%d", followers[numfollowers].scale), UNDO_NONE);
|
||||||
|
followers[numfollowers].scale = get_number(word2);
|
||||||
|
}
|
||||||
else if (fastcmp(word, "ATANGLE"))
|
else if (fastcmp(word, "ATANGLE"))
|
||||||
{
|
{
|
||||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].atangle), UNDO_NONE);
|
DEH_WriteUndoline(word, va("%d", followers[numfollowers].atangle), UNDO_NONE);
|
||||||
followers[numfollowers].atangle = (INT32)atoi(word2);
|
followers[numfollowers].atangle = (INT32)atoi(word2);
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(word, "HORZLAG"))
|
||||||
|
{
|
||||||
|
DEH_WriteUndoline(word, va("%d", followers[numfollowers].horzlag), UNDO_NONE);
|
||||||
|
followers[numfollowers].horzlag = (INT32)atoi(word2);
|
||||||
|
}
|
||||||
|
else if (fastcmp(word, "VERTLAG"))
|
||||||
|
{
|
||||||
|
DEH_WriteUndoline(word, va("%d", followers[numfollowers].vertlag), UNDO_NONE);
|
||||||
|
followers[numfollowers].vertlag = (INT32)atoi(word2);
|
||||||
|
}
|
||||||
|
else if (fastcmp(word, "BOBSPEED"))
|
||||||
|
{
|
||||||
|
DEH_WriteUndoline(word, va("%d", followers[numfollowers].bobspeed), UNDO_NONE);
|
||||||
|
followers[numfollowers].bobspeed = (INT32)atoi(word2);
|
||||||
|
}
|
||||||
|
else if (fastcmp(word, "BOBAMP"))
|
||||||
|
{
|
||||||
|
DEH_WriteUndoline(word, va("%d", followers[numfollowers].bobamp), UNDO_NONE);
|
||||||
|
followers[numfollowers].bobamp = (INT32)atoi(word2);
|
||||||
|
}
|
||||||
else if (fastcmp(word, "ZOFFSET") || (fastcmp(word, "ZOFFS")))
|
else if (fastcmp(word, "ZOFFSET") || (fastcmp(word, "ZOFFS")))
|
||||||
{
|
{
|
||||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].zoffs), UNDO_NONE);
|
DEH_WriteUndoline(word, va("%d", followers[numfollowers].zoffs), UNDO_NONE);
|
||||||
|
@ -824,7 +857,7 @@ static void readfollower(MYFILE *f)
|
||||||
{
|
{
|
||||||
INT32 startlen = strlen(testname);
|
INT32 startlen = strlen(testname);
|
||||||
char cpy[2];
|
char cpy[2];
|
||||||
deh_warning("There was already a follower with the same name. (%s)", testname);
|
//deh_warning("There was already a follower with the same name. (%s)", testname); This warning probably isn't necessary anymore?
|
||||||
sprintf(cpy, "%d", numfollowers);
|
sprintf(cpy, "%d", numfollowers);
|
||||||
memcpy(&testname[startlen], cpy, 2);
|
memcpy(&testname[startlen], cpy, 2);
|
||||||
// in that case, we'll be very lazy and copy numfollowers to the end of our skin name.
|
// in that case, we'll be very lazy and copy numfollowers to the end of our skin name.
|
||||||
|
@ -841,8 +874,28 @@ static void readfollower(MYFILE *f)
|
||||||
if (followers[numfollowers].zoffs < 0)
|
if (followers[numfollowers].zoffs < 0)
|
||||||
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;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
// also check if we forgot states :V
|
|
||||||
#define NOSTATE(field, field2) \
|
#define NOSTATE(field, field2) \
|
||||||
if (!followers[numfollowers].field) \
|
if (!followers[numfollowers].field) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -8348,12 +8348,14 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||||
if (setupm_fakecolor) // inverse should never happen
|
if (setupm_fakecolor) // inverse should never happen
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Fake the follower's in game appearance by now also applying some of its variables! coolio, eh?
|
||||||
|
follower_t fl = followers[setupm_fakefollower]; // shortcut for our sanity
|
||||||
// smooth floating, totally not stolen from rocket sneakers.
|
// smooth floating, totally not stolen from rocket sneakers.
|
||||||
const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise
|
const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise
|
||||||
fixed_t sine = 8 * FINESINE((((4*pi*(TICRATE)) * followertimer)>>ANGLETOFINESHIFT) & FINEMASK);
|
fixed_t sine = fl.bobamp * FINESINE((((8*pi*(fl.bobspeed)) * followertimer)>>ANGLETOFINESHIFT) & FINEMASK);
|
||||||
|
|
||||||
UINT8 *colormap = R_GetTranslationColormap(-1, setupm_fakecolor, 0);
|
UINT8 *colormap = R_GetTranslationColormap(-1, setupm_fakecolor, 0);
|
||||||
V_DrawMappedPatch(mx+65, my+90+(sine/FRACUNIT), flags, patch, colormap);
|
V_DrawFixedPatch((mx+65)*FRACUNIT, (my+131-fl.zoffs)*FRACUNIT+sine, fl.scale, flags, patch, colormap);
|
||||||
Z_Free(colormap);
|
Z_Free(colormap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
36
src/p_user.c
36
src/p_user.c
|
@ -8979,18 +8979,15 @@ static void P_HandleFollower(player_t *player)
|
||||||
// ^ handled by K_matchgenericextraflags oops
|
// ^ handled by K_matchgenericextraflags oops
|
||||||
|
|
||||||
|
|
||||||
// finally, add a cool floating effect to the z height, unless we have no zoffs, in which case I guess this means we WANT to be on the ground...???
|
// finally, add a cool floating effect to the z height.
|
||||||
if (fl.zoffs)
|
// not stolen from k_kart I swear!!
|
||||||
{
|
const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise
|
||||||
// not stolen from k_kart I swear!!
|
fixed_t sine = fl.bobamp * FINESINE((((8*pi*(fl.bobspeed)) * leveltime)>>ANGLETOFINESHIFT) & FINEMASK);
|
||||||
const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise
|
sz += sine;
|
||||||
fixed_t sine = 4 * FINESINE((((8*pi*(TICRATE*2)) * leveltime)>>ANGLETOFINESHIFT) & FINEMASK);
|
|
||||||
sz += sine;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!player->follower) // follower doesn't exist / isn't valid
|
if (!player->follower) // follower doesn't exist / isn't valid
|
||||||
{
|
{
|
||||||
CONS_Printf("Spawning follower...\n");
|
//CONS_Printf("Spawning follower...\n");
|
||||||
// so let's spawn one!
|
// so let's spawn one!
|
||||||
player->follower = P_SpawnMobj(sx, sy, sz, MT_FOLLOWER);
|
player->follower = P_SpawnMobj(sx, sy, sz, MT_FOLLOWER);
|
||||||
P_SetFollowerState(player->follower, fl.idlestate);
|
P_SetFollowerState(player->follower, fl.idlestate);
|
||||||
|
@ -9012,14 +9009,14 @@ static void P_HandleFollower(player_t *player)
|
||||||
P_SetFollowerState(player->follower, player->follower->state->nextstate);
|
P_SetFollowerState(player->follower, player->follower->state->nextstate);
|
||||||
|
|
||||||
// move the follower next to us (yes, this is really basic maths but it looks pretty damn clean in practice)!
|
// move the follower next to us (yes, this is really basic maths but it looks pretty damn clean in practice)!
|
||||||
player->follower->momx = (sx - player->follower->x)/2;
|
player->follower->momx = (sx - player->follower->x)/fl.horzlag;
|
||||||
player->follower->momy = (sy - player->follower->y)/2;
|
player->follower->momy = (sy - player->follower->y)/fl.horzlag;
|
||||||
player->follower->momz = (sz - player->follower->z)/6; // make z momentum a bit floatier, it'll look cute I promise!
|
player->follower->momz = (sz - player->follower->z)/fl.vertlag; // make z momentum a bit floatier, it'll look cute I promise!
|
||||||
player->follower->angle = player->mo->angle;
|
player->follower->angle = player->mo->angle;
|
||||||
player->follower->color = player->mo->color;
|
player->follower->color = player->mo->color;
|
||||||
player->follower->colorized = player->mo->colorized;
|
player->follower->colorized = player->mo->colorized;
|
||||||
|
|
||||||
P_SetScale(player->follower, player->mo->scale);
|
P_SetScale(player->follower, FixedMul(fl.scale, player->mo->scale));
|
||||||
K_MatchGenericExtraFlags(player->follower, player->mo);
|
K_MatchGenericExtraFlags(player->follower, player->mo);
|
||||||
|
|
||||||
|
|
||||||
|
@ -9028,7 +9025,7 @@ static void P_HandleFollower(player_t *player)
|
||||||
// hurt or dead
|
// hurt or dead
|
||||||
if (player->kartstuff[k_spinouttimer] || player->mo->health <= 0)
|
if (player->kartstuff[k_spinouttimer] || player->mo->health <= 0)
|
||||||
{
|
{
|
||||||
player->follower->angle = leveltime*48*ANG1;
|
player->follower->angle = -leveltime*48*ANG1; // spin out
|
||||||
if (player->follower->extravalue1 != 2)
|
if (player->follower->extravalue1 != 2)
|
||||||
{
|
{
|
||||||
player->follower->extravalue1 = 2;
|
player->follower->extravalue1 = 2;
|
||||||
|
@ -9037,20 +9034,23 @@ static void P_HandleFollower(player_t *player)
|
||||||
if (player->mo->health <= 0) // if dead, follow the player's z momentum exactly so they both look like they die at the same speed.
|
if (player->mo->health <= 0) // if dead, follow the player's z momentum exactly so they both look like they die at the same speed.
|
||||||
player->follower->momz = player->mo->momz;
|
player->follower->momz = player->mo->momz;
|
||||||
}
|
}
|
||||||
else if (player->speed > 10*player->mo->scale)
|
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)
|
if (player->follower->extravalue1 != 1)
|
||||||
{
|
{
|
||||||
player->follower->extravalue1 = 1;
|
player->follower->extravalue1 = 1;
|
||||||
P_SetFollowerState(player->follower, fl.followstate);
|
P_SetFollowerState(player->follower, fl.followstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // nvm you're slow
|
else // animations when nearly still. This includes winning and losing.
|
||||||
{
|
{
|
||||||
if (player->follower->extravalue1 != 0)
|
if (player->follower->extravalue1 != 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (player->exiting)
|
if (player->exiting) // win/ loss animations
|
||||||
{
|
{
|
||||||
if (K_IsPlayerLosing(player)) // L
|
if (K_IsPlayerLosing(player)) // L
|
||||||
{
|
{
|
||||||
|
@ -9069,7 +9069,7 @@ static void P_HandleFollower(player_t *player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else // normal standstill
|
||||||
{
|
{
|
||||||
player->follower->extravalue1 = 0;
|
player->follower->extravalue1 = 0;
|
||||||
P_SetFollowerState(player->follower, fl.idlestate);
|
P_SetFollowerState(player->follower, fl.idlestate);
|
||||||
|
|
|
@ -2775,7 +2775,7 @@ void SetFollower(INT32 playernum, INT32 skinnum)
|
||||||
if (skinnum >= -1 && skinnum <= numfollowers) // Make sure it exists!
|
if (skinnum >= -1 && skinnum <= numfollowers) // Make sure it exists!
|
||||||
{
|
{
|
||||||
player->followerskin = skinnum;
|
player->followerskin = skinnum;
|
||||||
CONS_Printf("Updated player follower num\n");
|
//CONS_Printf("Updated player follower num\n");
|
||||||
/*
|
/*
|
||||||
We don't spawn the follower here since it'll be easier to handle all of it in the Player thinker itself.
|
We don't spawn the follower here since it'll be easier to handle all of it in the Player thinker itself.
|
||||||
However, we will despawn it right here if there's any to make it easy for the player thinker to replace it or delete it.
|
However, we will despawn it right here if there's any to make it easy for the player thinker to replace it or delete it.
|
||||||
|
|
|
@ -124,11 +124,20 @@ typedef struct follower_s
|
||||||
{
|
{
|
||||||
char skinname[SKINNAMESIZE+1]; // Skin Name. This is what to refer to when asking the commands anything.
|
char skinname[SKINNAMESIZE+1]; // Skin Name. This is what to refer to when asking the commands anything.
|
||||||
char name[SKINNAMESIZE+1]; // Name. This is used for the menus. We'll just follow the same rules as skins for this.
|
char name[SKINNAMESIZE+1]; // Name. This is used for the menus. We'll just follow the same rules as skins for this.
|
||||||
|
|
||||||
|
fixed_t scale; // Scale relative to the player's.
|
||||||
|
|
||||||
// some position shenanigans:
|
// some position shenanigans:
|
||||||
INT32 atangle; // angle the object will be at around the player. The object itself will always face the same direction as the player.
|
INT32 atangle; // angle the object will be at around the player. The object itself will always face the same direction as the player.
|
||||||
INT32 dist; // distance relative to the player. (In a circle)
|
INT32 dist; // distance relative to the player. (In a circle)
|
||||||
INT32 zoffs; // Z offset relative to the player's height. Cannot be negative.
|
INT32 zoffs; // Z offset relative to the player's height. Cannot be negative.
|
||||||
|
|
||||||
|
// movement options
|
||||||
|
|
||||||
|
INT32 horzlag; // Lag for X/Y displacement. Default is 2. Must be > 0 because we divide by this number.
|
||||||
|
INT32 vertlag; // not Vert from Neptunia lagging, this is for Z displacement lag Default is 4. Must be > 0 because we divide by this number.
|
||||||
|
INT32 bobamp; // Bob amplitude. Default is 4.
|
||||||
|
INT32 bobspeed; // Arbitrary modifier for bobbing speed, default is TICRATE*2 (70).
|
||||||
|
|
||||||
// from there on out, everything is STATES to allow customization
|
// from there on out, everything is STATES to allow customization
|
||||||
// these are only set once when the action is performed and are then free to animate however they want.
|
// these are only set once when the action is performed and are then free to animate however they want.
|
||||||
|
@ -138,7 +147,6 @@ typedef struct follower_s
|
||||||
INT32 hurtstate; // state when the player is being hurt
|
INT32 hurtstate; // state when the player is being hurt
|
||||||
INT32 winstate; // state when the player has won
|
INT32 winstate; // state when the player has won
|
||||||
INT32 losestate; // state when the player has lost
|
INT32 losestate; // state when the player has lost
|
||||||
|
|
||||||
} follower_t;
|
} follower_t;
|
||||||
|
|
||||||
// -----------
|
// -----------
|
||||||
|
|
Loading…
Reference in a new issue