mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-26 07:21:48 +00:00
Merge branch 'hardcode-ivo-balls' into 'master'
Hardcode Mach Spheres (BIG performance boost for Phantom Cup!) See merge request KartKrew/Kart!1660
This commit is contained in:
commit
6666f6d024
17 changed files with 339 additions and 10 deletions
|
|
@ -4828,6 +4828,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
|
||||
// MT_THRUSTERPART
|
||||
"S_THRUSTERPART",
|
||||
|
||||
// MT_IVOBALL
|
||||
"S_IVOBALL",
|
||||
};
|
||||
|
||||
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",
|
||||
|
|
@ -6050,6 +6053,10 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
"MT_GGZICESHATTER",
|
||||
"MT_SIDEWAYSFREEZETHRUSTER",
|
||||
"MT_THRUSTERPART",
|
||||
|
||||
"MT_IVOBALL",
|
||||
"MT_PATROLIVOBALL",
|
||||
"MT_AIRIVOBALL",
|
||||
};
|
||||
|
||||
const char *const MOBJFLAG_LIST[] = {
|
||||
|
|
|
|||
82
src/info.c
82
src/info.c
|
|
@ -5674,6 +5674,9 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// MT_THRUSTERPART
|
||||
{SPR_SFTR, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_THRUSTERPART}, // S_THRUSTERPART
|
||||
|
||||
// MT_IVOBALL
|
||||
{SPR_BSPH, 2|FF_SEMIBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_IVOBALL
|
||||
};
|
||||
|
||||
mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||
|
|
@ -32118,6 +32121,85 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY|MF_NOCLIPTHING, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_IVOBALL
|
||||
3792, // doomednum
|
||||
S_IVOBALL, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // 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
|
||||
40*FRACUNIT, // radius
|
||||
128*FRACUNIT, // height
|
||||
0, // dispoffset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOCLIP|MF_SCENERY|MF_SPECIAL|MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_PATROLIVOBALL
|
||||
3808, // doomednum
|
||||
S_IVOBALL, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // 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
|
||||
28*FRACUNIT, // speed
|
||||
40*FRACUNIT, // radius
|
||||
128*FRACUNIT, // height
|
||||
0, // dispoffset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SCENERY|MF_ENEMY|MF_NOBLOCKMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_AIRIVOBALL
|
||||
3811, // doomednum
|
||||
S_IVOBALL, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // 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
|
||||
28*FRACUNIT, // speed
|
||||
50*FRACUNIT, // radius
|
||||
100*FRACUNIT, // height
|
||||
0, // dispoffset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SCENERY|MF_SPECIAL|MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6099,6 +6099,9 @@ typedef enum state
|
|||
// MT_THRUSTERPART
|
||||
S_THRUSTERPART,
|
||||
|
||||
// MT_IVOBALL
|
||||
S_IVOBALL,
|
||||
|
||||
S_FIRSTFREESLOT,
|
||||
S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1,
|
||||
NUMSTATES
|
||||
|
|
@ -7341,6 +7344,10 @@ typedef enum mobj_type
|
|||
MT_SIDEWAYSFREEZETHRUSTER,
|
||||
MT_THRUSTERPART,
|
||||
|
||||
MT_IVOBALL,
|
||||
MT_PATROLIVOBALL,
|
||||
MT_AIRIVOBALL,
|
||||
|
||||
MT_FIRSTFREESLOT,
|
||||
MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1,
|
||||
NUMMOBJTYPES
|
||||
|
|
|
|||
|
|
@ -313,6 +313,14 @@ void Obj_IceCubeBurst(player_t *player);
|
|||
void Obj_SidewaysFreezeThrusterInit(mobj_t *mobj);
|
||||
void Obj_SidewaysFreezeThrusterThink(mobj_t *mobj);
|
||||
|
||||
/* Ivo Balls */
|
||||
void Obj_IvoBallInit(mobj_t *mo);
|
||||
void Obj_IvoBallThink(mobj_t *mo);
|
||||
void Obj_IvoBallTouch(mobj_t *special, mobj_t *toucher);
|
||||
void Obj_PatrolIvoBallInit(mobj_t *mo);
|
||||
void Obj_PatrolIvoBallThink(mobj_t *mo);
|
||||
void Obj_PatrolIvoBallTouch(mobj_t *special, mobj_t *toucher);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -179,8 +179,14 @@ struct Mobj : mobj_t
|
|||
// Sound
|
||||
//
|
||||
|
||||
void voice(sfxenum_t sfx, int volume = 255) const { S_StartSoundAtVolume(this, sfx, volume); }
|
||||
bool voice_playing(sfxenum_t sfx) const { return S_SoundPlaying(this, sfx); }
|
||||
|
||||
void voice(sfxenum_t sfx, int volume = 255) const { S_StartSoundAtVolume(this, sfx, volume); }
|
||||
void voice_reduced(sfxenum_t sfx, const player_t* player, int volume = 255) const
|
||||
{
|
||||
S_ReducedVFXSoundAtVolume(this, sfx, volume, player);
|
||||
}
|
||||
|
||||
void voice_loop(sfxenum_t sfx, int volume = 255) const
|
||||
{
|
||||
if (!voice_playing(sfx))
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
charge.c
|
||||
mega-barrier.cpp
|
||||
frost-thrower.cpp
|
||||
ivoball.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(versus)
|
||||
|
|
|
|||
162
src/objects/ivoball.cpp
Normal file
162
src/objects/ivoball.cpp
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// CREDITS
|
||||
// Original Lua script by Callmore
|
||||
// Edits by Ivo, Angular and Sal
|
||||
// Hardcoded by jartha
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "../math/fixed.hpp"
|
||||
#include "../math/vec.hpp"
|
||||
#include "../mobj.hpp"
|
||||
|
||||
#include "../d_player.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_defs.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../sounds.h"
|
||||
#include "../tables.h"
|
||||
|
||||
using srb2::Mobj;
|
||||
using srb2::math::Fixed;
|
||||
using srb2::math::Vec2;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
Vec2<Fixed> angle_vector(angle_t x)
|
||||
{
|
||||
return Vec2<Fixed> {FCOS(x), FSIN(x)};
|
||||
}
|
||||
|
||||
struct IvoBall : Mobj
|
||||
{
|
||||
static constexpr tic_t kCooldown = TICRATE*2;
|
||||
static constexpr tic_t kFlashTime = TICRATE/2;
|
||||
static constexpr Fixed kRippleFactor = 128*FRACUNIT/3;
|
||||
static constexpr Fixed kBobHeight = 8*FRACUNIT;
|
||||
static constexpr tic_t kBobTime = kFlashTime * 16;
|
||||
static constexpr int kFloat = 24;
|
||||
|
||||
void extravalue1() = delete;
|
||||
tic_t timer() const { return mobj_t::extravalue1; }
|
||||
void timer(tic_t n) { mobj_t::extravalue1 = n; }
|
||||
|
||||
void extravalue2() = delete;
|
||||
fixed_t offset() const { return mobj_t::extravalue2; }
|
||||
void offset(fixed_t n) { mobj_t::extravalue2 = n; }
|
||||
|
||||
void init()
|
||||
{
|
||||
Fixed wave{(x / mapobjectscale) + (y / mapobjectscale)};
|
||||
offset(wave / kRippleFactor);
|
||||
color = SKINCOLOR_TANGERINE;
|
||||
sprzoff = kFloat * mapobjectscale;
|
||||
}
|
||||
|
||||
void think()
|
||||
{
|
||||
if (timer())
|
||||
{
|
||||
timer(timer() - 1);
|
||||
|
||||
if (timer() == 0)
|
||||
{
|
||||
renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
}
|
||||
|
||||
fixed_t ballTimer = leveltime + offset();
|
||||
Fixed bob = kBobHeight * Fixed {FSIN((M_TAU_FIXED * kBobTime) * ballTimer)};
|
||||
spriteyoffset = bob;
|
||||
|
||||
colorized = !((ballTimer / kFlashTime) & 1);
|
||||
}
|
||||
|
||||
void touch(Mobj* toucher)
|
||||
{
|
||||
if (timer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
renderflags |= RF_DONTDRAW;
|
||||
timer(kCooldown);
|
||||
|
||||
toucher->player->ringboost += 30;
|
||||
|
||||
if (P_IsDisplayPlayer(toucher->player))
|
||||
{
|
||||
S_StartSoundAtVolume(nullptr, sfx_ivobal, 160);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct PatrolIvoBall : IvoBall
|
||||
{
|
||||
void init()
|
||||
{
|
||||
Vec2<Fixed> v = angle_vector(angle) * Fixed {info->speed} * Fixed {mapobjectscale};
|
||||
momx = -v.x;
|
||||
momy = v.y;
|
||||
|
||||
IvoBall::init();
|
||||
}
|
||||
|
||||
void think()
|
||||
{
|
||||
if (!P_TryMove(this, x + momx, y + momy, true, nullptr))
|
||||
{
|
||||
angle += ANGLE_180;
|
||||
momx = -momx;
|
||||
momy = -momy;
|
||||
}
|
||||
|
||||
IvoBall::think();
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
void Obj_IvoBallInit(mobj_t* mobj)
|
||||
{
|
||||
static_cast<IvoBall*>(mobj)->init();
|
||||
}
|
||||
|
||||
void Obj_IvoBallThink(mobj_t* mobj)
|
||||
{
|
||||
static_cast<IvoBall*>(mobj)->think();
|
||||
}
|
||||
|
||||
void Obj_IvoBallTouch(mobj_t* special, mobj_t* toucher)
|
||||
{
|
||||
static_cast<IvoBall*>(special)->touch(static_cast<Mobj*>(toucher));
|
||||
}
|
||||
|
||||
void Obj_PatrolIvoBallInit(mobj_t* mobj)
|
||||
{
|
||||
static_cast<PatrolIvoBall*>(mobj)->init();
|
||||
}
|
||||
|
||||
void Obj_PatrolIvoBallThink(mobj_t* mobj)
|
||||
{
|
||||
static_cast<PatrolIvoBall*>(mobj)->think();
|
||||
}
|
||||
|
||||
void Obj_PatrolIvoBallTouch(mobj_t* special, mobj_t* toucher)
|
||||
{
|
||||
static_cast<PatrolIvoBall*>(special)->touch(static_cast<Mobj*>(toucher));
|
||||
}
|
||||
|
|
@ -974,6 +974,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
}
|
||||
|
||||
case MT_IVOBALL:
|
||||
case MT_AIRIVOBALL:
|
||||
{
|
||||
Obj_IvoBallTouch(special, toucher);
|
||||
return;
|
||||
}
|
||||
case MT_PATROLIVOBALL:
|
||||
{
|
||||
Obj_PatrolIvoBallTouch(special, toucher);
|
||||
return;
|
||||
}
|
||||
|
||||
default: // SOC or script pickup
|
||||
P_SetTarget(&special->target, toucher);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -158,9 +158,9 @@ boolean P_PlayerInPain(player_t *player);
|
|||
void P_ResetPlayer(player_t *player);
|
||||
boolean P_PlayerCanDamage(player_t *player, mobj_t *thing);
|
||||
|
||||
boolean P_IsLocalPlayer(player_t *player);
|
||||
boolean P_IsMachineLocalPlayer(player_t *player);
|
||||
boolean P_IsDisplayPlayer(player_t *player);
|
||||
boolean P_IsLocalPlayer(const player_t *player);
|
||||
boolean P_IsMachineLocalPlayer(const player_t *player);
|
||||
boolean P_IsDisplayPlayer(const player_t *player);
|
||||
|
||||
void P_SetPlayerAngle(player_t *player, angle_t angle);
|
||||
void P_ForceLocalAngle(player_t *player, angle_t angle);
|
||||
|
|
|
|||
12
src/p_map.c
12
src/p_map.c
|
|
@ -758,6 +758,18 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
|||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (tm.thing->type == MT_PATROLIVOBALL)
|
||||
{
|
||||
if (!thing->player)
|
||||
return BMIT_CONTINUE;
|
||||
if (tm.thing->z > thing->z + thing->height)
|
||||
return BMIT_CONTINUE; // overhead
|
||||
if (tm.thing->z + tm.thing->height < thing->z)
|
||||
return BMIT_CONTINUE; // underneath
|
||||
Obj_PatrolIvoBallTouch(tm.thing, thing);
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (thing->type == MT_BATTLEUFO)
|
||||
{
|
||||
if (tm.thing->type != MT_PLAYER)
|
||||
|
|
|
|||
27
src/p_mobj.c
27
src/p_mobj.c
|
|
@ -6825,6 +6825,17 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case MT_IVOBALL:
|
||||
case MT_AIRIVOBALL:
|
||||
{
|
||||
Obj_IvoBallThink(mobj);
|
||||
return;
|
||||
}
|
||||
case MT_PATROLIVOBALL:
|
||||
{
|
||||
Obj_PatrolIvoBallThink(mobj);
|
||||
return;
|
||||
}
|
||||
case MT_VWREF:
|
||||
case MT_VWREB:
|
||||
{
|
||||
|
|
@ -11088,6 +11099,11 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
|||
case MT_KURAGEN:
|
||||
thing->shadowscale = FRACUNIT/4;
|
||||
break;
|
||||
case MT_IVOBALL:
|
||||
case MT_PATROLIVOBALL:
|
||||
case MT_AIRIVOBALL:
|
||||
thing->shadowscale = FRACUNIT/2;
|
||||
break;
|
||||
default:
|
||||
if (thing->flags & (MF_ENEMY|MF_BOSS))
|
||||
thing->shadowscale = FRACUNIT;
|
||||
|
|
@ -14449,6 +14465,17 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
|
|||
Obj_SidewaysFreezeThrusterInit(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_IVOBALL:
|
||||
case MT_AIRIVOBALL:
|
||||
{
|
||||
Obj_IvoBallInit(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_PATROLIVOBALL:
|
||||
{
|
||||
Obj_PatrolIvoBallInit(mobj);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1026,7 +1026,7 @@ void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative)
|
|||
// Returns true if player is
|
||||
// ACTUALLY on the local machine
|
||||
//
|
||||
boolean P_IsMachineLocalPlayer(player_t *player)
|
||||
boolean P_IsMachineLocalPlayer(const player_t *player)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
|
|
@ -1051,7 +1051,7 @@ boolean P_IsMachineLocalPlayer(player_t *player)
|
|||
// on the local machine
|
||||
// (or simulated party)
|
||||
//
|
||||
boolean P_IsLocalPlayer(player_t *player)
|
||||
boolean P_IsLocalPlayer(const player_t *player)
|
||||
{
|
||||
if (player == NULL)
|
||||
{
|
||||
|
|
@ -1072,7 +1072,7 @@ boolean P_IsLocalPlayer(player_t *player)
|
|||
// Returns true if player is
|
||||
// currently being watched.
|
||||
//
|
||||
boolean P_IsDisplayPlayer(player_t *player)
|
||||
boolean P_IsDisplayPlayer(const player_t *player)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
|
|
|
|||
|
|
@ -613,7 +613,7 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id)
|
|||
S_StartSoundAtVolume(origin, sfx_id, 255);
|
||||
}
|
||||
|
||||
void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volume, player_t *owner)
|
||||
void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volume, const player_t *owner)
|
||||
{
|
||||
if (S_SoundDisabled())
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ void S_StartSound(const void *origin, sfxenum_t sound_id);
|
|||
void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume);
|
||||
|
||||
// Will start a sound, but only if VFX reduce is off or the owner isn't a display player.
|
||||
void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volume, player_t *owner);
|
||||
void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volume, const player_t *owner);
|
||||
#define S_ReducedVFXSound(a, b, c) S_ReducedVFXSoundAtVolume(a, b, 255, c)
|
||||
|
||||
// Stop sound for thing at <origin>
|
||||
|
|
|
|||
|
|
@ -1249,6 +1249,8 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
|
||||
{"glgz1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ice Cube shatters"},
|
||||
|
||||
{"ivobal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Ivo Ball
|
||||
|
||||
// Damage sounds
|
||||
{"dmga1", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
|
||||
{"dmga2", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
|
||||
|
|
|
|||
|
|
@ -1320,6 +1320,9 @@ typedef enum
|
|||
// Ice Cube
|
||||
sfx_glgz1,
|
||||
|
||||
// Ivo Ball
|
||||
sfx_ivobal,
|
||||
|
||||
// Damage sounds
|
||||
sfx_dmga1,
|
||||
sfx_dmga2,
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 xoffset)
|
|||
|
||||
returny = y;
|
||||
|
||||
boolean (*_isHighlightedPlayer)(player_t *) =
|
||||
boolean (*_isHighlightedPlayer)(const player_t *) =
|
||||
(demo.playback
|
||||
? P_IsDisplayPlayer
|
||||
: P_IsLocalPlayer
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue