mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-26 20:11:47 +00:00
Start on new Shrink
Currently just spawns an object that goes along the waypoint path
This commit is contained in:
parent
0c5b42a07e
commit
cf9bfcae02
9 changed files with 390 additions and 35 deletions
|
|
@ -5336,6 +5336,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
||||||
"MT_HYUDORO",
|
"MT_HYUDORO",
|
||||||
"MT_HYUDORO_CENTER",
|
"MT_HYUDORO_CENTER",
|
||||||
|
|
||||||
|
"MT_SHRINK_POHBEE",
|
||||||
|
|
||||||
"MT_SINK", // Kitchen Sink Stuff
|
"MT_SINK", // Kitchen Sink Stuff
|
||||||
"MT_SINK_SHIELD",
|
"MT_SINK_SHIELD",
|
||||||
"MT_SINKTRAIL",
|
"MT_SINKTRAIL",
|
||||||
|
|
|
||||||
27
src/info.c
27
src/info.c
|
|
@ -24009,6 +24009,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_SHRINK_POHBEE
|
||||||
|
-1, // doomednum
|
||||||
|
S_HYUDORO, // 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
|
||||||
|
32*FRACUNIT, // radius
|
||||||
|
24*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
0, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_SINK
|
{ // MT_SINK
|
||||||
-1, // doomednum
|
-1, // doomednum
|
||||||
S_SINK, // spawnstate
|
S_SINK, // spawnstate
|
||||||
|
|
|
||||||
|
|
@ -6362,6 +6362,8 @@ typedef enum mobj_type
|
||||||
MT_HYUDORO,
|
MT_HYUDORO,
|
||||||
MT_HYUDORO_CENTER,
|
MT_HYUDORO_CENTER,
|
||||||
|
|
||||||
|
MT_SHRINK_POHBEE,
|
||||||
|
|
||||||
MT_SINK, // Kitchen Sink Stuff
|
MT_SINK, // Kitchen Sink Stuff
|
||||||
MT_SINK_SHIELD,
|
MT_SINK_SHIELD,
|
||||||
MT_SINKTRAIL,
|
MT_SINKTRAIL,
|
||||||
|
|
|
||||||
36
src/k_kart.c
36
src/k_kart.c
|
|
@ -5581,46 +5581,12 @@ void K_DoSneaker(player_t *player, INT32 type)
|
||||||
|
|
||||||
static void K_DoShrink(player_t *user)
|
static void K_DoShrink(player_t *user)
|
||||||
{
|
{
|
||||||
INT32 i;
|
|
||||||
mobj_t *mobj, *next;
|
mobj_t *mobj, *next;
|
||||||
|
|
||||||
S_StartSound(user->mo, sfx_kc46); // Sound the BANG!
|
S_StartSound(user->mo, sfx_kc46); // Sound the BANG!
|
||||||
user->pflags |= PF_ATTACKDOWN;
|
user->pflags |= PF_ATTACKDOWN;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
Obj_CreateShrinkPohbees(user);
|
||||||
{
|
|
||||||
if (!playeringame[i] || players[i].spectator || !players[i].mo)
|
|
||||||
continue;
|
|
||||||
if (&players[i] == user)
|
|
||||||
continue;
|
|
||||||
if (players[i].position < user->position)
|
|
||||||
{
|
|
||||||
//P_FlashPal(&players[i], PAL_NUKE, 10);
|
|
||||||
|
|
||||||
// Grow should get taken away.
|
|
||||||
if (players[i].growshrinktimer > 0)
|
|
||||||
K_RemoveGrowShrink(&players[i]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Start shrinking!
|
|
||||||
K_DropItems(&players[i]);
|
|
||||||
players[i].growshrinktimer = -(15*TICRATE);
|
|
||||||
|
|
||||||
if (players[i].mo && !P_MobjWasRemoved(players[i].mo))
|
|
||||||
{
|
|
||||||
players[i].mo->scalespeed = mapobjectscale/TICRATE;
|
|
||||||
players[i].mo->destscale = FixedMul(mapobjectscale, SHRINK_SCALE);
|
|
||||||
|
|
||||||
if (K_PlayerShrinkCheat(&players[i]) == true)
|
|
||||||
{
|
|
||||||
players[i].mo->destscale = FixedMul(players[i].mo->destscale, SHRINK_SCALE);
|
|
||||||
}
|
|
||||||
|
|
||||||
S_StartSound(players[i].mo, sfx_kc59);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// kill everything in the kitem list while we're at it:
|
// kill everything in the kitem list while we're at it:
|
||||||
for (mobj = kitemcap; mobj; mobj = next)
|
for (mobj = kitemcap; mobj; mobj = next)
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,8 @@ void Obj_HyudoroThink(mobj_t *actor);
|
||||||
void Obj_HyudoroCenterThink(mobj_t *actor);
|
void Obj_HyudoroCenterThink(mobj_t *actor);
|
||||||
void Obj_HyudoroCollide(mobj_t *special, mobj_t *toucher);
|
void Obj_HyudoroCollide(mobj_t *special, mobj_t *toucher);
|
||||||
|
|
||||||
|
/* Shrink */
|
||||||
|
void Obj_PohbeeThinker(mobj_t *pohbee);
|
||||||
|
void Obj_CreateShrinkPohbees(player_t *owner);
|
||||||
|
|
||||||
#endif/*k_objects_H*/
|
#endif/*k_objects_H*/
|
||||||
|
|
|
||||||
|
|
@ -2044,6 +2044,7 @@ boolean K_SetupWaypointList(void)
|
||||||
// Loop through the waypointcap here so that all waypoints are added to the heap, and allow easier debugging
|
// Loop through the waypointcap here so that all waypoints are added to the heap, and allow easier debugging
|
||||||
for (waypointmobj = waypointcap; waypointmobj; waypointmobj = waypointmobj->tracer)
|
for (waypointmobj = waypointcap; waypointmobj; waypointmobj = waypointmobj->tracer)
|
||||||
{
|
{
|
||||||
|
waypointmobj->cusval = (INT32)numwaypoints;
|
||||||
K_SetupWaypoint(waypointmobj);
|
K_SetupWaypoint(waypointmobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
hyudoro.c
|
hyudoro.c
|
||||||
|
shrink.c
|
||||||
|
|
|
||||||
347
src/objects/shrink.c
Normal file
347
src/objects/shrink.c
Normal file
|
|
@ -0,0 +1,347 @@
|
||||||
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||||
|
// Copyright (C) 2022 by Kart Krew
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file shrink.c
|
||||||
|
/// \brief Shrink laser item code.
|
||||||
|
|
||||||
|
#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"
|
||||||
|
#include "../g_game.h"
|
||||||
|
#include "../z_zone.h"
|
||||||
|
#include "../k_waypoint.h"
|
||||||
|
|
||||||
|
#define POHBEE_HOVER (300 << FRACBITS)
|
||||||
|
#define POHBEE_SPEED (128 << FRACBITS)
|
||||||
|
#define POHBEE_TIME (15 * TICRATE)
|
||||||
|
#define POHBEE_DIST (2048 << FRACBITS)
|
||||||
|
#define POHBEE_CHAIN (16)
|
||||||
|
|
||||||
|
#define LASER_SPEED (20 << FRACBITS)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
POHBEE_MODE_SPAWN,
|
||||||
|
POHBEE_MODE_ACT,
|
||||||
|
POHBEE_MODE_DESPAWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define pohbee_mode(o) ((o)->cusval)
|
||||||
|
|
||||||
|
#define pohbee_waypoint_cur(o) ((o)->extravalue1)
|
||||||
|
#define pohbee_waypoint_dest(o) ((o)->extravalue2)
|
||||||
|
|
||||||
|
#define pohbee_owner(o) ((o)->target)
|
||||||
|
#define pohbee_laser(o) ((o)->tracer)
|
||||||
|
#define pohbee_chain(o) ((o)->hnext)
|
||||||
|
|
||||||
|
#define laser_owner(o) ((o)->target)
|
||||||
|
#define laser_pohbee(o) ((o)->tracer)
|
||||||
|
|
||||||
|
static void PohbeeMoveTo(mobj_t *pohbee, fixed_t destx, fixed_t desty, fixed_t destz)
|
||||||
|
{
|
||||||
|
pohbee->momx = destx - pohbee->x;
|
||||||
|
pohbee->momy = desty - pohbee->y;
|
||||||
|
pohbee->momz = destz - pohbee->z;
|
||||||
|
}
|
||||||
|
|
||||||
|
static fixed_t GenericDistance(
|
||||||
|
fixed_t curx, fixed_t cury, fixed_t curz,
|
||||||
|
fixed_t destx, fixed_t desty, fixed_t destz)
|
||||||
|
{
|
||||||
|
return P_AproxDistance(P_AproxDistance(destx - curx, desty - cury), destz - curz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fixed_t PohbeeWaypointZ(mobj_t *dest)
|
||||||
|
{
|
||||||
|
return dest->z + (FixedMul(POHBEE_HOVER, mapobjectscale) * P_MobjFlip(dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PohbeeSpawn(mobj_t *pohbee)
|
||||||
|
{
|
||||||
|
waypoint_t *curWaypoint = NULL;
|
||||||
|
waypoint_t *destWaypoint = NULL;
|
||||||
|
|
||||||
|
fixed_t distLeft = INT32_MAX;
|
||||||
|
fixed_t newX = pohbee->x;
|
||||||
|
fixed_t newY = pohbee->y;
|
||||||
|
fixed_t newZ = pohbee->z;
|
||||||
|
|
||||||
|
boolean finalize = false;
|
||||||
|
|
||||||
|
const boolean useshortcuts = false;
|
||||||
|
const boolean huntbackwards = false;
|
||||||
|
boolean pathfindsuccess = false;
|
||||||
|
path_t pathtofinish = {0};
|
||||||
|
size_t pathIndex = 0;
|
||||||
|
|
||||||
|
curWaypoint = K_GetWaypointFromIndex((size_t)pohbee_waypoint_cur(pohbee));
|
||||||
|
destWaypoint = K_GetWaypointFromIndex((size_t)pohbee_waypoint_dest(pohbee));
|
||||||
|
|
||||||
|
if (curWaypoint == NULL || destWaypoint == NULL)
|
||||||
|
{
|
||||||
|
// Waypoints aren't valid.
|
||||||
|
// Just transition into the next state.
|
||||||
|
pohbee_mode(pohbee) = POHBEE_MODE_ACT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distLeft = FixedMul(POHBEE_SPEED, mapobjectscale);
|
||||||
|
|
||||||
|
while (distLeft > 0)
|
||||||
|
{
|
||||||
|
fixed_t wpX = curWaypoint->mobj->x;
|
||||||
|
fixed_t wpY = curWaypoint->mobj->y;
|
||||||
|
fixed_t wpZ = PohbeeWaypointZ(curWaypoint->mobj);
|
||||||
|
|
||||||
|
fixed_t distToNext = GenericDistance(
|
||||||
|
newX, newY, newZ,
|
||||||
|
wpX, wpY, wpZ
|
||||||
|
);
|
||||||
|
|
||||||
|
if (distToNext > distLeft)
|
||||||
|
{
|
||||||
|
// Only made it partially there.
|
||||||
|
newX += FixedMul(FixedDiv(wpX - newX, distToNext), distLeft);
|
||||||
|
newY += FixedMul(FixedDiv(wpY - newY, distToNext), distLeft);
|
||||||
|
newZ += FixedMul(FixedDiv(wpZ - newZ, distToNext), distLeft);
|
||||||
|
|
||||||
|
distLeft = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Close enough to the next waypoint,
|
||||||
|
// move there and remove the distance.
|
||||||
|
newX = wpX;
|
||||||
|
newY = wpY;
|
||||||
|
newZ = wpZ;
|
||||||
|
|
||||||
|
distLeft -= distToNext;
|
||||||
|
|
||||||
|
if (curWaypoint == destWaypoint)
|
||||||
|
{
|
||||||
|
// Reached the end.
|
||||||
|
finalize = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create waypoint path to our destination.
|
||||||
|
// Crazy over-engineered, just to catch when
|
||||||
|
// waypoints are insanely close to each other :P
|
||||||
|
if (pathfindsuccess == false)
|
||||||
|
{
|
||||||
|
pathfindsuccess = K_PathfindToWaypoint(
|
||||||
|
curWaypoint, destWaypoint,
|
||||||
|
&pathtofinish,
|
||||||
|
useshortcuts, huntbackwards
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pathfindsuccess == false)
|
||||||
|
{
|
||||||
|
// Path isn't valid.
|
||||||
|
// Just transition into the next state.
|
||||||
|
finalize = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pathIndex++;
|
||||||
|
|
||||||
|
if (pathIndex >= pathtofinish.numnodes)
|
||||||
|
{
|
||||||
|
// Successfully reached the end of the path.
|
||||||
|
finalize = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now moving to the next waypoint.
|
||||||
|
curWaypoint = (waypoint_t *)pathtofinish.array[pathIndex].nodedata;
|
||||||
|
pohbee_waypoint_cur(pohbee) = (INT32)K_GetWaypointHeapIndex(curWaypoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PohbeeMoveTo(pohbee, newX, newY, newZ);
|
||||||
|
|
||||||
|
if (finalize == true)
|
||||||
|
{
|
||||||
|
pohbee_mode(pohbee) = POHBEE_MODE_ACT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pathfindsuccess == true)
|
||||||
|
{
|
||||||
|
Z_Free(pathtofinish.array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Obj_PohbeeThinker(mobj_t *pohbee)
|
||||||
|
{
|
||||||
|
pohbee->momx = 0;
|
||||||
|
pohbee->momy = 0;
|
||||||
|
pohbee->momz = 0;
|
||||||
|
|
||||||
|
switch (pohbee_mode(pohbee))
|
||||||
|
{
|
||||||
|
case POHBEE_MODE_SPAWN:
|
||||||
|
PohbeeSpawn(pohbee);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case POHBEE_MODE_ACT:
|
||||||
|
//PohbeeSpawn(pohbee);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case POHBEE_MODE_DESPAWN:
|
||||||
|
//PohbeeSpawn(pohbee);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// failsafe
|
||||||
|
pohbee_mode(pohbee) = POHBEE_MODE_SPAWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreatePohbeeForPlayer(player_t *target, player_t *owner)
|
||||||
|
{
|
||||||
|
const UINT32 traveldist = FixedMul(POHBEE_DIST, mapobjectscale) / FRACUNIT;
|
||||||
|
|
||||||
|
mobj_t *pohbee = NULL;
|
||||||
|
//mobj_t *laser = NULL;
|
||||||
|
|
||||||
|
waypoint_t *startWaypoint = NULL;
|
||||||
|
waypoint_t *endWaypoint = NULL;
|
||||||
|
|
||||||
|
I_Assert(target != NULL);
|
||||||
|
I_Assert(owner != NULL);
|
||||||
|
|
||||||
|
if (target->mo == NULL || P_MobjWasRemoved(target->mo) == true)
|
||||||
|
{
|
||||||
|
// No object for the target.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, go backwards to find our starting point.
|
||||||
|
{
|
||||||
|
const boolean useshortcuts = false;
|
||||||
|
const boolean huntbackwards = true;
|
||||||
|
boolean pathfindsuccess = false;
|
||||||
|
path_t pathtofinish = {0};
|
||||||
|
|
||||||
|
pathfindsuccess = K_PathfindThruCircuit(
|
||||||
|
target->nextwaypoint, traveldist,
|
||||||
|
&pathtofinish,
|
||||||
|
useshortcuts, huntbackwards
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pathfindsuccess == true)
|
||||||
|
{
|
||||||
|
startWaypoint = (waypoint_t *)pathtofinish.array[ pathtofinish.numnodes - 1 ].nodedata;
|
||||||
|
Z_Free(pathtofinish.array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startWaypoint = target->nextwaypoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, go forwards to get our ending point.
|
||||||
|
{
|
||||||
|
const boolean useshortcuts = false;
|
||||||
|
const boolean huntbackwards = false;
|
||||||
|
boolean pathfindsuccess = false;
|
||||||
|
path_t pathtofinish = {0};
|
||||||
|
|
||||||
|
pathfindsuccess = K_PathfindThruCircuit(
|
||||||
|
target->nextwaypoint, traveldist * 2,
|
||||||
|
&pathtofinish,
|
||||||
|
useshortcuts, huntbackwards
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pathfindsuccess == true)
|
||||||
|
{
|
||||||
|
endWaypoint = (waypoint_t *)pathtofinish.array[ pathtofinish.numnodes - 1 ].nodedata;
|
||||||
|
Z_Free(pathtofinish.array);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
endWaypoint = target->nextwaypoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to repair an incomplete pair, just in case.
|
||||||
|
if (startWaypoint == NULL && endWaypoint != NULL)
|
||||||
|
{
|
||||||
|
startWaypoint = endWaypoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endWaypoint == NULL && startWaypoint != NULL)
|
||||||
|
{
|
||||||
|
endWaypoint = startWaypoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startWaypoint == NULL || endWaypoint == NULL)
|
||||||
|
{
|
||||||
|
// Unable to create shrink lasers
|
||||||
|
// due to invalid waypoint structure...
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid spawning conditions,
|
||||||
|
// we can start creating each individual part.
|
||||||
|
pohbee = P_SpawnMobjFromMobj(startWaypoint->mobj, 0, 0, POHBEE_HOVER, MT_SHRINK_POHBEE);
|
||||||
|
|
||||||
|
P_SetTarget(&pohbee_owner(pohbee), owner->mo);
|
||||||
|
|
||||||
|
pohbee_mode(pohbee) = POHBEE_MODE_SPAWN;
|
||||||
|
|
||||||
|
pohbee_waypoint_cur(pohbee) = (INT32)K_GetWaypointHeapIndex(startWaypoint);
|
||||||
|
pohbee_waypoint_dest(pohbee) = (INT32)K_GetWaypointHeapIndex(endWaypoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Obj_CreateShrinkPohbees(player_t *owner)
|
||||||
|
{
|
||||||
|
UINT8 ownerPos = 1;
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
I_Assert(owner != NULL);
|
||||||
|
|
||||||
|
ownerPos = owner->position;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
player_t *player = NULL;
|
||||||
|
|
||||||
|
if (playeringame[i] == false)
|
||||||
|
{
|
||||||
|
// Not valid.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
player = &players[i];
|
||||||
|
|
||||||
|
if (player->spectator == true)
|
||||||
|
{
|
||||||
|
// Not playing.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->position > ownerPos)
|
||||||
|
{
|
||||||
|
// Too far behind.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreatePohbeeForPlayer(player, owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7841,6 +7841,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
Obj_HyudoroCenterThink(mobj);
|
Obj_HyudoroCenterThink(mobj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MT_SHRINK_POHBEE:
|
||||||
|
{
|
||||||
|
Obj_PohbeeThinker(mobj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MT_ROCKETSNEAKER:
|
case MT_ROCKETSNEAKER:
|
||||||
if (!mobj->target || !mobj->target->health)
|
if (!mobj->target || !mobj->target->health)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue