Merge branch 'master' of https://git.do.srb2.org/KartKrew/Kart.git into testers

This commit is contained in:
toaster 2022-01-17 01:01:08 +00:00
commit e8b0caf878
49 changed files with 3131 additions and 665 deletions

View file

@ -111,4 +111,5 @@ k_botitem.c
k_botsearch.c
k_grandprix.c
k_hud.c
k_terrain.c
k_brightmap.c

View file

@ -345,16 +345,6 @@ static void F_IntroDrawScene(void)
// DRAW A FULL PIC INSTEAD OF FLAT!
if (intro_scenenum == 0)
{
if (finalecount == 8)
S_StartSound(NULL, sfx_vroom);
else if (finalecount == 47)
{
// Need to use M_Random otherwise it always uses the same sound
INT32 rskin = M_RandomKey(numskins);
UINT8 rtaunt = M_RandomKey(2);
sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt];
S_StartSound(NULL, rsound);
}
background = W_CachePatchName("KARTKREW", PU_CACHE);
highres = true;
}
@ -453,6 +443,20 @@ void F_IntroTicker(void)
timetonext--;
if (intro_scenenum == 0)
{
if (finalecount == 8)
S_StartSound(NULL, sfx_vroom);
else if (finalecount == 47)
{
// Need to use M_Random otherwise it always uses the same sound
INT32 rskin = M_RandomKey(numskins);
UINT8 rtaunt = M_RandomKey(2);
sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt];
S_StartSound(NULL, rsound);
}
}
F_WriteText();
// check for skipping

View file

@ -261,7 +261,7 @@ INT32 stealtime = TICRATE/2;
INT32 sneakertime = TICRATE + (TICRATE/3);
INT32 itemtime = 8*TICRATE;
INT32 bubbletime = TICRATE/2;
INT32 comebacktime = 10*TICRATE;
INT32 comebacktime = 3*TICRATE;
INT32 bumptime = 6;
INT32 greasetics = 3*TICRATE;
INT32 wipeoutslowtime = 20;

View file

@ -40,9 +40,12 @@
#include "../r_things.h" // R_GetShadowZ
#include "../d_main.h"
#include "../p_slopes.h"
#include "../k_kart.h" // HITLAGJITTERS
#include "hw_md2.h"
// SRB2Kart
#include "../k_kart.h" // HITLAGJITTERS
#include "../r_fps.h"
#ifdef NEWCLIP
#include "hw_clip.h"
#endif
@ -3641,17 +3644,9 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
fixed_t slopez;
pslope_t *groundslope;
fixed_t interpx = thing->x;
fixed_t interpy = thing->y;
fixed_t interpz = thing->z;
// do interpolation
if (cv_frameinterpolation.value == 1)
{
interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
}
fixed_t interpx = R_InterpolateFixed(thing->old_x, thing->x);
fixed_t interpy = R_InterpolateFixed(thing->old_y, thing->y);
fixed_t interpz = R_InterpolateFixed(thing->old_z, thing->z);
// hitlag vibrating (todo: interp somehow?)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
@ -3673,7 +3668,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
interpy += thing->spryoff;
interpz += thing->sprzoff;
groundz = R_GetShadowZ(thing, &groundslope);
groundz = R_GetShadowZ(thing, &groundslope, interpx, interpy, interpz);
gpatch = (patch_t *)W_CachePatchName("DSHADOW", PU_SPRITE);
if (!(gpatch && ((GLPatch_t *)gpatch->hardware)->mipmap->format)) return;
@ -5084,25 +5079,18 @@ static void HWR_ProjectSprite(mobj_t *thing)
dispoffset = thing->info->dispoffset;
interpx = thing->x;
interpy = thing->y;
interpz = thing->z;
interpangle = (thing->player ? thing->player->drawangle : thing->angle);
interpx = R_InterpolateFixed(thing->old_x, thing->x);
interpy = R_InterpolateFixed(thing->old_y, thing->y);
interpz = R_InterpolateFixed(thing->old_z, thing->z);
interpangle = ANGLE_MAX;
if (cv_frameinterpolation.value == 1)
if (thing->player)
{
interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
if (thing->player)
{
interpangle = thing->player->old_drawangle + FixedMul(rendertimefrac, thing->player->drawangle - thing->player->old_drawangle);
}
else
{
interpangle = thing->old_angle + FixedMul(rendertimefrac, thing->angle - thing->old_angle);
}
interpangle = R_InterpolateAngle(thing->player->old_drawangle, thing->player->drawangle);
}
else
{
interpangle = R_InterpolateAngle(thing->old_angle, thing->angle);
}
// hitlag vibrating (todo: interp somehow?)
@ -5307,7 +5295,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (caster && !P_MobjWasRemoved(caster))
{
fixed_t groundz = R_GetShadowZ(thing, NULL);
fixed_t groundz = R_GetShadowZ(thing, NULL, interpx, interpy, interpz);
fixed_t floordiff = abs(((thing->eflags & MFE_VERTICALFLIP) ? caster->height : 0) + caster->z - groundz);
shadowheight = FIXED_TO_FLOAT(floordiff);
@ -5526,17 +5514,9 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
if (!thing)
return;
interpx = thing->x;
interpy = thing->y;
interpz = thing->z;
// do interpolation
if (cv_frameinterpolation.value == 1)
{
interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
}
interpx = R_InterpolateFixed(thing->old_x, thing->x);
interpy = R_InterpolateFixed(thing->old_y, thing->y);
interpz = R_InterpolateFixed(thing->old_z, thing->z);
// transform the origin point
tr_x = FIXED_TO_FLOAT(interpx) - gl_viewx;
@ -6771,7 +6751,6 @@ void HWR_DoPostProcessor(player_t *player)
// 10 by 10 grid. 2 coordinates (xy)
float v[SCREENVERTS][SCREENVERTS][2];
static double disStart = 0;
static fixed_t last_fractime = 0;
UINT8 x, y;
INT32 WAVELENGTH;
@ -6781,15 +6760,15 @@ void HWR_DoPostProcessor(player_t *player)
// Modifies the wave.
if (*type == postimg_water)
{
WAVELENGTH = 20; // Lower is longer
AMPLITUDE = 20; // Lower is bigger
FREQUENCY = 16; // Lower is faster
WAVELENGTH = 5;
AMPLITUDE = 20;
FREQUENCY = 8;
}
else
{
WAVELENGTH = 10; // Lower is longer
AMPLITUDE = 30; // Lower is bigger
FREQUENCY = 4; // Lower is faster
WAVELENGTH = 10;
AMPLITUDE = 60;
FREQUENCY = 4;
}
for (x = 0; x < SCREENVERTS; x++)
@ -6803,16 +6782,7 @@ void HWR_DoPostProcessor(player_t *player)
}
HWD.pfnPostImgRedraw(v);
if (!(paused || P_AutoPause()))
disStart += 1;
if (renderdeltatics > FRACUNIT)
{
disStart = disStart - FIXED_TO_FLOAT(last_fractime) + 1 + FIXED_TO_FLOAT(rendertimefrac);
}
else
{
disStart = disStart - FIXED_TO_FLOAT(last_fractime) + FIXED_TO_FLOAT(rendertimefrac);
}
last_fractime = rendertimefrac;
disStart += FIXED_TO_FLOAT(renderdeltatics);
// Capture the screen again for screen waving on the intermission
if(gamestate != GS_INTERMISSION)

View file

@ -46,6 +46,7 @@
// SRB2Kart
#include "../k_color.h"
#include "../k_kart.h" // HITLAGJITTERS
#include "../r_fps.h"
#ifdef HAVE_PNG
@ -1368,17 +1369,9 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
INT32 mod;
float finalscale;
fixed_t interpx = spr->mobj->x;
fixed_t interpy = spr->mobj->y;
fixed_t interpz = spr->mobj->z;
// do interpolation
if (cv_frameinterpolation.value == 1)
{
interpx = spr->mobj->old_x + FixedMul(rendertimefrac, spr->mobj->x - spr->mobj->old_x);
interpy = spr->mobj->old_y + FixedMul(rendertimefrac, spr->mobj->y - spr->mobj->old_y);
interpz = spr->mobj->old_z + FixedMul(rendertimefrac, spr->mobj->z - spr->mobj->old_z);
}
fixed_t interpx = R_InterpolateFixed(spr->mobj->old_x, spr->mobj->x);
fixed_t interpy = R_InterpolateFixed(spr->mobj->old_y, spr->mobj->y);
fixed_t interpz = R_InterpolateFixed(spr->mobj->old_z, spr->mobj->z);
// hitlag vibrating
if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG))
@ -1636,10 +1629,16 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
if (sprframe->rotate || papersprite)
{
fixed_t anglef = AngleFixed(spr->mobj->angle);
fixed_t anglef = INT32_MAX;
if (spr->mobj->player)
anglef = AngleFixed(spr->mobj->player->drawangle);
{
anglef = AngleFixed(R_InterpolateAngle(spr->mobj->player->old_drawangle, spr->mobj->player->drawangle));
}
else
{
anglef = AngleFixed(R_InterpolateAngle(spr->mobj->old_angle, spr->mobj->angle));
}
p.angley = FIXED_TO_FLOAT(anglef);
}
@ -1671,8 +1670,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
}
}
p.anglez = FIXED_TO_FLOAT(AngleFixed(spr->mobj->pitch));
p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll));
p.anglez = FIXED_TO_FLOAT(AngleFixed(R_InterpolateAngle(spr->mobj->old_pitch, spr->mobj->pitch)));
p.anglex = FIXED_TO_FLOAT(AngleFixed(R_InterpolateAngle(spr->mobj->old_roll, spr->mobj->roll)));
// SRB2CBTODO: MD2 scaling support
finalscale *= FIXED_TO_FLOAT(spr->mobj->scale);

View file

@ -56,6 +56,7 @@
#include "k_kart.h"
#include "k_color.h"
#include "k_hud.h"
#include "r_fps.h"
// coords are scaled
#define HU_INPUTX 0
@ -165,6 +166,8 @@ static tic_t cechotimer = 0;
static tic_t cechoduration = 5*TICRATE;
static INT32 cechoflags = 0;
static tic_t resynch_ticker = 0;
//======================================================================
// HEADS UP INIT
//======================================================================
@ -892,6 +895,60 @@ static inline boolean HU_keyInChatString(char *s, char ch)
//
//
static void HU_TickSongCredits(void)
{
if (cursongcredit.def == NULL) // No def
{
cursongcredit.x = cursongcredit.old_x = 0;
cursongcredit.anim = 0;
cursongcredit.trans = NUMTRANSMAPS;
return;
}
cursongcredit.old_x = cursongcredit.x;
if (cursongcredit.anim > 0)
{
char *str = va("\x1F"" %s", cursongcredit.def->source);
INT32 len = V_ThinStringWidth(str, V_ALLOWLOWERCASE|V_6WIDTHSPACE);
fixed_t destx = (len+7) * FRACUNIT;
if (cursongcredit.trans > 0)
{
cursongcredit.trans--;
}
if (cursongcredit.x < destx)
{
cursongcredit.x += (destx - cursongcredit.x) / 2;
}
if (cursongcredit.x > destx)
{
cursongcredit.x = destx;
}
cursongcredit.anim--;
}
else
{
if (cursongcredit.trans < NUMTRANSMAPS)
{
cursongcredit.trans++;
}
if (cursongcredit.x > 0)
{
cursongcredit.x /= 2;
}
if (cursongcredit.x < 0)
{
cursongcredit.x = 0;
}
}
}
void HU_Ticker(void)
{
if (dedicated)
@ -906,6 +963,49 @@ void HU_Ticker(void)
hu_showscores = false;
hu_keystrokes = false;
if (chat_on)
{
// count down the scroll timer.
if (chat_scrolltime > 0)
chat_scrolltime--;
}
else
{
chat_scrolltime = 0;
}
if (netgame) // would handle that in hu_drawminichat, but it's actually kinda awkward when you're typing a lot of messages. (only handle that in netgames duh)
{
size_t i = 0;
// handle spam while we're at it:
for(; (i<MAXPLAYERS); i++)
{
if (stop_spamming[i] > 0)
stop_spamming[i]--;
}
// handle chat timers
for (i=0; (i<chat_nummsg_min); i++)
{
if (chat_timers[i] > 0)
chat_timers[i]--;
else
HU_removeChatText_Mini();
}
}
cechotimer--;
if (gamestate != GS_LEVEL)
{
return;
}
resynch_ticker++;
HU_TickSongCredits();
}
#ifndef NONET
@ -1887,8 +1987,6 @@ static void HU_DrawCEcho(void)
echoptr = line;
echoptr++;
}
--cechotimer;
}
//
@ -1938,42 +2036,28 @@ static void HU_DrawDemoInfo(void)
void HU_DrawSongCredits(void)
{
char *str;
INT32 len, destx;
INT32 y = (r_splitscreen ? (BASEVIDHEIGHT/2)-4 : 32);
fixed_t x;
fixed_t y = (r_splitscreen ? (BASEVIDHEIGHT/2)-4 : 32) * FRACUNIT;
INT32 bgt;
if (!cursongcredit.def) // No def
{
return;
}
str = va("\x1F"" %s", cursongcredit.def->source);
len = V_ThinStringWidth(str, V_ALLOWLOWERCASE|V_6WIDTHSPACE);
destx = (len+7);
bgt = (NUMTRANSMAPS/2) + (cursongcredit.trans / 2);
x = R_InterpolateFixed(cursongcredit.old_x, cursongcredit.x);
if (cursongcredit.anim)
{
if (cursongcredit.trans > 0)
cursongcredit.trans--;
if (cursongcredit.x < destx)
cursongcredit.x += (destx - cursongcredit.x) / 2;
if (cursongcredit.x > destx)
cursongcredit.x = destx;
cursongcredit.anim--;
}
else
{
if (cursongcredit.trans < NUMTRANSMAPS)
cursongcredit.trans++;
if (cursongcredit.x > 0)
cursongcredit.x /= 2;
if (cursongcredit.x < 0)
cursongcredit.x = 0;
}
bgt = (NUMTRANSMAPS/2)+(cursongcredit.trans/2);
if (bgt < NUMTRANSMAPS)
V_DrawScaledPatch(cursongcredit.x, y-2, V_SNAPTOLEFT|(bgt<<V_ALPHASHIFT), songcreditbg);
{
V_DrawFixedPatch(x, y - (2 * FRACUNIT), FRACUNIT, V_SNAPTOLEFT|(bgt<<V_ALPHASHIFT), songcreditbg, NULL);
}
if (cursongcredit.trans < NUMTRANSMAPS)
V_DrawRightAlignedThinString(cursongcredit.x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
{
V_DrawRightAlignedThinStringAtFixed(x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
}
}
@ -1988,9 +2072,6 @@ void HU_Drawer(void)
// draw chat string plus cursor
if (chat_on)
{
// count down the scroll timer.
if (chat_scrolltime > 0)
chat_scrolltime--;
if (!OLDCHAT)
HU_DrawChat();
else
@ -1999,31 +2080,9 @@ void HU_Drawer(void)
else
{
typelines = 1;
chat_scrolltime = 0;
if (!OLDCHAT && cv_consolechat.value < 2 && netgame) // Don't display minimized chat if you set the mode to Window (Hidden)
HU_drawMiniChat(); // draw messages in a cool fashion.
}
if (netgame) // would handle that in hu_drawminichat, but it's actually kinda awkward when you're typing a lot of messages. (only handle that in netgames duh)
{
size_t i = 0;
// handle spam while we're at it:
for(; (i<MAXPLAYERS); i++)
{
if (stop_spamming[i] > 0)
stop_spamming[i]--;
}
// handle chat timers
for (i=0; (i<chat_nummsg_min); i++)
{
if (chat_timers[i] > 0)
chat_timers[i]--;
else
HU_removeChatText_Mini();
}
}
#endif
if (cechotimer)
@ -2062,12 +2121,10 @@ void HU_Drawer(void)
// draw desynch text
if (hu_redownloadinggamestate)
{
static UINT32 resynch_ticker = 0;
char resynch_text[14];
UINT32 i;
// Animate the dots
resynch_ticker++;
strcpy(resynch_text, "Resynching");
for (i = 0; i < (resynch_ticker / 16) % 4; i++)
strcat(resynch_text, ".");

View file

@ -235,7 +235,7 @@ mobj_t *K_SpawnSphereBox(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 f
(void)amount;
drop->angle = angle;
P_InitAngle(drop, angle);
P_Thrust(drop,
FixedAngle(P_RandomFixed() * 180) + angle,
P_RandomRange(4, 12) * mapobjectscale);
@ -469,16 +469,15 @@ void K_RunPaperItemSpawners(void)
firstUnspawnedEmerald
);
}
else if (P_RandomChance(FRACUNIT/3))
else
{
drop = K_SpawnSphereBox(
spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip),
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
10
);
}
else
{
K_FlipFromObject(drop, spotList[r]);
drop = K_CreatePaperItem(
spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip),
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
@ -529,7 +528,7 @@ static void K_SpawnOvertimeLaser(fixed_t x, fixed_t y, fixed_t scale)
mo->eflags |= MFE_VERTICALFLIP;
}
mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90;
P_InitAngle(mo, R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90);
mo->renderflags |= (RF_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player)));
P_SetScale(mo, scale);

View file

@ -662,7 +662,10 @@ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t
--------------------------------------------------*/
static botprediction_t *K_CreateBotPrediction(player_t *player)
{
const INT16 handling = K_GetKartTurnValue(player, KART_FULLTURN); // Reduce prediction based on how fast you can turn
// Stair janking makes it harder to steer, so attempt to steer harder.
const UINT8 jankDiv = (player->stairjank > 0 ? 2 : 1);
const INT16 handling = K_GetKartTurnValue(player, KART_FULLTURN) / jankDiv; // Reduce prediction based on how fast you can turn
const INT16 normal = KART_FULLTURN; // "Standard" handling to compare to
const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict

View file

@ -382,6 +382,8 @@ static void K_BotItemGenericTap(player_t *player, ticcmd_t *cmd)
--------------------------------------------------*/
static boolean K_BotRevealsGenericTrap(player_t *player, INT16 turnamt, boolean mine)
{
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
if (abs(turnamt) >= KART_FULLTURN/2)
{
// DON'T reveal on turns, we can place bananas on turns whenever we have multiple to spare,
@ -404,7 +406,7 @@ static boolean K_BotRevealsGenericTrap(player_t *player, INT16 turnamt, boolean
}
// Check your behind.
if (K_PlayerInCone(player, player->mo->radius * 16, 10, true) != NULL)
if (K_PlayerInCone(player, coneDist, 15, true) != NULL)
{
return true;
}
@ -536,16 +538,19 @@ static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd)
--------------------------------------------------*/
static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt)
{
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
SINT8 throwdir = -1;
boolean tryLookback = false;
player_t *target = NULL;
player->botvars.itemconfirm++;
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
target = K_PlayerInCone(player, coneDist, 15, true);
if (target != NULL)
{
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
throwdir = -1;
tryLookback = true;
}
if (abs(turnamt) >= KART_FULLTURN/2)
@ -564,7 +569,12 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt)
}
}
if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE)
if (tryLookback == true && throwdir == -1)
{
cmd->buttons |= BT_LOOKBACK;
}
if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE)
{
K_BotGenericPressItem(player, cmd, throwdir);
}
@ -585,12 +595,14 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt)
--------------------------------------------------*/
static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
{
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
SINT8 throwdir = 0;
boolean tryLookback = false;
player_t *target = NULL;
player->botvars.itemconfirm++;
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
target = K_PlayerInCone(player, coneDist, 15, true);
if (target != NULL)
{
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
@ -601,6 +613,7 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
{
player->botvars.itemconfirm += player->botvars.difficulty / 2;
throwdir = -1;
tryLookback = true;
}
else
{
@ -619,7 +632,12 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
}
}
if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE)
if (tryLookback == true && throwdir == -1)
{
cmd->buttons |= BT_LOOKBACK;
}
if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE)
{
K_BotGenericPressItem(player, cmd, throwdir);
}
@ -640,6 +658,7 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
--------------------------------------------------*/
static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
{
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
player_t *target = NULL;
player->botvars.itemconfirm++;
@ -649,13 +668,14 @@ static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
player->botvars.itemconfirm += player->botvars.difficulty / 2;
}
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
target = K_PlayerInCone(player, coneDist, 15, true);
if (target != NULL)
{
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
cmd->buttons |= BT_LOOKBACK;
}
if (player->botvars.itemconfirm > 2*TICRATE)
if (player->botvars.itemconfirm > 10*TICRATE)
{
K_BotGenericPressItem(player, cmd, -1);
}
@ -675,8 +695,10 @@ static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
--------------------------------------------------*/
static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
{
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y);
SINT8 throwdir = -1;
boolean tryLookback = false;
player_t *target = NULL;
player->botvars.itemconfirm++;
@ -688,11 +710,12 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
throwdir = 1;
}
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
target = K_PlayerInCone(player, coneDist, 15, true);
if (target != NULL)
{
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
throwdir = -1;
tryLookback = true;
}
if (stealth > 1 || player->itemroulette > 0)
@ -701,7 +724,12 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
throwdir = -1;
}
if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE)
if (tryLookback == true && throwdir == -1)
{
cmd->buttons |= BT_LOOKBACK;
}
if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE)
{
K_BotGenericPressItem(player, cmd, throwdir);
}
@ -720,6 +748,7 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
--------------------------------------------------*/
static boolean K_BotRevealsEggbox(player_t *player)
{
const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y);
player_t *target = NULL;
@ -737,7 +766,7 @@ static boolean K_BotRevealsEggbox(player_t *player)
}
// Check your behind.
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
target = K_PlayerInCone(player, coneDist, 15, true);
if (target != NULL)
{
return true;
@ -810,8 +839,9 @@ static void K_BotItemEggmanExplosion(player_t *player, ticcmd_t *cmd)
static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
{
const fixed_t topspeed = K_GetKartSpeed(player, false);
fixed_t radius = (player->mo->radius * 32);
fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
SINT8 throwdir = -1;
boolean tryLookback = false;
UINT8 snipeMul = 2;
player_t *target = NULL;
@ -823,24 +853,30 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
player->botvars.itemconfirm++;
target = K_PlayerInCone(player, radius, 10, false);
target = K_PlayerInCone(player, radius, 15, false);
if (target != NULL)
{
K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul);
throwdir = 1;
}
else if (K_PlayerInCone(player, radius, 10, true))
else
{
target = K_PlayerInCone(player, radius, 10, true);
target = K_PlayerInCone(player, radius, 15, true);
if (target != NULL)
{
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
throwdir = -1;
tryLookback = true;
}
}
if (player->botvars.itemconfirm > 5*TICRATE)
if (tryLookback == true && throwdir == -1)
{
cmd->buttons |= BT_LOOKBACK;
}
if (player->botvars.itemconfirm > 25*TICRATE)
{
K_BotGenericPressItem(player, cmd, throwdir);
}
@ -861,8 +897,9 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
static void K_BotItemJawz(player_t *player, ticcmd_t *cmd)
{
const fixed_t topspeed = K_GetKartSpeed(player, false);
fixed_t radius = (player->mo->radius * 32);
fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
SINT8 throwdir = 1;
boolean tryLookback = false;
UINT8 snipeMul = 2;
INT32 lastTarg = player->lastjawztarget;
player_t *target = NULL;
@ -875,11 +912,12 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd)
player->botvars.itemconfirm++;
target = K_PlayerInCone(player, radius, 10, true);
target = K_PlayerInCone(player, radius, 15, true);
if (target != NULL)
{
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
throwdir = -1;
tryLookback = true;
}
if (lastTarg != -1
@ -913,7 +951,12 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd)
}
}
if (player->botvars.itemconfirm > 5*TICRATE)
if (tryLookback == true && throwdir == -1)
{
cmd->buttons |= BT_LOOKBACK;
}
if (player->botvars.itemconfirm > 25*TICRATE)
{
K_BotGenericPressItem(player, cmd, throwdir);
}
@ -1007,7 +1050,7 @@ static void K_BotItemBubble(player_t *player, ticcmd_t *cmd)
}
else if (player->bubbleblowup >= bubbletime)
{
if (player->botvars.itemconfirm >= 10*TICRATE)
if (player->botvars.itemconfirm > 10*TICRATE)
{
hold = true;
}

View file

@ -619,7 +619,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
fixed_t avgX = 0, avgY = 0;
fixed_t avgDist = 0;
const fixed_t baseNudge = 128 * mapobjectscale;
const fixed_t baseNudge = predict->radius;
fixed_t maxNudge = distToPredict;
fixed_t nudgeDist = 0;
angle_t nudgeDir = 0;

View file

@ -17,6 +17,9 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
boolean damageitem = false;
boolean sprung = false;
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
return true;
if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
return true;
@ -108,6 +111,9 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
{
boolean damageitem = false;
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
return true;
if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
return true;
@ -186,6 +192,9 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
{
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
return true;
// Push fakes out of other item boxes
if (t2->type == MT_RANDOMITEM || t2->type == MT_EGGMANITEM)
{
@ -258,6 +267,9 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
{
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
return true;
if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
return true;
@ -331,6 +343,9 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2)
boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
{
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
return true;
if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
return true;
@ -398,6 +413,9 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2)
boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2)
{
if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0))
return true;
if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
return true;
@ -465,7 +483,8 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
{
boolean t1Condition = false;
boolean t2Condition = false;
boolean stung = false;
boolean stungT1 = false;
boolean stungT2 = false;
// Grow damage
t1Condition = (t1->scale > t2->scale + (mapobjectscale/8));
@ -537,25 +556,35 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
if (t1Condition == true)
{
P_PlayerRingBurst(t2->player, 1);
if (t2->player->rings <= 0)
{
P_DamageMobj(t2, t1, t1, 1, DMG_STING);
stung = true;
stungT2 = true;
}
P_PlayerRingBurst(t2->player, 1);
}
if (t2Condition == true)
{
P_PlayerRingBurst(t1->player, 1);
if (t1->player->rings <= 0)
{
P_DamageMobj(t1, t2, t2, 1, DMG_STING);
stung = true;
stungT1 = true;
}
P_PlayerRingBurst(t1->player, 1);
}
return stung;
// No damage hitlag for stinging.
if (stungT1 == true && stungT2 == false)
{
t2->eflags &= ~MFE_DAMAGEHITLAG;
}
else if (stungT2 == true && stungT1 == false)
{
t1->eflags &= ~MFE_DAMAGEHITLAG;
}
return (stungT1 || stungT2);
}

View file

@ -31,6 +31,7 @@
#include "r_main.h"
#include "s_sound.h"
#include "r_things.h"
#include "r_fps.h"
#define NUMPOSNUMS 10
#define NUMPOSFRAMES 7 // White, three blues, three reds
@ -835,48 +836,26 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, UINT8 cameraNu
return;
}
// TODO: needs da interp
// TODO: parts need interp
if (cam->chase == true && !player->spectator)
{
// Use the camera's properties.
viewpointX = cam->x;
viewpointY = cam->y;
viewpointZ = cam->z - point->z;
viewpointAngle = (INT32)cam->angle;
viewpointAiming = (INT32)cam->aiming;
viewpointRoll = (INT32)player->viewrollangle;
if (cv_frameinterpolation.value == 1)
{
viewpointX = cam->old_x + FixedMul(rendertimefrac, cam->x - cam->old_x);
viewpointY = cam->old_y + FixedMul(rendertimefrac, cam->y - cam->old_y);
viewpointZ = (cam->old_z + FixedMul(rendertimefrac, cam->z - cam->old_z)) - point->z;
viewpointAngle = (INT32)(cam->old_angle + FixedMul(rendertimefrac, cam->angle - cam->old_angle));
viewpointAiming = (INT32)(cam->old_aiming + FixedMul(rendertimefrac, cam->aiming - cam->old_aiming));
viewpointRoll = (INT32)(player->old_viewrollangle + FixedMul(rendertimefrac, player->viewrollangle - player->old_viewrollangle));
}
viewpointX = R_InterpolateFixed(cam->old_x, cam->x);
viewpointY = R_InterpolateFixed(cam->old_y, cam->y);
viewpointZ = R_InterpolateFixed(cam->old_z, cam->z) - point->z;
viewpointAngle = (INT32)R_InterpolateAngle(cam->old_angle, cam->angle);
viewpointAiming = (INT32)R_InterpolateAngle(cam->old_aiming, cam->aiming);
viewpointRoll = (INT32)R_InterpolateAngle(player->old_viewrollangle, player->viewrollangle);
}
else
{
// Use player properties.
viewpointX = player->mo->x;
viewpointY = player->mo->y;
viewpointZ = player->viewz - point->z;
viewpointAngle = (INT32)player->mo->angle;
viewpointX = R_InterpolateFixed(player->mo->old_x, player->mo->x);
viewpointY = R_InterpolateFixed(player->mo->old_y, player->mo->y);
viewpointZ = R_InterpolateFixed(player->mo->old_z, player->mo->z) - point->z; //player->old_viewz
viewpointAngle = (INT32)R_InterpolateAngle(player->mo->old_angle, player->mo->angle);
viewpointAiming = (INT32)player->aiming;
viewpointRoll = (INT32)player->viewrollangle;
if (cv_frameinterpolation.value == 1)
{
viewpointX = player->mo->old_x + FixedMul(rendertimefrac, player->mo->x - player->mo->old_x);
viewpointY = player->mo->old_y + FixedMul(rendertimefrac, player->mo->y - player->mo->old_y);
viewpointZ = (player->mo->old_z + FixedMul(rendertimefrac, player->viewz - player->mo->old_z)) - point->z; //player->old_viewz
viewpointAngle = (INT32)(player->mo->old_angle + FixedMul(rendertimefrac, player->mo->angle - player->mo->old_angle));
//viewpointAiming = (INT32)(player->mo->old_aiming + FixedMul(rendertimefrac, player->mo->aiming - player->mo->old_aiming));
viewpointRoll = (INT32)(player->old_viewrollangle + FixedMul(rendertimefrac, player->viewrollangle - player->old_viewrollangle));
}
viewpointRoll = (INT32)R_InterpolateAngle(player->old_viewrollangle, player->viewrollangle);
}
viewpointAngle += (INT32)angleOffset;
@ -2631,24 +2610,13 @@ static void K_drawKartPlayerCheck(void)
continue;
}
v.x = checkplayer->mo->x;
v.y = checkplayer->mo->y;
v.z = checkplayer->mo->z;
v.x = R_InterpolateFixed(checkplayer->mo->old_x, checkplayer->mo->x);
v.y = R_InterpolateFixed(checkplayer->mo->old_y, checkplayer->mo->y);
v.z = R_InterpolateFixed(checkplayer->mo->old_z, checkplayer->mo->z);
pPos.x = stplyr->mo->x;
pPos.y = stplyr->mo->y;
pPos.z = stplyr->mo->z;
if (cv_frameinterpolation.value == 1)
{
v.x = checkplayer->mo->old_x + FixedMul(rendertimefrac, checkplayer->mo->x - checkplayer->mo->old_x);
v.y = checkplayer->mo->old_y + FixedMul(rendertimefrac, checkplayer->mo->y - checkplayer->mo->old_y);
v.z = checkplayer->mo->old_z + FixedMul(rendertimefrac, checkplayer->mo->z - checkplayer->mo->old_z);
pPos.x = stplyr->mo->old_x + FixedMul(rendertimefrac, stplyr->mo->x - stplyr->mo->old_x);
pPos.y = stplyr->mo->old_y + FixedMul(rendertimefrac, stplyr->mo->y - stplyr->mo->old_y);
pPos.z = stplyr->mo->old_z + FixedMul(rendertimefrac, stplyr->mo->z - stplyr->mo->old_z);
}
pPos.x = R_InterpolateFixed(stplyr->mo->old_x, stplyr->mo->x);
pPos.y = R_InterpolateFixed(stplyr->mo->old_y, stplyr->mo->y);
pPos.z = R_InterpolateFixed(stplyr->mo->old_z, stplyr->mo->z);
distance = R_PointToDist2(pPos.x, pPos.y, v.x, v.y);
@ -2834,29 +2802,15 @@ static void K_drawKartNameTags(void)
if (thiscam->chase == true)
{
c.x = thiscam->x;
c.y = thiscam->y;
c.z = thiscam->z;
if (cv_frameinterpolation.value == 1)
{
c.x = thiscam->old_x + FixedMul(rendertimefrac, thiscam->x - thiscam->old_x);
c.y = thiscam->old_y + FixedMul(rendertimefrac, thiscam->y - thiscam->old_y);
c.z = thiscam->old_z + FixedMul(rendertimefrac, thiscam->z - thiscam->old_z);
}
c.x = R_InterpolateFixed(thiscam->old_x, thiscam->x);
c.y = R_InterpolateFixed(thiscam->old_y, thiscam->y);
c.z = R_InterpolateFixed(thiscam->old_z, thiscam->z);
}
else
{
c.x = stplyr->mo->x;
c.y = stplyr->mo->y;
c.z = stplyr->mo->z;
if (cv_frameinterpolation.value == 1)
{
c.x = stplyr->mo->old_x + FixedMul(rendertimefrac, stplyr->mo->x - stplyr->mo->old_x);
c.y = stplyr->mo->old_y + FixedMul(rendertimefrac, stplyr->mo->y - stplyr->mo->old_y);
c.z = stplyr->mo->old_z + FixedMul(rendertimefrac, stplyr->mo->z - stplyr->mo->old_z);
}
c.x = R_InterpolateFixed(stplyr->mo->old_x, stplyr->mo->x);
c.y = R_InterpolateFixed(stplyr->mo->old_y, stplyr->mo->y);
c.z = R_InterpolateFixed(stplyr->mo->old_z, stplyr->mo->z);
}
for (i = 0; i < MAXPLAYERS; i++)
@ -2895,16 +2849,9 @@ static void K_drawKartNameTags(void)
continue;
}
v.x = ntplayer->mo->x;
v.y = ntplayer->mo->y;
v.z = ntplayer->mo->z;
if (cv_frameinterpolation.value == 1)
{
v.x = ntplayer->mo->old_x + FixedMul(rendertimefrac, ntplayer->mo->x - ntplayer->mo->old_x);
v.y = ntplayer->mo->old_y + FixedMul(rendertimefrac, ntplayer->mo->y - ntplayer->mo->old_y);
v.z = ntplayer->mo->old_z + FixedMul(rendertimefrac, ntplayer->mo->z - ntplayer->mo->old_z);
}
v.x = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x);
v.y = R_InterpolateFixed(ntplayer->mo->old_y, ntplayer->mo->y);
v.z = R_InterpolateFixed(ntplayer->mo->old_z, ntplayer->mo->z);
if (!(ntplayer->mo->eflags & MFE_VERTICALFLIP))
{
@ -2959,16 +2906,9 @@ static void K_drawKartNameTags(void)
SINT8 localindicator = -1;
vector3_t v;
v.x = ntplayer->mo->x;
v.y = ntplayer->mo->y;
v.z = ntplayer->mo->z;
if (cv_frameinterpolation.value == 1)
{
v.x = ntplayer->mo->old_x + FixedMul(rendertimefrac, ntplayer->mo->x - ntplayer->mo->old_x);
v.y = ntplayer->mo->old_y + FixedMul(rendertimefrac, ntplayer->mo->y - ntplayer->mo->old_y);
v.z = ntplayer->mo->old_z + FixedMul(rendertimefrac, ntplayer->mo->z - ntplayer->mo->old_z);
}
v.x = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x);
v.y = R_InterpolateFixed(ntplayer->mo->old_y, ntplayer->mo->y);
v.z = R_InterpolateFixed(ntplayer->mo->old_z, ntplayer->mo->z);
v.z += (ntplayer->mo->height / 2);
@ -3208,14 +3148,8 @@ static void K_drawKartMinimap(void)
else
colormap = NULL;
interpx = g->mo->x;
interpy = g->mo->y;
if (cv_frameinterpolation.value == 1)
{
interpx = g->mo->old_x + FixedMul(rendertimefrac, g->mo->x - g->mo->old_x);
interpy = g->mo->old_y + FixedMul(rendertimefrac, g->mo->y - g->mo->old_y);
}
interpx = R_InterpolateFixed(g->mo->old_x, g->mo->x);
interpy = R_InterpolateFixed(g->mo->old_y, g->mo->y);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
g = g->next;
@ -3273,14 +3207,8 @@ static void K_drawKartMinimap(void)
else
colormap = NULL;
interpx = players[i].mo->x;
interpy = players[i].mo->y;
if (cv_frameinterpolation.value == 1)
{
interpx = players[i].mo->old_x + FixedMul(rendertimefrac, players[i].mo->x - players[i].mo->old_x);
interpy = players[i].mo->old_y + FixedMul(rendertimefrac, players[i].mo->y - players[i].mo->old_y);
}
interpx = R_InterpolateFixed(players[i].mo->old_x, players[i].mo->x);
interpy = R_InterpolateFixed(players[i].mo->old_y, players[i].mo->y);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
// Target reticule
@ -3308,14 +3236,8 @@ static void K_drawKartMinimap(void)
colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE);
}
interpx = mobj->x;
interpy = mobj->y;
if (cv_frameinterpolation.value == 1)
{
interpx = mobj->old_x + FixedMul(rendertimefrac, mobj->x - mobj->old_x);
interpy = mobj->old_y + FixedMul(rendertimefrac, mobj->y - mobj->old_y);
}
interpx = R_InterpolateFixed(mobj->old_x, mobj->x);
interpy = R_InterpolateFixed(mobj->old_y, mobj->y);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_spbminimap, colormap, AutomapPic);
}
@ -3345,14 +3267,8 @@ static void K_drawKartMinimap(void)
else
colormap = NULL;
interpx = players[localplayers[i]].mo->x;
interpy = players[localplayers[i]].mo->y;
if (cv_frameinterpolation.value == 1)
{
interpx = players[localplayers[i]].mo->old_x + FixedMul(rendertimefrac, players[localplayers[i]].mo->x - players[localplayers[i]].mo->old_x);
interpy = players[localplayers[i]].mo->old_y + FixedMul(rendertimefrac, players[localplayers[i]].mo->y - players[localplayers[i]].mo->old_y);
}
interpx = R_InterpolateFixed(players[localplayers[i]].mo->old_x, players[localplayers[i]].mo->x);
interpy = R_InterpolateFixed(players[localplayers[i]].mo->old_y, players[localplayers[i]].mo->y);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic);
@ -3631,7 +3547,7 @@ static void K_drawKartFinish(void)
x = ((TICRATE - stplyr->karthud[khud_cardanimation])*(xval > x ? xval : x))/TICRATE;
ox = ((TICRATE - (stplyr->karthud[khud_cardanimation] - 1))*(xval > x ? xval : x))/TICRATE;
interpx = ox + FixedMul(rendertimefrac, x - ox);
interpx = R_InterpolateFixed(ox, x);
if (r_splitscreen && stplyr == &players[displayplayers[1]])
interpx = -interpx;
@ -4028,7 +3944,7 @@ static void K_drawLapStartAnim(void)
const UINT8 t = stplyr->karthud[khud_lapanimation];
const UINT8 progress = 80 - t;
const UINT8 tOld = t - 1;
const UINT8 tOld = t + 1;
const UINT8 progressOld = 80 - tOld;
const tic_t leveltimeOld = leveltime - 1;
@ -4039,11 +3955,11 @@ static void K_drawLapStartAnim(void)
newval = (BASEVIDWIDTH/2 + (32 * max(0, t - 76))) * FRACUNIT;
oldval = (BASEVIDWIDTH/2 + (32 * max(0, tOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
interpx = R_InterpolateFixed(oldval, newval);
newval = (48 - (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (48 - (32 * max(0, progressOld - 76))) * FRACUNIT;
interpy = oldval + FixedMul(rendertimefrac, newval - oldval);
interpy = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, interpy,
@ -4054,7 +3970,7 @@ static void K_drawLapStartAnim(void)
{
newval = (4 - abs((signed)((leveltime % 8) - 4))) * FRACUNIT;
oldval = (4 - abs((signed)((leveltimeOld % 8) - 4))) * FRACUNIT;
interpy += oldval + FixedMul(rendertimefrac, newval - oldval);
interpy += R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, interpy,
@ -4066,7 +3982,7 @@ static void K_drawLapStartAnim(void)
{
newval = (62 - (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (62 - (32 * max(0, progressOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
interpx = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, // 27
@ -4078,7 +3994,7 @@ static void K_drawLapStartAnim(void)
{
newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
interpx = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, // 194
@ -4091,7 +4007,7 @@ static void K_drawLapStartAnim(void)
{
newval = (82 - (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (82 - (32 * max(0, progressOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
interpx = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, // 61
@ -4103,7 +4019,7 @@ static void K_drawLapStartAnim(void)
{
newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
interpx = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, // 194
@ -4115,7 +4031,7 @@ static void K_drawLapStartAnim(void)
{
newval = (208 + (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (208 + (32 * max(0, progressOld - 76))) * FRACUNIT;
interpx = oldval + FixedMul(rendertimefrac, newval - oldval);
interpx = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, // 221

View file

@ -33,6 +33,7 @@
#include "k_waypoint.h"
#include "k_bot.h"
#include "k_hud.h"
#include "k_terrain.h"
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
@ -1605,6 +1606,7 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo)
}
}
return 0; // couldn't find any offroad
}
@ -1616,7 +1618,17 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo)
*/
static void K_UpdateOffroad(player_t *player)
{
fixed_t offroadstrength = (K_CheckOffroadCollide(player->mo) << FRACBITS);
terrain_t *terrain = player->mo->terrain;
fixed_t offroadstrength = 0;
if (terrain != NULL && terrain->offroad > 0)
{
offroadstrength = (terrain->offroad << FRACBITS);
}
else
{
offroadstrength = (K_CheckOffroadCollide(player->mo) << FRACBITS);
}
// If you are in offroad, a timer starts.
if (offroadstrength)
@ -1709,6 +1721,7 @@ static void K_UpdateDraft(player_t *player)
{
fixed_t topspd = K_GetKartSpeed(player, false);
fixed_t draftdistance;
fixed_t minDist;
UINT8 leniency;
UINT8 i;
@ -1728,6 +1741,13 @@ static void K_UpdateDraft(player_t *player)
draftdistance = FixedMul(draftdistance, K_GetKartGameSpeedScalar(gamespeed));
}
minDist = 640 * player->mo->scale;
if (gametype == GT_BATTLE)
{
// TODO: gametyperules
minDist /= 4;
}
// On the contrary, the leniency period biases toward high weight.
// (See also: the leniency variable in K_SpawnDraftDust)
leniency = (3*TICRATE)/4 + ((player->kartweight-1) * (TICRATE/4));
@ -1786,7 +1806,7 @@ static void K_UpdateDraft(player_t *player)
#ifndef EASYDRAFTTEST
// TOO close to draft.
if (dist < FixedMul(RING_DIST>>1, player->mo->scale))
if (dist < minDist)
continue;
// Not close enough to draft.
@ -1963,7 +1983,7 @@ void K_SpawnDashDustRelease(player_t *player)
dust = P_SpawnMobj(newx, newy, player->mo->z, MT_FASTDUST);
P_SetTarget(&dust->target, player->mo);
dust->angle = travelangle - ((i&1) ? -1 : 1)*ANGLE_45;
P_InitAngle(dust, travelangle - ((i&1) ? -1 : 1) * ANGLE_45);
dust->destscale = player->mo->scale;
P_SetScale(dust, player->mo->scale);
@ -2043,7 +2063,7 @@ void K_SpawnNormalSpeedLines(player_t *player)
MT_FASTLINE);
P_SetTarget(&fast->target, player->mo);
fast->angle = K_MomentumAngle(player->mo);
P_InitAngle(fast, K_MomentumAngle(player->mo));
fast->momx = 3*player->mo->momx/4;
fast->momy = 3*player->mo->momy/4;
fast->momz = 3*P_GetMobjZMovement(player->mo)/4;
@ -2071,7 +2091,7 @@ void K_SpawnInvincibilitySpeedLines(mobj_t *mo)
fast->momz = 3*P_GetMobjZMovement(mo)/4;
P_SetTarget(&fast->target, mo);
fast->angle = K_MomentumAngle(mo);
P_InitAngle(fast, K_MomentumAngle(mo));
fast->color = mo->color;
fast->colorized = true;
K_MatchGenericExtraFlags(fast, mo);
@ -2211,19 +2231,19 @@ void K_KartMoveAnimation(player_t *player)
SINT8 destGlanceDir = 0;
SINT8 drift = player->drift;
// Uses turning over steering -- it's important to show player feedback immediately.
if (player->cmd.turning < -minturn)
{
turndir = -1;
}
else if (player->cmd.turning > minturn)
{
turndir = 1;
}
if (!lookback)
{
player->pflags &= ~PF_LOOKDOWN;
// Uses turning over steering -- it's important to show player feedback immediately.
if (player->cmd.turning < -minturn)
{
turndir = -1;
}
else if (player->cmd.turning > minturn)
{
turndir = 1;
}
}
else if (drift == 0)
{
@ -2854,6 +2874,13 @@ static void K_GetKartBoostPower(player_t *player)
{
// 30% - 44%, each point of speed adds 1.75%
fixed_t draftspeed = ((3*FRACUNIT)/10) + ((player->kartspeed-1) * ((7*FRACUNIT)/400));
if (gametype == GT_BATTLE)
{
// TODO: gametyperules
draftspeed *= 2;
}
speedboost += FixedMul(draftspeed, player->draftpower); // (Drafting suffers no boost stack penalty.)
numboosts++;
}
@ -2950,11 +2977,18 @@ UINT16 K_GetKartFlashing(player_t *player)
{
UINT16 tics = flashingtics;
if (!player)
if (gametype == GT_BATTLE)
{
// TODO: gametyperules
return 1;
}
if (player == NULL)
{
return tics;
}
tics += (tics/8) * (player->kartspeed);
return tics;
}
@ -3136,9 +3170,15 @@ void K_DoInstashield(player_t *player)
S_StartSound(player->mo, sfx_cdpcm9);
layera = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INSTASHIELDA);
layera->old_x = player->mo->old_x;
layera->old_y = player->mo->old_y;
layera->old_z = player->mo->old_z;
P_SetTarget(&layera->target, player->mo);
layerb = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INSTASHIELDB);
layerb->old_x = player->mo->old_x;
layerb->old_y = player->mo->old_y;
layerb->old_z = player->mo->old_z;
P_SetTarget(&layerb->target, player->mo);
}
@ -3441,13 +3481,14 @@ void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers)
karmahitbox->destscale = player->mo->destscale;
P_SetScale(karmahitbox, player->mo->scale);
player->karmadelay = comebacktime;
if (netgame)
{
CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]);
}
}
player->karmadelay = comebacktime;
K_CalculateBattleWanted();
K_CheckBumpers();
}
@ -3519,7 +3560,7 @@ void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount)
P_SetTarget(&newmo->tracer, victim->mo);
P_SetTarget(&newmo->target, player->mo);
newmo->angle = (diff * (newbumper-1));
P_InitAngle(newmo, (diff * (newbumper-1)));
newmo->color = victim->skincolor;
if (newbumper+1 < 2)
@ -3600,7 +3641,7 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32
mobj->z -= mobj->height>>1;
// change angle
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, x, y);
P_InitAngle(mobj, R_PointToAngle2(mobj->x, mobj->y, x, y));
// change slope
dist = P_AproxDistance(P_AproxDistance(x - mobj->x, y - mobj->y), z - mobj->z);
@ -3687,7 +3728,7 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
{
dust = P_SpawnMobj(source->x, source->y, source->z, MT_SMOKE);
P_SetMobjState(dust, S_OPAQUESMOKE1);
dust->angle = (ANGLE_180/16) * i;
P_InitAngle(dust, (ANGLE_180/16) * i);
P_SetScale(dust, source->scale);
dust->destscale = source->scale*10;
dust->scalespeed = source->scale/12;
@ -3800,7 +3841,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
th->z = th->floorz;
}
th->angle = an;
P_InitAngle(th, an);
th->momx = FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT));
th->momy = FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT));
@ -3968,7 +4009,10 @@ static void K_SpawnDriftElectricity(player_t *player)
y = P_ReturnThrustY(mo, verticalangle, verticalradius)
+ P_ReturnThrustY(mo, horizonatalangle, horizontalradius);
spark = P_SpawnMobjFromMobj(mo, x, y, 0, MT_DRIFTELECTRICITY);
spark->angle = sparkangle;
P_InitAngle(spark, sparkangle);
spark->momx = mo->momx;
spark->momy = mo->momy;
spark->momz = mo->momz;
spark->color = color;
K_GenericExtraFlagsNoZAdjust(spark, mo);
@ -4010,7 +4054,7 @@ void K_SpawnDriftElectricSparks(player_t *player)
fixed_t yoff = P_ReturnThrustY(mo, sparkangle, sparkradius);
mobj_t *spark = P_SpawnMobjFromMobj(mo, x + xoff, y + yoff, z, MT_DRIFTELECTRICSPARK);
spark->angle = sparkangle;
P_InitAngle(spark, sparkangle);
spark->color = color;
P_InstaThrust(spark, mo->angle + ANGLE_90, hspeed);
P_SetObjectMomZ(spark, vspeed, false);
@ -4061,7 +4105,7 @@ static void K_SpawnDriftSparks(player_t *player)
spark = P_SpawnMobj(newx, newy, player->mo->z, MT_DRIFTSPARK);
P_SetTarget(&spark->target, player->mo);
spark->angle = travelangle-(ANGLE_45/5)*player->drift;
P_InitAngle(spark, travelangle-(ANGLE_45/5)*player->drift);
spark->destscale = player->mo->scale;
P_SetScale(spark, player->mo->scale);
@ -4205,7 +4249,7 @@ static void K_SpawnAIZDust(player_t *player)
newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle - (player->aizdriftstrat*ANGLE_45), FixedMul(24*FRACUNIT, player->mo->scale));
spark = P_SpawnMobj(newx, newy, player->mo->z, MT_AIZDRIFTSTRAT);
spark->angle = travelangle+(player->aizdriftstrat*ANGLE_90);
P_InitAngle(spark, travelangle+(player->aizdriftstrat*ANGLE_90));
P_SetScale(spark, (spark->destscale = (3*player->mo->scale)>>2));
spark->momx = (6*player->mo->momx)/5;
@ -4257,7 +4301,7 @@ void K_SpawnBoostTrail(player_t *player)
flame = P_SpawnMobj(newx, newy, ground, MT_SNEAKERTRAIL);
P_SetTarget(&flame->target, player->mo);
flame->angle = travelangle;
P_InitAngle(flame, travelangle);
flame->fuse = TICRATE*2;
flame->destscale = player->mo->scale;
P_SetScale(flame, player->mo->scale);
@ -4313,7 +4357,7 @@ void K_SpawnSparkleTrail(mobj_t *mo)
newz = mo->z + (P_RandomRange(0, mo->height>>FRACBITS)*FRACUNIT);
sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL);
sparkle->angle = R_PointToAngle2(mo->x, mo->y, sparkle->x, sparkle->y);
P_InitAngle(sparkle, R_PointToAngle2(mo->x, mo->y, sparkle->x, sparkle->y));
sparkle->movefactor = R_PointToDist2(mo->x, mo->y, sparkle->x, sparkle->y); // Save the distance we spawned away from the player.
//CONS_Printf("movefactor: %d\n", sparkle->movefactor/FRACUNIT);
sparkle->extravalue1 = (sparkle->z - mo->z); // Keep track of our Z position relative to the player's, I suppose.
@ -4336,7 +4380,7 @@ void K_SpawnSparkleTrail(mobj_t *mo)
sparkle->color = mo->color;
}
void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad)
void K_SpawnWipeoutTrail(mobj_t *mo)
{
mobj_t *dust;
angle_t aoff;
@ -4359,17 +4403,10 @@ void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad)
mo->z, MT_WIPEOUTTRAIL);
P_SetTarget(&dust->target, mo);
dust->angle = K_MomentumAngle(mo);
P_InitAngle(dust, K_MomentumAngle(mo));
dust->destscale = mo->scale;
P_SetScale(dust, mo->scale);
K_FlipFromObject(dust, mo);
if (offroad) // offroad effect
{
dust->momx = mo->momx/2;
dust->momy = mo->momy/2;
dust->momz = P_GetMobjZMovement(mo)/2;
}
}
void K_SpawnDraftDust(mobj_t *mo)
@ -4429,7 +4466,7 @@ void K_SpawnDraftDust(mobj_t *mo)
P_SetMobjState(dust, S_DRAFTDUST1 + foff);
P_SetTarget(&dust->target, mo);
dust->angle = ang - (ANGLE_90 * sign); // point completely perpendicular from the player
P_InitAngle(dust, ang - (ANGLE_90 * sign)); // point completely perpendicular from the player
dust->destscale = mo->scale;
P_SetScale(dust, mo->scale);
K_FlipFromObject(dust, mo);
@ -4852,11 +4889,18 @@ void K_PuntMine(mobj_t *origMine, mobj_t *punter)
mine = P_SpawnMobj(origMine->x, origMine->y, origMine->z, MT_SSMINE);
P_SetTarget(&mine->target, mineOwner);
mine->angle = origMine->angle;
mine->flags2 = origMine->flags2;
mine->floorz = origMine->floorz;
mine->ceilingz = origMine->ceilingz;
// Copy interp data
mine->old_angle = origMine->old_angle;
mine->old_x = origMine->old_x;
mine->old_y = origMine->old_y;
mine->old_z = origMine->old_z;
// Since we aren't using P_KillMobj, we need to clean up the hnext reference
P_SetTarget(&mineOwner->hnext, NULL);
mineOwner->player->bananadrag = 0;
@ -4932,7 +4976,7 @@ static void K_DoThunderShield(player_t *player)
for (i=0; i<7; i++)
{
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK);
mo->angle = P_RandomRange(0, 359)*ANG1;
P_InitAngle(mo, P_RandomRange(0, 359)*ANG1);
mo->fuse = P_RandomRange(20, 50);
P_SetTarget(&mo->target, player->mo);
P_SetMobjState(mo, S_KLIT1);
@ -4945,7 +4989,7 @@ static void K_DoThunderShield(player_t *player)
sx = player->mo->x + FixedMul((player->mo->scale*THUNDERRADIUS), FINECOSINE((an*i)>>ANGLETOFINESHIFT));
sy = player->mo->y + FixedMul((player->mo->scale*THUNDERRADIUS), FINESINE((an*i)>>ANGLETOFINESHIFT));
mo = P_SpawnMobj(sx, sy, player->mo->z, MT_THOK);
mo-> angle = an*i;
P_InitAngle(mo, an*i);
mo->extravalue1 = THUNDERRADIUS; // Used to know whether we should teleport by radius or something.
mo->scale = player->mo->scale*3;
P_SetTarget(&mo->target, player->mo);
@ -5058,7 +5102,7 @@ void K_DoSneaker(player_t *player, INT32 type)
{
const fixed_t intendedboost = FRACUNIT/2;
if (!player->floorboost || player->floorboost == 3)
if (player->floorboost == 0 || player->floorboost == 3)
{
const sfxenum_t normalsfx = sfx_cdfm01;
const sfxenum_t smallsfx = sfx_cdfm40;
@ -5081,7 +5125,7 @@ void K_DoSneaker(player_t *player, INT32 type)
player->numsneakers++;
}
if (!player->sneakertimer)
if (player->sneakertimer == 0)
{
if (type == 2)
{
@ -5115,13 +5159,12 @@ void K_DoSneaker(player_t *player, INT32 type)
{
player->pflags |= PF_ATTACKDOWN;
K_PlayBoostTaunt(player->mo);
}
player->sneakertimer = sneakertime;
// set angle for spun out players:
player->boostangle = (INT32)player->mo->angle;
player->boostangle = player->mo->angle;
}
static void K_DoShrink(player_t *user)
@ -5203,6 +5246,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
return;
mo->standingslope = NULL;
mo->terrain = NULL;
mo->eflags |= MFE_SPRUNG;
@ -5263,7 +5307,7 @@ static void K_ThrowLandMine(player_t *player)
P_SetScale(landMine, player->mo->scale);
landMine->destscale = player->mo->destscale;
landMine->angle = player->mo->angle;
P_InitAngle(landMine, player->mo->angle);
landMine->momz = (30 * mapobjectscale * P_MobjFlip(player->mo)) + player->mo->momz;
landMine->color = player->skincolor;
@ -5419,6 +5463,12 @@ void K_DropHnextList(player_t *player, boolean keepshields)
dropwork->floorz = work->floorz;
dropwork->ceilingz = work->ceilingz;
// Copy interp data
dropwork->old_angle = work->old_angle;
dropwork->old_x = work->old_x;
dropwork->old_y = work->old_y;
dropwork->old_z = work->old_z;
if (ponground)
{
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
@ -5506,7 +5556,7 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8
P_SetScale(drop, drop->scale>>4);
drop->destscale = (3*drop->destscale)/2;
drop->angle = angle;
P_InitAngle(drop, angle);
P_Thrust(drop,
FixedAngle(P_RandomFixed() * 180) + angle,
16*mapobjectscale);
@ -6640,7 +6690,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
// update boost angle if not spun out
if (!player->spinouttimer && !player->wipeoutslow)
player->boostangle = (INT32)player->mo->angle;
player->boostangle = player->mo->angle;
K_GetKartBoostPower(player);
@ -6688,16 +6738,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
ghost->renderflags |= RF_DONTDRAW;
}
// Could probably be moved somewhere else.
K_HandleFootstepParticles(player->mo);
if (P_IsObjectOnGround(player->mo))
{
// Offroad dust
if (player->boostpower < FRACUNIT)
{
K_SpawnWipeoutTrail(player->mo, true);
if (leveltime % 6 == 0)
S_StartSound(player->mo, sfx_cdfm70);
}
// Draft dust
if (player->draftpower >= FRACUNIT)
{
@ -6913,7 +6958,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->sneakertimer && player->wipeoutslow > 0 && player->wipeoutslow < wipeoutslowtime+1)
player->wipeoutslow = wipeoutslowtime+1;
if (player->floorboost)
if (player->floorboost > 0)
player->floorboost--;
if (player->driftboost)
@ -6956,7 +7001,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
{
mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING);
ring->extravalue1 = 1; // Ring collect animation timer
ring->angle = player->mo->angle; // animation angle
P_InitAngle(ring, player->mo->angle); // animation angle
P_SetTarget(&ring->target, player->mo); // toucher for thinker
player->pickuprings++;
if (player->superring <= 3)
@ -7148,6 +7193,9 @@ void K_KartPlayerAfterThink(player_t *player)
}
ret = P_SpawnMobj(targ->mo->x, targ->mo->y, targ->mo->z, MT_PLAYERRETICULE);
ret->old_x = targ->mo->old_x;
ret->old_y = targ->mo->old_y;
ret->old_z = targ->mo->old_z;
P_SetTarget(&ret->target, targ->mo);
ret->frame |= ((leveltime % 10) / 2);
ret->tics = 1;
@ -7768,6 +7816,7 @@ void K_SpawnDriftBoostExplosion(player_t *player, int stage)
{
mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_DRIFTEXPLODE);
P_InitAngle(overlay, K_MomentumAngle(player->mo));
P_SetTarget(&overlay->target, player->mo);
P_SetScale(overlay, (overlay->destscale = player->mo->scale));
K_FlipFromObject(overlay, player->mo);
@ -8313,9 +8362,9 @@ static void K_KartSpindashWind(mobj_t *parent)
P_SetTarget(&wind->target, parent);
if (parent->momx || parent->momy)
wind->angle = R_PointToAngle2(0, 0, parent->momx, parent->momy);
P_InitAngle(wind, R_PointToAngle2(0, 0, parent->momx, parent->momy));
else
wind->angle = parent->player->drawangle;
P_InitAngle(wind, parent->player->drawangle);
wind->momx = 3 * parent->momx / 4;
wind->momy = 3 * parent->momy / 4;
@ -8348,7 +8397,7 @@ static void K_KartSpindash(player_t *player)
mobj_t *grease;
grease = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_TIREGREASE);
P_SetTarget(&grease->target, player->mo);
grease->angle = K_MomentumAngle(player->mo);
P_InitAngle(grease, K_MomentumAngle(player->mo));
grease->extravalue1 = i;
}
}
@ -8762,7 +8811,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ROCKETSNEAKER);
K_MatchGenericExtraFlags(mo, player->mo);
mo->flags |= MF_NOCLIPTHING;
mo->angle = player->mo->angle;
P_InitAngle(mo, player->mo->angle);
mo->threshold = 10;
mo->movecount = moloop%2;
mo->movedir = mo->lastlook = moloop+1;
@ -8872,7 +8921,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
break;
}
mo->flags |= MF_NOCLIPTHING;
mo->angle = newangle;
P_InitAngle(mo, newangle);
mo->threshold = 10;
mo->movecount = player->itemamount;
mo->movedir = mo->lastlook = moloop+1;
@ -8913,7 +8962,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
break;
}
mo->flags |= MF_NOCLIPTHING;
mo->angle = newangle;
P_InitAngle(mo, newangle);
mo->threshold = 10;
mo->movecount = player->itemamount;
mo->movedir = mo->lastlook = moloop+1;
@ -9309,7 +9358,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
spdl = P_SpawnMobj(sx, sy, sz, MT_FASTLINE);
P_SetTarget(&spdl->target, player->mo);
spdl->angle = R_PointToAngle2(spdl->x, spdl->y, player->mo->x, player->mo->y);
P_InitAngle(spdl, R_PointToAngle2(spdl->x, spdl->y, player->mo->x, player->mo->y));
spdl->rollangle = -ANG1*90*P_MobjFlip(player->mo); // angle them downwards relative to the player's gravity...
spdl->spriteyscale = player->trickboostpower+FRACUNIT;
spdl->momx = player->mo->momx;

View file

@ -76,7 +76,7 @@ void K_RunFinishLineBeam(void);
UINT16 K_DriftSparkColor(player_t *player, INT32 charge);
void K_SpawnBoostTrail(player_t *player);
void K_SpawnSparkleTrail(mobj_t *mo);
void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad);
void K_SpawnWipeoutTrail(mobj_t *mo);
void K_SpawnDraftDust(mobj_t *mo);
void K_DriftDustHandling(mobj_t *spawner);
void K_Squish(mobj_t *mo);

View file

@ -370,7 +370,7 @@ static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t *
P_SetMobjState(end1, S_FINISHBEAMEND1);
end1->renderflags = RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]);
end1->angle = lineangle;
P_InitAngle(end1, lineangle);
end2 = P_SpawnMobj(
v->x + (8*sx),
@ -381,7 +381,7 @@ static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t *
P_SetMobjState(end2, S_FINISHBEAMEND2);
end2->renderflags = RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]);
end2->angle = lineangle;
P_InitAngle(end2, lineangle);
P_SetTarget(&end2->tracer, end1);
end2->flags2 |= MF2_LINKDRAW;

View file

@ -582,7 +582,7 @@ static void K_MovePlayerToRespawnPoint(player_t *player)
P_SetTarget(&lasermo->target, player->mo);
lasermo->angle = stepha + ANGLE_90;
P_InitAngle(lasermo, stepha + ANGLE_90);
P_SetScale(lasermo, (lasermo->destscale = player->mo->scale));
}
}
@ -645,7 +645,7 @@ static void K_DropDashWait(player_t *player)
P_SetTarget(&laser->target, player->mo);
laser->angle = newangle + ANGLE_90;
P_InitAngle(laser, newangle + ANGLE_90);
laser->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo);
P_SetScale(laser, (laser->destscale = player->mo->scale));
}

1532
src/k_terrain.c Normal file

File diff suppressed because it is too large Load diff

459
src/k_terrain.h Normal file
View file

@ -0,0 +1,459 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2021 by ZDoom + GZDoom teams, and contributors
// Copyright (C) 2021 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2021 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 k_terrain.h
/// \brief Implementation of a TERRAIN-style lump for DRRR, ala GZDoom's codebase.
#ifndef __K_TERRAIN_H__
#define __K_TERRAIN_H__
#include "doomdata.h"
#include "doomdef.h"
#include "doomtype.h"
#include "m_fixed.h"
#include "p_mobj.h"
#define TERRAIN_NAME_LEN 32
typedef struct t_splash_s
{
// Splash definition.
// These are particles spawned when hitting the floor.
char name[TERRAIN_NAME_LEN]; // Lookup name.
UINT16 mobjType; // Thing type. MT_NULL to not spawn anything.
UINT16 sfx; // Sound to play.
fixed_t scale; // Thing scale multiplier.
UINT16 color; // Colorize effect. SKINCOLOR_NONE has no colorize.
fixed_t pushH; // Push-out horizontal multiplier.
fixed_t pushV; // Push-out vertical multiplier.
fixed_t spread; // Randomized spread distance.
angle_t cone; // Randomized angle of the push-out.
UINT8 numParticles; // Number of particles to spawn.
} t_splash_t;
typedef struct t_footstep_s
{
// Footstep definition.
// These are particles spawned when moving fast enough on a floor.
char name[TERRAIN_NAME_LEN]; // Lookup name.
UINT16 mobjType; // Thing type. MT_NULL to not spawn anything.
UINT16 sfx; // Sound to play.
fixed_t scale; // Thing scale multiplier.
UINT16 color; // Colorize effect. SKINCOLOR_NONE has no colorize.
fixed_t pushH; // Push-out horizontal multiplier.
fixed_t pushV; // Push-out vertical multiplier.
fixed_t spread; // Randomized spread distance.
angle_t cone; // Randomized angle of the push-out.
tic_t sfxFreq; // How frequently to play the sound.
tic_t frequency; // How frequently to spawn the particles.
fixed_t requiredSpeed; // Speed percentage you need to be at to trigger the particles.
} t_footstep_t;
typedef enum
{
// Terrain flag values.
TRF_LIQUID = 1, // Texture water properties (wavy, slippery, etc)
TRF_SNEAKERPANEL = 1<<1, // Texture is a booster
TRF_STAIRJANK = 1<<2, // Texture is bumpy road
TRF_TRIPWIRE = 1<<3 // Texture is a tripwire when used as a midtexture
} terrain_flags_t;
typedef struct terrain_s
{
// Terrain definition.
// These are all of the properties that the floor gets.
char name[TERRAIN_NAME_LEN]; // Lookup name.
size_t splashID; // Splash defintion ID.
size_t footstepID; // Footstep defintion ID.
fixed_t friction; // The default friction of this texture.
UINT8 offroad; // The default offroad level of this texture.
INT16 damageType; // The default damage type of this texture. (Negative means no damage).
UINT8 trickPanel; // Trick panel strength
UINT32 flags; // Flag values (see: terrain_flags_t)
} terrain_t;
typedef struct t_floor_s
{
// Terrain floor definition.
// Ties texture names to a .
// (Could be optimized by using texture IDs instead of names,
// but was concerned because I recall sooomething about those not being netsafe?
// Someone confirm if I just hallucinated that. :V)
char textureName[9]; // Floor texture name.
size_t terrainID; // Terrain definition ID.
} t_floor_t;
/*--------------------------------------------------
size_t K_GetSplashHeapIndex(t_splash_t *splash);
Returns a splash defintion's index in the
splash definition heap.
Input Arguments:-
splash - The splash definition to return the index of.
Return:-
The splash heap index, SIZE_MAX if the splash was invalid.
--------------------------------------------------*/
size_t K_GetSplashHeapIndex(t_splash_t *splash);
/*--------------------------------------------------
size_t K_GetNumSplashDefs(void);
Returns the number of splash definitions.
Input Arguments:-
None
Return:-
Length of splashDefs.
--------------------------------------------------*/
size_t K_GetNumSplashDefs(void);
/*--------------------------------------------------
t_splash_t *K_GetSplashByIndex(size_t checkIndex);
Retrieves a splash definition by its heap index.
Input Arguments:-
checkIndex - The heap index to retrieve.
Return:-
The splash definition, NULL if it didn't exist.
--------------------------------------------------*/
t_splash_t *K_GetSplashByIndex(size_t checkIndex);
/*--------------------------------------------------
t_splash_t *K_GetSplashByName(const char *checkName);
Retrieves a splash definition by its lookup name.
Input Arguments:-
checkName - The lookup name to retrieve.
Return:-
The splash definition, NULL if it didn't exist.
--------------------------------------------------*/
t_splash_t *K_GetSplashByName(const char *checkName);
/*--------------------------------------------------
size_t K_GetFootstepHeapIndex(t_footstep_t *footstep);
Returns a footstep defintion's index in the
footstep definition heap.
Input Arguments:-
footstep - The footstep definition to return the index of.
Return:-
The footstep heap index, SIZE_MAX if the footstep was invalid.
--------------------------------------------------*/
size_t K_GetFootstepHeapIndex(t_footstep_t *footstep);
/*--------------------------------------------------
size_t K_GetNumFootstepDefs(void);
Returns the number of footstep definitions.
Input Arguments:-
None
Return:-
Length of footstepDefs.
--------------------------------------------------*/
size_t K_GetNumFootstepDefs(void);
/*--------------------------------------------------
t_footstep_t *K_GetFootstepByIndex(size_t checkIndex);
Retrieves a footstep definition by its heap index.
Input Arguments:-
checkIndex - The heap index to retrieve.
Return:-
The footstep definition, NULL if it didn't exist.
--------------------------------------------------*/
t_footstep_t *K_GetFootstepByIndex(size_t checkIndex);
/*--------------------------------------------------
t_footstep_t *K_GetFootstepByName(const char *checkName);
Retrieves a footstep definition by its lookup name.
Input Arguments:-
checkName - The lookup name to retrieve.
Return:-
The footstep definition, NULL if it didn't exist.
--------------------------------------------------*/
t_footstep_t *K_GetFootstepByName(const char *checkName);
/*--------------------------------------------------
size_t K_GetTerrainHeapIndex(terrain_t *terrain);
Returns a terrain defintion's index in the
terrain definition heap.
Input Arguments:-
terrain - The terrain definition to return the index of.
Return:-
The terrain heap index, SIZE_MAX if the terrain was invalid.
--------------------------------------------------*/
size_t K_GetTerrainHeapIndex(terrain_t *terrain);
/*--------------------------------------------------
size_t K_GetNumTerrainDefs(void);
Returns the number of terrain definitions.
Input Arguments:-
None
Return:-
Length of terrainDefs.
--------------------------------------------------*/
size_t K_GetNumTerrainDefs(void);
/*--------------------------------------------------
terrain_t *K_GetTerrainByIndex(size_t checkIndex);
Retrieves a terrain definition by its heap index.
Input Arguments:-
checkIndex - The heap index to retrieve.
Return:-
The terrain definition, NULL if it didn't exist.
--------------------------------------------------*/
terrain_t *K_GetTerrainByIndex(size_t checkIndex);
/*--------------------------------------------------
terrain_t *K_GetTerrainByName(const char *checkName);
Retrieves a terrain definition by its lookup name.
Input Arguments:-
checkName - The lookup name to retrieve.
Return:-
The terrain definition, NULL if it didn't exist.
--------------------------------------------------*/
terrain_t *K_GetTerrainByName(const char *checkName);
/*--------------------------------------------------
terrain_t *K_GetDefaultTerrain(void);
Returns the default terrain definition, used
in cases where terrain is not set for a texture.
Input Arguments:-
None
Return:-
The default terrain definition, NULL if it didn't exist.
--------------------------------------------------*/
terrain_t *K_GetDefaultTerrain(void);
/*--------------------------------------------------
terrain_t *K_GetTerrainForTextureName(const char *checkName);
Returns the terrain definition applied to
the texture name inputted.
Input Arguments:-
checkName - The texture's name.
Return:-
The texture's terrain definition if it exists,
otherwise the default terrain if it exists,
otherwise NULL.
--------------------------------------------------*/
terrain_t *K_GetTerrainForTextureName(const char *checkName);
/*--------------------------------------------------
terrain_t *K_GetTerrainForTextureNum(INT32 textureNum);
Returns the terrain definition applied to
the texture ID inputted.
Input Arguments:-
textureNum - The texture's ID.
Return:-
The texture's terrain definition if it exists,
otherwise the default terrain if it exists,
otherwise NULL.
--------------------------------------------------*/
terrain_t *K_GetTerrainForTextureNum(INT32 textureNum);
/*--------------------------------------------------
terrain_t *K_GetTerrainForFlatNum(INT32 flatID);
Returns the terrain definition applied to
the level flat ID.
Input Arguments:-
flatID - The level flat's ID.
Return:-
The level flat's terrain definition if it exists,
otherwise the default terrain if it exists,
otherwise NULL.
--------------------------------------------------*/
terrain_t *K_GetTerrainForFlatNum(INT32 flatID);
/*--------------------------------------------------
void K_UpdateMobjTerrain(mobj_t *mo, INT32 flatID);
Updates an object's terrain pointer, based on
the level flat ID supplied. Intended to be called
when the object moves to new floors.
Input Arguments:-
mo - The object to update.
flatID - The level flat ID the object is standing on.
Return:-
None
--------------------------------------------------*/
void K_UpdateMobjTerrain(mobj_t *mo, INT32 flatID);
/*--------------------------------------------------
void K_ProcessTerrainEffect(mobj_t *mo);
Handles applying terrain effects to the object,
intended to be called in a thinker.
Currently only intended for players, but
could be modified to be inclusive of all
object types.
Input Arguments:-
mo - The object to apply effects to.
Return:-
None
--------------------------------------------------*/
void K_ProcessTerrainEffect(mobj_t *mo);
/*--------------------------------------------------
void K_SetDefaultFriction(mobj_t *mo);
Resets an object to their default friction values.
If they are on terrain with different friction,
they will update to that value.
Input Arguments:-
mo - The object to reset the friction values of.
Return:-
None
--------------------------------------------------*/
void K_SetDefaultFriction(mobj_t *mo);
/*--------------------------------------------------
void K_SpawnSplashForMobj(mobj_t *mo, fixed_t impact);
Spawns the splash particles for an object's
terrain type. Intended to be called when hitting a floor.
Input Arguments:-
mo - The object to spawn a splash for.
Return:-
None
--------------------------------------------------*/
void K_SpawnSplashForMobj(mobj_t *mo, fixed_t impact);
/*--------------------------------------------------
void K_HandleFootstepParticles(mobj_t *mo);
Spawns the footstep particles for an object's
terrain type. Intended to be called every tic.
Input Arguments:-
mo - The object to spawn footsteps for.
Return:-
None
--------------------------------------------------*/
void K_HandleFootstepParticles(mobj_t *mo);
/*--------------------------------------------------
void K_InitTerrain(UINT16 wadNum);
Finds the TERRAIN lumps in a WAD/PK3, and
processes all of them.
Input Arguments:-
wadNum - WAD file ID to process.
Return:-
None
--------------------------------------------------*/
void K_InitTerrain(UINT16 wadNum);
#endif // __K_TERRAIN_H__

View file

@ -1415,7 +1415,7 @@ static int lib_pTeleportMove(lua_State *L)
INLEVEL
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
LUA_Deprecated(L, "P_TeleportMove", "P_SetOrigin or P_MoveOrigin");
LUA_Deprecated(L, "P_TeleportMove", "P_SetOrigin\" or \"P_MoveOrigin");
lua_pushboolean(L, P_SetOrigin(thing, x, y, z));
LUA_PushUserdata(L, tmthing, META_MOBJ);
P_SetTarget(&tmthing, ptmthing);
@ -1456,6 +1456,42 @@ static int lib_pMoveOrigin(lua_State *L)
return 2;
}
static int lib_pInitAngle(lua_State *L)
{
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
angle_t newValue = luaL_checkangle(L, 2);
NOHUD
INLEVEL
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
P_InitAngle(thing, newValue);
return 0;
}
static int lib_pInitPitch(lua_State *L)
{
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
angle_t newValue = luaL_checkangle(L, 2);
NOHUD
INLEVEL
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
P_InitPitch(thing, newValue);
return 0;
}
static int lib_pInitRoll(lua_State *L)
{
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
angle_t newValue = luaL_checkangle(L, 2);
NOHUD
INLEVEL
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
P_InitRoll(thing, newValue);
return 0;
}
static int lib_pSlideMove(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -3588,11 +3624,10 @@ static int lib_kSpawnSparkleTrail(lua_State *L)
static int lib_kSpawnWipeoutTrail(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
boolean offroad = lua_optboolean(L, 2);
NOHUD
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
K_SpawnWipeoutTrail(mo, offroad);
K_SpawnWipeoutTrail(mo);
return 0;
}
@ -3872,6 +3907,9 @@ static luaL_Reg lib[] = {
{"P_TeleportMove",lib_pTeleportMove},
{"P_SetOrigin",lib_pSetOrigin},
{"P_MoveOrigin",lib_pMoveOrigin},
{"P_InitAngle",lib_pInitAngle},
{"P_InitPitch",lib_pInitPitch},
{"P_InitRoll",lib_pInitRoll},
{"P_SlideMove",lib_pSlideMove},
{"P_BounceMove",lib_pBounceMove},
{"P_CheckSight", lib_pCheckSight},

View file

@ -494,9 +494,6 @@ static int mobj_set(lua_State *L)
if (hook_cmd_running)
return luaL_error(L, "Do not alter mobj_t in CMD building code!");
if (hook_cmd_running)
return luaL_error(L, "Do not alter mobj_t in BuildCMD code!");
switch(field)
{
case mobj_valid:

View file

@ -281,7 +281,7 @@ static int player_get(lua_State *L)
else if (fastcmp(field,"handleboost"))
lua_pushinteger(L, plr->handleboost);
else if (fastcmp(field,"boostangle"))
lua_pushinteger(L, plr->boostangle);
lua_pushangle(L, plr->boostangle);
else if (fastcmp(field,"draftpower"))
lua_pushinteger(L, plr->draftpower);
else if (fastcmp(field,"draftleeway"))
@ -499,9 +499,6 @@ static int player_set(lua_State *L)
if (hook_cmd_running)
return luaL_error(L, "Do not alter player_t in CMD building code!");
if (hook_cmd_running)
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
if (fastcmp(field,"mo")) {
mobj_t *newmo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
plr->mo->player = NULL; // remove player pointer from old mobj
@ -626,7 +623,7 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"handleboost"))
plr->handleboost = luaL_checkinteger(L, 3);
else if (fastcmp(field,"boostangle"))
plr->boostangle = luaL_checkinteger(L, 3);
plr->boostangle = luaL_checkangle(L, 3);
else if (fastcmp(field,"draftpower"))
plr->draftpower = luaL_checkinteger(L, 3);
else if (fastcmp(field,"draftleeway"))
@ -861,7 +858,7 @@ static int karthud_set(lua_State *L)
if (hud_running)
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
if (hook_cmd_running)
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
return luaL_error(L, "Do not alter player_t in CMD building code!");
karthud[ks] = i;
return 0;
}

View file

@ -1220,7 +1220,7 @@ void A_StatueBurst(mobj_t *actor)
if (!locvar1 || !(new = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1)))
return;
new->angle = actor->angle;
P_InitAngle(new, actor->angle);
P_SetTarget(&new->target, actor->target);
if (locvar2)
P_SetMobjState(new, (statenum_t)locvar2);
@ -2519,8 +2519,8 @@ void A_LobShot(mobj_t *actor)
P_SetTarget(&shot->target, actor); // where it came from
shot->angle = an = actor->angle;
an >>= ANGLETOFINESHIFT;
P_InitAngle(shot, actor->angle);
an = actor->angle >> ANGLETOFINESHIFT;
dist = P_AproxDistance(actor->target->x - shot->x, actor->target->y - shot->y);
@ -2886,7 +2886,7 @@ void A_Boss1Laser(mobj_t *actor)
S_StartSound(actor, mobjinfo[locvar1].seesound);
point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET);
point->angle = actor->angle;
P_InitAngle(point, actor->angle);
point->fuse = dur+1;
P_SetTarget(&point->target, actor->target);
P_SetTarget(&actor->target, point);
@ -2896,7 +2896,7 @@ void A_Boss1Laser(mobj_t *actor)
point = P_SpawnMobj(x, y, z, locvar1);
P_SetTarget(&point->target, actor);
point->angle = actor->angle;
P_InitAngle(point, actor->angle);
speed = point->radius;
point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed);
point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed));
@ -2905,7 +2905,7 @@ void A_Boss1Laser(mobj_t *actor)
for (i = 0; i < 256; i++)
{
mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type);
mo->angle = point->angle;
P_InitAngle(mo, point->angle);
mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing
P_UnsetThingPosition(mo);
mo->flags = MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY;
@ -2937,7 +2937,7 @@ void A_Boss1Laser(mobj_t *actor)
if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1)
{
point = P_SpawnMobj(x, y, floorz, MT_EGGMOBILE_FIRE);
point->angle = actor->angle;
P_InitAngle(point, actor->angle);
point->destscale = actor->scale;
P_SetScale(point, point->destscale);
P_SetTarget(&point->target, actor);
@ -3521,7 +3521,7 @@ bossjustdie:
P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
P_ReturnThrustY(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
32<<FRACBITS, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InitAngle(mo2, mo->angle);
P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale);
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
P_SetMobjState(mo2, S_BOSSEGLZ1);
@ -3530,7 +3530,7 @@ bossjustdie:
P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
P_ReturnThrustY(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
32<<FRACBITS, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InitAngle(mo2, mo->angle);
P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale);
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
P_SetMobjState(mo2, S_BOSSEGLZ2);
@ -3542,7 +3542,7 @@ bossjustdie:
P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
P_ReturnThrustY(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
32<<FRACBITS, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InitAngle(mo2, mo->angle);
P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale);
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
P_SetMobjState(mo2, S_BOSSTANK1);
@ -3551,7 +3551,7 @@ bossjustdie:
P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
P_ReturnThrustY(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
32<<FRACBITS, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InitAngle(mo2, mo->angle);
P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale);
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
P_SetMobjState(mo2, S_BOSSTANK2);
@ -3559,7 +3559,7 @@ bossjustdie:
mo2 = P_SpawnMobjFromMobj(mo, 0, 0,
mobjinfo[MT_EGGMOBILE2].height + (32<<FRACBITS),
MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InitAngle(mo2, mo->angle);
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
mo2->momz += mo->momz;
P_SetMobjState(mo2, S_BOSSSPIGOT);
@ -3568,7 +3568,7 @@ bossjustdie:
case MT_EGGMOBILE3:
{
mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InitAngle(mo2, mo->angle);
P_SetMobjState(mo2, S_BOSSSEBH1);
}
break;
@ -3642,7 +3642,8 @@ bossjustdie:
pole->tracer->flags |= MF_NOCLIPTHING;
P_SetScale(pole, (pole->destscale = 2*FRACUNIT));
P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT));
pole->angle = pole->tracer->angle = mo->tracer->angle;
P_InitAngle(pole, mo->tracer->angle);
P_InitAngle(pole->tracer, mo->tracer->angle);
pole->tracer->tracer->angle = pole->angle - ANGLE_90;
pole->momx = P_ReturnThrustX(pole, pole->angle, speed);
pole->momy = P_ReturnThrustY(pole, pole->angle, speed);
@ -4011,7 +4012,7 @@ void A_AttractChase(mobj_t *actor)
sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS);
P_SetTarget(&sparkle->target, actor->target);
sparkle->angle = (actor->target->angle + (offset>>1)) + (offset * actor->target->player->sparkleanim);
P_InitAngle(sparkle, (actor->target->angle + (offset>>1)) + (offset * actor->target->player->sparkleanim));
actor->target->player->sparkleanim = (actor->target->player->sparkleanim+1) % 20;
P_KillMobj(actor, actor->target, actor->target, DMG_NORMAL);
@ -5265,7 +5266,7 @@ void A_RockSpawn(mobj_t *actor)
mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FALLINGROCK);
P_SetMobjState(mo, mobjinfo[type].spawnstate);
mo->angle = R_PointToAngle2(line->v2->x, line->v2->y, line->v1->x, line->v1->y);
P_InitAngle(mo, R_PointToAngle2(line->v2->x, line->v2->y, line->v1->x, line->v1->y));
P_InstaThrust(mo, mo->angle, dist + randomoomph);
mo->momz = dist + randomoomph;
@ -7131,7 +7132,7 @@ void A_Boss3ShockThink(mobj_t *actor)
snew->momx = (actor->momx + snext->momx) >> 1;
snew->momy = (actor->momy + snext->momy) >> 1;
snew->momz = (actor->momz + snext->momz) >> 1; // is this really needed?
snew->angle = (actor->angle + snext->angle) >> 1;
P_InitAngle(snew, (actor->angle + snext->angle) >> 1);
P_SetTarget(&snew->target, actor->target);
snew->fuse = actor->fuse;
@ -7283,7 +7284,7 @@ void A_SpawnObjectAbsolute(mobj_t *actor)
mo = P_SpawnMobj(x<<FRACBITS, y<<FRACBITS, z<<FRACBITS, type);
// Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn
mo->angle = actor->angle;
P_InitAngle(mo, actor->angle);
if (actor->eflags & MFE_VERTICALFLIP)
mo->flags2 |= MF2_OBJECTFLIP;
@ -7325,7 +7326,7 @@ void A_SpawnObjectRelative(mobj_t *actor)
(actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[type].height) - FixedMul(z<<FRACBITS, actor->scale)) : (actor->z + FixedMul(z<<FRACBITS, actor->scale)), type);
// Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn
mo->angle = actor->angle;
P_InitAngle(mo, actor->angle);
if (actor->eflags & MFE_VERTICALFLIP)
mo->flags2 |= MF2_OBJECTFLIP;
@ -8035,7 +8036,7 @@ void A_BossJetFume(mobj_t *actor)
P_SetScale(filler, filler->destscale);
if (actor->eflags & MFE_VERTICALFLIP)
filler->flags2 |= MF2_OBJECTFLIP;
filler->angle = actor->angle - ANGLE_180;
P_InitAngle(filler, actor->angle - ANGLE_180);
P_SetTarget(&actor->tracer, filler);
}*/
@ -9745,7 +9746,7 @@ void A_TrapShot(mobj_t *actor)
S_StartSound(missile, missile->info->seesound);
P_SetTarget(&missile->target, actor);
missile->angle = actor->angle;
P_InitAngle(missile, actor->angle);
speed = FixedMul(missile->info->speed, missile->scale);
@ -10324,7 +10325,7 @@ void A_BrakLobShot(mobj_t *actor)
S_StartSound(shot, shot->info->seesound);
P_SetTarget(&shot->target, actor); // where it came from
shot->angle = actor->angle;
P_InitAngle(shot, actor->angle);
// Horizontal axes first. First parameter is initial horizontal impulse, second is to correct its angle.
shot->momx = FixedMul(FixedMul(v, FINECOSINE(theta >> ANGLETOFINESHIFT)), FINECOSINE(shot->angle >> ANGLETOFINESHIFT));
@ -10391,7 +10392,7 @@ void A_NapalmScatter(mobj_t *actor)
mo = P_SpawnMobj(actor->x, actor->y, actor->z, typeOfShot);
P_SetTarget(&mo->target, actor->target); // Transfer target so Brak doesn't hit himself like an idiot
mo->angle = fa << ANGLETOFINESHIFT;
P_InitAngle(mo, fa << ANGLETOFINESHIFT);
mo->momx = FixedMul(FINECOSINE(fa),vx);
mo->momy = FixedMul(FINESINE(fa),vx);
mo->momz = vy;
@ -10415,7 +10416,7 @@ void A_SpawnFreshCopy(mobj_t *actor)
newObject = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->type);
newObject->flags2 = actor->flags2 & MF2_AMBUSH;
newObject->angle = actor->angle;
P_InitAngle(newObject, actor->angle);
newObject->color = actor->color;
P_SetTarget(&newObject->target, actor->target);
P_SetTarget(&newObject->tracer, actor->tracer);
@ -10451,7 +10452,7 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz
}
flicky = P_SpawnMobjFromMobj(actor, offsx, offsy, 0, flickytype);
flicky->angle = actor->angle;
P_InitAngle(flicky, actor->angle);
if (flickytype == MT_SEED)
flicky->z += P_MobjFlip(actor)*(actor->height - flicky->height)/2;
@ -10601,7 +10602,7 @@ void A_FlickyCenter(mobj_t *actor)
else if (actor->flags & MF_SLIDEME) // aimless
{
actor->tracer->fuse = 0; // less than 2*TICRATE means move aimlessly.
actor->tracer->angle = P_RandomKey(180)*ANG2;
P_InitAngle(actor->tracer, P_RandomKey(180)*ANG2);
}
else //orbit
actor->tracer->fuse = FRACUNIT;
@ -11302,7 +11303,7 @@ void A_ConnectToGround(mobj_t *actor)
{
work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar1);
if (work)
work->angle = ang;
P_InitAngle(work, ang);
ang += ANGLE_90;
workz += workh;
}
@ -11348,7 +11349,7 @@ void A_SpawnParticleRelative(mobj_t *actor)
(actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[MT_PARTICLE].height) - FixedMul(z<<FRACBITS, actor->scale)) : (actor->z + FixedMul(z<<FRACBITS, actor->scale)), MT_PARTICLE);
// Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn
mo->angle = actor->angle;
P_InitAngle(mo, actor->angle);
if (actor->eflags & MFE_VERTICALFLIP)
mo->flags2 |= MF2_OBJECTFLIP;
@ -12095,7 +12096,7 @@ void A_Boss5MakeJunk(mobj_t *actor)
broked->fuse = TICRATE;
else
broked->fuse = (((locvar2 & 1) ? 4 : 2)*TICRATE)/3;
broked->angle = ang;
P_InitAngle(broked, ang);
P_InstaThrust(broked, ang, ((locvar2 & 2) ? 8 : 5)*actor->scale);
P_SetObjectMomZ(broked, (((locvar2) ? 4 : 0) + P_RandomRange(2, 5))<<FRACBITS, false);
if (locvar1 > 0)
@ -12174,7 +12175,7 @@ static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fi
mobjtype
);
dust->angle = ang*i + ANGLE_90;
P_InitAngle(dust, ang*i + ANGLE_90);
P_SetScale(dust, FixedMul(initscale, scale));
dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(), scale);
dust->scalespeed = scale/24;
@ -12379,7 +12380,7 @@ static mobj_t *P_TrainSeg(mobj_t *src, fixed_t x, fixed_t y, fixed_t z, angle_t
s->fuse = 16*TICRATE;
s->sprite = spr;
s->frame = frame|FF_PAPERSPRITE;
s->angle = ang;
P_InitAngle(s, ang);
P_Thrust(s, src->angle, 7*FRACUNIT);
return s;
}
@ -12751,7 +12752,7 @@ void A_SaloonDoorSpawn(mobj_t *actor)
// One door...
if (!(door = P_SpawnMobjFromMobj(actor, c, s, 0, locvar1))) return;
door->angle = ang + ANGLE_180;
P_InitAngle(door, ang + ANGLE_180);
door->extravalue1 = AngleFixed(door->angle); // Origin angle
door->extravalue2 = 0; // Angular speed
P_SetTarget(&door->tracer, actor); // Origin door
@ -12759,7 +12760,7 @@ void A_SaloonDoorSpawn(mobj_t *actor)
// ...two door!
if (!(door = P_SpawnMobjFromMobj(actor, -c, -s, 0, locvar1))) return;
door->angle = ang;
P_InitAngle(door, ang);
door->extravalue1 = AngleFixed(door->angle); // Origin angle
door->extravalue2 = 0; // Angular speed
P_SetTarget(&door->tracer, actor); // Origin door
@ -12955,7 +12956,7 @@ void A_SpawnPterabytes(mobj_t *actor)
c = FINECOSINE(fa);
s = FINESINE(fa);
waypoint = P_SpawnMobjFromMobj(actor, FixedMul(c, rad), FixedMul(s, rad), 0, MT_PTERABYTEWAYPOINT);
waypoint->angle = ang + ANGLE_90;
P_InitAngle(waypoint, ang + ANGLE_90);
P_SetTarget(&waypoint->tracer, actor);
ptera = P_SpawnMobjFromMobj(waypoint, 0, 0, 0, MT_PTERABYTE);
ptera->angle = waypoint->angle;
@ -13129,7 +13130,7 @@ void A_DragonbomberSpawn(mobj_t *actor)
segment = P_SpawnMobjFromMobj(mo, x, y, 0, MT_DRAGONTAIL);
P_SetTarget(&segment->target, mo);
P_SetTarget(&mo->tracer, segment);
segment->angle = mo->angle;
P_InitAngle(segment, mo->angle);
mo = segment;
}
for (i = 0; i < 2; i++) // spawn wings
@ -13399,6 +13400,9 @@ void A_JawzChase(mobj_t *actor)
}
ret = P_SpawnMobj(actor->tracer->x, actor->tracer->y, actor->tracer->z, MT_PLAYERRETICULE);
ret->old_x = actor->tracer->old_x;
ret->old_y = actor->tracer->old_y;
ret->old_z = actor->tracer->old_z;
P_SetTarget(&ret->target, actor->tracer);
ret->frame |= ((leveltime % 10) / 2) + 5;
ret->color = actor->cvmem;
@ -13531,7 +13535,7 @@ static void SpawnSPBDust(mobj_t *mo)
P_SetScale(dust, mo->scale*2);
dust->colorized = true;
dust->color = SKINCOLOR_RED;
dust->angle = mo->angle - FixedAngle(FRACUNIT*90 - FRACUNIT*180*i); // The first one will spawn to the right of the spb, the second one to the left.
P_InitAngle(dust, mo->angle - FixedAngle(FRACUNIT*90 - FRACUNIT*180*i)); // The first one will spawn to the right of the spb, the second one to the left.
P_Thrust(dust, dust->angle, 6*dust->scale);
K_MatchGenericExtraFlags(dust, mo);
@ -13568,7 +13572,7 @@ static void SpawnSPBAIZDust(mobj_t *mo, INT32 dir)
spark->flags = MF_NOGRAVITY|MF_PAIN;
P_SetTarget(&spark->target, mo);
spark->angle = travelangle+(dir*ANGLE_90);
P_InitAngle(spark, travelangle+(dir*ANGLE_90));
P_SetScale(spark, (spark->destscale = mo->scale*3/2));
spark->momx = (6*mo->momx)/5;
@ -13587,7 +13591,7 @@ static void SpawnSPBSpeedLines(mobj_t *actor)
MT_FASTLINE);
P_SetTarget(&fast->target, actor);
fast->angle = K_MomentumAngle(actor);
P_InitAngle(fast, K_MomentumAngle(actor));
fast->color = SKINCOLOR_RED;
fast->colorized = true;
K_MatchGenericExtraFlags(fast, actor);
@ -14289,7 +14293,7 @@ void A_RandomShadowFrame(mobj_t *actor)
P_SetScale(fake, FRACUNIT*3/2);
fake->scale = FRACUNIT*3/2;
fake->destscale = FRACUNIT*3/2;
fake->angle = actor->angle;
P_InitAngle(fake, actor->angle);
fake->tics = -1;
actor->renderflags |= RF_DONTDRAW;
actor->extravalue1 = 1;
@ -14677,6 +14681,8 @@ void A_FlameShieldPaper(mobj_t *actor)
paper->frame |= framea;
}
P_InitAngle(paper, paper->angle);
paper->extravalue1 = i;
}
}

View file

@ -1054,6 +1054,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY;
P_SetThingPosition(target);
target->standingslope = NULL;
target->terrain = NULL;
target->pmomz = 0;
target->player->playerstate = PST_DEAD;
@ -1184,7 +1185,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
mo->angle = FixedAngle((P_RandomKey(36)*10)<<FRACBITS);
mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InitAngle(mo2, mo->angle);
P_SetMobjState(mo2, S_BOSSSEBH2);
if (++i == 2) // we've already removed 2 of these, let's stop now
@ -1251,6 +1252,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
kart->eflags |= MFE_DAMAGEHITLAG;
P_SetObjectMomZ(kart, 6*FRACUNIT, false);
kart->extravalue1 = target->player->kartweight;
// Copy interp data
kart->old_angle = target->old_angle;
kart->old_x = target->old_x;
kart->old_y = target->old_y;
kart->old_z = target->old_z;
}
if (source && !P_MobjWasRemoved(source))
@ -1322,7 +1329,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
for (i = 0; i < 2; i++)
{
mobj_t *blast = P_SpawnMobjFromMobj(target, 0, 0, target->info->height >> 1, MT_BATTLEBUMPER_BLAST);
blast->angle = angle + i*ANGLE_90;
P_InitAngle(blast, angle + i*ANGLE_90);
P_SetScale(blast, 2*blast->scale/3);
blast->destscale = 2*blast->scale;
}
@ -1547,7 +1554,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\
P_SetMobjState(chunk, target->info->xdeathstate);\
chunk->health = 0;\
chunk->angle = angtweak;\
P_InitAngle(chunk, angtweak);\
P_UnsetThingPosition(chunk);\
chunk->flags = MF_NOCLIP;\
chunk->x += xmov;\
@ -1569,7 +1576,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);
P_SetMobjState(chunk, target->info->deathstate);
chunk->health = 0;
chunk->angle = ang + ANGLE_180;
P_InitAngle(chunk, ang + ANGLE_180);
P_UnsetThingPosition(chunk);
chunk->flags = MF_NOCLIP;
chunk->x -= xoffs;
@ -1615,7 +1622,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\
P_SetMobjState(chunk, target->info->xdeathstate);\
chunk->health = 0;\
chunk->angle = target->angle;\
P_InitAngle(chunk, target->angle);\
P_UnsetThingPosition(chunk);\
chunk->flags = MF_NOCLIP;\
chunk->x += xmov - forwardxoffs;\
@ -1641,7 +1648,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
P_SetMobjState(chunk, target->info->deathstate);
chunk->health = 0;
chunk->angle = target->angle;
P_InitAngle(chunk, target->angle);
P_UnsetThingPosition(chunk);
chunk->flags = MF_NOCLIP;
chunk->x += forwardxoffs - xoffs;
@ -1766,7 +1773,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM);
boom->scale = player->mo->scale;
boom->angle = player->mo->angle;
P_InitAngle(boom, player->mo->angle);
P_SetTarget(&boom->target, player->mo);
}
@ -1838,7 +1845,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!(target->flags & MF_SHOOTABLE))
return false; // shouldn't happen...
if (!(damagetype & DMG_DEATHMASK) && target->hitlag > 0)
if (!(damagetype & DMG_DEATHMASK) && target->hitlag > 0 && inflictor == NULL)
return false;
}
@ -1922,7 +1929,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (combo == false)
{
if (player->flashing > 0)
if (player->mo->hitlag == 0 && player->flashing > 0)
{
// Post-hit invincibility
K_DoInstashield(player);

View file

@ -168,7 +168,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec); // SRB2Kart
#define P_IsObjectFlipped(o) ((o)->eflags & MFE_VERTICALFLIP)
boolean P_InQuicksand(mobj_t *mo);
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff);
boolean P_PlayerHitFloor(player_t *player, boolean fromAir);
void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
void P_RestoreMusic(player_t *player);
@ -385,6 +385,7 @@ extern camera_t *mapcampointer;
extern fixed_t tmx;
extern fixed_t tmy;
extern pslope_t *tmfloorslope, *tmceilingslope;
extern INT32 tmfloorpic, tmceilingpic;
/* cphipps 2004/08/30 */
extern void P_MapStart(void);
@ -410,6 +411,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
boolean P_Move(mobj_t *actor, fixed_t speed);
boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
void P_InitAngle(mobj_t *thing, angle_t newValue);
void P_InitPitch(mobj_t *thing, angle_t newValue);
void P_InitRoll(mobj_t *thing, angle_t newValue);
void P_SlideMove(mobj_t *mo);
void P_BouncePlayerMove(mobj_t *mo);
void P_BounceMove(mobj_t *mo);

View file

@ -24,12 +24,13 @@
#include "r_sky.h"
#include "s_sound.h"
#include "w_wad.h"
#include "k_kart.h" // SRB2kart 011617
#include "k_collide.h"
#include "k_respawn.h"
#include "hu_stuff.h" // SRB2kart
#include "i_system.h" // SRB2kart
#include "k_terrain.h"
#include "r_splats.h"
@ -60,6 +61,7 @@ mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz
mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
ffloor_t *tmfloorrover, *tmceilingrover;
pslope_t *tmfloorslope, *tmceilingslope;
INT32 tmfloorpic, tmceilingpic;
static fixed_t tmfloorstep;
static fixed_t tmceilingstep;
@ -155,6 +157,30 @@ boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
return P_TeleportMove(thing, x, y, z);
}
//
// P_InitAngle - Change an object's angle, including interp values.
//
void P_InitAngle(mobj_t *thing, angle_t newValue)
{
thing->angle = thing->old_angle = newValue;
}
//
// P_InitPitch - Change an object's pitch, including interp values.
//
void P_InitPitch(mobj_t *thing, angle_t newValue)
{
thing->pitch = thing->old_pitch = newValue;
}
//
// P_InitRoll - Change an object's roll, including interp values.
//
void P_InitRoll(mobj_t *thing, angle_t newValue)
{
thing->roll = thing->old_roll = newValue;
}
// =========================================================================
// MOVEMENT ITERATOR FUNCTIONS
// =========================================================================
@ -267,9 +293,7 @@ static boolean P_SpecialIsLinedefCrossType(line_t *ld)
//
boolean P_DoSpring(mobj_t *spring, mobj_t *object)
{
//INT32 pflags;
const fixed_t hscale = mapobjectscale + (mapobjectscale - object->scale);
const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale);
const fixed_t scaleVal = FixedSqrt(FixedMul(mapobjectscale, spring->scale));
fixed_t vertispeed = spring->info->mass;
fixed_t horizspeed = spring->info->damage;
UINT16 starcolor = (spring->info->painchance % numskincolors);
@ -303,6 +327,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
}
object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you.
object->terrain = NULL;
object->eflags |= MFE_SPRUNG; // apply this flag asap!
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
@ -346,13 +371,13 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (vertispeed)
{
object->momz = FixedMul(vertispeed, FixedSqrt(FixedMul(vscale, spring->scale)));
object->momz = FixedMul(vertispeed, scaleVal);
}
if (horizspeed)
{
angle_t finalAngle = spring->angle;
fixed_t finalSpeed = FixedMul(horizspeed, FixedSqrt(FixedMul(hscale, spring->scale)));
fixed_t finalSpeed = FixedMul(horizspeed, scaleVal);
fixed_t objectSpeed;
if (object->player)
@ -408,7 +433,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
mobj_t *grease;
grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE);
P_SetTarget(&grease->target, object);
grease->angle = K_MomentumAngle(object);
P_InitAngle(grease, K_MomentumAngle(object));
grease->extravalue1 = i;
}
@ -444,6 +469,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
}
object->standingslope = NULL; // No launching off at silly angles for you.
object->terrain = NULL;
switch (spring->type)
{
@ -1430,6 +1456,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
tmfloorz = thing->z + thing->height;
tmfloorrover = NULL;
tmfloorslope = NULL;
tmfloorpic = -1;
}
return true;
}
@ -1449,6 +1476,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
tmfloorz = tmceilingz = topz; // block while in air
tmceilingrover = NULL;
tmceilingslope = NULL;
tmceilingpic = -1;
tmfloorthing = thing; // needed for side collision
}
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
@ -1456,6 +1484,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
tmceilingz = topz;
tmceilingrover = NULL;
tmceilingslope = NULL;
tmceilingpic = -1;
tmfloorthing = thing; // thing we may stand on
}
}
@ -1471,6 +1500,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
tmceilingz = thing->z;
tmceilingrover = NULL;
tmceilingslope = NULL;
tmceilingpic = -1;
}
return true;
}
@ -1490,6 +1520,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
tmfloorz = tmceilingz = topz; // block while in air
tmfloorrover = NULL;
tmfloorslope = NULL;
tmfloorpic = -1;
tmfloorthing = thing; // needed for side collision
}
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
@ -1497,6 +1528,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
tmfloorz = topz;
tmfloorrover = NULL;
tmfloorslope = NULL;
tmfloorpic = -1;
tmfloorthing = thing; // thing we may stand on
}
}
@ -1676,6 +1708,7 @@ static boolean PIT_CheckLine(line_t *ld)
ceilingline = ld;
tmceilingrover = openceilingrover;
tmceilingslope = opentopslope;
tmceilingpic = opentoppic;
tmceilingstep = openceilingstep;
if (thingtop == tmthing->ceilingz)
{
@ -1688,6 +1721,7 @@ static boolean PIT_CheckLine(line_t *ld)
tmfloorz = openbottom;
tmfloorrover = openfloorrover;
tmfloorslope = openbottomslope;
tmfloorpic = openbottompic;
tmfloorstep = openfloorstep;
if (tmthing->z == tmthing->floorz)
{
@ -1784,6 +1818,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmceilingrover = NULL;
tmfloorslope = newsubsec->sector->f_slope;
tmceilingslope = newsubsec->sector->c_slope;
tmfloorpic = newsubsec->sector->floorpic;
tmceilingpic = newsubsec->sector->ceilingpic;
tmfloorstep = 0;
tmceilingstep = 0;
@ -1837,6 +1873,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmfloorz = topheight - sinklevel;
tmfloorrover = rover;
tmfloorslope = *rover->t_slope;
tmfloorpic = *rover->toppic;
}
}
else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0)
@ -1845,6 +1882,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmceilingz = bottomheight + sinklevel;
tmceilingrover = rover;
tmceilingslope = *rover->b_slope;
tmceilingpic = *rover->bottompic;
}
}
}
@ -1868,6 +1906,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmfloorz = thing->z;
tmfloorrover = rover;
tmfloorslope = NULL;
tmfloorpic = *rover->toppic;
}
}
// Quicksand blocks never change heights otherwise.
@ -1885,6 +1924,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmfloorz = tmdropoffz = topheight;
tmfloorrover = rover;
tmfloorslope = *rover->t_slope;
tmfloorpic = *rover->toppic;
}
if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
&& !(rover->flags & FF_PLATFORM)
@ -1893,6 +1933,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmceilingz = tmdrpoffceilz = bottomheight;
tmceilingrover = rover;
tmceilingslope = *rover->b_slope;
tmceilingpic = *rover->bottompic;
}
}
}
@ -1967,12 +2008,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmfloorz = tmdropoffz = polytop;
tmfloorslope = NULL;
tmfloorrover = NULL;
tmfloorpic = polysec->ceilingpic;
}
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) {
tmceilingz = tmdrpoffceilz = polybottom;
tmceilingslope = NULL;
tmceilingrover = NULL;
tmceilingpic = polysec->floorpic;
}
}
plink = (polymaplink_t *)(plink->link.next);
@ -2390,6 +2433,8 @@ boolean PIT_PushableMoved(mobj_t *thing)
ffloor_t *oldceilrover = tmceilingrover;
pslope_t *oldfslope = tmfloorslope;
pslope_t *oldcslope = tmceilingslope;
INT32 oldfpic = tmfloorpic;
INT32 oldcpic = tmceilingpic;
// Move the player
P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true);
@ -2406,6 +2451,8 @@ boolean PIT_PushableMoved(mobj_t *thing)
tmceilingrover = oldceilrover;
tmfloorslope = oldfslope;
tmceilingslope = oldcslope;
tmfloorpic = oldfpic;
tmceilingpic = oldcpic;
thing->momz = stand->momz;
}
else
@ -2655,9 +2702,14 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (!(thing->flags & MF_NOCLIPHEIGHT))
{
// Assign thing's standingslope if needed
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) {
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP))
{
K_UpdateMobjTerrain(thing, tmfloorpic);
if (!startingonground && tmfloorslope)
{
P_HandleSlopeLanding(thing, tmfloorslope);
}
if (thing->momz <= 0)
{
@ -2665,12 +2717,19 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
P_SetPitchRollFromSlope(thing, thing->standingslope);
if (thing->momz == 0 && thing->player && !startingonground)
{
P_PlayerHitFloor(thing->player, true);
}
}
}
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP))
{
K_UpdateMobjTerrain(thing, tmceilingpic);
if (!startingonground && tmceilingslope)
{
P_HandleSlopeLanding(thing, tmceilingslope);
}
if (thing->momz >= 0)
{
@ -2678,12 +2737,18 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
P_SetPitchRollFromSlope(thing, thing->standingslope);
if (thing->momz == 0 && thing->player && !startingonground)
{
P_PlayerHitFloor(thing->player, true);
}
}
}
}
else // don't set standingslope if you're not going to clip against it
else
{
// don't set standingslope if you're not going to clip against it
thing->standingslope = NULL;
thing->terrain = NULL;
}
/* FIXME: slope step down (even up) has some false
positives, so just ignore them entirely. */
@ -3667,7 +3732,7 @@ stairstep:
tmymove = 0;
}
if (!P_TryMove(mo, newx, newy, true)) {
if (success)
if (success || P_MobjWasRemoved(mo))
return; // Good enough!!
else
goto retry;
@ -3791,6 +3856,9 @@ void P_BounceMove(mobj_t *mo)
INT32 hitcount;
fixed_t mmomx = 0, mmomy = 0;
if (P_MobjWasRemoved(mo))
return;
if (mo->player)
{
P_BouncePlayerMove(mo);
@ -3914,7 +3982,11 @@ bounceback:
mo->momy = tmymove;
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true))
{
if (P_MobjWasRemoved(mo))
return;
goto retry;
}
}
//

View file

@ -342,6 +342,7 @@ fixed_t openceilingstep;
fixed_t openceilingdrop;
fixed_t openfloorstep;
fixed_t openfloordrop;
INT32 opentoppic, openbottompic;
// P_CameraLineOpening
// P_LineOpening, but for camera
@ -537,6 +538,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
highceiling = INT32_MIN;
lowfloor = INT32_MAX;
opentopslope = openbottomslope = NULL;
opentoppic = openbottompic = -1;
openceilingstep = 0;
openceilingdrop = 0;
openfloorstep = 0;
@ -556,6 +558,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
opentop = height[lo];
highceiling = height[hi];
opentopslope = sector[lo]->c_slope;
opentoppic = sector[lo]->ceilingpic;
if (mobj)
{
@ -575,6 +578,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
openbottom = height[hi];
lowfloor = height[lo];
openbottomslope = sector[hi]->f_slope;
openbottompic = sector[hi]->floorpic;
if (mobj)
{
@ -747,6 +751,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (bottomheight < open[FRONT].top) {
open[FRONT].top = bottomheight;
opentopslope = *rover->b_slope;
opentoppic = *rover->bottompic;
open[FRONT].ceilingrover = rover;
}
else if (bottomheight < highceiling)
@ -758,6 +763,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (topheight > open[FRONT].bottom) {
open[FRONT].bottom = topheight;
openbottomslope = *rover->t_slope;
openbottompic = *rover->toppic;
open[FRONT].floorrover = rover;
}
else if (topheight > lowfloor)
@ -789,6 +795,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (bottomheight < open[BACK].top) {
open[BACK].top = bottomheight;
opentopslope = *rover->b_slope;
opentoppic = *rover->bottompic;
open[BACK].ceilingrover = rover;
}
else if (bottomheight < highceiling)
@ -800,6 +807,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (topheight > open[BACK].bottom) {
open[BACK].bottom = topheight;
openbottomslope = *rover->t_slope;
openbottompic = *rover->toppic;
open[BACK].floorrover = rover;
}
else if (topheight > lowfloor)

View file

@ -63,6 +63,7 @@ extern fixed_t openceilingstep;
extern fixed_t openceilingdrop;
extern fixed_t openfloorstep;
extern fixed_t openfloordrop;
extern INT32 opentoppic, openbottompic;
void P_LineOpening(line_t *plinedef, mobj_t *mobj);

View file

@ -40,6 +40,7 @@
#include "k_color.h"
#include "k_respawn.h"
#include "k_bot.h"
#include "k_terrain.h"
static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}};
consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL);
@ -1201,7 +1202,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
gravityadd = -((gravityadd/5) + (gravityadd/8));
}
gravityadd = FixedMul(gravityadd, mo->scale);
gravityadd = FixedMul(gravityadd, mapobjectscale);
return gravityadd;
}
@ -1340,7 +1341,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
mo->momy = FixedMul(mo->momy, mo->friction);
}
mo->friction = ORIG_FRICTION;
K_SetDefaultFriction(mo);
}
}
else
@ -1505,7 +1506,10 @@ void P_XYMovement(mobj_t *mo)
oldy = mo->y;
if (mo->flags & MF_NOCLIPHEIGHT)
{
mo->standingslope = NULL;
mo->terrain = NULL;
}
// adjust various things based on slope
if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) {
@ -1671,6 +1675,7 @@ void P_XYMovement(mobj_t *mo)
{
mo->momz = transfermomz;
mo->standingslope = NULL;
mo->terrain = NULL;
P_SetPitchRoll(mo, ANGLE_90,
transferslope->xydirection
+ (transferslope->zangle
@ -1689,6 +1694,8 @@ void P_XYMovement(mobj_t *mo)
else
{
P_BounceMove(mo);
if (P_MobjWasRemoved(mo))
return;
xmove = ymove = 0;
S_StartSound(mo, mo->info->activesound);
@ -1782,6 +1789,7 @@ void P_XYMovement(mobj_t *mo)
mo->momz = P_MobjFlip(mo)*FRACUNIT/2;
mo->z = predictedz + P_MobjFlip(mo);
mo->standingslope = NULL;
mo->terrain = NULL;
//CONS_Printf("Launched off of flat surface running into downward slope\n");
}
}
@ -1837,6 +1845,9 @@ void P_SceneryXYMovement(mobj_t *mo)
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy))
P_BounceMove(mo);
if (P_MobjWasRemoved(mo))
return;
if ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz))
return; // no friction when airborne
@ -2274,6 +2285,8 @@ boolean P_ZMovement(mobj_t *mo)
}
P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly
K_UpdateMobjTerrain(mo, ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingpic : tmfloorpic));
if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
{
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
@ -2383,7 +2396,7 @@ boolean P_ZMovement(mobj_t *mo)
MT_KART_TIRE
);
tire->angle = mo->angle;
P_InitAngle(tire, mo->angle);
tire->fuse = 3*TICRATE;
P_InstaThrust(tire, tireAngle, 4 * mo->scale);
P_SetObjectMomZ(tire, 4*FRACUNIT, false);
@ -2403,7 +2416,7 @@ boolean P_ZMovement(mobj_t *mo)
MT_KART_TIRE
);
tire->angle = mo->angle;
P_InitAngle(tire, mo->angle);
tire->fuse = 3*TICRATE;
P_InstaThrust(tire, tireAngle, 4 * mo->scale);
P_SetObjectMomZ(tire, 4*FRACUNIT, false);
@ -2503,12 +2516,17 @@ boolean P_ZMovement(mobj_t *mo)
if (mo->type == MT_STEAM)
return true;
}
else if (!(mo->flags & MF_NOGRAVITY)) // Gravity here!
else
{
/// \todo may not be needed (done in P_MobjThinker normally)
mo->eflags &= ~MFE_JUSTHITFLOOR;
mo->terrain = NULL;
P_CheckGravity(mo, true);
if (!(mo->flags & MF_NOGRAVITY)) // Gravity here!
{
/// \todo may not be needed (done in P_MobjThinker normally)
mo->eflags &= ~MFE_JUSTHITFLOOR;
P_CheckGravity(mo, true);
}
}
if (((mo->z + mo->height > mo->ceilingz && !(mo->eflags & MFE_VERTICALFLIP))
@ -2712,20 +2730,29 @@ void P_PlayerZMovement(mobj_t *mo)
if (onground && !(mo->flags & MF_NOCLIPHEIGHT))
{
if (mo->eflags & MFE_VERTICALFLIP)
{
mo->z = mo->ceilingz - mo->height;
}
else
{
mo->z = mo->floorz;
}
K_UpdateMobjTerrain(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingpic : tmfloorpic));
// Get up if you fell.
if (mo->player->panim == PA_HURT && mo->player->spinouttimer == 0 && mo->player->tumbleBounces == 0)
{
P_SetPlayerMobjState(mo, S_KART_STILL);
}
if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) {
if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope))
{
// Handle landing on slope during Z movement
P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope));
}
if (P_MobjFlip(mo)*mo->momz < 0) // falling
if (P_MobjFlip(mo) * mo->momz < 0) // falling
{
boolean clipmomz = !(P_CheckDeathPitCollide(mo));
@ -2736,29 +2763,38 @@ void P_PlayerZMovement(mobj_t *mo)
P_PlayerPolyObjectZMovement(mo);
if (clipmomz)
{
mo->momz = (tmfloorthing ? tmfloorthing->momz : 0);
}
}
else if (tmfloorthing)
mo->momz = tmfloorthing->momz;
}
else if (!(mo->flags & MF_NOGRAVITY)) // Gravity here!
{
if (P_IsObjectInGoop(mo) && !(mo->flags & MF_NOCLIPHEIGHT))
{
if (mo->z < mo->floorz)
{
mo->z = mo->floorz;
mo->momz = 0;
}
else if (mo->z + mo->height > mo->ceilingz)
{
mo->z = mo->ceilingz - mo->height;
mo->momz = 0;
}
mo->momz = tmfloorthing->momz;
}
}
else
{
mo->terrain = NULL;
if (!(mo->flags & MF_NOGRAVITY)) // Gravity here!
{
if (P_IsObjectInGoop(mo) && !(mo->flags & MF_NOCLIPHEIGHT))
{
if (mo->z < mo->floorz)
{
mo->z = mo->floorz;
mo->momz = 0;
}
else if (mo->z + mo->height > mo->ceilingz)
{
mo->z = mo->ceilingz - mo->height;
mo->momz = 0;
}
}
/// \todo may not be needed (done in P_MobjThinker normally)
mo->eflags &= ~MFE_JUSTHITFLOOR;
P_CheckGravity(mo, true);
}
/// \todo may not be needed (done in P_MobjThinker normally)
mo->eflags &= ~MFE_JUSTHITFLOOR;
P_CheckGravity(mo, true);
}
if (((mo->eflags & MFE_VERTICALFLIP && mo->z < mo->floorz) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height > mo->ceilingz))
@ -3048,6 +3084,26 @@ void P_MobjCheckWater(mobj_t *mobj)
}
}
if (mobj->terrain != NULL)
{
if (mobj->terrain->flags & TRF_LIQUID)
{
// This floor is water.
mobj->eflags |= MFE_TOUCHWATER;
if (mobj->eflags & MFE_VERTICALFLIP)
{
mobj->watertop = thingtop + height;
mobj->waterbottom = thingtop;
}
else
{
mobj->watertop = mobj->z;
mobj->waterbottom = mobj->z - height;
}
}
}
if (mobj->watertop > top2)
mobj->watertop = top2;
@ -3056,7 +3112,9 @@ void P_MobjCheckWater(mobj_t *mobj)
// Spectators and dead players don't get to do any of the things after this.
if (p && (p->spectator || p->playerstate != PST_LIVE))
{
return;
}
// The rest of this code only executes on a water state change.
if (!!(mobj->eflags & MFE_UNDERWATER) == wasinwater)
@ -3073,6 +3131,30 @@ void P_MobjCheckWater(mobj_t *mobj)
|| ((mobj->info->flags & MF_PUSHABLE) && mobj->fuse) // Previously pushable, might be moving still
)
{
fixed_t waterZ = INT32_MAX;
fixed_t solidZ = INT32_MAX;
fixed_t diff = INT32_MAX;
fixed_t thingZ = INT32_MAX;
boolean splashValid = false;
if (mobj->eflags & MFE_VERTICALFLIP)
{
waterZ = mobj->waterbottom;
solidZ = mobj->ceilingz;
}
else
{
waterZ = mobj->watertop;
solidZ = mobj->floorz;
}
diff = waterZ - solidZ;
if (mobj->eflags & MFE_VERTICALFLIP)
{
diff = -diff;
}
// Time to spawn the bubbles!
{
INT32 i;
@ -3131,12 +3213,15 @@ void P_MobjCheckWater(mobj_t *mobj)
// Check to make sure you didn't just cross into a sector to jump out of
// that has shallower water than the block you were originally in.
if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->watertop-mobj->floorz <= height>>1)
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= height>>1))
if (diff <= (height >> 1))
{
return;
}
if (mobj->eflags & MFE_GOOWATER || wasingoo) { // Decide what happens to your momentum when you enter/leave goopy water.
if (P_MobjFlip(mobj)*mobj->momz > 0)
if (mobj->eflags & MFE_GOOWATER || wasingoo)
{
// Decide what happens to your momentum when you enter/leave goopy water.
if (P_MobjFlip(mobj) * mobj->momz > 0)
{
mobj->momz -= (mobj->momz/8); // cut momentum a little bit to prevent multiple bobs
//CONS_Printf("leaving\n");
@ -3148,25 +3233,42 @@ void P_MobjCheckWater(mobj_t *mobj)
//CONS_Printf("entering\n");
}
}
else if (wasinwater && P_MobjFlip(mobj)*mobj->momz > 0)
mobj->momz = FixedMul(mobj->momz, FixedDiv(780*FRACUNIT, 457*FRACUNIT)); // Give the mobj a little out-of-water boost.
if (P_MobjFlip(mobj)*mobj->momz < 0)
else if (wasinwater && P_MobjFlip(mobj) * mobj->momz > 0)
{
if ((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz <= mobj->waterbottom)
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz >= mobj->watertop))
// Give the mobj a little out-of-water boost.
mobj->momz = FixedMul(mobj->momz, FixedDiv(780*FRACUNIT, 457*FRACUNIT));
}
if (mobj->eflags & MFE_VERTICALFLIP)
{
thingZ = thingtop - (height >> 1);
splashValid = (thingZ - mobj->momz <= waterZ);
}
else
{
thingZ = mobj->z + (height >> 1);
splashValid = (thingZ - mobj->momz >= waterZ);
}
if (P_MobjFlip(mobj) * mobj->momz <= 0)
{
if (splashValid == true)
{
// Spawn a splash
mobj_t *splish;
mobjtype_t splishtype = (mobj->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH;
if (mobj->eflags & MFE_VERTICALFLIP)
{
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype);
splish = P_SpawnMobj(mobj->x, mobj->y, waterZ - FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype);
splish->flags2 |= MF2_OBJECTFLIP;
splish->eflags |= MFE_VERTICALFLIP;
}
else
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype);
{
splish = P_SpawnMobj(mobj->x, mobj->y, waterZ, splishtype);
}
splish->destscale = mobj->scale;
P_SetScale(splish, mobj->scale);
}
@ -3175,40 +3277,37 @@ void P_MobjCheckWater(mobj_t *mobj)
if (p && p->waterskip < 2
&& ((p->speed/3 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water.
|| (p->speed > 20*mapobjectscale && p->waterskip)) // Already skipped once, so you can skip once more!
&& ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop)
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom)))
&& (splashValid == true))
{
const fixed_t hop = 5<<FRACBITS;
const fixed_t hop = 5 * mobj->scale;
mobj->momx = (4*mobj->momx)/5;
mobj->momy = (4*mobj->momy)/5;
if (mobj->eflags & MFE_VERTICALFLIP)
mobj->momz = FixedMul(-hop, mobj->scale);
else
mobj->momz = FixedMul(hop, mobj->scale);
mobj->momz = hop * P_MobjFlip(mobj);
p->waterskip++;
}
}
else if (P_MobjFlip(mobj)*mobj->momz > 0)
else if (P_MobjFlip(mobj) * mobj->momz > 0)
{
if (((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz > mobj->waterbottom)
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz < mobj->watertop))
&& !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side
if (splashValid == true && !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side
{
// Spawn a splash
mobj_t *splish;
mobjtype_t splishtype = (mobj->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH;
if (mobj->eflags & MFE_VERTICALFLIP)
{
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype);
splish = P_SpawnMobj(mobj->x, mobj->y, waterZ - FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype);
splish->flags2 |= MF2_OBJECTFLIP;
splish->eflags |= MFE_VERTICALFLIP;
}
else
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype);
{
splish = P_SpawnMobj(mobj->x, mobj->y, waterZ, splishtype);
}
splish->destscale = mobj->scale;
P_SetScale(splish, mobj->scale);
}
@ -4050,7 +4149,7 @@ static void P_SpawnItemCapsuleParts(mobj_t *mobj)
part = part->hnext;
P_SetTarget(&part->target, mobj);
P_SetMobjState(part, buttState);
part->angle = i * ANG_CAPSULE;
P_InitAngle(part, i * ANG_CAPSULE);
part->movedir = spin; // rotation speed
part->movefactor = 0; // z offset
part->extravalue1 = buttScale; // relative scale
@ -4061,7 +4160,7 @@ static void P_SpawnItemCapsuleParts(mobj_t *mobj)
part = part->hnext;
P_SetTarget(&part->target, mobj);
P_SetMobjState(part, S_ITEMCAPSULE_TOP_SIDE);
part->angle = i * ANG_CAPSULE;
P_InitAngle(part, i * ANG_CAPSULE);
part->movedir = spin; // rotation speed
part->movefactor = mobj->info->height - part->info->height; // z offset
}
@ -4386,7 +4485,7 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb
mobj->z -= mobj->height>>1;
// change angle
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, x, y);
P_InitAngle(mobj, R_PointToAngle2(mobj->x, mobj->y, x, y));
// change slope
dist = P_AproxDistance(P_AproxDistance(x - mobj->x, y - mobj->y), z - mobj->z);
@ -5069,7 +5168,7 @@ static void P_FlameJetSceneryThink(mobj_t *mobj)
flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME);
P_SetMobjState(flame, S_FLAMEJETFLAME4);
flame->angle = mobj->angle;
P_InitAngle(flame, mobj->angle);
if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side
flame->momz = mobj->fuse << (FRACBITS - 2);
@ -5530,7 +5629,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
{
mobj_t *blast = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BATTLEBUMPER_BLAST);
blast->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy) + ANGLE_45;
P_InitAngle(blast, R_PointToAngle2(0, 0, mobj->momx, mobj->momy) + ANGLE_45);
blast->destscale *= 4;
if (i & 1)
@ -6815,12 +6914,15 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (( mobj->fuse & 1 ))
{
nudge = 4*mobj->target->radius;
/* unrotate interp angle */
mobj->old_angle -= ANGLE_90;
}
else
{
nudge = 2*mobj->target->radius;
/* rotate the papersprite frames to see the flat angle */
mobj->angle += ANGLE_90;
mobj->old_angle += ANGLE_90;
}
P_MoveOrigin(mobj,
@ -7015,6 +7117,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
return false;
}
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
mobj->old_x = mobj->target->old_x;
mobj->old_y = mobj->target->old_y;
mobj->old_z = mobj->target->old_z;
break;
case MT_INSTASHIELDB:
mobj->renderflags ^= RF_DONTDRAW;
@ -7027,6 +7132,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
return false;
}
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
mobj->old_x = mobj->target->old_x;
mobj->old_y = mobj->target->old_y;
mobj->old_z = mobj->target->old_z;
K_MatchGenericExtraFlags(mobj, mobj->target);
break;
case MT_BATTLEPOINT:
@ -7399,7 +7507,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->z + (mobj->height/2) + (P_RandomRange(-20,20) * mobj->scale),
MT_FASTLINE);
fast->angle = mobj->angle;
P_InitAngle(fast, mobj->angle);
fast->momx = 3*mobj->target->momx/4;
fast->momy = 3*mobj->target->momy/4;
fast->momz = 3*P_GetMobjZMovement(mobj->target)/4;
@ -7461,7 +7569,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (underlayst != S_NULL)
{
mobj_t *underlay = P_SpawnMobj(mobj->target->x, mobj->target->y, mobj->target->z, MT_FLAMESHIELDUNDERLAY);
underlay->angle = mobj->angle;
P_InitAngle(underlay, mobj->angle);
P_SetMobjState(underlay, underlayst);
}
break;
@ -8839,7 +8947,7 @@ static boolean P_FuseThink(mobj_t *mobj)
for (i = 0; i < 5; i++)
{
mobj_t *debris = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_DEBRIS);
debris->angle = FixedAngle(P_RandomRange(0,360)<<FRACBITS);
P_InitAngle(debris, FixedAngle(P_RandomRange(0,360)<<FRACBITS));
P_InstaThrust(debris, debris->angle, P_RandomRange(3,18)*(FRACUNIT/4));
debris->momz = P_RandomRange(4,8)<<FRACBITS;
if (!i) // kinda hacky :V
@ -9615,7 +9723,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_CRUSHSTACEAN:
{
mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_CRUSHCLAW);
bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);;
P_InitAngle(bigmeatyclaw, mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270));
P_SetTarget(&mobj->tracer, bigmeatyclaw);
P_SetTarget(&bigmeatyclaw->tracer, mobj);
mobj->reactiontime >>= 1;
@ -9624,7 +9732,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_BANPYURA:
{
mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BANPSPRING);
bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);;
P_InitAngle(bigmeatyclaw, mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270));
P_SetTarget(&mobj->tracer, bigmeatyclaw);
P_SetTarget(&bigmeatyclaw->tracer, mobj);
mobj->reactiontime >>= 1;
@ -9757,7 +9865,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break;
case MT_MINECARTEND:
P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID));
mobj->tracer->angle = mobj->angle + ANGLE_90;
P_InitAngle(mobj->tracer, mobj->angle + ANGLE_90);
break;
case MT_TORCHFLOWER:
{
@ -9879,7 +9987,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
angle_t ang = i * diff;
mobj_t *side = P_SpawnMobj(mobj->x + FINECOSINE((ang>>ANGLETOFINESHIFT) & FINEMASK),
mobj->y + FINESINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_DAYTONAPINETREE_SIDE);
side->angle = ang;
P_InitAngle(side, ang);
side->target = mobj;
side->threshold = i;
}
@ -9896,7 +10004,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
cur = P_SpawnMobj(mobj->x + FINECOSINE(((mobj->angle*8)>>ANGLETOFINESHIFT) & FINEMASK),
mobj->y + FINESINE(((mobj->angle*8)>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_EZZPROPELLER_BLADE);
cur->angle = mobj->angle;
P_InitAngle(cur, mobj->angle);
P_SetTarget(&cur->hprev, prev);
P_SetTarget(&prev->hnext, cur);
@ -9956,7 +10064,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
cur->threshold = i;
P_MoveOrigin(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)),
cur->y + ((cur->radius>>FRACBITS) * FINESINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)), cur->z);
cur->angle = ANGLE_90*(cur->threshold+1);
P_InitAngle(cur, ANGLE_90*(cur->threshold+1));
P_SetTarget(&cur->hprev, prev);
P_SetTarget(&prev->hnext, cur);
@ -10385,6 +10493,8 @@ void P_PrecipitationEffects(void)
boolean effects_lightning = (precipprops[curWeather].effects & PRECIPFX_LIGHTNING);
boolean lightningStrike = false;
boolean sounds_rain = (rainsfx != sfx_None && (!leveltime || leveltime % rainfreq == 1));
// No thunder except every other tic.
if (!(leveltime & 1))
{
@ -10429,29 +10539,48 @@ void P_PrecipitationEffects(void)
if (sound_disabled)
return; // Sound off? D'aw, no fun.
if (!sounds_rain && !sounds_thunder)
return; // no need to calculate volume at ALL
if (players[g_localplayers[0]].mo->subsector->sector->ceilingpic == skyflatnum)
volume = 255; // Sky above? We get it full blast.
else
{
fixed_t x, y, yl, yh, xl, xh;
INT64 x, y, yl, yh, xl, xh;
fixed_t closedist, newdist;
// Essentially check in a 1024 unit radius of the player for an outdoor area.
yl = players[g_localplayers[0]].mo->y - 1024*FRACUNIT;
yh = players[g_localplayers[0]].mo->y + 1024*FRACUNIT;
xl = players[g_localplayers[0]].mo->x - 1024*FRACUNIT;
xh = players[g_localplayers[0]].mo->x + 1024*FRACUNIT;
closedist = 2048*FRACUNIT;
for (y = yl; y <= yh; y += FRACUNIT*64)
for (x = xl; x <= xh; x += FRACUNIT*64)
#define RADIUSSTEP (64*FRACUNIT)
#define SEARCHRADIUS (16*RADIUSSTEP)
yl = yh = players[g_localplayers[0]].mo->y;
yl -= SEARCHRADIUS;
while (yl < INT32_MIN)
yl += RADIUSSTEP;
yh += SEARCHRADIUS;
while (yh > INT32_MAX)
yh -= RADIUSSTEP;
xl = xh = players[g_localplayers[0]].mo->x;
xl -= SEARCHRADIUS;
while (xl < INT32_MIN)
xl += RADIUSSTEP;
xh += SEARCHRADIUS;
while (xh > INT32_MAX)
xh -= RADIUSSTEP;
closedist = SEARCHRADIUS*2;
#undef SEARCHRADIUS
for (y = yl; y <= yh; y += RADIUSSTEP)
for (x = xl; x <= xh; x += RADIUSSTEP)
{
if (R_PointInSubsector(x, y)->sector->ceilingpic == skyflatnum) // Found the outdoors!
if (R_PointInSubsector((fixed_t)x, (fixed_t)y)->sector->ceilingpic == skyflatnum) // Found the outdoors!
{
newdist = S_CalculateSoundDistance(players[g_localplayers[0]].mo->x, players[g_localplayers[0]].mo->y, 0, x, y, 0);
newdist = S_CalculateSoundDistance(players[g_localplayers[0]].mo->x, players[g_localplayers[0]].mo->y, 0, (fixed_t)x, (fixed_t)y, 0);
if (newdist < closedist)
closedist = newdist;
}
}
#undef RADIUSSTEP
volume = 255 - (closedist>>(FRACBITS+2));
}
@ -10461,7 +10590,7 @@ void P_PrecipitationEffects(void)
else if (volume > 255)
volume = 255;
if (rainsfx != sfx_None && (!leveltime || leveltime % rainfreq == 1))
if (sounds_rain)
S_StartSoundAtVolume(players[g_localplayers[0]].mo, rainsfx, volume);
if (!sounds_thunder)
@ -10717,7 +10846,7 @@ void P_SpawnPlayer(INT32 playernum)
mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER);
(mobj->player = p)->mo = mobj;
mobj->angle = 0;
mobj->angle = mobj->old_angle = 0;
// set color translations for player sprites
mobj->color = p->skincolor;
@ -10804,6 +10933,12 @@ void P_AfterPlayerSpawn(INT32 playernum)
mobj_t *mobj = p->mo;
UINT8 i;
// Update interpolation
mobj->old_x = mobj->x;
mobj->old_y = mobj->y;
mobj->old_z = mobj->z;
mobj->old_angle = mobj->angle;
P_SetPlayerAngle(p, mobj->angle);
p->viewheight = P_GetPlayerViewHeight(p);
@ -11398,7 +11533,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle)
spawnee->friction = mroll;\
spawnee->movefactor = mwidthset;\
spawnee->movecount = dist;\
spawnee->angle = myaw;\
P_InitAngle(spawnee, myaw);\
spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\
spawnee->flags2 |= (mflags2apply|moreflags2);\
spawnee->eflags |= meflagsapply;\
@ -11597,29 +11732,29 @@ static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong)
statenum_t rollerstate = strong ? S_REDBOOSTERROLLER : S_YELLOWBOOSTERROLLER;
mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG);
seg->angle = angle - ANGLE_90;
P_InitAngle(seg, angle - ANGLE_90);
P_SetMobjState(seg, facestate);
seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG);
seg->angle = angle + ANGLE_90;
P_InitAngle(seg, angle + ANGLE_90);
P_SetMobjState(seg, facestate);
seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG);
seg->angle = angle;
P_InitAngle(seg, angle);
P_SetMobjState(seg, leftstate);
seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG);
seg->angle = angle;
P_InitAngle(seg, angle);
P_SetMobjState(seg, rightstate);
seg = P_SpawnMobjFromMobj(mobj, 13*(x1 + x2), 13*(y1 + y2), 0, MT_BOOSTERROLLER);
seg->angle = angle;
P_InitAngle(seg, angle);
P_SetMobjState(seg, rollerstate);
seg = P_SpawnMobjFromMobj(mobj, 13*(x1 - x2), 13*(y1 - y2), 0, MT_BOOSTERROLLER);
seg->angle = angle;
P_InitAngle(seg, angle);
P_SetMobjState(seg, rollerstate);
seg = P_SpawnMobjFromMobj(mobj, -13*(x1 + x2), -13*(y1 + y2), 0, MT_BOOSTERROLLER);
seg->angle = angle;
P_InitAngle(seg, angle);
P_SetMobjState(seg, rollerstate);
seg = P_SpawnMobjFromMobj(mobj, -13*(x1 - x2), -13*(y1 - y2), 0, MT_BOOSTERROLLER);
seg->angle = angle;
P_InitAngle(seg, angle);
P_SetMobjState(seg, rollerstate);
return true;
@ -11796,19 +11931,19 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
case MT_THZTREE:
{ // Spawn the branches
angle_t mobjangle = FixedAngle((mthing->angle % 113) << FRACBITS);
P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_22h;
P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h;
P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270;
P_InitAngle(P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_22h);
P_InitAngle(P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_157h);
P_InitAngle(P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_270);
}
break;
case MT_CEZPOLE1:
case MT_CEZPOLE2:
{ // Spawn the banner
angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS);
P_SpawnMobjFromMobj(mobj,
P_InitAngle(P_SpawnMobjFromMobj(mobj,
P_ReturnThrustX(mobj, mobjangle, 4 << FRACBITS),
P_ReturnThrustY(mobj, mobjangle, 4 << FRACBITS),
0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2))->angle = mobjangle + ANGLE_90;
0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2)), mobjangle + ANGLE_90);
}
break;
case MT_HHZTREE_TOP:
@ -11817,7 +11952,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
mobj_t* leaf;
#define doleaf(x, y) \
leaf = P_SpawnMobjFromMobj(mobj, x, y, 0, MT_HHZTREE_PART);\
leaf->angle = mobjangle;\
P_InitAngle(leaf, mobjangle);\
P_SetMobjState(leaf, leaf->info->seestate);\
mobjangle += ANGLE_90
doleaf(FRACUNIT, 0);
@ -11841,7 +11976,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
fixed_t xoffs = FINECOSINE(fa);
fixed_t yoffs = FINESINE(fa);
mobj_t* leaf = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, 0, MT_BIGFERNLEAF);
leaf->angle = angle;
P_InitAngle(leaf, angle);
angle += ANGLE_45;
}
break;
@ -11951,7 +12086,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius),
mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius),
mobj->z, MT_WALLSPIKEBASE);
base->angle = mobjangle + ANGLE_90;
P_InitAngle(base, mobjangle + ANGLE_90);
base->destscale = mobj->destscale;
P_SetScale(base, mobj->scale);
P_SetTarget(&base->target, mobj);
@ -12137,7 +12272,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
leaf = P_SpawnMobj(mobj->x + FINECOSINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK),
mobj->y + FINESINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK), top, MT_AAZTREE_LEAF);
leaf->angle = mobj->angle;
P_InitAngle(leaf, mobj->angle);
// Small coconut for each leaf
P_SpawnMobj(mobj->x + (32 * FINECOSINE((mobj->angle>>ANGLETOFINESHIFT) & FINEMASK)),
@ -12354,7 +12489,9 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
return mobj;
if (doangle)
mobj->angle = FixedAngle(mthing->angle << FRACBITS);
{
P_InitAngle(mobj, FixedAngle(mthing->angle << FRACBITS));
}
if ((mobj->flags & MF_SPRING)
&& mobj->info->damage != 0
@ -12366,8 +12503,8 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
mobj->spryoff = FixedMul(mobj->radius, FINESINE(a >> ANGLETOFINESHIFT));
}
mobj->pitch = FixedAngle(mthing->pitch << FRACBITS);
mobj->roll = FixedAngle(mthing->roll << FRACBITS);
P_InitPitch(mobj, FixedAngle(mthing->pitch << FRACBITS));
P_InitRoll(mobj, FixedAngle(mthing->roll << FRACBITS));
mthing->mobj = mobj;
@ -12774,7 +12911,7 @@ mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type,
P_SetTarget(&th->target, source); // where it came from
an = R_PointToAngle2(x, y, dest->x, dest->y);
th->angle = an;
P_InitAngle(th, an);
an >>= ANGLETOFINESHIFT;
th->momx = FixedMul(speed, FINECOSINE(an));
th->momy = FixedMul(speed, FINESINE(an));
@ -12836,7 +12973,7 @@ mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t
P_SetTarget(&th->target, source->target); // where it came from
an = R_PointToAngle2(0, 0, source->momx, source->momy) + (ANG1*shiftingAngle);
th->angle = an;
P_InitAngle(th, an);
an >>= ANGLETOFINESHIFT;
th->momx = FixedMul(speed, FINECOSINE(an));
th->momy = FixedMul(speed, FINESINE(an));
@ -12901,7 +13038,7 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za,
P_SetTarget(&th->target, source); // where it came from
an = R_PointToAngle2(x, y, xa, ya);
th->angle = an;
P_InitAngle(th, an);
an >>= ANGLETOFINESHIFT;
th->momx = FixedMul(speed, FINECOSINE(an));
th->momy = FixedMul(speed, FINESINE(an));
@ -12980,7 +13117,7 @@ mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type)
else
an = R_PointToAngle2(source->x, source->y, dest->x, dest->y);
th->angle = an;
P_InitAngle(th, an);
an >>= ANGLETOFINESHIFT;
th->momx = FixedMul(speed, FINECOSINE(an));
th->momy = FixedMul(speed, FINESINE(an));
@ -13068,7 +13205,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai
speed = th->info->speed;
th->angle = an;
P_InitAngle(th, an);
th->momx = FixedMul(speed, FINECOSINE(an>>ANGLETOFINESHIFT));
th->momy = FixedMul(speed, FINESINE(an>>ANGLETOFINESHIFT));
@ -13138,6 +13275,17 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
newmobj->z = mobj->z + mobj->height - zofs - newmobj->height;
}
// EXPERIMENT: Let all objects set their interp values relative to their owner's old values.
// This will hopefully create a lot less mobj-specific spawn cases,
// but if there's any weird scenarios feel free to remove again.
newmobj->old_x = mobj->old_x + xofs;
newmobj->old_y = mobj->old_y + yofs;
newmobj->old_z = mobj->old_z + zofs;
/*
newmobj->angle = mobj->angle;
newmobj->old_angle = mobj->old_angle;
*/
return newmobj;
}
@ -13154,6 +13302,14 @@ fixed_t P_GetMobjHead(const mobj_t *mobj)
fixed_t P_GetMobjFeet(const mobj_t *mobj)
{
/*
| |
| |
/--\------/ |
| |
-----------------
*/
return P_IsObjectFlipped(mobj) ? mobj->z + mobj->height : mobj->z;
}
@ -13186,4 +13342,4 @@ fixed_t P_GetMobjZMovement(mobj_t *mo)
speed = FixedHypot(mo->momx, mo->momy);
return P_ReturnThrustY(mo, slope->zangle, P_ReturnThrustX(mo, angDiff, speed));
}
}

View file

@ -397,6 +397,7 @@ typedef struct mobj_s
fixed_t sprxoff, spryoff, sprzoff; // Sprite offsets in real space, does NOT affect position or collision
struct terrain_s *terrain; // Terrain definition of the floor this object last hit. NULL when in the air.
INT32 hitlag; // Sal-style hit lag, straight from Captain Fetch's jowls
// WARNING: New fields must be added separately to savegame and Lua.

View file

@ -38,6 +38,7 @@
// SRB2Kart
#include "k_battle.h"
#include "k_pwrlv.h"
#include "k_terrain.h"
savedata_t savedata;
UINT8 *save_p;
@ -1540,6 +1541,7 @@ typedef enum
MD2_KITEMCAP = 1<<26,
MD2_ITNEXT = 1<<27,
MD2_LASTMOMZ = 1<<28,
MD2_TERRAIN = 1<<29,
} mobj_diff2_t;
typedef enum
@ -1782,6 +1784,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_ITNEXT;
if (mobj->lastmomz)
diff2 |= MD2_LASTMOMZ;
if (mobj->terrain != NULL)
diff2 |= MD2_TERRAIN;
if (diff2 != 0)
diff |= MD_MORE;
@ -1979,6 +1983,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
{
WRITEINT32(save_p, mobj->lastmomz);
}
if (diff2 & MD2_TERRAIN)
{
WRITEUINT32(save_p, K_GetTerrainHeapIndex(mobj->terrain));
}
WRITEUINT32(save_p, mobj->mobjnum);
}
@ -2885,19 +2893,19 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->info = &mobjinfo[mobj->type];
if (diff & MD_POS)
{
mobj->x = READFIXED(save_p);
mobj->y = READFIXED(save_p);
mobj->angle = READANGLE(save_p);
mobj->pitch = READANGLE(save_p);
mobj->roll = READANGLE(save_p);
mobj->x = mobj->old_x = READFIXED(save_p);
mobj->y = mobj->old_y = READFIXED(save_p);
mobj->angle = mobj->old_angle = READANGLE(save_p);
mobj->pitch = mobj->old_pitch = READANGLE(save_p);
mobj->roll = mobj->old_roll = READANGLE(save_p);
}
else
{
mobj->x = mobj->spawnpoint->x << FRACBITS;
mobj->y = mobj->spawnpoint->y << FRACBITS;
mobj->angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT);
mobj->pitch = FixedAngle(mobj->spawnpoint->pitch*FRACUNIT);
mobj->roll = FixedAngle(mobj->spawnpoint->roll*FRACUNIT);
mobj->x = mobj->old_x = mobj->spawnpoint->x << FRACBITS;
mobj->y = mobj->old_y = mobj->spawnpoint->y << FRACBITS;
mobj->angle = mobj->old_angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT);
mobj->pitch = mobj->old_pitch = FixedAngle(mobj->spawnpoint->pitch*FRACUNIT);
mobj->roll = mobj->old_roll = FixedAngle(mobj->spawnpoint->roll*FRACUNIT);
}
if (diff & MD_MOM)
{
@ -3077,6 +3085,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
{
mobj->lastmomz = READINT32(save_p);
}
if (diff2 & MD2_TERRAIN)
{
mobj->terrain = (terrain_t *)(size_t)READUINT32(save_p);
}
else
{
mobj->terrain = NULL;
}
if (diff & MD_REDFLAG)
{
@ -4103,6 +4119,15 @@ static void P_RelinkPointers(void)
if (!(mobj->itnext = P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "itnext not found on %d\n", mobj->type);
}
if (mobj->terrain)
{
temp = (UINT32)(size_t)mobj->terrain;
mobj->terrain = K_GetTerrainByIndex(temp);
if (mobj->terrain == NULL)
{
CONS_Debug(DBG_GAMELOGIC, "terrain not found on %d\n", mobj->type);
}
}
if (mobj->player)
{
if ( mobj->player->awayviewmobj)

View file

@ -91,6 +91,7 @@
#include "k_waypoint.h"
#include "k_bot.h"
#include "k_grandprix.h"
#include "k_terrain.h" // TRF_TRIPWIRE
#include "k_brightmap.h"
// Replay names have time
@ -660,6 +661,9 @@ flatfound:
levelflat->u.flat.baselumpnum = LUMPERROR;
}
levelflat->terrain =
K_GetTerrainForTextureName(levelflat->name);
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
return ( numlevelflats++ );
@ -1940,18 +1944,15 @@ static void P_ProcessLinedefsAfterSidedefs(void)
size_t i = numlines;
register line_t *ld = lines;
const INT32 TEX_TRIPWIRE = R_TextureNumForName("TRIPWIRE");
const INT32 TEX_4RIPWIRE = R_TextureNumForName("4RIPWIRE");
for (; i--; ld++)
{
INT32 midtexture = sides[ld->sidenum[0]].midtexture;
terrain_t *terrain = K_GetTerrainForTextureNum(midtexture);
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
if (midtexture == TEX_TRIPWIRE ||
midtexture == TEX_4RIPWIRE)
if (terrain != NULL && (terrain->flags & TRF_TRIPWIRE))
{
ld->tripwire = true;
}
@ -4227,7 +4228,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
return true;
// If so...
G_PreLevelTitleCard();
// but not if joining because the fade may time us out
if (!fromnetsave)
G_PreLevelTitleCard();
return true;
}

View file

@ -17,6 +17,7 @@
#include "doomdata.h"
#include "doomstat.h"
#include "r_defs.h"
#include "k_terrain.h"
// map md5, sent to players via PT_SERVERINFO
extern unsigned char mapmd5[16];
@ -71,6 +72,8 @@ typedef struct
UINT16 width, height;
terrain_t *terrain;
// for flat animation
INT32 animseq; // start pos. in the anim sequence
INT32 numpics;

View file

@ -850,6 +850,7 @@ void P_SlopeLaunch(mobj_t *mo)
//CONS_Printf("Launched off of slope.\n");
mo->standingslope = NULL;
mo->terrain = NULL;
if (mo->player)
{

View file

@ -43,6 +43,7 @@
#include "k_kart.h"
#include "console.h" // CON_LogMessage
#include "k_respawn.h"
#include "k_terrain.h"
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
@ -3633,7 +3634,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (mobj)
{
if (line->flags & ML_EFFECT1)
mobj->angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y);
P_InitAngle(mobj, R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y));
CONS_Debug(DBG_GAMELOGIC, "Linedef Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", line->special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow.
}
else
@ -3928,7 +3929,7 @@ void P_SetupSignExit(player_t *player)
if (player->mo && !P_MobjWasRemoved(player->mo))
{
thing = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->floorz, MT_SIGN);
thing->angle = player->mo->angle;
P_InitAngle(thing, player->mo->angle);
P_SetupSignObject(thing, player->mo, true); // Use :youfuckedup: sign face
}
}
@ -4333,7 +4334,9 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
// Conveyor stuff
if (section3 == 2 || section3 == 4)
{
player->onconveyor = section3;
}
special = section1;
@ -4657,7 +4660,7 @@ DoneSection2:
case 6: // SRB2kart 190117 - Sneaker Panel
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
{
if (!player->floorboost)
if (player->floorboost == 0)
player->floorboost = 3;
else
player->floorboost = 2;
@ -5050,6 +5053,7 @@ void P_PlayerInSpecialSector(player_t *player)
if (!player->mo)
return;
K_ProcessTerrainEffect(player->mo);
originalsector = player->mo->subsector->sector;
P_PlayerOnSpecial3DFloor(player, originalsector); // Handle FOFs first.

View file

@ -97,7 +97,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
P_FlashPal(thing->player, PAL_MIXUP, 10);
}
thing->angle = angle;
P_InitAngle(thing, angle);
thing->momx = thing->momy = thing->momz = 0;
@ -171,7 +171,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
P_FlashPal(thing->player, PAL_MIXUP, 10);
}
thing->angle = angle;
P_InitAngle(thing, angle);
return true;
}

View file

@ -52,6 +52,7 @@
#include "k_respawn.h"
#include "k_bot.h"
#include "k_grandprix.h"
#include "k_terrain.h" // K_SpawnSplashForMobj
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
@ -379,7 +380,7 @@ void P_GiveFinishFlags(player_t *player)
fixed_t xoffs = FINECOSINE(fa);
fixed_t yoffs = FINESINE(fa);
mobj_t* flag = P_SpawnMobjFromMobj(player->mo, xoffs, yoffs, 0, MT_FINISHFLAG);
flag->angle = angle;
P_InitAngle(flag, angle);
angle += FixedAngle(120*FRACUNIT);
P_SetTarget(&flag->target, player->mo);
@ -1274,17 +1275,18 @@ void P_DoPlayerExit(player_t *player)
//
// Handles player hitting floor surface.
// Returns whether to clip momz.
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
boolean P_PlayerHitFloor(player_t *player, boolean fromAir)
{
boolean clipmomz;
(void)dorollstuff;
I_Assert(player->mo != NULL);
clipmomz = !(P_CheckDeathPitCollide(player->mo));
// SRB2Kart: removed lots of really vanilla-specific code here
if (fromAir == true && clipmomz == true)
{
K_SpawnSplashForMobj(player->mo, abs(player->mo->momz));
}
return clipmomz;
}
@ -2138,8 +2140,6 @@ void P_MovePlayer(player_t *player)
player->mo->rollangle = 0;
}
player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame.
//{ SRB2kart
// Drifting sound
@ -2176,7 +2176,7 @@ void P_MovePlayer(player_t *player)
if (trailScale > 0)
{
const angle_t forwardangle = K_MomentumAngle(player->mo);
const fixed_t playerVisualRadius = player->mo->radius + 8*FRACUNIT;
const fixed_t playerVisualRadius = player->mo->radius + (8 * player->mo->scale);
const size_t numFrames = S_WATERTRAIL8 - S_WATERTRAIL1;
const statenum_t curOverlayFrame = S_WATERTRAIL1 + (leveltime % numFrames);
const statenum_t curUnderlayFrame = S_WATERTRAILUNDERLAY1 + (leveltime % numFrames);
@ -2197,7 +2197,7 @@ void P_MovePlayer(player_t *player)
// underlay
water = P_SpawnMobj(x1, y1,
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY);
water->angle = forwardangle - ANGLE_180 - ANGLE_22h;
P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h);
water->destscale = trailScale;
water->momx = player->mo->momx;
water->momy = player->mo->momy;
@ -2208,7 +2208,7 @@ void P_MovePlayer(player_t *player)
// overlay
water = P_SpawnMobj(x1, y1,
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL);
water->angle = forwardangle - ANGLE_180 - ANGLE_22h;
P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h);
water->destscale = trailScale;
water->momx = player->mo->momx;
water->momy = player->mo->momy;
@ -2220,7 +2220,7 @@ void P_MovePlayer(player_t *player)
// Underlay
water = P_SpawnMobj(x2, y2,
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY);
water->angle = forwardangle - ANGLE_180 + ANGLE_22h;
P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h);
water->destscale = trailScale;
water->momx = player->mo->momx;
water->momy = player->mo->momy;
@ -2231,7 +2231,7 @@ void P_MovePlayer(player_t *player)
// Overlay
water = P_SpawnMobj(x2, y2,
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL);
water->angle = forwardangle - ANGLE_180 + ANGLE_22h;
P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h);
water->destscale = trailScale;
water->momx = player->mo->momx;
water->momy = player->mo->momy;
@ -2267,7 +2267,7 @@ void P_MovePlayer(player_t *player)
K_SpawnSparkleTrail(player->mo);
if (player->wipeoutslow > 1 && (leveltime & 1))
K_SpawnWipeoutTrail(player->mo, false);
K_SpawnWipeoutTrail(player->mo);
K_DriftDustHandling(player->mo);
@ -3989,7 +3989,7 @@ static void P_HandleFollower(player_t *player)
P_SetTarget(&player->follower, P_SpawnMobj(sx, sy, sz, MT_FOLLOWER));
P_SetFollowerState(player->follower, fl.idlestate);
P_SetTarget(&player->follower->target, player->mo); // we need that to know when we need to disappear
player->follower->angle = player->mo->angle;
P_InitAngle(player->follower, player->mo->angle);
// This is safe to only spawn it here, the follower is removed then respawned when switched.
if (bubble)
@ -4052,10 +4052,8 @@ static void P_HandleFollower(player_t *player)
if (player->pflags & PF_NOCONTEST)
player->follower->renderflags |= RF_DONTDRAW;
if (player->speed && (player->follower->momx || player->follower->momy))
player->follower->angle = K_MomentumAngle(player->follower);
// if we're moving let's make the angle the direction we're moving towards. This is to avoid drifting / reverse looking awkward.
// Make sure the follower itself is also moving however, otherwise we'll be facing angle 0
// if we're moving let's make the angle the direction we're moving towards. This is to avoid drifting / reverse looking awkward.
player->follower->angle = K_MomentumAngle(player->follower);
// Finally, if the follower has bubbles, move them, set their scale, etc....
// This is what I meant earlier by it being easier, now we can just use this weird lil loop to get the job done!
@ -4504,8 +4502,6 @@ void P_PlayerThink(player_t *player)
P_MovePlayer(player);
}
player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame.
// Unset statis flag after moving.
// In other words, if you manually set stasis via code,
// it lasts for one tic.
@ -4557,7 +4553,7 @@ void P_PlayerThink(player_t *player)
|| (player->pflags & PF_NOCONTEST) // NO CONTEST explosion
|| ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay)))
{
if (player->flashing > 0 && player->flashing < K_GetKartFlashing(player)
if (player->flashing > 1 && player->flashing < K_GetKartFlashing(player)
&& (leveltime & 1))
player->mo->renderflags |= RF_DONTDRAW;
else

View file

@ -23,6 +23,8 @@
#include "z_zone.h" // Check R_Prep3DFloors
#include "taglist.h"
#include "k_terrain.h"
seg_t *curline;
side_t *sidedef;
line_t *linedef;
@ -67,11 +69,35 @@ boolean R_IsRipplePlane(sector_t *sector, ffloor_t *rover, int ceiling)
static void R_PlaneLightOverride(sector_t *sector, boolean ceiling, INT32 *lightlevel)
{
if (GETSECSPECIAL(sector->special, 4) == 6) // Fullbright sneaker panels
terrain_t *t = NULL;
if (ceiling == true)
{
if ((ceiling && (sector->flags & SF_FLIPSPECIAL_CEILING))
|| (!ceiling && (sector->flags & SF_FLIPSPECIAL_FLOOR)))
t = K_GetTerrainForFlatNum(sector->ceilingpic);
}
else
{
t = K_GetTerrainForFlatNum(sector->floorpic);
}
if (t != NULL)
{
if (t->flags & TRF_SNEAKERPANEL)
{
*lightlevel = 255;
}
}
else
{
// Sector effect sneaker panels (DEPRECATED)
if (GETSECSPECIAL(sector->special, 4) == 6)
{
if ((ceiling && (sector->flags & SF_FLIPSPECIAL_CEILING))
|| (!ceiling && (sector->flags & SF_FLIPSPECIAL_FLOOR)))
{
*lightlevel = 255;
}
}
}
}

View file

@ -32,7 +32,6 @@ static viewvars_t skyview_new[MAXSPLITSCREENPLAYERS];
static viewvars_t *oldview = &pview_old[0];
viewvars_t *newview = &pview_new[0];
enum viewcontext_e viewcontext = VIEWCONTEXT_PLAYER1;
static fixed_t R_LerpFixed(fixed_t from, fixed_t to, fixed_t frac)
@ -147,3 +146,23 @@ void R_SetViewContext(enum viewcontext_e _viewcontext)
break;
}
}
fixed_t R_InterpolateFixed(fixed_t from, fixed_t to)
{
if (cv_frameinterpolation.value == 0)
{
return to;
}
return (from + R_LerpFixed(from, to, rendertimefrac));
}
angle_t R_InterpolateAngle(angle_t from, angle_t to)
{
if (cv_frameinterpolation.value == 0)
{
return to;
}
return (from + R_LerpAngle(from, to, rendertimefrac));
}

View file

@ -56,4 +56,7 @@ void R_UpdateViewInterpolation(void);
// Set the current view context (the viewvars pointed to by newview)
void R_SetViewContext(enum viewcontext_e _viewcontext);
fixed_t R_InterpolateFixed(fixed_t from, fixed_t to);
angle_t R_InterpolateAngle(angle_t from, angle_t to);
#endif

View file

@ -46,6 +46,7 @@
// SRB2kart
#include "k_color.h"
#include "k_kart.h" // HITLAGJITTERS
#include "r_fps.h"
#define MINZ (FRACUNIT*4)
#define BASEYCENTER (BASEVIDHEIGHT/2)
@ -1147,15 +1148,21 @@ static void R_SplitSprite(vissprite_t *sprite)
// Get the first visible floor below the object for shadows
// shadowslope is filled with the floor's slope, if provided
//
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
fixed_t R_GetShadowZ(
mobj_t *thing, pslope_t **shadowslope,
fixed_t interpx, fixed_t interpy, fixed_t interpz)
{
fixed_t halfHeight = interpz + (thing->height >> 1);
boolean isflipped = thing->eflags & MFE_VERTICALFLIP;
fixed_t floorz = P_GetFloorZ(thing, thing->subsector->sector, interpx, interpy, NULL);
fixed_t ceilingz = P_GetCeilingZ(thing, thing->subsector->sector, interpx, interpy, NULL);
fixed_t z, groundz = isflipped ? INT32_MAX : INT32_MIN;
pslope_t *slope, *groundslope = NULL;
msecnode_t *node;
sector_t *sector;
ffloor_t *rover;
#define CHECKZ (isflipped ? z > thing->z+thing->height/2 && z < groundz : z < thing->z+thing->height/2 && z > groundz)
#define CHECKZ (isflipped ? z > halfHeight && z < groundz : z < halfHeight && z > groundz)
for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next)
{
@ -1166,7 +1173,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
if (sector->heightsec != -1)
z = isflipped ? sectors[sector->heightsec].ceilingheight : sectors[sector->heightsec].floorheight;
else
z = isflipped ? P_GetSectorCeilingZAt(sector, thing->x, thing->y) : P_GetSectorFloorZAt(sector, thing->x, thing->y);
z = isflipped ? P_GetSectorCeilingZAt(sector, interpx, interpy) : P_GetSectorFloorZAt(sector, interpx, interpy);
if CHECKZ
{
@ -1180,7 +1187,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE)))
continue;
z = isflipped ? P_GetFFloorBottomZAt(rover, thing->x, thing->y) : P_GetFFloorTopZAt(rover, thing->x, thing->y);
z = isflipped ? P_GetFFloorBottomZAt(rover, interpx, interpy) : P_GetFFloorTopZAt(rover, interpx, interpy);
if CHECKZ
{
@ -1190,10 +1197,10 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
}
}
if (isflipped ? (thing->ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))
: (thing->floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))))
if (isflipped ? (ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))
: (floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))))
{
groundz = isflipped ? thing->ceilingz : thing->floorz;
groundz = isflipped ? ceilingz : floorz;
groundslope = NULL;
}
@ -1204,10 +1211,10 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
{
INT32 xl, xh, yl, yh, bx, by;
xl = (unsigned)(thing->x - thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)(thing->x + thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)(thing->y - thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(thing->y + thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
xl = (unsigned)(interpx - thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)(interpx + thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)(interpy - thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(interpy + thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
@ -1244,7 +1251,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
// We're inside it! Yess...
z = po->lines[0]->backsector->ceilingheight;
if (z < thing->z+thing->height/2 && z > groundz)
if (z < halfHeight && z > groundz)
{
groundz = z;
groundslope = NULL;
@ -1267,11 +1274,12 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
static void R_SkewShadowSprite(
mobj_t *thing, pslope_t *groundslope,
fixed_t groundz, INT32 spriteheight, fixed_t scalemul,
fixed_t *shadowyscale, fixed_t *shadowskew)
fixed_t *shadowyscale, fixed_t *shadowskew,
fixed_t interpx, fixed_t interpy)
{
// haha let's try some dumb stuff
fixed_t xslope, zslope;
angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - groundslope->xydirection) >> ANGLETOFINESHIFT;
angle_t sloperelang = (R_PointToAngle(interpx, interpy) - groundslope->xydirection) >> ANGLETOFINESHIFT;
xslope = FixedMul(FINESINE(sloperelang), groundslope->zdelta);
zslope = FixedMul(FINECOSINE(sloperelang), groundslope->zdelta);
@ -1287,7 +1295,10 @@ static void R_SkewShadowSprite(
*shadowskew = xslope;
}
static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz)
static void R_ProjectDropShadow(
mobj_t *thing, vissprite_t *vis,
fixed_t scale, fixed_t tx, fixed_t tz,
fixed_t interpx, fixed_t interpy, fixed_t interpz)
{
vissprite_t *shadow;
patch_t *patch;
@ -1296,7 +1307,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
fixed_t groundz;
pslope_t *groundslope;
groundz = R_GetShadowZ(thing, &groundslope);
groundz = R_GetShadowZ(thing, &groundslope, interpx, interpy, interpz);
if (abs(groundz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes
@ -1310,7 +1321,14 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadowskew = 0;
if (groundslope)
R_SkewShadowSprite(thing, groundslope, groundz, patch->height, FRACUNIT, &shadowyscale, &shadowskew);
{
R_SkewShadowSprite(
thing,
groundslope, groundz,
patch->height, FRACUNIT,
&shadowyscale, &shadowskew,
interpx, interpy);
}
tx -= patch->width * shadowxscale/2;
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
@ -1329,8 +1347,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadow->mobjflags = 0;
shadow->sortscale = vis->sortscale;
shadow->dispoffset = vis->dispoffset - 5;
shadow->gx = thing->x;
shadow->gy = thing->y;
shadow->gx = interpx;
shadow->gy = interpy;
shadow->gzt = groundz + patch->height * shadowyscale / 2;
shadow->gz = shadow->gzt - patch->height * shadowyscale;
shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
@ -1468,26 +1486,18 @@ static void R_ProjectSprite(mobj_t *thing)
#endif
// uncapped/interpolation
fixed_t interpx = thing->x;
fixed_t interpy = thing->y;
fixed_t interpz = thing->z;
angle_t interpangle = (thing->player ? thing->player->drawangle : thing->angle);
fixed_t interpx = R_InterpolateFixed(thing->old_x, thing->x);
fixed_t interpy = R_InterpolateFixed(thing->old_y, thing->y);
fixed_t interpz = R_InterpolateFixed(thing->old_z, thing->z);
angle_t interpangle = ANGLE_MAX;
// do interpolation
if (cv_frameinterpolation.value == 1)
if (thing->player)
{
interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
if (thing->player)
{
interpangle = thing->player->old_drawangle + FixedMul(rendertimefrac, thing->player->drawangle - thing->player->old_drawangle);
}
else
{
interpangle = thing->old_angle + FixedMul(rendertimefrac, thing->angle - thing->old_angle);
}
interpangle = R_InterpolateAngle(thing->player->old_drawangle, thing->player->drawangle);
}
else
{
interpangle = R_InterpolateAngle(thing->old_angle, thing->angle);
}
// hitlag vibrating (todo: interp somehow?)
@ -1815,11 +1825,10 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t linkscale;
thing = thing->tracer;
if (cv_frameinterpolation.value == 1)
{
interpx = thing->old_x + FixedMul(thing->x - thing->old_x, rendertimefrac);
interpy = thing->old_y + FixedMul(thing->y - thing->old_y, rendertimefrac);
}
interpx = R_InterpolateFixed(thing->old_x, thing->x);
interpy = R_InterpolateFixed(thing->old_y, thing->y);
interpz = R_InterpolateFixed(thing->old_z, thing->z);
// hitlag vibrating (todo: interp somehow?)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
@ -1909,7 +1918,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (shadowdraw || shadoweffects)
{
fixed_t groundz = R_GetShadowZ(thing, NULL);
fixed_t groundz = R_GetShadowZ(thing, NULL, interpx, interpy, interpz);
boolean isflipped = (thing->eflags & MFE_VERTICALFLIP);
if (shadoweffects)
@ -1933,7 +1942,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (shadowskew)
{
R_SkewShadowSprite(thing, thing->standingslope, groundz, patch->height, shadowscale, &spriteyscale, &sheartan);
R_SkewShadowSprite(thing, thing->standingslope, groundz, patch->height, shadowscale, &spriteyscale, &sheartan, interpx, interpy);
gzt = (isflipped ? (thing->z + thing->height) : thing->z) + patch->height * spriteyscale / 2;
gz = gzt - patch->height * spriteyscale;
@ -2132,7 +2141,10 @@ static void R_ProjectSprite(mobj_t *thing)
R_SplitSprite(vis);
if (oldthing->shadowscale && cv_shadow.value)
R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, basetz);
{
R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, basetz,
interpx, interpy, interpz);
}
// Debug
++objectsdrawn;
@ -2158,17 +2170,9 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
fixed_t gz, gzt;
// uncapped/interpolation
fixed_t interpx = thing->x;
fixed_t interpy = thing->y;
fixed_t interpz = thing->z;
// do interpolation
if (cv_frameinterpolation.value == 1)
{
interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
}
fixed_t interpx = R_InterpolateFixed(thing->old_x, thing->x);
fixed_t interpy = R_InterpolateFixed(thing->old_y, thing->y);
fixed_t interpz = R_InterpolateFixed(thing->old_z, thing->z);
// transform the origin point
tr_x = interpx - viewx;

View file

@ -59,7 +59,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap);
extern INT16 negonearray[MAXVIDWIDTH];
extern INT16 screenheightarray[MAXVIDWIDTH];
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope, fixed_t interpx, fixed_t interpy, fixed_t interpz);
//SoM: 6/5/2000: Light sprites correctly!
void R_AddSprites(sector_t *sec, INT32 lightlevel);

View file

@ -1580,7 +1580,7 @@ void S_ShowMusicCredit(void)
{
cursongcredit.def = def;
cursongcredit.anim = 5*TICRATE;
cursongcredit.x = 0;
cursongcredit.x = cursongcredit.old_x =0;
cursongcredit.trans = NUMTRANSMAPS;
return;
}

View file

@ -179,8 +179,9 @@ extern struct cursongcredit
{
musicdef_t *def;
UINT16 anim;
INT32 x;
UINT8 trans;
fixed_t x;
fixed_t old_x;
} cursongcredit;
extern musicdef_t *musicdefstart;

View file

@ -517,7 +517,7 @@ static inline void I_SetChannels(void)
}
}
void I_SetSfxVolume(UINT8 volume)
void I_SetSfxVolume(int volume)
{
INT32 i;
@ -1466,7 +1466,7 @@ void I_ResumeSong(void)
#endif
}
void I_SetMusicVolume(UINT8 volume)
void I_SetMusicVolume(int volume)
{
(void)volume;
}
@ -1477,6 +1477,9 @@ boolean I_SetSongTrack(int track)
return false;
}
void I_UpdateSongLagThreshold(void){}
void I_UpdateSongLagConditions(void){}
/// ------------------------
/// MUSIC FADING
/// ------------------------

View file

@ -185,6 +185,16 @@ INT32 AngleDeltaSigned(angle_t a1, angle_t a2)
return (INT32)(a1) - (INT32)(a2);
}
float AngleToFloat(angle_t x)
{
return x / (float)ANG1;
}
angle_t FloatToAngle(float f)
{
return (angle_t)(f * ANG1);
}
#include "t_ftan.c"
#include "t_fsin.c"

View file

@ -108,6 +108,8 @@ FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor);
// difference between two angle_t
FUNCMATH INT32 AngleDelta(angle_t a1, angle_t a2);
FUNCMATH INT32 AngleDeltaSigned(angle_t a1, angle_t a2);
FUNCMATH float AngleToFloat(angle_t x);
FUNCMATH angle_t FloatToAngle(float f);
/// The FixedAcos function
FUNCMATH angle_t FixedAcos(fixed_t x);

View file

@ -45,7 +45,7 @@ UINT8 *screens[5];
// screens[3] = fade screen start
// screens[4] = fade screen end, postimage tempoarary buffer
consvar_t cv_ticrate = CVAR_INIT ("showfps", "No", 0, CV_YesNo, NULL);
consvar_t cv_ticrate = CVAR_INIT ("showfps", "No", CV_SAVE, CV_YesNo, NULL);
static void CV_palette_OnChange(void);
@ -2216,6 +2216,18 @@ void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *st
V_DrawThinString(x, y, option, string);
}
void V_DrawCenteredThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
{
x -= (V_ThinStringWidth(string, option) / 2) * FRACUNIT;
V_DrawThinStringAtFixed(x, y, option, string);
}
void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
{
x -= V_ThinStringWidth(string, option) * FRACUNIT;
V_DrawThinStringAtFixed(x, y, option, string);
}
// Draws a number using the PING font thingy.
// TODO: Merge number drawing functions into one with "font name" selection.

View file

@ -261,6 +261,8 @@ void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *st
#define V_DrawThinStringAtFixed( x,y,option,string ) \
V__DrawOneScaleString (x,y,FRACUNIT,option,TINY_FONT,string)
void V_DrawCenteredThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
void V_DrawRightAlignedThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);
// Draws a titlecard font string.
// timer: when the letters start appearing (leave to 0 to disable)

View file

@ -69,6 +69,8 @@
#include "m_misc.h" // M_MapNumber
#include "g_game.h" // G_SetGameModified
#include "k_terrain.h"
#ifdef HWRENDER
#include "hardware/hw_main.h"
#include "hardware/hw_glob.h"
@ -866,6 +868,8 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
break;
}
K_InitTerrain(numwadfiles - 1);
if (refreshdirmenu & REFRESHDIR_GAMEDATA)
G_LoadGameData();
DEH_UpdateMaxFreeslots();