Add Obj_BeginEmeraldOrbit, seamless transition into orbit

This commit is contained in:
James R 2023-08-19 03:24:22 -07:00
parent 7f89bee3f2
commit 4bdc05824c
3 changed files with 78 additions and 19 deletions

View file

@ -207,6 +207,7 @@ void Obj_SneakerPanelCollide(mobj_t *pad, mobj_t *mo);
/* Emerald */
void Obj_SpawnEmeraldSparks(mobj_t *source);
void Obj_EmeraldThink(mobj_t *emerald);
void Obj_BeginEmeraldOrbit(mobj_t *emerald, mobj_t *target, fixed_t radius, INT32 revolution_time);
#ifdef __cplusplus
} // extern "C"

View file

@ -3,8 +3,16 @@
#include "../info.h"
#include "../m_random.h"
#include "../p_local.h"
#include "../r_main.h"
#include "../tables.h"
#define emerald_type(o) ((o)->extravalue1)
#define emerald_anim_start(o) ((o)->movedir)
#define emerald_revolution_time(o) ((o)->threshold)
#define emerald_start_radius(o) ((o)->movecount)
#define emerald_target_radius(o) ((o)->extravalue2)
#define emerald_z_shift(o) ((o)->reactiontime)
void Obj_SpawnEmeraldSparks(mobj_t *mobj)
{
if (leveltime % 3 != 0)
@ -25,31 +33,64 @@ void Obj_SpawnEmeraldSparks(mobj_t *mobj)
sparkle->sprzoff = mobj->sprzoff;
}
static INT32 get_elapsed(mobj_t *emerald)
{
return leveltime - min((tic_t)emerald_anim_start(emerald), leveltime);
}
static INT32 get_revolve_time(mobj_t *emerald)
{
return max(1, emerald_revolution_time(emerald));
}
static fixed_t get_suck_factor(mobj_t *emerald)
{
const INT32 suck_time = get_revolve_time(emerald) * 2;
return (min(get_elapsed(emerald), suck_time) * FRACUNIT) / suck_time;
}
static fixed_t get_current_radius(mobj_t *emerald)
{
fixed_t s = emerald_start_radius(emerald);
fixed_t t = emerald_target_radius(emerald);
return s + FixedMul(t - s, get_suck_factor(emerald));
}
static fixed_t get_bob(mobj_t *emerald)
{
angle_t phase = get_elapsed(emerald) * ((ANGLE_MAX / get_revolve_time(emerald)) / 2);
return FixedMul(30 * mapobjectscale, FSIN(emerald->angle + phase));
}
static fixed_t center_of(mobj_t *mobj)
{
return mobj->z + (mobj->height / 2);
}
static fixed_t get_target_z(mobj_t *emerald)
{
fixed_t shift = FixedMul(emerald_z_shift(emerald), FRACUNIT - get_suck_factor(emerald));
return center_of(emerald->target) + get_bob(emerald) + shift;
}
static void Obj_EmeraldOrbitPlayer(mobj_t *emerald)
{
const int kOrbitTics = 64;
const int kPhaseTics = 128;
const fixed_t orbit_radius = 100 * mapobjectscale;
const fixed_t orbit_height = 30 * mapobjectscale;
mobj_t *targ = emerald->target;
angle_t a = emerald->angle;
fixed_t x = FixedMul(orbit_radius, FCOS(a));
fixed_t y = FixedMul(orbit_radius, FSIN(a));
angle_t phase = (ANGLE_MAX / kPhaseTics) * (leveltime % kPhaseTics);
fixed_t r = get_current_radius(emerald);
fixed_t x = FixedMul(r, FCOS(emerald->angle));
fixed_t y = FixedMul(r, FSIN(emerald->angle));
P_MoveOrigin(
emerald,
targ->x + x,
targ->y + y,
targ->z + targ->height + FixedMul(orbit_height, FSIN(a + phase))
emerald->target->x + x,
emerald->target->y + y,
get_target_z(emerald)
);
emerald->angle += ANGLE_MAX / kOrbitTics;
emerald->angle += ANGLE_MAX / get_revolve_time(emerald);
}
void Obj_EmeraldThink(mobj_t *emerald)
@ -84,3 +125,20 @@ void Obj_EmeraldThink(mobj_t *emerald)
K_BattleOvertimeKiller(emerald);
}
void Obj_BeginEmeraldOrbit(mobj_t *emerald, mobj_t *target, fixed_t radius, INT32 revolution_time)
{
P_SetTarget(&emerald->target, target);
emerald_anim_start(emerald) = leveltime;
emerald_revolution_time(emerald) = revolution_time;
emerald_start_radius(emerald) = R_PointToDist2(target->x, target->y, emerald->x, emerald->y);
emerald_target_radius(emerald) = radius;
emerald->angle = R_PointToAngle2(target->x, target->y, emerald->x, emerald->y);
emerald_z_shift(emerald) = emerald->z - get_target_z(emerald);
emerald->flags |= MF_NOGRAVITY | MF_NOCLIP | MF_NOCLIPTHING | MF_NOCLIPHEIGHT;
emerald->shadowscale = 0;
}

View file

@ -883,7 +883,7 @@ boolean Obj_UFOEmeraldCollect(mobj_t *ufo, mobj_t *toucher)
const int kScaleTics = 16;
// Emerald will now orbit the player
P_SetTarget(&emerald->target, toucher);
Obj_BeginEmeraldOrbit(emerald, toucher, 100 * mapobjectscale, 64);
// Scale down because the emerald is huge
// Super Emerald needs to be scaled down further