mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-13 17:16:37 +00:00
Hyudoro object code
This commit is contained in:
parent
910ebe9d0f
commit
c6e7fe2d29
7 changed files with 432 additions and 6 deletions
|
|
@ -465,6 +465,7 @@ typedef struct player_s
|
|||
|
||||
UINT16 hyudorotimer; // Duration of the Hyudoro offroad effect itself
|
||||
SINT8 stealingtimer; // if >0 you are stealing, if <0 you are being stolen from
|
||||
mobj_t *hoverhyudoro; // First hyudoro hovering next to player
|
||||
|
||||
UINT16 sneakertimer; // Duration of a Sneaker Boost (from Sneakers or level boosters)
|
||||
UINT8 numsneakers; // Number of stacked sneaker effects
|
||||
|
|
|
|||
|
|
@ -24570,13 +24570,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
64*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
32*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
MF_SPECIAL|MF_NOCLIP|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "k_hud.h"
|
||||
#include "k_terrain.h"
|
||||
#include "k_director.h"
|
||||
#include "k_objects.h"
|
||||
|
||||
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
|
||||
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
|
||||
|
|
@ -5178,6 +5179,7 @@ static void K_FlameDashLeftoverSmoke(mobj_t *src)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void K_DoHyudoroSteal(player_t *player)
|
||||
{
|
||||
INT32 i, numplayers = 0;
|
||||
|
|
@ -5255,6 +5257,7 @@ static void K_DoHyudoroSteal(player_t *player)
|
|||
S_StartSound(NULL, sfx_s3k92);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void K_DoSneaker(player_t *player, INT32 type)
|
||||
{
|
||||
|
|
@ -9563,7 +9566,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
|
||||
{
|
||||
player->itemamount--;
|
||||
K_DoHyudoroSteal(player); // yes. yes they do.
|
||||
//K_DoHyudoroSteal(player); // yes. yes they do.
|
||||
Obj_HyudoroDeploy(player->mo);
|
||||
K_PlayAttackTaunt(player->mo);
|
||||
}
|
||||
break;
|
||||
case KITEM_POGOSPRING:
|
||||
|
|
|
|||
1
src/objects/Sourcefile
Normal file
1
src/objects/Sourcefile
Normal file
|
|
@ -0,0 +1 @@
|
|||
hyudoro.c
|
||||
402
src/objects/hyudoro.c
Normal file
402
src/objects/hyudoro.c
Normal file
|
|
@ -0,0 +1,402 @@
|
|||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_main.h"
|
||||
#include "../s_sound.h"
|
||||
|
||||
enum {
|
||||
HYU_PATROL,
|
||||
HYU_RETURN,
|
||||
HYU_HOVER,
|
||||
};
|
||||
|
||||
// TODO: make these general functions
|
||||
|
||||
static fixed_t
|
||||
K_GetSpeed (mobj_t *mobj)
|
||||
{
|
||||
return FixedHypot(mobj->momx, mobj->momy);
|
||||
}
|
||||
|
||||
static void
|
||||
K_ChangePlayerItem
|
||||
( player_t * player,
|
||||
INT32 itemtype,
|
||||
INT32 itemamount)
|
||||
{
|
||||
player->itemtype = itemtype;
|
||||
player->itemamount = itemamount;
|
||||
K_UnsetItemOut(player);
|
||||
}
|
||||
|
||||
#define hyudoro_mode(o) ((o)->extravalue1)
|
||||
#define hyudoro_itemtype(o) ((o)->movefactor)
|
||||
#define hyudoro_itemcount(o) ((o)->movecount)
|
||||
#define hyudoro_hover_stack(o) ((o)->threshold)
|
||||
#define hyudoro_next(o) ((o)->tracer)
|
||||
#define hyudoro_stackpos(o) ((o)->reactiontime)
|
||||
|
||||
// cannot be combined
|
||||
#define hyudoro_center(o) ((o)->target)
|
||||
#define hyudoro_target(o) ((o)->target)
|
||||
|
||||
#define hyudoro_center_max_radius(o) ((o)->threshold)
|
||||
#define hyudoro_center_master(o) ((o)->target)
|
||||
|
||||
static angle_t
|
||||
trace_angle (mobj_t *hyu)
|
||||
{
|
||||
mobj_t *center = hyu->target;
|
||||
|
||||
if (hyu->x != center->x || hyu->y != center->y)
|
||||
{
|
||||
return R_PointToAngle2(
|
||||
center->x, center->y, hyu->x, hyu->y);
|
||||
}
|
||||
else
|
||||
return hyu->angle;
|
||||
}
|
||||
|
||||
static angle_t
|
||||
get_look_angle (mobj_t *thing)
|
||||
{
|
||||
player_t *player = thing->player;
|
||||
|
||||
return player ? player->angleturn : thing->angle;
|
||||
}
|
||||
|
||||
static boolean
|
||||
is_hyudoro (mobj_t *thing)
|
||||
{
|
||||
return thing && thing->type == MT_HYUDORO;
|
||||
}
|
||||
|
||||
static mobj_t *
|
||||
get_hyudoro_master (mobj_t *hyu)
|
||||
{
|
||||
mobj_t *center = hyudoro_center(hyu);
|
||||
|
||||
return center ? hyudoro_center_master(center) : NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
sine_bob
|
||||
( mobj_t * hyu,
|
||||
angle_t a,
|
||||
fixed_t sineofs)
|
||||
{
|
||||
hyu->sprzoff = FixedMul(hyu->height,
|
||||
sineofs + FINESINE(a >> ANGLETOFINESHIFT));
|
||||
}
|
||||
|
||||
static void
|
||||
project_hyudoro (mobj_t *hyu)
|
||||
{
|
||||
mobj_t *center = hyudoro_center(hyu);
|
||||
|
||||
angle_t angleStep = FixedMul(5 * ANG1,
|
||||
FixedDiv(hyudoro_center_max_radius(center),
|
||||
center->radius));
|
||||
|
||||
angle_t angle = trace_angle(hyu) + angleStep;
|
||||
|
||||
fixed_t d = center->radius;
|
||||
|
||||
fixed_t x = P_ReturnThrustX(center, angle, d);
|
||||
fixed_t y = P_ReturnThrustY(center, angle, d);
|
||||
|
||||
hyu->momx = (center->x + x) - hyu->x;
|
||||
hyu->momy = (center->y + y) - hyu->y;
|
||||
hyu->angle = angle + ANGLE_90;
|
||||
|
||||
sine_bob(hyu, angle, FRACUNIT);
|
||||
}
|
||||
|
||||
static void
|
||||
project_hyudoro_hover (mobj_t *hyu)
|
||||
{
|
||||
const INT32 bob_speed = 64;
|
||||
|
||||
mobj_t *target = hyudoro_target(hyu);
|
||||
|
||||
// Turns a bit toward its target
|
||||
angle_t ang = get_look_angle(target) + ANGLE_67h;
|
||||
fixed_t rad = (target->radius * 2) + hyu->radius;
|
||||
|
||||
fixed_t zofs = hyudoro_stackpos(hyu) *
|
||||
((target->height / 2) + (hyu->height * 2));
|
||||
|
||||
P_MoveOrigin(hyu,
|
||||
target->x - P_ReturnThrustX(hyu, ang, rad),
|
||||
target->y - P_ReturnThrustY(hyu, ang, rad),
|
||||
target->z + (zofs * P_MobjFlip(target)));
|
||||
|
||||
// Cancel momentum from HYU_RETURN.
|
||||
// (And anything else! I don't trust this game!!)
|
||||
hyu->momx = 0;
|
||||
hyu->momy = 0;
|
||||
|
||||
hyu->angle = ang;
|
||||
|
||||
// copies sprite tilting
|
||||
hyu->pitch = target->pitch;
|
||||
hyu->roll = target->roll;
|
||||
|
||||
sine_bob(hyu,
|
||||
(leveltime & (bob_speed - 1)) *
|
||||
(ANGLE_MAX / bob_speed), -(3*FRACUNIT/4));
|
||||
}
|
||||
|
||||
static void
|
||||
spawn_hyudoro_shadow (mobj_t *hyu)
|
||||
{
|
||||
mobj_t *shadow = P_SpawnMobjFromMobj(
|
||||
hyu, 0, 0, 0, MT_SHADOW);
|
||||
|
||||
shadow->whiteshadow = true;
|
||||
|
||||
shadow->shadowscale = hyu->shadowscale;
|
||||
hyu->shadowscale = 0;
|
||||
|
||||
P_SetTarget(&shadow->tracer, hyu);
|
||||
}
|
||||
|
||||
static void
|
||||
move_to_player (mobj_t *hyu)
|
||||
{
|
||||
mobj_t *target = hyudoro_target(hyu);
|
||||
|
||||
angle_t angle;
|
||||
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
angle = R_PointToAngle2(
|
||||
hyu->x, hyu->y, target->x, target->y);
|
||||
|
||||
P_InstaThrust(hyu, angle, (hyu->radius / 2) +
|
||||
max(hyu->radius, K_GetSpeed(target)));
|
||||
|
||||
hyu->z = target->z; // stay level with target
|
||||
hyu->angle = angle;
|
||||
}
|
||||
|
||||
static void
|
||||
deliver_item (mobj_t *hyu)
|
||||
{
|
||||
mobj_t *target = hyudoro_target(hyu);
|
||||
player_t *player = target->player;
|
||||
|
||||
P_SetTarget(&hyudoro_target(hyu), NULL);
|
||||
|
||||
K_ChangePlayerItem(player,
|
||||
hyudoro_itemtype(hyu),
|
||||
hyudoro_itemcount(hyu));
|
||||
|
||||
S_StartSound(target, sfx_itpick);
|
||||
|
||||
// Stop moving here
|
||||
hyu->momx = 0;
|
||||
hyu->momy = 0;
|
||||
|
||||
hyu->tics = 4;
|
||||
|
||||
hyu->destscale = target->scale / 4;
|
||||
hyu->scalespeed =
|
||||
abs(hyu->scale - hyu->destscale) / hyu->tics;
|
||||
}
|
||||
|
||||
static void
|
||||
append_hyudoro
|
||||
( mobj_t ** head,
|
||||
mobj_t * hyu)
|
||||
{
|
||||
INT32 lastpos = 0;
|
||||
|
||||
while (is_hyudoro(*head))
|
||||
{
|
||||
lastpos = hyudoro_stackpos(*head);
|
||||
head = &hyudoro_next(*head);
|
||||
}
|
||||
|
||||
hyudoro_stackpos(hyu) = lastpos + 1;
|
||||
*head = hyu;
|
||||
}
|
||||
|
||||
static boolean
|
||||
hyudoro_patrol_hit_player
|
||||
( mobj_t * hyu,
|
||||
mobj_t * toucher)
|
||||
{
|
||||
player_t *player = toucher->player;
|
||||
|
||||
mobj_t *center = hyudoro_center(hyu);
|
||||
|
||||
if (!player)
|
||||
return false;
|
||||
|
||||
// Cannot hit its master
|
||||
if (toucher == get_hyudoro_master(hyu))
|
||||
return false;
|
||||
|
||||
// Don't punish a punished player
|
||||
if (player->hyudorotimer)
|
||||
return false;
|
||||
|
||||
// NO ITEM?
|
||||
if (!player->itemamount)
|
||||
return false;
|
||||
|
||||
K_AddHitLag(toucher, TICRATE/2, true);
|
||||
|
||||
player->hyudorotimer = hyudorotime;
|
||||
player->stealingtimer = hyudorotime;
|
||||
|
||||
hyudoro_mode(hyu) = HYU_RETURN;
|
||||
hyudoro_itemtype(hyu) = player->itemtype;
|
||||
hyudoro_itemcount(hyu) = player->itemamount;
|
||||
|
||||
K_ChangePlayerItem(player, KITEM_NONE, 0);
|
||||
|
||||
P_SetTarget(&hyudoro_target(hyu),
|
||||
hyudoro_center_master(center));
|
||||
|
||||
if (center)
|
||||
P_RemoveMobj(center);
|
||||
|
||||
hyu->renderflags &= ~(RF_DONTDRAW);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean
|
||||
hyudoro_return_hit_player
|
||||
( mobj_t * hyu,
|
||||
mobj_t * toucher)
|
||||
{
|
||||
player_t *player = toucher->player;
|
||||
|
||||
if (toucher != hyudoro_target(hyu))
|
||||
return false;
|
||||
|
||||
// If the player already has an item, just hover beside
|
||||
// them until they use/lose it.
|
||||
if (player->itemamount || player->itemroulette)
|
||||
{
|
||||
hyudoro_mode(hyu) = HYU_HOVER;
|
||||
append_hyudoro(&player->hoverhyudoro, hyu);
|
||||
}
|
||||
else
|
||||
{
|
||||
deliver_item(hyu);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Obj_HyudoroDeploy (mobj_t *master)
|
||||
{
|
||||
mobj_t *center = P_SpawnMobjFromMobj(
|
||||
master, 0, 0, 0, MT_HYUDORO_CENTER);
|
||||
|
||||
mobj_t *hyu = P_SpawnMobjFromMobj(
|
||||
center, 0, 0, 0, MT_HYUDORO);
|
||||
|
||||
// This allows a Lua override
|
||||
if (!hyudoro_center_max_radius(center))
|
||||
{
|
||||
hyudoro_center_max_radius(center) =
|
||||
128 * center->scale;
|
||||
}
|
||||
|
||||
center->radius = hyu->radius;
|
||||
|
||||
P_InitAngle(hyu, master->angle);
|
||||
P_SetTarget(&hyudoro_center(hyu), center);
|
||||
P_SetTarget(&hyudoro_center_master(center), master);
|
||||
|
||||
hyudoro_mode(hyu) = HYU_PATROL;
|
||||
|
||||
// Set splitscreen player visibility
|
||||
if (master->player)
|
||||
{
|
||||
hyu->renderflags |= RF_DONTDRAW &
|
||||
~(K_GetPlayerDontDrawFlag(master->player));
|
||||
}
|
||||
|
||||
spawn_hyudoro_shadow(hyu); // this sucks btw
|
||||
|
||||
S_StartSound(master, sfx_s3k92); // scary ghost noise
|
||||
}
|
||||
|
||||
void
|
||||
Obj_HyudoroThink (mobj_t *hyu)
|
||||
{
|
||||
// Might get set from clipping slopes
|
||||
hyu->momz = 0;
|
||||
|
||||
switch (hyudoro_mode(hyu))
|
||||
{
|
||||
case HYU_PATROL:
|
||||
if (hyudoro_center(hyu))
|
||||
project_hyudoro(hyu);
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
mobj_t *ghost = P_SpawnGhostMobj(hyu);
|
||||
|
||||
// Flickers every frame
|
||||
ghost->extravalue1 = 1;
|
||||
ghost->extravalue2 = 2;
|
||||
|
||||
// copy per-splitscreen-player visibility
|
||||
ghost->renderflags =
|
||||
(hyu->renderflags & RF_DONTDRAW);
|
||||
|
||||
ghost->tics = 8;
|
||||
|
||||
P_SetTarget(&ghost->tracer, hyu);
|
||||
}
|
||||
break;
|
||||
|
||||
case HYU_RETURN:
|
||||
move_to_player(hyu);
|
||||
break;
|
||||
|
||||
case HYU_HOVER:
|
||||
if (hyudoro_target(hyu))
|
||||
project_hyudoro_hover(hyu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Obj_HyudoroCenterThink (mobj_t *center)
|
||||
{
|
||||
fixed_t max_radius = hyudoro_center_max_radius(center);
|
||||
|
||||
if (center->radius < max_radius)
|
||||
center->radius += max_radius / 64;
|
||||
}
|
||||
|
||||
void
|
||||
Obj_HyudoroCollide
|
||||
( mobj_t * hyu,
|
||||
mobj_t * toucher)
|
||||
{
|
||||
switch (hyudoro_mode(hyu))
|
||||
{
|
||||
case HYU_PATROL:
|
||||
hyudoro_patrol_hit_player(hyu, toucher);
|
||||
break;
|
||||
|
||||
case HYU_RETURN:
|
||||
hyudoro_return_hit_player(hyu, toucher);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
#include "k_boss.h"
|
||||
#include "k_respawn.h"
|
||||
#include "p_spec.h"
|
||||
#include "k_objects.h"
|
||||
|
||||
// CTF player names
|
||||
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
|
||||
|
|
@ -483,6 +484,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
S_StartSound(toucher, sfx_s1b2);
|
||||
return;
|
||||
|
||||
case MT_HYUDORO:
|
||||
Obj_HyudoroCollide(special, toucher);
|
||||
return;
|
||||
|
||||
case MT_RING:
|
||||
case MT_FLINGRING:
|
||||
if (special->extravalue1)
|
||||
|
|
|
|||
16
src/p_mobj.c
16
src/p_mobj.c
|
|
@ -42,6 +42,7 @@
|
|||
#include "k_respawn.h"
|
||||
#include "k_bot.h"
|
||||
#include "k_terrain.h"
|
||||
#include "k_objects.h"
|
||||
|
||||
static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL);
|
||||
|
|
@ -6559,8 +6560,8 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
}
|
||||
else if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
mobj->momx = 1;
|
||||
mobj->momy = 0;
|
||||
//mobj->momx = 1;
|
||||
//mobj->momy = 0;
|
||||
mobj->flags &= ~MF_NOCLIPTHING;
|
||||
mobj->flags |= MF_NOGRAVITY;
|
||||
}
|
||||
|
|
@ -7717,6 +7718,16 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case MT_HYUDORO:
|
||||
{
|
||||
Obj_HyudoroThink(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_HYUDORO_CENTER:
|
||||
{
|
||||
Obj_HyudoroCenterThink(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_ROCKETSNEAKER:
|
||||
if (!mobj->target || !mobj->target->health)
|
||||
{
|
||||
|
|
@ -9671,6 +9682,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
|||
case MT_SSMINE_SHIELD:
|
||||
case MT_LANDMINE:
|
||||
case MT_BALLHOG:
|
||||
case MT_HYUDORO:
|
||||
case MT_SINK:
|
||||
case MT_ROCKETSNEAKER:
|
||||
case MT_SPB:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue