Make big items look better

- Bobbing
- Scaling
- Different heights on debris

Also cap scale in full scale maps
This commit is contained in:
Sally Coolatta 2023-04-29 17:46:41 -04:00
parent 5b415de3fe
commit d9d561ee28
8 changed files with 176 additions and 128 deletions

View file

@ -22348,12 +22348,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_kc2e, // deathsound
60*FRACUNIT, // speed
48*FRACUNIT, // radius
48*FRACUNIT, // height
64*FRACUNIT, // height
0, // display offset
100, // mass
MT_RANDOMITEMPOP, // damage
sfx_None, // activesound
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
MF_NOSQUISH|MF_PICKUPFROMBELOW|MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
S_RANDOMITEM1 // raisestate
},
@ -22375,12 +22375,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_kc2e, // deathsound
60*FRACUNIT, // speed
48*FRACUNIT, // radius
48*FRACUNIT, // height
64*FRACUNIT, // height
0, // display offset
100, // mass
MT_RANDOMITEMPOP, // damage
sfx_None, // activesound
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
MF_NOSQUISH|MF_PICKUPFROMBELOW|MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
@ -23271,7 +23271,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass
1, // damage
sfx_cdfm28, // activesound
MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN, // flags
MF_NOSQUISH|MF_PICKUPFROMBELOW|MF_SHOOTABLE|MF_DONTENCOREMAP|MF_APPLYTERRAIN, // flags
S_NULL // raisestate
},
@ -23298,7 +23298,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass
1, // damage
sfx_None, // activesound
MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN, // flags
MF_NOSQUISH|MF_PICKUPFROMBELOW|MF_SHOOTABLE|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP|MF_APPLYTERRAIN, // flags
S_NULL // raisestate
},

View file

@ -241,44 +241,6 @@ void K_ReduceVFX(mobj_t *mo, player_t *owner)
}
}
player_t *K_GetItemBoxPlayer(mobj_t *mobj)
{
fixed_t closest = INT32_MAX;
player_t *player = NULL;
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!(playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo) && !players[i].spectator))
{
continue;
}
// Always use normal item box rules -- could pass in "2" for fakes but they blend in better like this
if (P_CanPickupItem(&players[i], 1))
{
fixed_t dist = P_AproxDistance(P_AproxDistance(
players[i].mo->x - mobj->x,
players[i].mo->y - mobj->y),
players[i].mo->z - mobj->z
);
if (dist > 8192*mobj->scale)
{
continue;
}
if (dist < closest)
{
player = &players[i];
closest = dist;
}
}
}
return player;
}
// Angle reflection used by springs & speed pads
angle_t K_ReflectAngle(angle_t yourangle, angle_t theirangle, fixed_t yourspeed, fixed_t theirspeed)
{
@ -6804,6 +6766,8 @@ static void K_MoveHeldObjects(player_t *player)
if (cur->type == MT_EGGMANITEM_SHIELD)
{
Obj_RandomItemVisuals(cur);
// Decided that this should use their "canon" color.
cur->color = SKINCOLOR_BLACK;
}

View file

@ -37,7 +37,6 @@ Make sure this matches the actual number of states
#define STUMBLE_STEEP_VAL ANG60
#define STUMBLE_STEEP_VAL_AIR (ANG30 + ANG10)
player_t *K_GetItemBoxPlayer(mobj_t *mobj);
angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed);
void K_RegisterKartStuff(void);

View file

@ -118,6 +118,11 @@ void Obj_UpdateRingShooterFace(mobj_t *part);
void Obj_AudienceInit(mobj_t * mobj, mapthing_t *mthing, INT32 followerpick);
void Obj_AudienceThink(mobj_t * mobj, boolean focusonplayer);
/* Random Item Boxes */
void Obj_RandomItemVisuals(mobj_t *mobj);
boolean Obj_RandomItemSpawnIn(mobj_t *mobj);
fixed_t Obj_RandomItemScale(fixed_t oldScale);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -16,4 +16,5 @@ target_sources(SRB2SDL2 PRIVATE
drop-target.c
ring-shooter.c
audience.c
random-item.c
)

View file

@ -45,8 +45,8 @@ spawn_debris
INT32 angle)
{
const fixed_t height_table[NUM_DEBRIS_TYPES] = {
50*FRACUNIT,
35*FRACUNIT,
24*FRACUNIT,
};
mobj_t *debris = P_SpawnMobjFromMobj(

153
src/objects/random-item.c Normal file
View file

@ -0,0 +1,153 @@
// 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 random-item.c
/// \brief Random item boxes
#include "../doomdef.h"
#include "../doomstat.h"
#include "../k_objects.h"
#include "../g_game.h"
#include "../p_local.h"
#include "../r_defs.h"
#include "../k_battle.h"
#include "../m_random.h"
#define FLOAT_HEIGHT ( 12 * FRACUNIT )
#define FLOAT_TIME ( 2 * TICRATE )
#define FLOAT_ANGLE ( ANGLE_MAX / FLOAT_TIME )
#define SCALE_LO ( FRACUNIT * 2 / 3 )
#define SCALE_HI ( FRACUNIT )
#define SCALE_TIME ( 5 * TICRATE / 2 )
#define SCALE_ANGLE ( ANGLE_MAX / SCALE_TIME )
#define item_vfxtimer(o) ((o)->cvmem)
static player_t *GetItemBoxPlayer(mobj_t *mobj)
{
fixed_t closest = INT32_MAX;
player_t *player = NULL;
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!(playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo) && !players[i].spectator))
{
continue;
}
// Always use normal item box rules -- could pass in "2" for fakes but they blend in better like this
if (P_CanPickupItem(&players[i], 1))
{
fixed_t dist = P_AproxDistance(P_AproxDistance(
players[i].mo->x - mobj->x,
players[i].mo->y - mobj->y),
players[i].mo->z - mobj->z
);
if (dist > 8192*mobj->scale)
{
continue;
}
if (dist < closest)
{
player = &players[i];
closest = dist;
}
}
}
return player;
}
static void ItemBoxColor(mobj_t *mobj)
{
player_t *player = GetItemBoxPlayer(mobj);
skincolornum_t color = SKINCOLOR_BLACK;
if (player != NULL)
{
color = player->skincolor;
}
mobj->color = color;
mobj->colorized = false;
}
static void ItemBoxBob(mobj_t *mobj)
{
const fixed_t sine = FINESINE((FLOAT_ANGLE * item_vfxtimer(mobj)) >> ANGLETOFINESHIFT);
const fixed_t bob = FixedMul(FLOAT_HEIGHT, sine);
mobj->spriteyoffset = FLOAT_HEIGHT + bob;
}
static void ItemBoxScaling(mobj_t *mobj)
{
const fixed_t sine = FINESINE((SCALE_ANGLE * item_vfxtimer(mobj)) >> ANGLETOFINESHIFT);
const fixed_t newScale = SCALE_LO + FixedMul(SCALE_HI - SCALE_LO, (sine + FRACUNIT) >> 1);
mobj->spritexscale = mobj->spriteyscale = newScale;
}
void Obj_RandomItemVisuals(mobj_t *mobj)
{
ItemBoxColor(mobj);
ItemBoxBob(mobj);
ItemBoxScaling(mobj);
item_vfxtimer(mobj)++;
}
boolean Obj_RandomItemSpawnIn(mobj_t *mobj)
{
if ((leveltime == starttime) && !(gametyperules & GTR_CIRCUIT) && (mobj->flags2 & MF2_BOSSNOTRAP)) // here on map start?
{
if (gametyperules & GTR_PAPERITEMS)
{
if (battleprisons == true)
{
;
}
else
{
mobj_t *paperspawner = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PAPERITEMSPOT);
paperspawner->spawnpoint = mobj->spawnpoint;
mobj->spawnpoint->mobj = paperspawner;
P_RemoveMobj(mobj);
return false;
}
}
// poof into existance
P_UnsetThingPosition(mobj);
mobj->flags &= ~(MF_NOCLIPTHING|MF_NOBLOCKMAP);
mobj->renderflags &= ~RF_DONTDRAW;
P_SetThingPosition(mobj);
P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_EXPLODE);
nummapboxes++;
}
return true;
}
fixed_t Obj_RandomItemScale(fixed_t oldScale)
{
const fixed_t intendedScale = oldScale * 3;
const fixed_t maxScale = FixedDiv(128*FRACUNIT, mobjinfo[MT_RANDOMITEM].radius); // don't make them larger than the blockmap can handle
return min(intendedScale, maxScale);
}
void Obj_RandomItemSpawn(mobj_t *mobj)
{
item_vfxtimer(mobj) = P_RandomRange(PR_DECORATION, 0, SCALE_TIME - 1);
mobj->destscale = Obj_RandomItemScale(mobj->destscale);
P_SetScale(mobj, mobj->destscale);
}

View file

@ -7273,18 +7273,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
break;
}
case MT_EGGMANITEM:
{
player_t *player = K_GetItemBoxPlayer(mobj);
UINT8 color = SKINCOLOR_BLACK;
if (player != NULL)
{
color = player->skincolor;
}
mobj->color = color;
mobj->colorized = false;
}
Obj_RandomItemVisuals(mobj);
/* FALLTHRU */
case MT_BANANA:
mobj->friction = ORIG_FRICTION/4;
@ -7313,7 +7302,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->type == MT_EGGMANITEM)
{
// Grow to match the actual items
mobj->destscale *= 3;
mobj->destscale = Obj_RandomItemScale(mobj->destscale);
}
}
}
@ -9446,73 +9435,13 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
}
break;
case MT_RANDOMITEM:
if ((leveltime == starttime) && !(gametyperules & GTR_CIRCUIT) && (mobj->flags2 & MF2_BOSSNOTRAP)) // here on map start?
if (Obj_RandomItemSpawnIn(mobj) == false)
{
if (gametyperules & GTR_PAPERITEMS)
{
if (battleprisons == true)
{
;
}
else
{
mobj_t *paperspawner = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PAPERITEMSPOT);
paperspawner->spawnpoint = mobj->spawnpoint;
mobj->spawnpoint->mobj = paperspawner;
P_RemoveMobj(mobj);
return false;
}
}
// poof into existance
P_UnsetThingPosition(mobj);
mobj->flags &= ~(MF_NOCLIPTHING|MF_NOBLOCKMAP);
mobj->renderflags &= ~RF_DONTDRAW;
P_SetThingPosition(mobj);
P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_EXPLODE);
nummapboxes++;
return false;
}
// FALLTHRU
/* FALLTHRU */
case MT_SPHEREBOX:
if (mobj->threshold == 70)
{
mobj->color = K_RainbowColor(leveltime);
mobj->colorized = true;
if ((gametyperules & GTR_OVERTIME) && battleovertime.enabled)
{
angle_t ang = FixedAngle((leveltime % 360) << FRACBITS);
fixed_t z = battleovertime.z;
fixed_t dist;
mobj_t *ghost;
/*if (z < mobj->subsector->sector->floorheight)
z = mobj->subsector->sector->floorheight;*/
if (mobj->extravalue1 < 512)
mobj->extravalue1++;
dist = mobj->extravalue1 * mapobjectscale;
P_MoveOrigin(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist),
battleovertime.y + P_ReturnThrustY(NULL, ang, dist), z);
ghost = P_SpawnGhostMobj(mobj);
ghost->fuse = 4;
ghost->frame |= FF_FULLBRIGHT;
}
}
else
{
player_t *player = K_GetItemBoxPlayer(mobj);
UINT8 color = SKINCOLOR_BLACK;
if (player != NULL)
{
color = player->skincolor;
}
mobj->color = color;
mobj->colorized = false;
}
Obj_RandomItemVisuals(mobj);
break;
case MT_MONITOR_PART:
Obj_MonitorPartThink(mobj);
@ -9778,8 +9707,6 @@ static boolean P_FuseThink(mobj_t *mobj)
// Transfer flags2 (strongbox, objectflip, bossnotrap)
newmobj->flags2 = mobj->flags2;
if (mobj->threshold == 70)
newmobj->threshold = 70;
}
P_RemoveMobj(mobj); // make sure they disappear
@ -10922,8 +10849,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break;
case MT_RANDOMITEM:
case MT_SPHEREBOX:
mobj->destscale *= 3;
P_SetScale(mobj, mobj->scale * 3);
Obj_RandomItemSpawn(mobj);
break;
default:
break;
@ -13223,7 +13149,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
// Ambush = double size (grounded) / half size (aerial)
if (!(mthing->args[2] & TMICF_INVERTSIZE) == !P_IsObjectOnGround(mobj))
{
mobj->extravalue1 = min(mobj->extravalue1 << 1, FixedDiv(64*FRACUNIT, mobj->info->radius)); // don't make them larger than the blockmap can handle
mobj->extravalue1 = min(mobj->extravalue1 << 1, FixedDiv(128*FRACUNIT, mobj->info->radius)); // don't make them larger than the blockmap can handle
mobj->scalespeed <<= 1;
}
break;