Merge branch 'chunky-items' into 'master'

Bigger, chunkier items test

See merge request KartKrew/Kart!1177
This commit is contained in:
Oni 2023-05-01 03:28:52 +00:00
commit 1c9ee9f907
10 changed files with 189 additions and 155 deletions

View file

@ -22354,12 +22354,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
},
@ -22381,12 +22381,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,13 +23271,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_kc2e, // deathsound
0, // speed
24*FRACUNIT, // radius
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
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
},
@ -23304,7 +23304,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,12 @@ 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);
void Obj_RandomItemSpawn(mobj_t *mobj);
#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(MAPBLOCKSIZE, 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

@ -1144,28 +1144,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
{
target->fuse = 2;
}
else if (inDuel == false)
else
{
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (&players[i] == source->player)
{
continue;
}
if (playeringame[i] && !players[i].spectator && players[i].lives != 0)
{
break;
}
}
if (i < MAXPLAYERS)
{
// Respawn items in multiplayer, don't respawn them when alone
target->fuse = 2*TICRATE + 2;
}
target->fuse = 2*TICRATE + 2;
}
}
}

View file

@ -50,9 +50,7 @@ extern "C" {
#define BMBOUNDFIX(xl, xh, yl, yh) {if (xl > xh) xl = 0; if (yl > yh) yl = 0;}
// MAXRADIUS is for precalculated sector block boxes
// the spider demon is larger,
// but we do not have any moving sectors nearby
#define MAXRADIUS (32*FRACUNIT)
#define MAXRADIUS (MAPBLOCKSIZE >> 1)
// max Z move up or down without jumping
// above this, a height difference is considered as a 'dropoff'

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;
@ -7309,6 +7298,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
S_StartSound(mobj, mobj->info->activesound);
mobj->momx = mobj->momy = 0;
mobj->health = 1;
if (mobj->type == MT_EGGMANITEM)
{
// Grow to match the actual items
mobj->destscale = Obj_RandomItemScale(mobj->destscale);
}
}
}
else
@ -9440,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);
@ -9772,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
@ -10345,9 +10278,6 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
thing->whiteshadow = false;
break;
case MT_EGGMANITEM:
thing->shadowscale = FRACUNIT;
thing->whiteshadow = false;
break;
case MT_EGGMANITEM_SHIELD:
thing->shadowscale = 3*FRACUNIT/2;
thing->whiteshadow = false;
@ -10917,6 +10847,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
// Remove before release
CONS_Alert(CONS_WARNING, "Boss waypoints are deprecated. Did you forget to remove the old checkpoints, too?\n");
break;
case MT_RANDOMITEM:
case MT_SPHEREBOX:
Obj_RandomItemSpawn(mobj);
break;
default:
break;
}
@ -12194,8 +12128,6 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
{
(void)mthing;
switch (i)
{
case MT_ITEMCAPSULE:
@ -13207,7 +13139,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(MAPBLOCKSIZE, mobj->info->radius)); // don't make them larger than the blockmap can handle
mobj->scalespeed <<= 1;
}
break;