mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-22 07:52:30 +00:00
Merge branch 'battle-release' into 'master'
Battle is (almost) ready for release Closes #681 See merge request KartKrew/Kart!1788
This commit is contained in:
commit
10f8bb5a3f
33 changed files with 485 additions and 177 deletions
|
|
@ -856,6 +856,7 @@ consvar_t cv_kartdebugnodes = ServerCheat("debugnodes", "Off").on_off().descript
|
|||
consvar_t cv_1pswap = PlayerCheat("1pswap", "1").min_max(1, MAXSPLITSCREENPLAYERS).description("Let P1's Profile control a different splitscreen player");
|
||||
|
||||
consvar_t cv_debugfinishline = PlayerCheat("debugfinishline", "Off").on_off().description("Highlight finish lines, respawn lines, death pits and instakill planes with high contrast colors");
|
||||
consvar_t cv_debughudtracker = PlayerCheat("debughudtracker", "Off").on_off().description("Highlight overlapping HUD tracker blocks");
|
||||
|
||||
consvar_t cv_debugrank = PlayerCheat("debugrank", "Off").description("Show GP rank state on the HUD; optionally force a rank grade").values({
|
||||
{0, "Off"},
|
||||
|
|
|
|||
|
|
@ -982,6 +982,9 @@ struct player_t
|
|||
icecubevars_t icecube;
|
||||
|
||||
level_tally_t tally;
|
||||
|
||||
tic_t darkness_start;
|
||||
tic_t darkness_end;
|
||||
};
|
||||
|
||||
// WARNING FOR ANYONE ABOUT TO ADD SOMETHING TO THE PLAYER STRUCT, G_PlayerReborn WANTS YOU TO SUFFER
|
||||
|
|
|
|||
|
|
@ -803,8 +803,12 @@ struct exitcondition_t
|
|||
extern tic_t racecountdown, exitcountdown, musiccountdown;
|
||||
extern exitcondition_t g_exit;
|
||||
|
||||
extern tic_t darktimer;
|
||||
extern fixed_t darkness;
|
||||
#define DARKNESS_FADE_TIME (8)
|
||||
extern struct darkness_t
|
||||
{
|
||||
tic_t start, end;
|
||||
fixed_t value[MAXSPLITSCREENPLAYERS];
|
||||
} g_darkness;
|
||||
|
||||
#define DEFAULT_GRAVITY (4*FRACUNIT/5)
|
||||
extern fixed_t gravity;
|
||||
|
|
|
|||
|
|
@ -277,8 +277,7 @@ UINT8 useSeal = 1;
|
|||
tic_t racecountdown, exitcountdown, musiccountdown; // for racing
|
||||
exitcondition_t g_exit;
|
||||
|
||||
tic_t darktimer;
|
||||
fixed_t darkness;
|
||||
darkness_t g_darkness;
|
||||
|
||||
fixed_t gravity;
|
||||
fixed_t mapobjectscale;
|
||||
|
|
|
|||
|
|
@ -85,9 +85,6 @@ extern boolean pausebreakkey;
|
|||
|
||||
extern boolean promptactive;
|
||||
|
||||
extern tic_t darktimer;
|
||||
extern fixed_t darkness;
|
||||
|
||||
extern consvar_t cv_tutorialprompt;
|
||||
|
||||
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection;
|
||||
|
|
|
|||
|
|
@ -1861,6 +1861,7 @@ static void HU_DrawTitlecardCEcho(size_t num)
|
|||
INT32 y = BASEVIDHEIGHT/2;
|
||||
INT32 pnumlines = 0;
|
||||
INT32 timeroffset = 0;
|
||||
INT32 fadeout = state->duration * 2 / 3;
|
||||
|
||||
char *line;
|
||||
char *echoptr;
|
||||
|
|
@ -1916,7 +1917,7 @@ static void HU_DrawTitlecardCEcho(size_t num)
|
|||
*line = '\0';
|
||||
|
||||
ofs = V_CenteredTitleCardStringOffset(echoptr, p4);
|
||||
V_DrawTitleCardString(x - ofs, y, echoptr, 0, false, timer, TICRATE*4, p4);
|
||||
V_DrawTitleCardString(x - ofs, y, echoptr, 0, false, timer, fadeout, p4);
|
||||
|
||||
y += p4 ? 18 : 32;
|
||||
|
||||
|
|
@ -2660,7 +2661,7 @@ void HU_ClearTitlecardCEcho(void)
|
|||
}
|
||||
|
||||
// Similar but for titlecard CEcho and also way less convoluted because I have no clue whatever the fuck they were trying above.
|
||||
void HU_DoTitlecardCEcho(player_t *player, const char *msg, boolean interrupt)
|
||||
void HU_DoTitlecardCEchoForDuration(player_t *player, const char *msg, boolean interrupt, tic_t duration)
|
||||
{
|
||||
if (player && !P_IsDisplayPlayer(player))
|
||||
{
|
||||
|
|
@ -2687,5 +2688,10 @@ void HU_DoTitlecardCEcho(player_t *player, const char *msg, boolean interrupt)
|
|||
strncat(state->text, "\\", sizeof(state->text) - strlen(state->text) - 1);
|
||||
state->text[sizeof(state->text) - 1] = '\0';
|
||||
state->start = gametic;
|
||||
state->duration = TICRATE*6 + strlen(state->text);
|
||||
state->duration = duration ? duration : TICRATE*6 + strlen(state->text);
|
||||
}
|
||||
|
||||
void HU_DoTitlecardCEcho(player_t *player, const char *msg, boolean interrupt)
|
||||
{
|
||||
HU_DoTitlecardCEchoForDuration(player, msg, interrupt, 0u);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ void HU_DoCEcho(const char *msg);
|
|||
|
||||
// Titlecard CECHO shite
|
||||
void HU_DoTitlecardCEcho(player_t *player, const char *msg, boolean interrupt);
|
||||
void HU_DoTitlecardCEchoForDuration(player_t *player, const char *msg, boolean interrupt, tic_t duration);
|
||||
void HU_ClearTitlecardCEcho(void);
|
||||
|
||||
void DoSayCommand(char *message, SINT8 target, UINT8 flags, UINT8 source);
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
powerup.cpp
|
||||
spectator.cpp
|
||||
timer.cpp
|
||||
emerald-win.cpp
|
||||
)
|
||||
|
|
|
|||
41
src/hud/emerald-win.cpp
Normal file
41
src/hud/emerald-win.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include "../v_draw.hpp"
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../i_time.h"
|
||||
#include "../k_hud.h"
|
||||
#include "../screen.h"
|
||||
|
||||
using srb2::Draw;
|
||||
|
||||
void K_drawEmeraldWin(void)
|
||||
{
|
||||
constexpr float kScale = 0.25;
|
||||
constexpr int kH = 72 * kScale;
|
||||
constexpr int kYPad = 12;
|
||||
constexpr int kWidth = 34 + 4;
|
||||
|
||||
if (I_GetTime() % 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Draw row = Draw(BASEVIDWIDTH / 2, BASEVIDHEIGHT / 2).scale(kScale).flags(V_ADD);
|
||||
//Draw(0, row.y()).size(BASEVIDWIDTH, 1).fill(35);
|
||||
|
||||
Draw top = row.y(-kYPad);
|
||||
Draw bot = row.xy(-kWidth / 2, kH + kYPad);
|
||||
|
||||
auto put = [](Draw& row, int x, int n)
|
||||
{
|
||||
row.x(x * kWidth).colormap(static_cast<skincolornum_t>(SKINCOLOR_CHAOSEMERALD1 + n)).patch("EMRCA0");
|
||||
};
|
||||
|
||||
put(top, -1, 3);
|
||||
put(top, 0, 0);
|
||||
put(top, 1, 4);
|
||||
|
||||
put(bot, -1, 5);
|
||||
put(bot, 0, 1);
|
||||
put(bot, 1, 2);
|
||||
put(bot, 2, 6);
|
||||
}
|
||||
|
|
@ -30982,7 +30982,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_cdfm19, // deathsound
|
||||
0, // speed
|
||||
60*FRACUNIT, // radius
|
||||
104*FRACUNIT, // height
|
||||
156*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
0, // damage
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@
|
|||
#include "p_spec.h"
|
||||
#include "k_objects.h"
|
||||
#include "k_rank.h"
|
||||
#include "music.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "m_easing.h"
|
||||
|
||||
#define BARRIER_MIN_RADIUS (768 * mapobjectscale)
|
||||
|
||||
// Battle overtime info
|
||||
struct battleovertime battleovertime;
|
||||
|
|
@ -37,6 +42,9 @@ INT32 numgotboxes = 0;
|
|||
UINT8 maptargets = 0; // Capsules in map
|
||||
UINT8 numtargets = 0; // Capsules busted
|
||||
|
||||
// Battle: someone won by collecting all 7 Chaos Emeralds
|
||||
boolean g_emeraldWin = false;
|
||||
|
||||
INT32 K_StartingBumperCount(void)
|
||||
{
|
||||
if (tutorialchallenge == TUTORIALSKIP_INPROGRESS)
|
||||
|
|
@ -142,6 +150,12 @@ void K_CheckBumpers(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (numingame <= 2 && battleovertime.enabled && battleovertime.radius <= BARRIER_MIN_RADIUS)
|
||||
{
|
||||
Music_Stop("battle_overtime");
|
||||
S_StartSound(NULL, sfx_kc4b); // Loud noise helps mask transition
|
||||
}
|
||||
|
||||
if (K_Cooperative())
|
||||
{
|
||||
if (nobumpers > 0 && nobumpers >= numingame)
|
||||
|
|
@ -184,6 +198,7 @@ void K_CheckEmeralds(player_t *player)
|
|||
player->roundscore = 100; // lmao
|
||||
|
||||
P_DoAllPlayersExit(0, false);
|
||||
g_emeraldWin = true;
|
||||
}
|
||||
|
||||
UINT16 K_GetChaosEmeraldColor(UINT32 emeraldType)
|
||||
|
|
@ -678,19 +693,47 @@ void K_RunBattleOvertime(void)
|
|||
{
|
||||
battleovertime.enabled++;
|
||||
if (battleovertime.enabled == TICRATE)
|
||||
{
|
||||
S_StartSound(NULL, sfx_bhurry);
|
||||
if (battleovertime.enabled == 10*TICRATE)
|
||||
HU_DoTitlecardCEchoForDuration(NULL, "HURRY UP!!", true, 2*TICRATE);
|
||||
Music_DelayEnd("level", 0);
|
||||
}
|
||||
else if (battleovertime.enabled == 10*TICRATE)
|
||||
{
|
||||
S_StartSound(NULL, sfx_kc40);
|
||||
P_StartQuake(5, 64 * mapobjectscale, 0, NULL);
|
||||
battleovertime.start = leveltime;
|
||||
}
|
||||
|
||||
if (!Music_Playing("level") && !Music_Playing("battle_overtime"))
|
||||
{
|
||||
Music_Play("battle_overtime");
|
||||
Music_Play("battle_overtime_stress");
|
||||
|
||||
// Sync approximately with looping section of
|
||||
// battle_overtime. (This is file dependant.)
|
||||
Music_Seek("battle_overtime_stress", 1756);
|
||||
}
|
||||
}
|
||||
else if (battleovertime.radius > 0)
|
||||
{
|
||||
const fixed_t minradius = 768 * mapobjectscale;
|
||||
const fixed_t minradius = BARRIER_MIN_RADIUS;
|
||||
const fixed_t oldradius = battleovertime.radius;
|
||||
|
||||
if (battleovertime.radius > minradius)
|
||||
battleovertime.radius -= (battleovertime.initial_radius / (30*TICRATE));
|
||||
{
|
||||
tic_t t = leveltime - battleovertime.start;
|
||||
const tic_t duration = 30*TICRATE;
|
||||
battleovertime.radius = Easing_OutSine(min(t, duration) * FRACUNIT / duration, battleovertime.initial_radius, minradius);
|
||||
}
|
||||
|
||||
if (battleovertime.radius < minradius)
|
||||
if (battleovertime.radius <= minradius && oldradius > minradius)
|
||||
{
|
||||
battleovertime.radius = minradius;
|
||||
K_CheckBumpers();
|
||||
S_StartSound(NULL, sfx_kc40);
|
||||
P_StartQuake(5, 64 * mapobjectscale, 0, NULL);
|
||||
}
|
||||
|
||||
// Subtract the 10 second grace period of the barrier
|
||||
if (battleovertime.enabled < 25*TICRATE)
|
||||
|
|
@ -822,6 +865,8 @@ void K_BattleInit(boolean singleplayercontext)
|
|||
|
||||
g_battleufo.due = starttime;
|
||||
g_battleufo.previousId = Obj_RandomBattleUFOSpawnerID() - 1;
|
||||
|
||||
g_emeraldWin = false;
|
||||
}
|
||||
|
||||
UINT8 K_Bumpers(player_t *player)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ extern struct battleovertime
|
|||
UINT16 enabled; ///< Has this been initalized yet?
|
||||
fixed_t radius; ///< Radius of kill field
|
||||
fixed_t initial_radius; ///< Starting radius of kill field
|
||||
tic_t start; ///< Leveltime to decrease kill field radius from
|
||||
fixed_t x, y, z; ///< Position to center on
|
||||
} battleovertime;
|
||||
|
||||
|
|
@ -32,6 +33,7 @@ extern struct battleufo
|
|||
extern boolean battleprisons;
|
||||
extern INT32 nummapboxes, numgotboxes; // keep track of spawned battle mode items
|
||||
extern UINT8 maptargets, numtargets;
|
||||
extern boolean g_emeraldWin;
|
||||
|
||||
INT32 K_StartingBumperCount(void);
|
||||
boolean K_IsPlayerWanted(player_t *player);
|
||||
|
|
|
|||
|
|
@ -5663,6 +5663,9 @@ void K_drawKartHUD(void)
|
|||
if ((gametyperules & GTR_KARMA) && !r_splitscreen && (stplyr->karthud[khud_yougotem] % 2)) // * YOU GOT EM *
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2 - (SHORT(kp_yougotem->width)/2), 32, V_HUDTRANS, kp_yougotem);
|
||||
|
||||
if (g_emeraldWin)
|
||||
K_drawEmeraldWin();
|
||||
|
||||
// Draw FREE PLAY.
|
||||
K_drawKartFreePlay();
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ void K_drawSpectatorHUD(boolean director);
|
|||
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, UINT8 mode);
|
||||
void K_drawKart2PTimestamp(void);
|
||||
void K_drawKart4PTimestamp(void);
|
||||
void K_drawEmeraldWin(void);
|
||||
void K_DrawMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, UINT16 map, const UINT8 *colormap);
|
||||
void K_DrawLikeMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, patch_t *patch, const UINT8 *colormap);
|
||||
void K_drawTargetHUD(const vector3_t *origin, player_t *player);
|
||||
|
|
|
|||
|
|
@ -26,9 +26,18 @@
|
|||
|
||||
using namespace srb2;
|
||||
|
||||
extern "C" consvar_t cv_debughudtracker;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
enum class Visibility
|
||||
{
|
||||
kHidden,
|
||||
kVisible,
|
||||
kTransparent,
|
||||
};
|
||||
|
||||
struct TargetTracking
|
||||
{
|
||||
static constexpr int kMaxLayers = 2;
|
||||
|
|
@ -54,8 +63,9 @@ struct TargetTracking
|
|||
};
|
||||
|
||||
mobj_t* mobj;
|
||||
vector3_t point;
|
||||
trackingResult_t result;
|
||||
fixed_t camDist;
|
||||
bool foreground;
|
||||
|
||||
skincolornum_t color() const
|
||||
{
|
||||
|
|
@ -157,6 +167,7 @@ struct TargetTracking
|
|||
private:
|
||||
Graphics graphics() const
|
||||
{
|
||||
using layers = decltype(Animation::layers);
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_SUPER_FLICKY:
|
||||
|
|
@ -186,7 +197,9 @@ private:
|
|||
{{8, 2, {kp_capsuletarget_near[1]}}}, // 4P
|
||||
},
|
||||
{{ // Far
|
||||
{2, 3, {kp_capsuletarget_far[0], kp_capsuletarget_far_text}}, // 1P
|
||||
{2, 3, foreground ?
|
||||
layers {kp_capsuletarget_far[0], kp_capsuletarget_far_text} :
|
||||
layers {kp_capsuletarget_far[0]}}, // 1P
|
||||
{{2, 3, {kp_capsuletarget_far[1]}}}, // 4P
|
||||
}},
|
||||
};
|
||||
|
|
@ -194,15 +207,121 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
bool is_player_tracking_target(player_t *player = stplyr)
|
||||
{
|
||||
if ((gametyperules & (GTR_BUMPERS|GTR_CLOSERPLAYERS)) != (GTR_BUMPERS|GTR_CLOSERPLAYERS))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (K_Cooperative())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inDuel)
|
||||
{
|
||||
// Always draw targets in 1v1 but don't draw player's
|
||||
// own target on their own viewport.
|
||||
return player != stplyr;
|
||||
}
|
||||
|
||||
// Except for DUEL mode, Overtime hides all TARGETs except
|
||||
// the kiosk.
|
||||
if (battleovertime.enabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player->emeralds != 0 && K_IsPlayerWanted(stplyr))
|
||||
{
|
||||
// The player who is about to win because of emeralds
|
||||
// gets a TARGET on them
|
||||
if (K_NumEmeralds(player) == 6) // 6 out of 7
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// WANTED player sees TARGETs on players holding
|
||||
// emeralds
|
||||
if (K_IsPlayerWanted(stplyr))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return K_IsPlayerWanted(player);
|
||||
}
|
||||
|
||||
bool is_object_tracking_target(const mobj_t* mobj)
|
||||
{
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_BATTLECAPSULE:
|
||||
case MT_CDUFO:
|
||||
return battleprisons;
|
||||
|
||||
case MT_PLAYER:
|
||||
return is_player_tracking_target(mobj->player);
|
||||
|
||||
case MT_OVERTIME_CENTER:
|
||||
return inDuel == false && battleovertime.enabled;
|
||||
|
||||
case MT_EMERALD:
|
||||
return Obj_EmeraldCanHUDTrack(mobj) &&
|
||||
((specialstageinfo.valid && specialstageinfo.ufo) || is_player_tracking_target());
|
||||
|
||||
case MT_MONITOR:
|
||||
return is_player_tracking_target() && Obj_MonitorGetEmerald(mobj) != 0;
|
||||
|
||||
case MT_SUPER_FLICKY:
|
||||
return Obj_IsSuperFlickyTargettingYou(mobj, stplyr->mo);
|
||||
|
||||
case MT_SPRAYCAN:
|
||||
return !(mobj->renderflags & (RF_TRANSMASK | RF_DONTDRAW)); // the spraycan wasn't collected yet
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Visibility is_object_visible(mobj_t* mobj)
|
||||
{
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_SUPER_FLICKY:
|
||||
// Always flickers.
|
||||
return (leveltime & 1) ? Visibility::kVisible : Visibility::kHidden;
|
||||
|
||||
case MT_SPRAYCAN:
|
||||
// Flickers, but only when visible.
|
||||
return P_CheckSight(stplyr->mo, mobj) && (leveltime & 1) ? Visibility::kVisible : Visibility::kHidden;
|
||||
|
||||
default:
|
||||
// Transparent when not visible.
|
||||
return P_CheckSight(stplyr->mo, mobj) ? Visibility::kVisible : Visibility::kTransparent;
|
||||
}
|
||||
}
|
||||
|
||||
void K_DrawTargetTracking(const TargetTracking& target)
|
||||
{
|
||||
Visibility visibility = is_object_visible(target.mobj);
|
||||
|
||||
if (visibility == Visibility::kHidden)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t* colormap = target.colormap();
|
||||
|
||||
trackingResult_t result = {};
|
||||
const trackingResult_t& result = target.result;
|
||||
int32_t timer = 0;
|
||||
|
||||
K_ObjectTracking(&result, &target.point, false);
|
||||
|
||||
if (result.onScreen == false)
|
||||
{
|
||||
// Off-screen, draw alongside the borders of the screen.
|
||||
|
|
@ -363,6 +482,17 @@ void K_DrawTargetTracking(const TargetTracking& target)
|
|||
{
|
||||
// Draw simple overlay.
|
||||
vector2_t targetPos = {result.x, result.y};
|
||||
INT32 trans = [&]
|
||||
{
|
||||
switch (visibility)
|
||||
{
|
||||
case Visibility::kTransparent:
|
||||
return V_30TRANS;
|
||||
|
||||
default:
|
||||
return target.foreground ? 0 : V_80TRANS;
|
||||
}
|
||||
}();
|
||||
|
||||
TargetTracking::Animation anim = target.animation();
|
||||
|
||||
|
|
@ -374,7 +504,7 @@ void K_DrawTargetTracking(const TargetTracking& target)
|
|||
targetPos.x - ((patch->width << FRACBITS) >> 1),
|
||||
targetPos.y - ((patch->height << FRACBITS) >> 1),
|
||||
FRACUNIT,
|
||||
V_SPLITSCREEN | anim.video_flags,
|
||||
V_SPLITSCREEN | anim.video_flags | trans,
|
||||
patch,
|
||||
colormap
|
||||
);
|
||||
|
|
@ -382,105 +512,66 @@ void K_DrawTargetTracking(const TargetTracking& target)
|
|||
}
|
||||
}
|
||||
|
||||
bool is_player_tracking_target(player_t *player = stplyr)
|
||||
void K_CullTargetList(std::vector<TargetTracking>& targetList)
|
||||
{
|
||||
if ((gametyperules & (GTR_BUMPERS|GTR_CLOSERPLAYERS)) != (GTR_BUMPERS|GTR_CLOSERPLAYERS))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
constexpr int kBlockSize = 20;
|
||||
constexpr int kXBlocks = BASEVIDWIDTH / kBlockSize;
|
||||
constexpr int kYBlocks = BASEVIDHEIGHT / kBlockSize;
|
||||
bool map[kXBlocks][kYBlocks] = {};
|
||||
|
||||
if (K_Cooperative())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
constexpr fixed_t kTrackerRadius = 30*FRACUNIT/2; // just an approximation of common HUD tracker
|
||||
|
||||
if (player == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int debugColorCycle = 0;
|
||||
|
||||
if (inDuel)
|
||||
{
|
||||
// Always draw targets in 1v1 but don't draw player's
|
||||
// own target on their own viewport.
|
||||
return player != stplyr;
|
||||
}
|
||||
|
||||
// Except for DUEL mode, Overtime hides all TARGETs except
|
||||
// the kiosk.
|
||||
if (battleovertime.enabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player->emeralds != 0 && K_IsPlayerWanted(stplyr))
|
||||
{
|
||||
// The player who is about to win because of emeralds
|
||||
// gets a TARGET on them
|
||||
if (K_NumEmeralds(player) == 6) // 6 out of 7
|
||||
std::for_each(
|
||||
targetList.rbegin(),
|
||||
targetList.rend(),
|
||||
[&](TargetTracking& tr)
|
||||
{
|
||||
return true;
|
||||
if (tr.result.onScreen == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fixed_t x1 = std::max(((tr.result.x - kTrackerRadius) / kBlockSize) / FRACUNIT, 0);
|
||||
fixed_t x2 = std::min(((tr.result.x + kTrackerRadius) / kBlockSize) / FRACUNIT, kXBlocks - 1);
|
||||
fixed_t y1 = std::max(((tr.result.y - kTrackerRadius) / kBlockSize) / FRACUNIT, 0);
|
||||
fixed_t y2 = std::min(((tr.result.y + kTrackerRadius) / kBlockSize) / FRACUNIT, kYBlocks - 1);
|
||||
|
||||
bool allMine = true;
|
||||
|
||||
for (fixed_t x = x1; x <= x2; ++x)
|
||||
{
|
||||
for (fixed_t y = y1; y <= y2; ++y)
|
||||
{
|
||||
if (map[x][y])
|
||||
{
|
||||
allMine = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
map[x][y] = true;
|
||||
|
||||
if (cv_debughudtracker.value)
|
||||
{
|
||||
V_DrawFill(x * kBlockSize, y * kBlockSize, kBlockSize, kBlockSize, 39 + debugColorCycle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allMine)
|
||||
{
|
||||
// This tracker claims every square
|
||||
tr.foreground = true;
|
||||
}
|
||||
|
||||
if (++debugColorCycle > 8)
|
||||
{
|
||||
debugColorCycle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// WANTED player sees TARGETs on players holding
|
||||
// emeralds
|
||||
if (K_IsPlayerWanted(stplyr))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return K_IsPlayerWanted(player);
|
||||
}
|
||||
|
||||
bool is_object_tracking_target(const mobj_t* mobj)
|
||||
{
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_BATTLECAPSULE:
|
||||
case MT_CDUFO:
|
||||
return battleprisons;
|
||||
|
||||
case MT_PLAYER:
|
||||
return is_player_tracking_target(mobj->player);
|
||||
|
||||
case MT_OVERTIME_CENTER:
|
||||
return inDuel == false && battleovertime.enabled;
|
||||
|
||||
case MT_EMERALD:
|
||||
return Obj_EmeraldCanHUDTrack(mobj) &&
|
||||
((specialstageinfo.valid && specialstageinfo.ufo) || is_player_tracking_target());
|
||||
|
||||
case MT_MONITOR:
|
||||
return is_player_tracking_target() && Obj_MonitorGetEmerald(mobj) != 0;
|
||||
|
||||
case MT_SUPER_FLICKY:
|
||||
return Obj_IsSuperFlickyTargettingYou(mobj, stplyr->mo);
|
||||
|
||||
case MT_SPRAYCAN:
|
||||
return !(mobj->renderflags & (RF_TRANSMASK | RF_DONTDRAW)); // the spraycan wasn't collected yet
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_object_visible(mobj_t* mobj)
|
||||
{
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_SUPER_FLICKY:
|
||||
// Always flickers.
|
||||
return (leveltime & 1);
|
||||
|
||||
case MT_SPRAYCAN:
|
||||
// Flickers, but only when visible.
|
||||
return P_CheckSight(stplyr->mo, mobj) && (leveltime & 1);
|
||||
|
||||
default:
|
||||
// Flicker when not visible.
|
||||
return P_CheckSight(stplyr->mo, mobj) || (leveltime & 1);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
|
|
@ -506,23 +597,28 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (is_object_visible(mobj) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
vector3_t pos = {
|
||||
R_InterpolateFixed(mobj->old_x, mobj->x) + mobj->sprxoff,
|
||||
R_InterpolateFixed(mobj->old_y, mobj->y) + mobj->spryoff,
|
||||
R_InterpolateFixed(mobj->old_z, mobj->z) + mobj->sprzoff + (mobj->height >> 1),
|
||||
};
|
||||
|
||||
targetList.push_back({mobj, pos, R_PointToDist2(origin->x, origin->y, pos.x, pos.y)});
|
||||
TargetTracking tr;
|
||||
|
||||
tr.mobj = mobj;
|
||||
tr.camDist = R_PointToDist2(origin->x, origin->y, pos.x, pos.y);
|
||||
tr.foreground = false;
|
||||
|
||||
K_ObjectTracking(&tr.result, &pos, false);
|
||||
|
||||
targetList.push_back(tr);
|
||||
}
|
||||
|
||||
// Sort by distance from camera. Further trackers get
|
||||
// drawn first so nearer ones draw over them.
|
||||
std::sort(targetList.begin(), targetList.end(), [](const auto& a, const auto& b) { return a.camDist > b.camDist; });
|
||||
|
||||
K_CullTargetList(targetList);
|
||||
|
||||
std::for_each(targetList.cbegin(), targetList.cend(), K_DrawTargetTracking);
|
||||
}
|
||||
|
|
|
|||
38
src/k_kart.c
38
src/k_kart.c
|
|
@ -116,7 +116,7 @@ static void K_SpawnDuelOnlyItems(void)
|
|||
void K_TimerReset(void)
|
||||
{
|
||||
starttime = introtime = 0;
|
||||
darkness = darktimer = 0;
|
||||
memset(&g_darkness, 0, sizeof g_darkness);
|
||||
numbulbs = 1;
|
||||
inDuel = rainbowstartavailable = false;
|
||||
linecrossed = 0;
|
||||
|
|
@ -7044,7 +7044,11 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8
|
|||
drop->movecount = amount;
|
||||
}
|
||||
|
||||
drop->flags |= MF_NOCLIPTHING;
|
||||
if (type < FIRSTPOWERUP)
|
||||
{
|
||||
// Pick up power-ups immediately
|
||||
drop->flags |= MF_NOCLIPTHING;
|
||||
}
|
||||
|
||||
if (gametyperules & GTR_CLOSERPLAYERS)
|
||||
{
|
||||
|
|
@ -8796,18 +8800,38 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
K_UpdateTripwire(player);
|
||||
|
||||
if ((battleovertime.enabled >= 10*TICRATE) && !(player->pflags & PF_ELIMINATED) && !player->exiting)
|
||||
if (battleovertime.enabled)
|
||||
{
|
||||
fixed_t distanceToBarrier = 0;
|
||||
fixed_t distanceToCenter = 0;
|
||||
|
||||
if (battleovertime.radius > 0)
|
||||
{
|
||||
distanceToBarrier = R_PointToDist2(player->mo->x, player->mo->y, battleovertime.x, battleovertime.y) - (player->mo->radius * 2);
|
||||
distanceToCenter = R_PointToDist2(player->mo->x, player->mo->y, battleovertime.x, battleovertime.y);
|
||||
}
|
||||
|
||||
if (distanceToBarrier > battleovertime.radius)
|
||||
if (distanceToCenter + player->mo->radius > battleovertime.radius)
|
||||
{
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER);
|
||||
if (distanceToCenter - (player->mo->radius * 2) > battleovertime.radius &&
|
||||
(battleovertime.enabled >= 10*TICRATE) &&
|
||||
!(player->pflags & PF_ELIMINATED) &&
|
||||
!player->exiting)
|
||||
{
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER);
|
||||
}
|
||||
|
||||
if (leveltime < player->darkness_end)
|
||||
{
|
||||
if (leveltime > player->darkness_end - DARKNESS_FADE_TIME)
|
||||
{
|
||||
player->darkness_start = leveltime - (player->darkness_end - leveltime);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->darkness_start = leveltime;
|
||||
}
|
||||
|
||||
player->darkness_end = leveltime + (2 * DARKNESS_FADE_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ boolean Obj_IsSuperFlickyTargettingYou(const mobj_t *flicky, mobj_t *player);
|
|||
void Obj_BattleUFOLegThink(mobj_t *leg);
|
||||
void Obj_BattleUFOThink(mobj_t *ufo);
|
||||
void Obj_SpawnBattleUFOLegs(mobj_t *ufo);
|
||||
void Obj_BattleUFODeath(mobj_t *ufo);
|
||||
void Obj_BattleUFODeath(mobj_t *ufo, mobj_t *inflictor);
|
||||
void Obj_LinkBattleUFOSpawner(mobj_t *spawner);
|
||||
void Obj_UnlinkBattleUFOSpawner(mobj_t *spawner);
|
||||
void Obj_SpawnBattleUFOFromSpawner(void);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ void Music_Init(void)
|
|||
Tune& tune = g_tunes.insert("level");
|
||||
|
||||
tune.priority = 1;
|
||||
tune.fade_out = 1500;
|
||||
tune.fade_out_inclusive = false;
|
||||
tune.resume_fade_in = 750;
|
||||
tune.sync = true;
|
||||
tune.credit = true;
|
||||
|
|
@ -48,6 +50,20 @@ void Music_Init(void)
|
|||
tune.fade_out = 3500;
|
||||
}
|
||||
|
||||
{
|
||||
Tune& tune = g_tunes.insert("battle_overtime", g_tunes.find("level"));
|
||||
|
||||
tune.song = "shwdwn";
|
||||
tune.priority = 11;
|
||||
}
|
||||
|
||||
{
|
||||
Tune& tune = g_tunes.insert("battle_overtime_stress", g_tunes.find("battle_overtime"));
|
||||
|
||||
tune.song = "shwdn2";
|
||||
tune.priority = 10;
|
||||
}
|
||||
|
||||
{
|
||||
Tune& tune = g_tunes.insert("grow");
|
||||
|
||||
|
|
@ -216,7 +232,7 @@ void Music_DelayEnd(const char* id, tic_t duration)
|
|||
}
|
||||
}
|
||||
|
||||
void Music_Seek(const char* id, tic_t set)
|
||||
void Music_Seek(const char* id, UINT32 set)
|
||||
{
|
||||
Tune* tune = g_tunes.find(id);
|
||||
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@ void Music_UnSuspend(const char *id);
|
|||
//
|
||||
|
||||
|
||||
// Seek to a specific time in the tune.
|
||||
void Music_Seek(const char *id, tic_t set);
|
||||
// Seek to a specific time in milliseconds in the tune.
|
||||
void Music_Seek(const char *id, UINT32 set);
|
||||
|
||||
// Remap a tune to another song. Use the lump name, with the
|
||||
// 'O_' at the beginning removed. song is case insensitive.
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ void TuneManager::seek(Tune* tune)
|
|||
uint32_t end = I_GetSongLength();
|
||||
uint32_t loop = I_GetSongLoopPoint();
|
||||
|
||||
uint32_t pos = detail::tics_to_msec(tune->seek + tune->elapsed()) * tune->speed();
|
||||
uint32_t pos = (tune->seek + detail::tics_to_msec(tune->elapsed())) * tune->speed();
|
||||
|
||||
if (pos > end && (end - loop) > 0u)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#define MUSIC_TUNE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
|
|
@ -68,7 +69,7 @@ public:
|
|||
bool nightcoreable = false;
|
||||
|
||||
// Start playing this number of tics into the tune.
|
||||
tic_t seek = 0;
|
||||
std::uint32_t seek = 0;
|
||||
|
||||
// these track state
|
||||
bool can_fade_out = true;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ struct UFO : Mobj
|
|||
|
||||
void spawn_beam()
|
||||
{
|
||||
Mobj *x = spawn_from<Mobj>({0, 0, height / 4}, MT_BATTLEUFO_BEAM);
|
||||
Mobj *x = spawn_from<Mobj>({0, 0, sprzoff() + 26}, MT_BATTLEUFO_BEAM);
|
||||
|
||||
x->renderflags |= RF_FLOORSPRITE|RF_NOSPLATBILLBOARD|RF_SLOPESPLAT|RF_NOSPLATROLLANGLE;
|
||||
x->colorized = true;
|
||||
|
|
@ -107,8 +107,12 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
Fixed ofs = mobjinfo[MT_BATTLEUFO].height / 4;
|
||||
|
||||
Spawner* spawner = next(g_battleufo.previousId);
|
||||
UFO* ufo = static_cast<UFO*>(P_SpawnMobjFromMobj(spawner, 0, 0, 250*FRACUNIT, MT_BATTLEUFO));
|
||||
UFO* ufo = static_cast<UFO*>(P_SpawnMobjFromMobj(spawner, 0, 0, 250*FRACUNIT - ofs, MT_BATTLEUFO));
|
||||
|
||||
ufo->sprzoff(ofs * spawner->scale());
|
||||
|
||||
ufo->spawner(spawner);
|
||||
}
|
||||
|
|
@ -137,14 +141,14 @@ void Obj_BattleUFOThink(mobj_t *mobj)
|
|||
K_BattleOvertimeKiller(mobj);
|
||||
}
|
||||
|
||||
void Obj_BattleUFODeath(mobj_t *mobj)
|
||||
void Obj_BattleUFODeath(mobj_t *mobj, mobj_t *inflictor)
|
||||
{
|
||||
UFO* ufo = static_cast<UFO*>(mobj);
|
||||
const SINT8 flip = P_MobjFlip(ufo);
|
||||
|
||||
ufo->momz = -(8*mapobjectscale)/2;
|
||||
|
||||
K_CreatePaperItem(
|
||||
mobj_t* drop = K_CreatePaperItem(
|
||||
ufo->x,
|
||||
ufo->y,
|
||||
ufo->z + (flip),
|
||||
|
|
@ -154,6 +158,14 @@ void Obj_BattleUFODeath(mobj_t *mobj)
|
|||
BATTLE_POWERUP_TIME
|
||||
);
|
||||
|
||||
if (!P_MobjWasRemoved(inflictor) && inflictor->type == MT_INSTAWHIP)
|
||||
{
|
||||
// Take momentum of player who whips
|
||||
inflictor = inflictor->target;
|
||||
}
|
||||
|
||||
drop->momz = !P_MobjWasRemoved(inflictor) ? inflictor->momz : 0;
|
||||
|
||||
if (ufo->spawner())
|
||||
{
|
||||
g_battleufo.previousId = ufo->spawner()->id();
|
||||
|
|
@ -196,6 +208,7 @@ void Obj_BattleUFOLegThink(mobj_t *leg)
|
|||
|
||||
// TODO: Take gravflip into account
|
||||
P_MoveOrigin(leg, x, y, leg->z);
|
||||
leg->sprzoff = leg->target->sprzoff;
|
||||
}
|
||||
|
||||
leg->momz = leg->target->momz;
|
||||
|
|
|
|||
|
|
@ -749,7 +749,8 @@ void Obj_CreateShrinkPohbees(player_t *owner)
|
|||
|
||||
ownerPos = owner->position;
|
||||
|
||||
darktimer = POHBEE_TIME;
|
||||
g_darkness.start = leveltime;
|
||||
g_darkness.end = leveltime + POHBEE_TIME + DARKNESS_FADE_TIME;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -56,14 +56,15 @@ constexpr int kSearchRadius = 1920;
|
|||
constexpr int kFlightRadius = 1280;
|
||||
constexpr int kPeckingRadius = 256;
|
||||
|
||||
constexpr int kFlightSpeed = 2;
|
||||
constexpr int kPeckingSpeed = 8;
|
||||
constexpr fixed_t kFlightSpeed = 2*FRACUNIT;
|
||||
constexpr fixed_t kPeckingSpeed = FRACUNIT/2;
|
||||
constexpr fixed_t kWeakSpeed = FRACUNIT/2;
|
||||
|
||||
constexpr fixed_t kRebound = 8*FRACUNIT/9;
|
||||
|
||||
constexpr tic_t kDelay = 8;
|
||||
constexpr tic_t kStunTime = 5*TICRATE;
|
||||
constexpr tic_t kBlockTime = 1*TICRATE;
|
||||
constexpr tic_t kStunTime = 10*TICRATE;
|
||||
constexpr tic_t kBlockTime = 5*TICRATE;
|
||||
|
||||
constexpr int kRiseTime = 1*TICRATE;
|
||||
constexpr int kRiseSpeed = 4;
|
||||
|
|
@ -394,15 +395,20 @@ struct Flicky : mobj_t
|
|||
|
||||
const Fly oldFly = fly();
|
||||
|
||||
if (d < ANGLE_11hh && dist < kPeckingRadius * mapobjectscale)
|
||||
if (mode() == Mode::kWeak)
|
||||
{
|
||||
P_Thrust(this, th, FixedMul(kWeakSpeed, mapobjectscale));
|
||||
fly(Fly::kNormal);
|
||||
}
|
||||
else if (d < ANGLE_11hh && dist < kPeckingRadius * mapobjectscale)
|
||||
{
|
||||
// Drastically speed up when about to intersect
|
||||
P_Thrust(this, th, kPeckingSpeed * mapobjectscale);
|
||||
P_Thrust(this, th, FixedMul(kPeckingSpeed, mapobjectscale));
|
||||
fly(Fly::kZoom);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_Thrust(this, th, kFlightSpeed * mapobjectscale);
|
||||
P_Thrust(this, th, FixedMul(kFlightSpeed, mapobjectscale));
|
||||
fly(Fly::kNormal);
|
||||
}
|
||||
|
||||
|
|
@ -493,6 +499,7 @@ struct Flicky : mobj_t
|
|||
{
|
||||
momx = -(momx);
|
||||
momy = -(momy);
|
||||
P_SetObjectMomZ(this, 8*FRACUNIT, false);
|
||||
}
|
||||
|
||||
void nerf()
|
||||
|
|
@ -505,7 +512,6 @@ struct Flicky : mobj_t
|
|||
void whip()
|
||||
{
|
||||
reflect();
|
||||
P_SetObjectMomZ(this, 8*FRACUNIT, false);
|
||||
|
||||
nerf();
|
||||
|
||||
|
|
|
|||
|
|
@ -396,9 +396,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
P_InstaThrust(player->mo, player->mo->angle, 20<<FRACBITS);
|
||||
return;
|
||||
case MT_FLOATINGITEM: // SRB2Kart
|
||||
// Avoid being picked up immediately
|
||||
if (special->scale < special->destscale/2)
|
||||
return;
|
||||
if (special->threshold >= FIRSTPOWERUP)
|
||||
{
|
||||
if (P_PlayerInPain(player))
|
||||
|
|
@ -408,6 +405,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Avoid being picked up immediately
|
||||
if (special->scale < special->destscale/2)
|
||||
return;
|
||||
|
||||
if (!P_CanPickupItem(player, 3) || (player->itemamount && player->itemtype != special->threshold))
|
||||
return;
|
||||
|
||||
|
|
@ -2352,7 +2353,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
Obj_MonitorOnDeath(target);
|
||||
break;
|
||||
case MT_BATTLEUFO:
|
||||
Obj_BattleUFODeath(target);
|
||||
Obj_BattleUFODeath(target, inflictor);
|
||||
break;
|
||||
case MT_BLENDEYE_MAIN:
|
||||
VS_BlendEye_Death(target);
|
||||
|
|
@ -3103,7 +3104,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
if (clash)
|
||||
{
|
||||
player->spheres = max(player->spheres - 10, 0);
|
||||
player->spheres = max(player->spheres - 5, 0);
|
||||
|
||||
if (inflictor)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -785,7 +785,14 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
|||
return BMIT_CONTINUE; // overhead
|
||||
}
|
||||
|
||||
P_SetObjectMomZ(tm.thing, FRACUNIT, true);
|
||||
if (!tm.thing->player || !tm.thing->player->fastfall)
|
||||
{
|
||||
P_SetObjectMomZ(tm.thing, FRACUNIT, true);
|
||||
}
|
||||
|
||||
fixed_t friction = 33*FRACUNIT/35;
|
||||
tm.thing->momx = FixedMul(tm.thing->momx, friction);
|
||||
tm.thing->momy = FixedMul(tm.thing->momy, friction);
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6400,7 +6400,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
|
||||
if (!(mobj->renderflags & RF_DONTDRAW))
|
||||
{
|
||||
const INT32 numberdisplaymin = ((mobj->target->player->itemtype == KITEM_ORBINAUT) ? 5 : 2);
|
||||
//const INT32 numberdisplaymin = ((mobj->target->player->itemtype == KITEM_ORBINAUT) ? 5 : 2);
|
||||
|
||||
// Set it to use the correct states for its condition
|
||||
if (mobj->target->player->itemRoulette.active)
|
||||
|
|
@ -6490,6 +6490,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
|
||||
mobj->tracer->destscale = scale;
|
||||
|
||||
#if 0
|
||||
if (mobj->target->player->itemamount >= numberdisplaymin
|
||||
&& mobj->target->player->itemamount <= 10) // Meh, too difficult to support greater than this; convert this to a decent HUD object and then maybe :V
|
||||
{
|
||||
|
|
@ -6507,6 +6508,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
P_SetScale(numx, mobj->scale);
|
||||
numx->destscale = scale;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (K_IsPlayerWanted(mobj->target->player) && mobj->movecount != 1)
|
||||
|
|
@ -7449,7 +7451,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
case MT_FLOATINGITEM:
|
||||
{
|
||||
P_ResetPitchRoll(mobj);
|
||||
if (mobj->flags & MF_NOCLIPTHING)
|
||||
if (!(mobj->flags & MF_NOGRAVITY))
|
||||
{
|
||||
if (P_CheckDeathPitCollide(mobj))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -787,6 +787,10 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
WRITEUINT8(save->p, players[i].icecube.wiggle);
|
||||
WRITEUINT32(save->p, players[i].icecube.frozenat);
|
||||
WRITEUINT8(save->p, players[i].icecube.shaketimer);
|
||||
|
||||
// darkness
|
||||
WRITEUINT32(save->p, players[i].darkness_start);
|
||||
WRITEUINT32(save->p, players[i].darkness_end);
|
||||
}
|
||||
|
||||
TracyCZoneEnd(__zone);
|
||||
|
|
@ -1358,6 +1362,10 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
players[i].icecube.frozenat = READUINT32(save->p);
|
||||
players[i].icecube.shaketimer = READUINT8(save->p);
|
||||
|
||||
// darkness
|
||||
players[i].darkness_start = READUINT32(save->p);
|
||||
players[i].darkness_end = READUINT32(save->p);
|
||||
|
||||
//players[i].viewheight = P_GetPlayerViewHeight(players[i]); // scale cannot be factored in at this point
|
||||
}
|
||||
|
||||
|
|
@ -6433,6 +6441,7 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
|
|||
WRITEINT32(save->p, numgotboxes);
|
||||
WRITEUINT8(save->p, numtargets);
|
||||
WRITEUINT8(save->p, battleprisons);
|
||||
WRITEUINT8(save->p, g_emeraldWin);
|
||||
|
||||
WRITEUINT8(save->p, gamespeed);
|
||||
WRITEUINT8(save->p, numlaps);
|
||||
|
|
@ -6445,6 +6454,7 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
|
|||
WRITEUINT16(save->p, battleovertime.enabled);
|
||||
WRITEFIXED(save->p, battleovertime.radius);
|
||||
WRITEFIXED(save->p, battleovertime.initial_radius);
|
||||
WRITEUINT32(save->p, battleovertime.start);
|
||||
WRITEFIXED(save->p, battleovertime.x);
|
||||
WRITEFIXED(save->p, battleovertime.y);
|
||||
WRITEFIXED(save->p, battleovertime.z);
|
||||
|
|
@ -6476,8 +6486,8 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
|
|||
|
||||
WRITEUINT32(save->p, g_pointlimit);
|
||||
|
||||
WRITEUINT32(save->p, darktimer);
|
||||
WRITEFIXED(save->p, darkness);
|
||||
WRITEUINT32(save->p, g_darkness.start);
|
||||
WRITEUINT32(save->p, g_darkness.end);
|
||||
|
||||
WRITEUINT16(save->p, numchallengedestructibles);
|
||||
|
||||
|
|
@ -6617,6 +6627,7 @@ static boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading)
|
|||
numgotboxes = READINT32(save->p);
|
||||
numtargets = READUINT8(save->p);
|
||||
battleprisons = (boolean)READUINT8(save->p);
|
||||
g_emeraldWin = (boolean)READUINT8(save->p);
|
||||
|
||||
gamespeed = READUINT8(save->p);
|
||||
numlaps = READUINT8(save->p);
|
||||
|
|
@ -6629,6 +6640,7 @@ static boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading)
|
|||
battleovertime.enabled = READUINT16(save->p);
|
||||
battleovertime.radius = READFIXED(save->p);
|
||||
battleovertime.initial_radius = READFIXED(save->p);
|
||||
battleovertime.start = READUINT32(save->p);
|
||||
battleovertime.x = READFIXED(save->p);
|
||||
battleovertime.y = READFIXED(save->p);
|
||||
battleovertime.z = READFIXED(save->p);
|
||||
|
|
@ -6660,8 +6672,8 @@ static boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading)
|
|||
|
||||
g_pointlimit = READUINT32(save->p);
|
||||
|
||||
darktimer = READUINT32(save->p);
|
||||
darkness = READFIXED(save->p);
|
||||
g_darkness.start = READUINT32(save->p);
|
||||
g_darkness.end = READUINT32(save->p);
|
||||
|
||||
numchallengedestructibles = READUINT16(save->p);
|
||||
|
||||
|
|
|
|||
|
|
@ -8202,7 +8202,7 @@ void P_LoadLevelMusic(void)
|
|||
Music_Remap("level", music);
|
||||
|
||||
tic_t level_music_start = starttime + (TICRATE/2);
|
||||
Music_Seek("level", std::max(leveltime, level_music_start) - level_music_start);
|
||||
Music_Seek("level", (std::max(leveltime, level_music_start) - level_music_start) * 1000UL / TICRATE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
55
src/p_tick.c
55
src/p_tick.c
|
|
@ -46,6 +46,7 @@
|
|||
#include "k_objects.h"
|
||||
#include "music.h"
|
||||
#include "k_dialogue.h"
|
||||
#include "m_easing.h"
|
||||
|
||||
#include "lua_profile.h"
|
||||
|
||||
|
|
@ -767,6 +768,43 @@ void P_RunChaseCameras(void)
|
|||
}
|
||||
}
|
||||
|
||||
static fixed_t P_GetDarkness(tic_t start, tic_t end)
|
||||
{
|
||||
if (leveltime <= end)
|
||||
{
|
||||
tic_t fade = end - DARKNESS_FADE_TIME;
|
||||
tic_t t;
|
||||
|
||||
if (leveltime < fade) // dark or darkening
|
||||
{
|
||||
t = leveltime - start;
|
||||
t = min(t, DARKNESS_FADE_TIME);
|
||||
}
|
||||
else // lightening
|
||||
{
|
||||
t = end - leveltime;
|
||||
}
|
||||
|
||||
return Easing_Linear((t * FRACUNIT) / DARKNESS_FADE_TIME, 0, FRACUNIT/7);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void P_TickDarkness(void)
|
||||
{
|
||||
const fixed_t globalValue = P_GetDarkness(g_darkness.start, g_darkness.end);
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i <= r_splitscreen; ++i)
|
||||
{
|
||||
const player_t *p = &players[displayplayers[i]];
|
||||
fixed_t value = P_GetDarkness(p->darkness_start, p->darkness_end);
|
||||
|
||||
g_darkness.value[i] = value ? value : globalValue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_Ticker
|
||||
//
|
||||
|
|
@ -1045,22 +1083,7 @@ void P_Ticker(boolean run)
|
|||
if (racecountdown > 1)
|
||||
racecountdown--;
|
||||
|
||||
const fixed_t darkdelta = FRACUNIT/50;
|
||||
const fixed_t maxdark = FRACUNIT/7;
|
||||
if (darktimer) // dark or darkening
|
||||
{
|
||||
darktimer--;
|
||||
darkness += darkdelta;
|
||||
darkness = min(darkness, maxdark);
|
||||
}
|
||||
else if (darkness >= darkdelta) // lightening
|
||||
{
|
||||
darkness -= darkdelta;
|
||||
}
|
||||
else // light
|
||||
{
|
||||
darkness = 0;
|
||||
}
|
||||
P_TickDarkness();
|
||||
|
||||
if (exitcountdown >= 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "i_time.h"
|
||||
#include "m_fixed.h"
|
||||
#include "r_draw.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_main.h"
|
||||
#include "g_game.h"
|
||||
|
||||
|
|
@ -43,7 +44,7 @@ INT32 R_AdjustLightLevel(INT32 light)
|
|||
|
||||
if (!debugrender_highlight && cv_debugrender_contrast.value == 0)
|
||||
{
|
||||
const fixed_t darken = FixedMul(FixedMul(darkness, mapheaderinfo[gamemap-1]->darkness), kRange);
|
||||
const fixed_t darken = FixedMul(FixedMul(g_darkness.value[R_GetViewNumber()], mapheaderinfo[gamemap-1]->darkness), kRange);
|
||||
return std::clamp((light * FRACUNIT) - darken, 0, kRange) / FRACUNIT;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2296,7 +2296,7 @@ static void Command_Tunes_f(void)
|
|||
Music_Play("stereo");
|
||||
|
||||
if (argc > 3)
|
||||
Music_Seek("stereo", (atoi(COM_Argv(3)) * TICRATE) / 1000);
|
||||
Music_Seek("stereo", atoi(COM_Argv(3)));
|
||||
|
||||
if (argc > 2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ TYPEDEF (tolinfo_t);
|
|||
TYPEDEF (cupheader_t);
|
||||
TYPEDEF (unloaded_cupheader_t);
|
||||
TYPEDEF (exitcondition_t);
|
||||
TYPEDEF (darkness_t);
|
||||
|
||||
// font.h
|
||||
TYPEDEF (font_t);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue