mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-31 12:13:16 +00:00
Lots more UFO work
- UFO is able to be damaged. (No damage values set yet, so it has an obnoxious amount of health.) - Emerald becomes collectible when fully damaged. - Jawz can target the UFO. - Tweaked some of the speed values.
This commit is contained in:
parent
dc6caf1eb3
commit
d1b2e42560
7 changed files with 146 additions and 36 deletions
|
|
@ -29061,7 +29061,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
{ // MT_SPECIAL_UFO
|
||||
-1, // doomednum
|
||||
S_CHAOSEMERALD1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
101, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
|
|
|
|||
63
src/k_kart.c
63
src/k_kart.c
|
|
@ -6716,12 +6716,18 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
player_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range)
|
||||
mobj_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range)
|
||||
{
|
||||
fixed_t best = INT32_MAX;
|
||||
player_t *wtarg = NULL;
|
||||
mobj_t *wtarg = NULL;
|
||||
INT32 i;
|
||||
|
||||
if (specialStage.active == true)
|
||||
{
|
||||
// Always target the UFO.
|
||||
return specialStage.ufo;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
angle_t thisang = ANGLE_MAX;
|
||||
|
|
@ -6737,7 +6743,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range)
|
|||
player = &players[i];
|
||||
|
||||
// Don't target yourself, stupid.
|
||||
if (player == source)
|
||||
if (source != NULL && player == source)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -6776,7 +6782,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range)
|
|||
|
||||
if (gametyperules & GTR_CIRCUIT)
|
||||
{
|
||||
if (player->position >= source->position)
|
||||
if (source != NULL && player->position >= source->position)
|
||||
{
|
||||
// Don't pay attention to people who aren't above your position
|
||||
continue;
|
||||
|
|
@ -6818,7 +6824,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range)
|
|||
|
||||
if (thisScore < best)
|
||||
{
|
||||
wtarg = player;
|
||||
wtarg = player->mo;
|
||||
best = thisScore;
|
||||
}
|
||||
}
|
||||
|
|
@ -7944,24 +7950,32 @@ void K_KartPlayerAfterThink(player_t *player)
|
|||
// Jawz reticule (seeking)
|
||||
if (player->itemtype == KITEM_JAWZ && (player->pflags & PF_ITEMOUT))
|
||||
{
|
||||
INT32 lastTargID = player->lastjawztarget;
|
||||
player_t *lastTarg = NULL;
|
||||
player_t *targ = NULL;
|
||||
const INT32 lastTargID = player->lastjawztarget;
|
||||
mobj_t *lastTarg = NULL;
|
||||
|
||||
INT32 targID = MAXPLAYERS;
|
||||
mobj_t *targ = NULL;
|
||||
|
||||
mobj_t *ret = NULL;
|
||||
|
||||
if ((lastTargID >= 0 && lastTargID <= MAXPLAYERS)
|
||||
if (specialStage.active == true && lastTargID == MAXPLAYERS)
|
||||
{
|
||||
// Aiming at the UFO.
|
||||
lastTarg = specialStage.ufo;
|
||||
}
|
||||
else if ((lastTargID >= 0 && lastTargID <= MAXPLAYERS)
|
||||
&& playeringame[lastTargID] == true)
|
||||
{
|
||||
if (players[lastTargID].spectator == false)
|
||||
{
|
||||
lastTarg = &players[lastTargID];
|
||||
lastTarg = players[lastTargID].mo;
|
||||
}
|
||||
}
|
||||
|
||||
if (player->throwdir == -1)
|
||||
{
|
||||
// Backwards Jawz targets yourself.
|
||||
targ = player;
|
||||
targ = player->mo;
|
||||
player->jawztargetdelay = 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -7970,9 +7984,14 @@ void K_KartPlayerAfterThink(player_t *player)
|
|||
targ = K_FindJawzTarget(player->mo, player, ANGLE_45);
|
||||
}
|
||||
|
||||
if (targ != NULL && targ->mo != NULL && P_MobjWasRemoved(targ->mo) == false)
|
||||
if (targ != NULL && P_MobjWasRemoved(targ) == false)
|
||||
{
|
||||
if (targ - players == lastTargID)
|
||||
if (targ->player != NULL)
|
||||
{
|
||||
targID = targ->player - players;
|
||||
}
|
||||
|
||||
if (targID == lastTargID)
|
||||
{
|
||||
// Increment delay.
|
||||
if (player->jawztargetdelay < 10)
|
||||
|
|
@ -7991,33 +8010,33 @@ void K_KartPlayerAfterThink(player_t *player)
|
|||
else
|
||||
{
|
||||
// Allow a swap.
|
||||
if (P_IsDisplayPlayer(player) || P_IsDisplayPlayer(targ))
|
||||
if (P_IsDisplayPlayer(player) || P_IsDisplayPlayer(targ->player))
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k89);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound(targ->mo, sfx_s3k89);
|
||||
S_StartSound(targ, sfx_s3k89);
|
||||
}
|
||||
|
||||
player->lastjawztarget = targ - players;
|
||||
player->lastjawztarget = targID;
|
||||
player->jawztargetdelay = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targ == NULL || targ->mo == NULL || P_MobjWasRemoved(targ->mo) == true)
|
||||
if (targ == NULL || P_MobjWasRemoved(targ) == true)
|
||||
{
|
||||
player->lastjawztarget = -1;
|
||||
player->jawztargetdelay = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = P_SpawnMobj(targ->mo->x, targ->mo->y, targ->mo->z, MT_PLAYERRETICULE);
|
||||
ret->old_x = targ->mo->old_x;
|
||||
ret->old_y = targ->mo->old_y;
|
||||
ret->old_z = targ->mo->old_z;
|
||||
P_SetTarget(&ret->target, targ->mo);
|
||||
ret = P_SpawnMobj(targ->x, targ->y, targ->z, MT_PLAYERRETICULE);
|
||||
ret->old_x = targ->old_x;
|
||||
ret->old_y = targ->old_y;
|
||||
ret->old_z = targ->old_z;
|
||||
P_SetTarget(&ret->target, targ);
|
||||
ret->frame |= ((leveltime % 10) / 2);
|
||||
ret->tics = 1;
|
||||
ret->color = player->skincolor;
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void K_UpdateHnextList(player_t *player, boolean clean);
|
|||
void K_DropHnextList(player_t *player, boolean keepshields);
|
||||
void K_RepairOrbitChain(mobj_t *orbit);
|
||||
void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player);
|
||||
player_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range);
|
||||
mobj_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range);
|
||||
INT32 K_GetKartRingPower(player_t *player, boolean boosted);
|
||||
void K_UpdateDistanceFromFinishLine(player_t *const player);
|
||||
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ mobj_t *Obj_SpawnBrolyKi(mobj_t *source, tic_t duration);
|
|||
|
||||
/* Special Stage UFO */
|
||||
void Obj_SpecialUFOThinker(mobj_t *bomb);
|
||||
boolean Obj_SpecialUFODamage(mobj_t *ufo, mobj_t *inflictor, mobj_t *source, UINT8 damageType);
|
||||
mobj_t *Obj_CreateSpecialUFO(void);
|
||||
UINT32 K_GetSpecialUFODistance(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -140,17 +140,21 @@ static void JawzChase(mobj_t *th, boolean grounded)
|
|||
|
||||
if (jawz_chase(th) == NULL || P_MobjWasRemoved(jawz_chase(th)) == true)
|
||||
{
|
||||
mobj_t *newChase = NULL;
|
||||
player_t *owner = NULL;
|
||||
|
||||
th->angle = K_MomentumAngle(th);
|
||||
|
||||
if (jawz_owner(th) != NULL && P_MobjWasRemoved(jawz_owner(th)) == false
|
||||
&& jawz_owner(th)->player != NULL)
|
||||
if ((jawz_owner(th) != NULL && P_MobjWasRemoved(jawz_owner(th)) == false)
|
||||
&& (jawz_owner(th)->player != NULL))
|
||||
{
|
||||
player_t *newPlayer = K_FindJawzTarget(th, jawz_owner(th)->player, ANGLE_90);
|
||||
owner = jawz_owner(th)->player;
|
||||
}
|
||||
|
||||
if (newPlayer != NULL)
|
||||
{
|
||||
P_SetTarget(&jawz_chase(th), newPlayer->mo);
|
||||
}
|
||||
newChase = K_FindJawzTarget(th, owner, ANGLE_90);
|
||||
if (newChase != NULL)
|
||||
{
|
||||
P_SetTarget(&jawz_chase(th), newChase);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file shrink.c
|
||||
/// \brief Shrink laser item code.
|
||||
/// \file ufo.c
|
||||
/// \brief Special Stage UFO
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
|
|
@ -24,11 +24,11 @@
|
|||
#include "../k_waypoint.h"
|
||||
#include "../k_specialstage.h"
|
||||
|
||||
#define UFO_BASE_SPEED (12 * FRACUNIT) // UFO's slowest speed.
|
||||
#define UFO_SPEEDUP (FRACUNIT)
|
||||
#define UFO_BASE_SPEED (16 * FRACUNIT) // UFO's slowest speed.
|
||||
#define UFO_SPEEDUP (FRACUNIT >> 3)
|
||||
#define UFO_SLOWDOWN (FRACUNIT >> 2)
|
||||
#define UFO_SPACING (1024 * FRACUNIT)
|
||||
#define UFO_DEADZONE (512 * FRACUNIT)
|
||||
#define UFO_DEADZONE (768 * FRACUNIT)
|
||||
#define UFO_SPEEDFACTOR (FRACUNIT * 9 / 10)
|
||||
|
||||
#define ufo_waypoint(o) ((o)->extravalue1)
|
||||
|
|
@ -49,6 +49,11 @@ static fixed_t GenericDistance(
|
|||
return P_AproxDistance(P_AproxDistance(destx - curx, desty - cury), destz - curz);
|
||||
}
|
||||
|
||||
static boolean UFOEmeraldChase(mobj_t *ufo)
|
||||
{
|
||||
return (ufo->health <= 1);
|
||||
}
|
||||
|
||||
static void UFOUpdateDistanceToFinish(mobj_t *ufo)
|
||||
{
|
||||
waypoint_t *finishLine = K_GetFinishLineWaypoint();
|
||||
|
|
@ -314,17 +319,86 @@ static void UFOMove(mobj_t *ufo)
|
|||
}
|
||||
}
|
||||
|
||||
static void UFOEmeraldVFX(mobj_t *ufo)
|
||||
{
|
||||
if (leveltime % 3 == 0)
|
||||
{
|
||||
mobj_t *sparkle = P_SpawnMobjFromMobj(
|
||||
ufo,
|
||||
P_RandomRange(PR_SPARKLE, -48, 48) * FRACUNIT,
|
||||
P_RandomRange(PR_SPARKLE, -48, 48) * FRACUNIT,
|
||||
P_RandomRange(PR_SPARKLE, 0, 64) * FRACUNIT,
|
||||
MT_EMERALDSPARK
|
||||
);
|
||||
|
||||
sparkle->color = ufo->color;
|
||||
sparkle->momz += 8 * ufo->scale * P_MobjFlip(ufo);
|
||||
}
|
||||
}
|
||||
|
||||
void Obj_SpecialUFOThinker(mobj_t *ufo)
|
||||
{
|
||||
UFOMove(ufo);
|
||||
UFOUpdateAngle(ufo);
|
||||
UFOUpdateDistanceToFinish(ufo);
|
||||
UFOUpdateSpeed(ufo);
|
||||
|
||||
if (UFOEmeraldChase(ufo) == true)
|
||||
{
|
||||
// Spawn emerald sparkles
|
||||
UFOEmeraldVFX(ufo);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 GetUFODamage(mobj_t *inflictor)
|
||||
{
|
||||
if (inflictor == NULL || P_MobjWasRemoved(inflictor) == true)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (inflictor->type)
|
||||
{
|
||||
default:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean Obj_SpecialUFODamage(mobj_t *ufo, mobj_t *inflictor, mobj_t *source, UINT8 damageType)
|
||||
{
|
||||
UINT8 damage = 1;
|
||||
|
||||
(void)source;
|
||||
(void)damageType;
|
||||
|
||||
if (UFOEmeraldChase(ufo) == true)
|
||||
{
|
||||
// Damaged fully already, no need for any more.
|
||||
ufo->flags = (ufo->flags & ~MF_SHOOTABLE) | (MF_SPECIAL|MF_PICKUPFROMBELOW); // Double check flags, just to be sure.
|
||||
return false;
|
||||
}
|
||||
|
||||
damage = GetUFODamage(inflictor);
|
||||
|
||||
if (damage >= ufo->health - 1)
|
||||
{
|
||||
// Turn into just an emerald, and make it collectible!
|
||||
ufo->health = 1;
|
||||
ufo->flags = (ufo->flags & ~MF_SHOOTABLE) | (MF_SPECIAL|MF_PICKUPFROMBELOW);
|
||||
return true;
|
||||
}
|
||||
|
||||
ufo->health -= damage;
|
||||
K_SetHitLagForObjects(ufo, inflictor, damage * 6, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
static mobj_t *InitSpecialUFO(waypoint_t *start)
|
||||
{
|
||||
mobj_t *ufo = NULL;
|
||||
mobj_t *underlay = NULL;
|
||||
|
||||
if (start == NULL)
|
||||
{
|
||||
|
|
@ -343,6 +417,13 @@ static mobj_t *InitSpecialUFO(waypoint_t *start)
|
|||
|
||||
ufo_speed(ufo) = UFO_BASE_SPEED;
|
||||
|
||||
ufo->color = SKINCOLOR_CHAOSEMERALD1;
|
||||
|
||||
underlay = P_SpawnMobjFromMobj(ufo, 0, 0, 0, MT_OVERLAY);
|
||||
P_SetTarget(&underlay->target, ufo);
|
||||
P_SetMobjState(underlay, S_CHAOSEMERALD_UNDER);
|
||||
underlay->color = ufo->color;
|
||||
|
||||
return ufo;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2222,6 +2222,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
}
|
||||
else
|
||||
{
|
||||
if (target->type == MT_SPECIAL_UFO)
|
||||
{
|
||||
return Obj_SpecialUFODamage(target, inflictor, source, damagetype);
|
||||
}
|
||||
|
||||
if (damagetype & DMG_STEAL)
|
||||
{
|
||||
// Not a player, steal damage is intended to not do anything
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue