mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-03-03 09:51:15 +00:00
Add follower bubbles with the BUBBLESCALE field
This commit is contained in:
parent
3f43107eea
commit
2bee969c6a
7 changed files with 153 additions and 5 deletions
|
|
@ -719,6 +719,7 @@ static void readfollower(MYFILE *f)
|
|||
|
||||
// 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].bubblescale = 0; // No bubble by default
|
||||
followers[numfollowers].atangle = 230;
|
||||
followers[numfollowers].dist = 32; // changed from 16 to 32 to better account for ogl models
|
||||
followers[numfollowers].height = 16;
|
||||
|
|
@ -774,6 +775,11 @@ static void readfollower(MYFILE *f)
|
|||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].scale), UNDO_NONE);
|
||||
followers[numfollowers].scale = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "BUBBLESCALE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].bubblescale), UNDO_NONE);
|
||||
followers[numfollowers].bubblescale = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "ATANGLE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].atangle), UNDO_NONE);
|
||||
|
|
@ -917,6 +923,8 @@ if (followers[numfollowers].field < threshold) \
|
|||
FALLBACK(bobamp, "BOBAMP", 0, 0);
|
||||
FALLBACK(bobspeed, "BOBSPEED", 0, 0);
|
||||
FALLBACK(hitconfirmtime, "HITCONFIRMTIME", 1, 1);
|
||||
FALLBACK(scale, "SCALE", 1, 1); // No null/negative scale
|
||||
FALLBACK(bubblescale, "BUBBLESCALE", 0, 0); // No negative scale
|
||||
|
||||
// Special case for color I suppose
|
||||
if (followers[numfollowers].defaultcolor < 0 || followers[numfollowers].defaultcolor > MAXSKINCOLORS-1)
|
||||
|
|
@ -7546,6 +7554,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_GCHAOHAPPY3",
|
||||
"S_GCHAOHAPPY4",
|
||||
|
||||
"S_FOLLOWERBUBBLE_FRONT",
|
||||
"S_FOLLOWERBUBBLE_BACK",
|
||||
|
||||
"S_CHEESEIDLE",
|
||||
"S_CHEESEFLY",
|
||||
"S_CHEESESAD1",
|
||||
|
|
@ -8404,6 +8415,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_BATTLECAPSULE_PIECE",
|
||||
|
||||
"MT_FOLLOWER",
|
||||
"MT_FOLLOWERBUBBLE_FRONT",
|
||||
"MT_FOLLOWERBUBBLE_BACK",
|
||||
|
||||
#ifdef SEENAMES
|
||||
"MT_NAMECHECK",
|
||||
|
|
|
|||
64
src/info.c
64
src/info.c
|
|
@ -73,8 +73,8 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"ICEB","CNDL","DOCH","DUCK","GTRE","CHES","CHIM","DRGN","LZMN","PGSS",
|
||||
"ZTCH","MKMA","MKMP","RTCH","BOWL","BOWH","BRRL","BRRR","HRSE","TOAH",
|
||||
"BFRT","OFRT","RFRT","PFRT","ASPK","HBST","HBSO","HBSF","WBLZ","WBLN",
|
||||
"FWRK","MXCL","RGSP","DRAF","GRES","OTFG","DBOS","XMS4","XMS5","GCHA",
|
||||
"CHEZ","VIEW"
|
||||
"FWRK","MXCL","RGSP","DRAF","GRES","OTFG","DBOS","XMS4","XMS5","FBUB",
|
||||
"GCHA","CHEZ","VIEW"
|
||||
};
|
||||
|
||||
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)
|
||||
|
|
@ -3513,6 +3513,10 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// followers:
|
||||
|
||||
// bubble
|
||||
{SPR_FBUB, 11|FF_ANIMATE|FF_TRANS70|FF_FULLBRIGHT, -1, {NULL}, 10, 3, S_FOLLOWERBUBBLE_FRONT}, // S_FOLLOWERBUBBLE_FRONT
|
||||
{SPR_FBUB, FF_ANIMATE|0|FF_FULLBRIGHT, -1, {NULL}, 10, 3, S_FOLLOWERBUBBLE_BACK}, // S_FOLLOWERBUBBLE_BACK
|
||||
|
||||
// generic chao:
|
||||
{SPR_GCHA, FF_ANIMATE, -1, {NULL}, 1, 4, S_GCHAOIDLE}, //S_GCHAOIDLE
|
||||
{SPR_GCHA, 2|FF_ANIMATE, -1, {NULL}, 1, 2, S_GCHAOFLY}, //S_GCHAOFLY
|
||||
|
|
@ -20854,6 +20858,62 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FOLLOWERBUBBLE_FRONT
|
||||
-1, // doomednum
|
||||
S_FOLLOWERBUBBLE_FRONT, // 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
|
||||
0, // speed
|
||||
8<<FRACBITS, // radius
|
||||
16<<FRACBITS, // height
|
||||
2, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
|
||||
MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL, // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FOLLOWERBUBBLE_BACK
|
||||
-1, // doomednum
|
||||
S_FOLLOWERBUBBLE_BACK, // 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
|
||||
0, // speed
|
||||
8<<FRACBITS, // radius
|
||||
16<<FRACBITS, // height
|
||||
-2, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
|
||||
MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL, // raisestate
|
||||
},
|
||||
|
||||
// ============================================================================================================================//
|
||||
|
||||
#ifdef SEENAMES
|
||||
|
|
|
|||
|
|
@ -800,6 +800,7 @@ typedef enum sprite
|
|||
SPR_XMS4,
|
||||
SPR_XMS5,
|
||||
|
||||
SPR_FBUB, // follower bubble
|
||||
SPR_GCHA, // follower: generic chao
|
||||
SPR_CHEZ, // follower: cheese
|
||||
|
||||
|
|
@ -4189,6 +4190,10 @@ typedef enum state
|
|||
|
||||
// followers:
|
||||
|
||||
// bubble:
|
||||
S_FOLLOWERBUBBLE_FRONT,
|
||||
S_FOLLOWERBUBBLE_BACK,
|
||||
|
||||
// generic chao:
|
||||
S_GCHAOIDLE,
|
||||
S_GCHAOFLY,
|
||||
|
|
@ -5077,6 +5082,8 @@ typedef enum mobj_type
|
|||
MT_BATTLECAPSULE_PIECE,
|
||||
|
||||
MT_FOLLOWER,
|
||||
MT_FOLLOWERBUBBLE_FRONT,
|
||||
MT_FOLLOWERBUBBLE_BACK,
|
||||
|
||||
#ifdef SEENAMES
|
||||
MT_NAMECHECK,
|
||||
|
|
|
|||
20
src/p_mobj.c
20
src/p_mobj.c
|
|
@ -6476,9 +6476,23 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
// 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)
|
||||
{
|
||||
// Remove possible hnext list (bubble)
|
||||
mobj_t *bub = mobj->hnext;
|
||||
mobj_t *tmp;
|
||||
|
||||
while (bub && !P_MobjWasRemoved(bub))
|
||||
{
|
||||
tmp = bub->hnext;
|
||||
P_RemoveMobj(bub);
|
||||
bub = tmp;
|
||||
}
|
||||
|
||||
P_RemoveMobj(mobj);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case MT_HOOP:
|
||||
if (mobj->fuse > 1)
|
||||
P_MoveHoop(mobj);
|
||||
|
|
@ -8798,7 +8812,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
|
||||
if (curstate >= S_FLAMESHIELD1 && curstate < S_FLAMESHIELDDASH1 && ((curstate-S_FLAMESHIELD1) & 1))
|
||||
viewingangle += ANGLE_180;
|
||||
|
||||
|
||||
destx = mobj->target->x + P_ReturnThrustX(mobj->target, viewingangle, mobj->scale>>4);
|
||||
desty = mobj->target->y + P_ReturnThrustY(mobj->target, viewingangle, mobj->scale>>4);
|
||||
}
|
||||
|
|
@ -11847,7 +11861,7 @@ 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.
|
||||
|
|
|
|||
40
src/p_user.c
40
src/p_user.c
|
|
@ -8084,6 +8084,10 @@ static void P_HandleFollower(player_t *player)
|
|||
fixed_t sx, sy, sz;
|
||||
UINT8 color;
|
||||
|
||||
fixed_t bubble; // bubble scale (0 if no bubble)
|
||||
mobj_t *bmobj; // temp bubble mobj
|
||||
|
||||
|
||||
if (!player->followerready)
|
||||
return; // we aren't ready to perform anything follower related yet.
|
||||
|
||||
|
|
@ -8105,6 +8109,7 @@ static void P_HandleFollower(player_t *player)
|
|||
|
||||
an = player->mo->angle + (fl.atangle)*ANG1; // it's aproximative but it really doesn't matter in the grand scheme of things...
|
||||
zoffs = (fl.zoffs)*FRACUNIT;
|
||||
bubble = fl.bubblescale; // 0 if no bubble to spawn.
|
||||
|
||||
// do you like angle maths? I certainly don't...
|
||||
sx = player->mo->x + FixedMul((player->mo->scale*fl.dist), FINECOSINE((an)>>ANGLETOFINESHIFT));
|
||||
|
|
@ -8151,6 +8156,18 @@ static void P_HandleFollower(player_t *player)
|
|||
P_SetTarget(&player->follower->target, player->mo); // we need that to know when we need to disappear
|
||||
player->follower->angle = player->mo->angle;
|
||||
|
||||
// This is safe to only spawn it here, the follower is removed then respawned when switched.
|
||||
if (bubble)
|
||||
{
|
||||
bmobj = P_SpawnMobj(player->follower->x, player->follower->y, player->follower->z, MT_FOLLOWERBUBBLE_FRONT);
|
||||
P_SetTarget(&player->follower->hnext, bmobj);
|
||||
P_SetTarget(&bmobj->target, player->follower); // Used to know if we have to despawn at some point.
|
||||
|
||||
bmobj = P_SpawnMobj(player->follower->x, player->follower->y, player->follower->z, MT_FOLLOWERBUBBLE_BACK);
|
||||
P_SetTarget(&player->follower->hnext->hnext, bmobj); // this seems absolutely stupid, I know, but this will make updating the momentums/flags of these a bit easier.
|
||||
P_SetTarget(&bmobj->target, player->follower); // Ditto
|
||||
}
|
||||
|
||||
player->follower->extravalue1 = 0; // extravalue1 is used to know what "state set" to use.
|
||||
/*
|
||||
0 = idle
|
||||
|
|
@ -8205,6 +8222,29 @@ static void P_HandleFollower(player_t *player)
|
|||
// if we're moving let's make the angle the direction we're moving towards. This is to avoid drifting / reverse looking awkward.
|
||||
// Make sure the follower itself is also moving however, otherwise we'll be facing angle 0
|
||||
|
||||
// Finally, if the follower has bubbles, move them, set their scale, etc....
|
||||
// This is what I meant earlier by it being easier, now we can just use this weird lil loop to get the job done!
|
||||
|
||||
bmobj = player->follower->hnext; // will be NULL if there's no bubble
|
||||
|
||||
while (bmobj && !P_MobjWasRemoved(bmobj))
|
||||
{
|
||||
// match follower's momentums and (e)flags(2).
|
||||
bmobj->momx = player->follower->momx;
|
||||
bmobj->momy = player->follower->momy;
|
||||
bmobj->momz = player->follower->momz;
|
||||
|
||||
P_SetScale(bmobj, FixedMul(bubble, player->mo->scale));
|
||||
K_GenericExtraFlagsNoZAdjust(bmobj, player->follower);
|
||||
bmobj->flags2 = (player->follower->flags2 & ~MF2_SHADOW)|(player->mo->flags2 & MF2_SHADOW);
|
||||
|
||||
if (player->follower->threshold) // threshold means the follower was "despawned" with S_NULL (is actually just set to S_INVISIBLE)
|
||||
P_SetMobjState(bmobj, S_INVISIBLE); // sooooo... let's do the same!
|
||||
|
||||
bmobj = bmobj->hnext; // switch to other bubble layer or exit
|
||||
}
|
||||
|
||||
|
||||
if (player->follower->threshold)
|
||||
return; // Threshold means the follower was "despanwed" with S_NULL.
|
||||
|
||||
|
|
|
|||
|
|
@ -3043,6 +3043,8 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
|||
void SetFollower(INT32 playernum, INT32 skinnum)
|
||||
{
|
||||
player_t *player = &players[playernum];
|
||||
mobj_t *bub;
|
||||
mobj_t *tmp;
|
||||
|
||||
player->followerready = true; // we are ready to perform follower related actions in the player thinker, now.
|
||||
if (skinnum >= -1 && skinnum <= numfollowers) // Make sure it exists!
|
||||
|
|
@ -3053,6 +3055,17 @@ void SetFollower(INT32 playernum, INT32 skinnum)
|
|||
*/
|
||||
if (player->follower && skinnum != player->followerskin) // this is also called when we change colour so don't respawn the follower unless we changed skins
|
||||
{
|
||||
|
||||
// Remove follower's possible hnext list (bubble)
|
||||
bub = player->follower->hnext;
|
||||
|
||||
while (bub && !P_MobjWasRemoved(bub))
|
||||
{
|
||||
tmp = bub->hnext;
|
||||
P_RemoveMobj(bub);
|
||||
bub = tmp;
|
||||
}
|
||||
|
||||
P_RemoveMobj(player->follower);
|
||||
player->follower = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ typedef struct follower_s
|
|||
UINT8 defaultcolor; // default color for menus.
|
||||
|
||||
fixed_t scale; // Scale relative to the player's.
|
||||
fixed_t bubblescale; // Bubble scale relative to the player scale. If not set, no bubble will spawn (default)
|
||||
|
||||
// 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.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue