Servant Hand: Refactor to use its own thinker

Since it's already ticking for the sake of a fuse, make it handle its own movement/scaling as well.

Spawning is still handled by the player thinker (and can be blocked by hitlag), but this permits it to disappear when a player dies/disconnects the server.
This commit is contained in:
toaster 2023-07-18 15:45:49 +01:00
parent beebfd0d2f
commit e6619df2d4
4 changed files with 62 additions and 38 deletions

View file

@ -8339,7 +8339,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
{ {
K_KartEbrakeVisuals(player); K_KartEbrakeVisuals(player);
Obj_ServantHandHandling(player); Obj_ServantHandSpawning(player);
} }
if (K_GetKartButtons(player) & BT_BRAKE && if (K_GetKartButtons(player) & BT_BRAKE &&

View file

@ -144,7 +144,8 @@ void Obj_GachaBomReboundThink(mobj_t *mobj);
void Obj_SpawnGachaBomRebound(mobj_t *source, mobj_t *target); void Obj_SpawnGachaBomRebound(mobj_t *source, mobj_t *target);
/* Servant Hand */ /* Servant Hand */
void Obj_ServantHandHandling(player_t *player); void Obj_ServantHandSpawning(player_t *player);
void Obj_ServantHandThink(mobj_t *hand);
void Obj_PointPlayersToXY(fixed_t x, fixed_t y); void Obj_PointPlayersToXY(fixed_t x, fixed_t y);
/* Super Flicky Controller */ /* Super Flicky Controller */

View file

@ -8,7 +8,7 @@
#include "../r_main.h" #include "../r_main.h"
#include "../g_game.h" #include "../g_game.h"
void Obj_ServantHandHandling(player_t *player) void Obj_ServantHandSpawning(player_t *player)
{ {
if (player->pflags & PF_WRONGWAY || player->pflags & PF_POINTME) if (player->pflags & PF_WRONGWAY || player->pflags & PF_POINTME)
{ {
@ -36,71 +36,86 @@ void Obj_ServantHandHandling(player_t *player)
} }
} }
} }
if (player->hand)
{
player->hand->destscale = mapobjectscale;
}
} }
else if (player->handtimer != 0) else if (player->handtimer != 0)
{ {
player->handtimer--; player->handtimer--;
} }
}
void Obj_ServantHandThink(mobj_t *hand)
{
UINT8 handtimer = 0;
player_t *player = NULL;
if (P_MobjWasRemoved(hand->target))
{
P_RemoveMobj(hand);
return;
}
if (hand->target->health && hand->target->player && hand->target->player->hand == hand)
{
player = hand->target->player;
handtimer = hand->target->player->handtimer;
}
if (player->hand)
{ {
const fixed_t handpokespeed = 4; const fixed_t handpokespeed = 4;
const fixed_t looping = handpokespeed - abs((player->hand->threshold % (handpokespeed*2)) - handpokespeed); const fixed_t looping = handpokespeed - abs((hand->threshold % (handpokespeed*2)) - handpokespeed);
fixed_t xoffs = 0, yoffs = 0; fixed_t xoffs = 0, yoffs = 0;
player->hand->color = player->skincolor; if (hand->fuse != 0)
player->hand->angle = player->besthanddirection;
if (player->hand->fuse != 0)
{ {
; ;
} }
else if (looping != 0) else if (looping != 0)
{ {
xoffs = FixedMul(2 * looping * mapobjectscale, FINECOSINE(player->hand->angle >> ANGLETOFINESHIFT)), xoffs = FixedMul(2 * looping * mapobjectscale, FINECOSINE(hand->angle >> ANGLETOFINESHIFT)),
yoffs = FixedMul(2 * looping * mapobjectscale, FINESINE(player->hand->angle >> ANGLETOFINESHIFT)), yoffs = FixedMul(2 * looping * mapobjectscale, FINESINE(hand->angle >> ANGLETOFINESHIFT)),
player->hand->threshold++; hand->threshold++;
} }
else if (player->handtimer == 0) else if (handtimer == 0)
{ {
player->hand->fuse = 8; hand->fuse = 8;
} }
else else
{ {
player->hand->threshold++; hand->threshold++;
} }
if (player->hand->fuse != 0) if (hand->fuse != 0)
{ {
if ((player->hand->fuse > 4) ^ (player->handtimer < TICRATE/2)) if ((hand->fuse > 4) ^ (handtimer < TICRATE/2))
{ {
player->hand->spritexscale = FRACUNIT/3; hand->spritexscale = FRACUNIT/3;
player->hand->spriteyscale = 3*FRACUNIT; hand->spriteyscale = 3*FRACUNIT;
} }
else else
{ {
player->hand->spritexscale = 2*FRACUNIT; hand->spritexscale = 2*FRACUNIT;
player->hand->spriteyscale = FRACUNIT/2; hand->spriteyscale = FRACUNIT/2;
} }
} }
P_MoveOrigin(player->hand, if (player != NULL)
player->mo->x + xoffs, {
player->mo->y + yoffs, hand->color = player->skincolor;
player->mo->z + player->mo->height + 30*mapobjectscale hand->angle = player->besthanddirection;
);
K_FlipFromObject(player->hand, player->mo);
player->hand->sprzoff = player->mo->sprzoff; P_MoveOrigin(hand,
player->mo->x + xoffs,
player->mo->y + yoffs,
player->mo->z + player->mo->height + 30*mapobjectscale
);
K_FlipFromObject(hand, player->mo);
player->hand->renderflags &= ~RF_DONTDRAW; hand->sprzoff = player->mo->sprzoff;
player->hand->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(player));
hand->renderflags &= ~RF_DONTDRAW;
hand->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(player));
}
} }
} }

View file

@ -7380,6 +7380,13 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
Obj_MantaRingThink(mobj); Obj_MantaRingThink(mobj);
break; break;
} }
case MT_SERVANTHAND:
{
Obj_ServantHandThink(mobj);
if (P_MobjWasRemoved(mobj))
return false;
break;
}
case MT_BALLHOG: case MT_BALLHOG:
{ {
mobj_t *ghost = P_SpawnGhostMobj(mobj); mobj_t *ghost = P_SpawnGhostMobj(mobj);
@ -9831,10 +9838,11 @@ static boolean P_FuseThink(mobj_t *mobj)
} }
case MT_SERVANTHAND: case MT_SERVANTHAND:
{ {
if (!mobj->target if (P_MobjWasRemoved(mobj->target)
|| P_MobjWasRemoved(mobj->target) || !mobj->target->health
|| !mobj->target->player || !mobj->target->player
|| mobj->target->player->handtimer == 0) || mobj->target->player->handtimer == 0
|| mobj->target->player->hand != mobj)
{ {
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
return false; return false;