mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-24 00:42:32 +00:00
Merge branch 'ancient-gear' into 'master'
Ancient Gear (resolves #1599) Closes #1599 See merge request kart-krew-dev/ring-racers-internal!2726
This commit is contained in:
commit
c7b3a49c85
20 changed files with 398 additions and 8 deletions
|
|
@ -3294,7 +3294,8 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
|
|||
|| (++offset && fastcmp(params[0], "HITMIDAIR"))
|
||||
|| (++offset && fastcmp(params[0], "HITDRAFTERLOOKBACK"))
|
||||
|| (++offset && fastcmp(params[0], "GIANTRACERSHRUNKENORBI"))
|
||||
|| (++offset && fastcmp(params[0], "RETURNMARKTOSENDER")))
|
||||
|| (++offset && fastcmp(params[0], "RETURNMARKTOSENDER"))
|
||||
|| (++offset && fastcmp(params[0], "ALLANCIENTGEARS")))
|
||||
{
|
||||
//PARAMCHECK(1);
|
||||
ty = UCRP_TRIPWIREHYUU + offset;
|
||||
|
|
|
|||
|
|
@ -3120,6 +3120,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_TOXAA_DEAD",
|
||||
"S_TOXAB",
|
||||
"S_TOXBA",
|
||||
|
||||
"S_ANCIENTGEAR",
|
||||
"S_ANCIENTGEAR_PART",
|
||||
};
|
||||
|
||||
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",
|
||||
|
|
@ -4036,6 +4039,9 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
"MT_TOXOMISTER_POLE",
|
||||
"MT_TOXOMISTER_EYE",
|
||||
"MT_TOXOMISTER_CLOUD",
|
||||
|
||||
"MT_ANCIENTGEAR",
|
||||
"MT_ANCIENTGEAR_PART",
|
||||
};
|
||||
|
||||
const char *const MOBJFLAG_LIST[] = {
|
||||
|
|
|
|||
57
src/info.c
57
src/info.c
|
|
@ -812,6 +812,8 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"TOXA",
|
||||
"TOXB",
|
||||
|
||||
"GEAR",
|
||||
|
||||
// Pulley
|
||||
"HCCH",
|
||||
"HCHK",
|
||||
|
|
@ -3713,6 +3715,9 @@ state_t states[NUMSTATES] =
|
|||
{SPR_TOXA, 0, 175, {NULL}, 0, 0, S_NULL}, // S_TOXAA_DEAD
|
||||
{SPR_TOXA, 1, -1, {NULL}, 0, 0, S_TOXAB}, // S_TOXAB
|
||||
{SPR_TOXB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 6, 5, S_TOXBA}, // S_TOXBA
|
||||
|
||||
{SPR_GEAR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_ANCIENTGEAR
|
||||
{SPR_GEAR, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_ANCIENTGEAR_PART
|
||||
};
|
||||
|
||||
mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||
|
|
@ -22880,6 +22885,58 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
MF_SPECIAL|MF_NOGRAVITY|MF_DONTENCOREMAP|MF_ELEMENTAL, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_ANCIENTGEAR
|
||||
323, // doomednum
|
||||
S_ANCIENTGEAR, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_gotgea, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_ANCIENTGEAR, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_gshc4, // deathsound
|
||||
0, // speed
|
||||
64*FRACUNIT, // radius
|
||||
128*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SPECIAL|MF_NOGRAVITY|MF_DONTENCOREMAP|MF_NOSQUISH, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
{ // MT_ANCIENTGEAR_PART
|
||||
-1, // doomednum
|
||||
S_ANCIENTGEAR_PART, // 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
|
||||
64*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SCENERY|MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP|MF_NOSQUISH, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1349,6 +1349,8 @@ typedef enum sprite
|
|||
SPR_TOXA,
|
||||
SPR_TOXB,
|
||||
|
||||
SPR_GEAR,
|
||||
|
||||
// Pulley
|
||||
SPR_HCCH,
|
||||
SPR_HCHK,
|
||||
|
|
@ -4197,6 +4199,9 @@ typedef enum state
|
|||
S_TOXAB,
|
||||
S_TOXBA,
|
||||
|
||||
S_ANCIENTGEAR,
|
||||
S_ANCIENTGEAR_PART,
|
||||
|
||||
S_FIRSTFREESLOT,
|
||||
S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1,
|
||||
NUMSTATES
|
||||
|
|
@ -5136,6 +5141,9 @@ typedef enum mobj_type
|
|||
MT_TOXOMISTER_EYE,
|
||||
MT_TOXOMISTER_CLOUD,
|
||||
|
||||
MT_ANCIENTGEAR,
|
||||
MT_ANCIENTGEAR_PART,
|
||||
|
||||
MT_FIRSTFREESLOT,
|
||||
MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1,
|
||||
NUMMOBJTYPES
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@ void K_CheckEmeralds(player_t *player)
|
|||
player->angleturn + ANGLE_180,
|
||||
400*mapobjectscale,
|
||||
6*TICRATE,
|
||||
FRACUNIT/16
|
||||
FRACUNIT/16,
|
||||
3*TICRATE
|
||||
);
|
||||
|
||||
g_emeraldWin += g_endcam.swirlDuration;
|
||||
|
|
|
|||
|
|
@ -131,6 +131,11 @@ struct EndCam : endcam_t
|
|||
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
active = false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Archive(T&& ar)
|
||||
{
|
||||
|
|
@ -203,7 +208,7 @@ void K_LoadEndCamera(savebuffer_t *save)
|
|||
endcam_cast().Archive(srb2::UnArchiveWrapper(save));
|
||||
}
|
||||
|
||||
void K_StartRoundWinCamera(mobj_t *origin, angle_t focusAngle, fixed_t finalRadius, tic_t panDuration, fixed_t panSpeed)
|
||||
void K_StartRoundWinCamera(mobj_t *origin, angle_t focusAngle, fixed_t finalRadius, tic_t panDuration, fixed_t panSpeed, tic_t swirlDuration)
|
||||
{
|
||||
const fixed_t angF = AngleFixed(focusAngle);
|
||||
|
||||
|
|
@ -211,7 +216,7 @@ void K_StartRoundWinCamera(mobj_t *origin, angle_t focusAngle, fixed_t finalRadi
|
|||
g_endcam.startRadius = {2400*mapobjectscale, 800*mapobjectscale};
|
||||
g_endcam.endRadius = {finalRadius, finalRadius / 2};
|
||||
|
||||
g_endcam.swirlDuration = 3*TICRATE;
|
||||
g_endcam.swirlDuration = swirlDuration;
|
||||
g_endcam.startAngle = angF + (90*FRACUNIT);
|
||||
g_endcam.endAngle = angF + (720*FRACUNIT);
|
||||
|
||||
|
|
@ -224,3 +229,8 @@ void K_StartRoundWinCamera(mobj_t *origin, angle_t focusAngle, fixed_t finalRadi
|
|||
g_darkness.start = leveltime;
|
||||
g_darkness.end = leveltime + g_endcam.swirlDuration + DARKNESS_FADE_TIME;
|
||||
}
|
||||
|
||||
void K_StopRoundWinCamera(void)
|
||||
{
|
||||
endcam_cast().Stop();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,10 @@ extern endcam_t g_endcam;
|
|||
void K_CommitEndCamera(void);
|
||||
|
||||
// Automatically set up a cool camera in one-shot.
|
||||
void K_StartRoundWinCamera(mobj_t *origin, angle_t focusAngle, fixed_t finalRadius, tic_t panDuration, fixed_t panSpeed);
|
||||
void K_StartRoundWinCamera(mobj_t *origin, angle_t focusAngle, fixed_t finalRadius, tic_t panDuration, fixed_t panSpeed, tic_t swirlDuration);
|
||||
|
||||
// Stop the end camera
|
||||
void K_StopRoundWinCamera(void);
|
||||
|
||||
/// ...
|
||||
|
||||
|
|
|
|||
|
|
@ -8038,6 +8038,17 @@ void K_drawKartHUD(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (stplyr == Obj_GetAncientGearCollectingPlayer())
|
||||
{
|
||||
srb2::Draw(BASEVIDWIDTH / 2, 130)
|
||||
.flags(V_SNAPTOBOTTOM)
|
||||
.font(srb2::Draw::Font::kGamemode)
|
||||
.align(srb2::Draw::Align::kCenter)
|
||||
.scale(0.80f)
|
||||
.text("YOU GOT AN ANCIENT GEAR")
|
||||
;
|
||||
}
|
||||
|
||||
// TODO better voice chat speaking indicator integration for spectators
|
||||
{
|
||||
char speakingstring[2048];
|
||||
|
|
|
|||
|
|
@ -4589,7 +4589,8 @@ void K_CheckpointCrossAward(player_t *player)
|
|||
player->angleturn + ANGLE_180,
|
||||
400*mapobjectscale,
|
||||
6*TICRATE,
|
||||
FRACUNIT/16
|
||||
FRACUNIT/16,
|
||||
3*TICRATE
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -4835,7 +4836,8 @@ void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UIN
|
|||
R_PointToAngle2(source->x, source->y, victim->mo->x, victim->mo->y) + ANGLE_135,
|
||||
200*mapobjectscale,
|
||||
8*TICRATE,
|
||||
FRACUNIT/512
|
||||
FRACUNIT/512,
|
||||
3*TICRATE
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -488,6 +488,17 @@ boolean Obj_ToxomisterPoleCollide(mobj_t *pole, mobj_t *toucher);
|
|||
boolean Obj_ToxomisterCloudCollide(mobj_t *cloud, mobj_t *toucher);
|
||||
fixed_t Obj_GetToxomisterCloudDrag(mobj_t *cloud);
|
||||
|
||||
/* Ancient Gear */
|
||||
void Obj_AncientGearSpawn(mobj_t *gear);
|
||||
void Obj_AncientGearPartThink(mobj_t *part);
|
||||
void Obj_AncientGearRemoved(mobj_t *gear);
|
||||
void Obj_AncientGearTouch(mobj_t *gear, mobj_t *toucher);
|
||||
void Obj_AncientGearDeath(mobj_t *gear, mobj_t *source);
|
||||
void Obj_AncientGearDeadThink(mobj_t *gear);
|
||||
void Obj_AncientGearLevelInit(void);
|
||||
player_t *Obj_GetAncientGearCollectingPlayer(void);
|
||||
boolean Obj_AllAncientGearsCollected(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -668,7 +668,9 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
|
|||
mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle)));
|
||||
|
||||
mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value;
|
||||
mt->scale = player->mo->scale;
|
||||
mt->scale = FixedDiv(player->mo->scale, mapobjectscale);
|
||||
mt->spritexscale = FRACUNIT;
|
||||
mt->spriteyscale = FRACUNIT;
|
||||
memset(mt->thing_args, 0, NUM_MAPTHING_ARGS*sizeof(*mt->thing_args));
|
||||
memset(mt->thing_stringargs, 0x00, NUM_MAPTHING_STRINGARGS*sizeof(*mt->thing_stringargs));
|
||||
mt->special = 0;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "k_podium.h"
|
||||
#include "k_pwrlv.h"
|
||||
#include "k_profiles.h"
|
||||
#include "k_objects.h" // Obj_AllAncientGearsCollected
|
||||
|
||||
gamedata_t *gamedata = NULL;
|
||||
boolean netUnlocked[MAXUNLOCKABLES];
|
||||
|
|
@ -2035,6 +2036,8 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
return (player->roundconditions.giant_foe_shrunken_orbi);
|
||||
case UCRP_RETURNMARKTOSENDER:
|
||||
return (player->roundconditions.returntosender_mark);
|
||||
case UCRP_ALLANCIENTGEARS:
|
||||
return Obj_AllAncientGearsCollected();
|
||||
|
||||
case UCRP_TRACKHAZARD:
|
||||
{
|
||||
|
|
@ -2948,6 +2951,8 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
return "hit a giant racer with a shrunken Orbinaut";
|
||||
case UCRP_RETURNMARKTOSENDER:
|
||||
return "when cursed with Eggmark, blow up the racer responsible";
|
||||
case UCRP_ALLANCIENTGEARS:
|
||||
return "collect all Ancient Gears";
|
||||
|
||||
case UCRP_TRACKHAZARD:
|
||||
{
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ typedef enum
|
|||
UCRP_HITDRAFTERLOOKBACK, // Hit a player that's behind you, while looking back at them, and they're drafting off you
|
||||
UCRP_GIANTRACERSHRUNKENORBI, // Hit a giant racer with a shrunken Orbinaut
|
||||
UCRP_RETURNMARKTOSENDER, // Hit the player responsible for Eggman Marking you with that explosion
|
||||
UCRP_ALLANCIENTGEARS, // Collect all Ancient Gears in a map
|
||||
|
||||
UCRP_TRACKHAZARD, // (Don't) get hit by a track hazard (maybe specific lap)
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
exp.c
|
||||
bail.c
|
||||
toxomister.cpp
|
||||
ancient-gear.c
|
||||
)
|
||||
|
||||
add_subdirectory(versus)
|
||||
|
|
|
|||
237
src/objects/ancient-gear.c
Normal file
237
src/objects/ancient-gear.c
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by Lachlan "Lach" Wright
|
||||
// Copyright (C) 2025 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 ancient-gear.c
|
||||
/// \brief Ancient Gear object code.
|
||||
|
||||
#include "../p_local.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../k_endcam.h"
|
||||
#include "../k_hud.h"
|
||||
#include "../m_cond.h"
|
||||
|
||||
#define DEATH_FREEZE_TIME (5*TICRATE)
|
||||
#define DEATH_TIME (2*TICRATE)
|
||||
#define DEATH_RISE_SPEED (3*FRACUNIT)
|
||||
|
||||
#define DELTA_YAW (-ANG2)
|
||||
#define DELTA_ROLL (ANG2)
|
||||
static const angle_t DELTA_YAW_ACCELERATION = (-ANG1 / 2);
|
||||
static const angle_t DELTA_ROLL_ACCELERATION = (ANG1 / 3);
|
||||
static const fixed_t DELTA_SPRITEXSCALE = ((FRACUNIT/4 - FRACUNIT) / DEATH_TIME);
|
||||
static const fixed_t DELTA_SPRITEYSCALE = ((FRACUNIT*3 - FRACUNIT) / DEATH_TIME);
|
||||
static const tic_t TRANS_SHIFT_RATE = (DEATH_TIME / 10);
|
||||
|
||||
static UINT16 numGears = 0;
|
||||
static boolean allGearsCollected = false;
|
||||
static player_t *collectingPlayer = NULL;
|
||||
|
||||
static void UpdateAncientGearPart(mobj_t *part)
|
||||
{
|
||||
mobj_t *gear = part->target;
|
||||
fixed_t radius = FixedMul(FixedMul(part->movefactor, gear->scale), gear->spritexscale);
|
||||
fixed_t xOffset = P_ReturnThrustX(NULL, part->angle - ANGLE_90, radius);
|
||||
fixed_t yOffset = P_ReturnThrustY(NULL, part->angle - ANGLE_90, radius);
|
||||
|
||||
P_InstaScale(part, gear->scale);
|
||||
P_MoveOrigin(part,
|
||||
gear->x + xOffset,
|
||||
gear->y + yOffset,
|
||||
gear->z + gear->height / 2
|
||||
);
|
||||
part->angle += gear->extravalue1;
|
||||
part->rollangle += gear->extravalue2 * part->extravalue1;
|
||||
part->spritexscale = gear->spritexscale;
|
||||
part->spriteyscale = gear->spriteyscale;
|
||||
}
|
||||
|
||||
void Obj_AncientGearSpawn(mobj_t *gear)
|
||||
{
|
||||
UINT8 i;
|
||||
mobj_t *part = gear;
|
||||
|
||||
numGears++;
|
||||
|
||||
gear->extravalue1 = DELTA_YAW;
|
||||
gear->extravalue2 = DELTA_ROLL;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(gear, 0, 0, 0, MT_ANCIENTGEAR_PART));
|
||||
P_SetTarget(&part->hnext->hprev, part);
|
||||
part = part->hnext;
|
||||
P_SetTarget(&part->target, gear);
|
||||
|
||||
part->angle += (i & 1) * ANGLE_180;
|
||||
|
||||
if (i < 2) // middle parts
|
||||
{
|
||||
part->angle += ANGLE_90;
|
||||
part->movefactor = 10 * FRACUNIT; // horizontal offset from hitbox
|
||||
part->extravalue1 = 0; // direction to roll the sprite
|
||||
part->frame = (part->frame & ~FF_FRAMEMASK) | 1;
|
||||
P_SetTarget(&part->tracer, gear);
|
||||
part->flags2 |= MF2_LINKDRAW;
|
||||
}
|
||||
else // side parts
|
||||
{
|
||||
part->movefactor = 7 * FRACUNIT; // horizontal offset from hitbox
|
||||
part->extravalue1 = (i & 1) * 2 - 1; // direction to roll the sprite
|
||||
if (i > 3) // fake brightmaps
|
||||
{
|
||||
part->frame = (part->frame & ~FF_FRAMEMASK) | 3 | FF_FULLBRIGHT;
|
||||
part->dispoffset++;
|
||||
}
|
||||
else
|
||||
{
|
||||
part->frame = (part->frame & ~FF_FRAMEMASK) | 2;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAncientGearPart(part);
|
||||
part->old_x = part->x;
|
||||
part->old_y = part->y;
|
||||
part->old_z = part->z;
|
||||
part->old_angle = part->angle;
|
||||
part->old_scale = part->scale;
|
||||
}
|
||||
}
|
||||
|
||||
void Obj_AncientGearPartThink(mobj_t *part)
|
||||
{
|
||||
if (P_MobjWasRemoved(part->target))
|
||||
{
|
||||
P_RemoveMobj(part);
|
||||
return;
|
||||
}
|
||||
UpdateAncientGearPart(part);
|
||||
}
|
||||
|
||||
void Obj_AncientGearRemoved(mobj_t *gear)
|
||||
{
|
||||
while (!P_MobjWasRemoved(gear->hnext))
|
||||
{
|
||||
P_RemoveMobj(gear->hnext);
|
||||
}
|
||||
}
|
||||
|
||||
void Obj_AncientGearTouch(mobj_t *gear, mobj_t *toucher)
|
||||
{
|
||||
P_KillMobj(gear, NULL, toucher, DMG_NORMAL);
|
||||
}
|
||||
|
||||
void Obj_AncientGearDeath(mobj_t *gear, mobj_t *source)
|
||||
{
|
||||
if (--numGears == 0)
|
||||
{
|
||||
allGearsCollected = true;
|
||||
M_UpdateUnlockablesAndExtraEmblems(true, true);
|
||||
}
|
||||
|
||||
gear->fuse = DEATH_TIME;
|
||||
gear->shadowscale = gear->spritexscale;
|
||||
|
||||
// give the gear some upwards momentum
|
||||
gear->flags |= MF_NOCLIPHEIGHT;
|
||||
P_SetObjectMomZ(gear, DEATH_RISE_SPEED, false);
|
||||
|
||||
// don't activate the round win camera if there is no camera target,
|
||||
// or if the round win camera is already active for any actual reason
|
||||
if (P_MobjWasRemoved(source) || source->player == NULL || g_endcam.active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// track the collecting player to display a message for them
|
||||
collectingPlayer = source->player;
|
||||
P_SetTarget(&gear->target, source);
|
||||
|
||||
// play the collection jingle!
|
||||
S_StartSound(NULL, gear->info->seesound);
|
||||
|
||||
// fade out the music for as long as the sound plays
|
||||
g_musicfade.start = leveltime;
|
||||
g_musicfade.end = g_musicfade.start + DEATH_FREEZE_TIME;
|
||||
g_musicfade.fade = 12;
|
||||
g_musicfade.ticked = false;
|
||||
|
||||
// start the round win camera
|
||||
gear->flags2 |= MF2_BEYONDTHEGRAVE; // a gear with this flag will stop the round win camera upon next thinking
|
||||
K_StartRoundWinCamera(
|
||||
source,
|
||||
source->player->angleturn,
|
||||
FixedMul(cv_cam_dist[0].value, mapobjectscale),
|
||||
6*TICRATE,
|
||||
FRACUNIT/16,
|
||||
DEATH_FREEZE_TIME
|
||||
);
|
||||
}
|
||||
|
||||
void Obj_AncientGearDeadThink(mobj_t *gear)
|
||||
{
|
||||
mobj_t *part = gear;
|
||||
|
||||
// if the round win camera was activated, tell it to stop focusing on the player,
|
||||
// and show the player a message
|
||||
if (gear->flags2 & MF2_BEYONDTHEGRAVE)
|
||||
{
|
||||
gear->flags2 &= ~MF2_BEYONDTHEGRAVE;
|
||||
K_StopRoundWinCamera();
|
||||
|
||||
collectingPlayer = NULL;
|
||||
K_AddMessage(
|
||||
numGears > 0 ? va("%d Ancient Gear%s left!", numGears, numGears == 1 ? "" : "s")
|
||||
: "All Ancient Gears collected!"
|
||||
, true, false
|
||||
);
|
||||
}
|
||||
|
||||
// play another sound once immediately after the round win camera finishes
|
||||
if (!(gear->flags2 & MF2_DONTRESPAWN))
|
||||
{
|
||||
gear->flags2 |= MF2_DONTRESPAWN;
|
||||
S_StartSound(gear, gear->info->deathsound);
|
||||
}
|
||||
|
||||
// increase the translucency level every so often
|
||||
if (gear->fuse % TRANS_SHIFT_RATE == 0)
|
||||
{
|
||||
while (!P_MobjWasRemoved(part = part->hnext))
|
||||
{
|
||||
part->frame += FF_TRANS10;
|
||||
}
|
||||
}
|
||||
|
||||
// accelerate the spinning and rotating
|
||||
gear->extravalue1 += DELTA_YAW_ACCELERATION;
|
||||
gear->extravalue2 += DELTA_ROLL_ACCELERATION;
|
||||
|
||||
// stretch the gear
|
||||
gear->spritexscale += DELTA_SPRITEXSCALE;
|
||||
gear->spriteyscale += DELTA_SPRITEYSCALE;
|
||||
gear->shadowscale = gear->spritexscale;
|
||||
}
|
||||
|
||||
void Obj_AncientGearLevelInit(void)
|
||||
{
|
||||
numGears = 0;
|
||||
allGearsCollected = false;
|
||||
collectingPlayer = NULL;
|
||||
}
|
||||
|
||||
player_t *Obj_GetAncientGearCollectingPlayer(void)
|
||||
{
|
||||
return collectingPlayer;
|
||||
}
|
||||
|
||||
boolean Obj_AllAncientGearsCollected(void)
|
||||
{
|
||||
return allGearsCollected;
|
||||
}
|
||||
|
|
@ -1137,6 +1137,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
Obj_ToxomisterCloudCollide(special, toucher);
|
||||
return;
|
||||
|
||||
case MT_ANCIENTGEAR:
|
||||
Obj_AncientGearTouch(special, toucher);
|
||||
return;
|
||||
|
||||
default: // SOC or script pickup
|
||||
P_SetTarget(&special->target, toucher);
|
||||
break;
|
||||
|
|
@ -2364,6 +2368,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
case MT_FLYBOT767:
|
||||
Obj_FlybotDeath(target);
|
||||
break;
|
||||
case MT_ANCIENTGEAR:
|
||||
Obj_AncientGearDeath(target, source);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
19
src/p_mobj.c
19
src/p_mobj.c
|
|
@ -6798,6 +6798,11 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
Obj_TickStoneShoeChain(mobj);
|
||||
return;
|
||||
}
|
||||
case MT_ANCIENTGEAR_PART:
|
||||
{
|
||||
Obj_AncientGearPartThink(mobj);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
if (mobj->fuse)
|
||||
{ // Scenery object fuse! Very basic!
|
||||
|
|
@ -7000,6 +7005,11 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
|
|||
VS_BlendEye_Generator_DeadThinker(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_ANCIENTGEAR:
|
||||
{
|
||||
Obj_AncientGearDeadThink(mobj);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -11179,6 +11189,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
|||
case MT_BATTLEUFO:
|
||||
case MT_SPRAYCAN:
|
||||
case MT_CHECKPOINT_END:
|
||||
case MT_ANCIENTGEAR:
|
||||
thing->shadowscale = FRACUNIT;
|
||||
break;
|
||||
case MT_SMALLMACE:
|
||||
|
|
@ -11724,6 +11735,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
case MT_CABOTRON:
|
||||
Obj_SSCabotronMobjSpawn(mobj);
|
||||
break;
|
||||
case MT_ANCIENTGEAR:
|
||||
Obj_AncientGearSpawn(mobj);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -12011,6 +12025,11 @@ void P_RemoveMobj(mobj_t *mobj)
|
|||
Obj_FlybotRemoved(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_ANCIENTGEAR:
|
||||
{
|
||||
Obj_AncientGearRemoved(mobj);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -7634,6 +7634,8 @@ static void P_InitLevelSettings(void)
|
|||
nummapspraycans = 0;
|
||||
numchallengedestructibles = 0;
|
||||
|
||||
Obj_AncientGearLevelInit();
|
||||
|
||||
// circuit, race and competition stuff
|
||||
numcheatchecks = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1543,6 +1543,9 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
// :apple:
|
||||
{"aple", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
||||
// Ancient Gear
|
||||
{"gotgea", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
||||
// SRB2kart - Skin sounds
|
||||
{"kwin", false, 64, 96, -1, NULL, 0, SKSKWIN, -1, LUMPERROR, ""},
|
||||
{"klose", false, 64, 96, -1, NULL, 0, SKSKLOSE, -1, LUMPERROR, ""},
|
||||
|
|
|
|||
|
|
@ -1619,6 +1619,9 @@ typedef enum
|
|||
// :apple:
|
||||
sfx_aple,
|
||||
|
||||
// Ancient Gear
|
||||
sfx_gotgea,
|
||||
|
||||
// And LASTLY, Kart's skin sounds.
|
||||
sfx_kwin,
|
||||
sfx_klose,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue