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

This commit is contained in:
toaster 2022-11-26 16:43:21 +00:00
commit 00e28b2915
42 changed files with 2349 additions and 1777 deletions

View file

@ -2550,6 +2550,9 @@ void CL_ClearPlayer(INT32 playernum)
memset(&players[playernum], 0, sizeof (player_t));
players[playernum].followerskin = -1; // don't have a ghost follower
players[playernum].fakeskin = players[playernum].lastfakeskin = MAXSKINS; // don't avoid eggman
RemoveAdminPlayer(playernum); // don't stay admin after you're gone
}

View file

@ -35,8 +35,8 @@
// Extra abilities/settings for skins (combinable stuff)
typedef enum
{
SF_HIRES = 1, // Draw the sprite at different size?
SF_MACHINE = 1<<1, // Beep boop. Are you a robot?
SF_MACHINE = 1, // Beep boop. Are you a robot?
SF_IRONMAN = 1<<1, // Pick a new skin during POSITION. I main Random!
// free up to and including 1<<31
} skinflags_t;
@ -310,6 +310,8 @@ typedef struct botvars_s
UINT8 diffincrease; // In GP: bot difficulty will increase this much next round
boolean rival; // If true, they're the GP rival
// All entries above persist between rounds and must be recorded in demos
fixed_t rubberband; // Bot rubberband value
UINT16 controller; // Special bot controller linedef ID
@ -385,6 +387,9 @@ typedef struct player_s
INT32 skin;
UINT32 availabilities;
UINT8 fakeskin; // ironman
UINT8 lastfakeskin;
UINT8 kartspeed; // Kart speed stat between 1 and 9
UINT8 kartweight; // Kart weight stat between 1 and 9

View file

@ -3282,6 +3282,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
//"S_ITEMCAPSULE_BOTTOM",
//"S_ITEMCAPSULE_INSIDE",
"S_MAGICIANBOX",
"S_MAGICIANBOXTOP",
"S_MAGICIANBOXBOTTOM",
// Signpost sparkles
"S_SIGNSPARK1",
"S_SIGNSPARK2",
@ -5284,6 +5288,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_FLOATINGITEM",
"MT_ITEMCAPSULE",
"MT_ITEMCAPSULE_PART",
"MT_MAGICIANBOX",
"MT_SIGNSPARKLE",
@ -6323,8 +6328,8 @@ struct int_const_s const INT_CONST[] = {
{"CR_ZOOMTUBE",CR_ZOOMTUBE},
// Character flags (skinflags_t)
{"SF_HIRES",SF_HIRES},
{"SF_MACHINE",SF_MACHINE},
{"SF_IRONMAN",SF_IRONMAN},
// Sound flags
{"SF_TOTALLYSINGLE",SF_TOTALLYSINGLE},
@ -6691,6 +6696,7 @@ struct int_const_s const INT_CONST[] = {
{"V_OVERLAY",V_OVERLAY},
{"V_ALLOWLOWERCASE",V_ALLOWLOWERCASE},
{"V_FLIP",V_FLIP},
{"V_VFLIP",V_VFLIP},
{"V_SNAPTOTOP",V_SNAPTOTOP},
{"V_SNAPTOBOTTOM",V_SNAPTOBOTTOM},
{"V_SNAPTOLEFT",V_SNAPTOLEFT},

View file

@ -2729,7 +2729,7 @@ void F_EndTextPrompt(boolean forceexec, boolean noexec)
// \todo net safety, maybe loop all player thinkers?
if ((promptwasactive || forceexec) && !noexec && promptpostexectag)
{
if (tmthing) // edge case where starting an invalid prompt immediately on level load will make P_MapStart fail
if (tm.thing) // edge case where starting an invalid prompt immediately on level load will make P_MapStart fail
P_LinedefExecute(promptpostexectag, promptmo, NULL);
else
{

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,13 @@ extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality;
extern tic_t demostarttime;
typedef struct democharlist_s {
UINT8 mapping; // No, this isn't about levels. It maps to loaded character ID.
UINT8 kartspeed;
UINT8 kartweight;
UINT32 flags;
} democharlist_t;
// Publicly-accessible demo vars
struct demovars_s {
char titlename[65];
@ -54,6 +61,9 @@ struct demovars_s {
boolean freecam;
UINT8 numskins;
democharlist_t *skinlist;
UINT8 currentskinid[MAXPLAYERS];
};
extern struct demovars_s demo;
@ -102,20 +112,18 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname);
typedef enum
{
GHC_NORMAL = 0,
GHC_SUPER,
GHC_FIREFLOWER,
GHC_INVINCIBLE,
GHC_RETURNSKIN // not actually a colour
GHC_SUPER
} ghostcolor_t;
extern UINT8 demo_extradata[MAXPLAYERS];
extern UINT8 demo_writerng;
#define DXD_RESPAWN 0x01 // "respawn" command in console
#define DXD_SKIN 0x02 // skin changed
#define DXD_NAME 0x04 // name changed
#define DXD_COLOR 0x08 // color changed
#define DXD_PLAYSTATE 0x10 // state changed between playing, spectating, or not in-game
#define DXD_PLAYSTATE 0x01 // state changed between playing, spectating, or not in-game
#define DXD_RESPAWN 0x02 // "respawn" command in console
#define DXD_SKIN 0x04 // skin changed
#define DXD_NAME 0x08 // name changed
#define DXD_COLOR 0x10 // color changed
#define DXD_FOLLOWER 0x20 // follower was changed
#define DXD_WEAPONPREF 0x40 // netsynced playsim settings were changed
@ -123,6 +131,8 @@ extern UINT8 demo_writerng;
#define DXD_PST_SPECTATING 0x02
#define DXD_PST_LEFT 0x03
#define DXD_PST_ISBOT 0x80 // extra flag
// Record/playback tics
void G_ReadDemoExtraData(void);
void G_WriteDemoExtraData(void);
@ -155,6 +165,8 @@ typedef struct demoghost {
UINT8 *buffer, *p, color;
UINT8 fadein;
UINT16 version;
UINT8 numskins;
democharlist_t *skinlist;
mobj_t oldmo, *mo;
struct demoghost *next;
} demoghost;

View file

@ -2239,6 +2239,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
UINT16 skincolor;
INT32 skin;
UINT32 availabilities;
UINT8 fakeskin;
UINT8 lastfakeskin;
tic_t jointime;
@ -2285,9 +2287,21 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
skincolor = players[player].skincolor;
skin = players[player].skin;
// SRB2kart
kartspeed = players[player].kartspeed;
kartweight = players[player].kartweight;
if (betweenmaps)
{
fakeskin = MAXSKINS;
kartspeed = skins[players[player].skin].kartspeed;
kartweight = skins[players[player].skin].kartweight;
charflags = skins[players[player].skin].flags;
}
else
{
fakeskin = players[player].fakeskin;
kartspeed = players[player].kartspeed;
kartweight = players[player].kartweight;
charflags = players[player].charflags;
}
lastfakeskin = players[player].lastfakeskin;
followerready = players[player].followerready;
followercolor = players[player].followercolor;
@ -2295,8 +2309,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
availabilities = players[player].availabilities;
charflags = players[player].charflags;
followitem = players[player].followitem;
bot = players[player].bot;
@ -2413,10 +2425,13 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
// save player config truth reborn
p->skincolor = skincolor;
p->skin = skin;
p->fakeskin = fakeskin;
p->kartspeed = kartspeed;
p->kartweight = kartweight;
//
p->charflags = charflags;
p->lastfakeskin = lastfakeskin;
p->availabilities = availabilities;
p->followitem = followitem;
@ -2549,7 +2564,7 @@ static boolean G_CheckSpot(INT32 playernum, mapthing_t *mthing)
if (!K_CheckPlayersRespawnColliding(playernum, x, y))
return false;
if (!P_CheckPosition(players[playernum].mo, x, y))
if (!P_CheckPosition(players[playernum].mo, x, y, NULL))
return false;
return true;

View file

@ -188,7 +188,10 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
offsetx = (float)(gpatch->leftoffset) * fscalew;
// top offset
offsety = (float)(gpatch->topoffset) * fscaleh;
if (option & V_VFLIP)
offsety = (float)(gpatch->height - gpatch->topoffset) * fscaleh;
else
offsety = (float)(gpatch->topoffset) * fscaleh;
cx -= offsetx;
cy -= offsety;
@ -249,8 +252,16 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
v[2].s = v[1].s = hwrPatch->max_s;
}
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = hwrPatch->max_t;
if (option & V_VFLIP)
{
v[0].t = v[1].t = hwrPatch->max_t;
v[2].t = v[3].t = 0.0f;
}
else
{
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = hwrPatch->max_t;
}
flags = PF_NoDepthTest;

View file

@ -5298,7 +5298,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
flip ^= (1<<rot);
}
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
if (thing->skin && ((skin_t *)thing->skin)->highresscale != FRACUNIT)
this_scale *= FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale);
spr_width = spritecachedinfo[lumpoff].width;

View file

@ -543,6 +543,9 @@ char sprnames[NUMSPRITES + 1][5] =
"KINF", // Invincibility flash
"INVI", // Invincibility speedlines
"ICAP", // Item capsules
"MGBX", // Heavy Magician transform box
"MGBT", // Heavy Magician transform box top
"MGBB", // Heavy Magician transform box bottom
"WIPD", // Wipeout dust trail
"DRIF", // Drift Sparks
@ -3891,6 +3894,10 @@ state_t states[NUMSTATES] =
//{SPR_ICAP, FF_FLOORSPRITE|4, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM
//{SPR_ICAP, FF_FLOORSPRITE|5, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_INSIDE
{SPR_MGBX, FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_MAGICIANBOX
{SPR_MGBT, FF_FLOORSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_MAGICIANBOX_TOP
{SPR_MGBB, FF_FLOORSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_MAGICIANBOX_BOTTOM
{SPR_SGNS, FF_ADD|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1
{SPR_SGNS, FF_ADD|FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2
{SPR_SGNS, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_SIGNSPARK4}, // S_SIGNSPARK3
@ -22398,6 +22405,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_MAGICIANBOX
-1, // doomednum
S_MAGICIANBOX, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
20*FRACUNIT, // radius
20*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
{ // MT_SIGNSPARKLE
-1, // doomednum
S_SIGNSPARK1, // spawnstate

View file

@ -1089,6 +1089,9 @@ typedef enum sprite
SPR_KINF, // Invincibility flash
SPR_INVI, // Invincibility speedlines
SPR_ICAP, // Item capsules
SPR_MGBX, // Heavy Magician transform box
SPR_MGBT, // Heavy Magician transform box top
SPR_MGBB, // Heavy Magician transform box bottom
SPR_WIPD, // Wipeout dust trail
SPR_DRIF, // Drift Sparks
@ -4295,6 +4298,10 @@ typedef enum state
//S_ITEMCAPSULE_BOTTOM,
//S_ITEMCAPSULE_INSIDE,
S_MAGICIANBOX,
S_MAGICIANBOX_TOP,
S_MAGICIANBOX_BOTTOM,
// Signpost sparkles
S_SIGNSPARK1,
S_SIGNSPARK2,
@ -6333,6 +6340,7 @@ typedef enum mobj_type
MT_FLOATINGITEM,
MT_ITEMCAPSULE,
MT_ITEMCAPSULE_PART,
MT_MAGICIANBOX,
MT_SIGNSPARKLE,

View file

@ -655,12 +655,12 @@ boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2)
{
// Counter desyncs
/*mobj_t *oldthing = thing;
mobj_t *oldtmthing = tmthing;
mobj_t *oldtm.thing = tm.thing;
P_Thrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y), 4*thing->scale);
P_Thrust(tm.thing, R_PointToAngle2(thing->x, thing->y, tm.thing->x, tm.thing->y), 4*thing->scale);
thing = oldthing;
P_SetTarget(&tmthing, oldtmthing);*/
P_SetTarget(&tm.thing, oldtm.thing);*/
if (P_PlayerInPain(t2->player)
|| t2->player->flashing || t2->player->hyudorotimer

View file

@ -1745,7 +1745,10 @@ static boolean K_drawKartPositionFaces(void)
boolean completed[MAXPLAYERS];
INT32 rankplayer[MAXPLAYERS];
INT32 bumperx, emeraldx, numplayersingame = 0;
INT32 xoff, yoff, flipflag = 0;
UINT8 workingskin;
UINT8 *colormap;
UINT32 skinflags;
ranklines = 0;
memset(completed, 0, sizeof (completed));
@ -1830,15 +1833,36 @@ static boolean K_drawKartPositionFaces(void)
bumperx = FACE_X+19;
emeraldx = FACE_X+16;
skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[rankplayer[i]]].flags
: skins[players[rankplayer[i]].skin].flags;
// Flip SF_IRONMAN portraits, but only if they're transformed
if (skinflags & SF_IRONMAN
&& !(players[rankplayer[i]].charflags & SF_IRONMAN) )
{
flipflag = V_FLIP|V_VFLIP; // blonic flip
xoff = yoff = 16;
} else
{
flipflag = 0;
xoff = yoff = 0;
}
if (players[rankplayer[i]].mo->color)
{
colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE);
if ((skin_t*)players[rankplayer[i]].mo->skin)
workingskin = (skin_t*)players[rankplayer[i]].mo->skin - skins;
else
workingskin = players[rankplayer[i]].skin;
colormap = R_GetTranslationColormap(workingskin, players[rankplayer[i]].mo->color, GTC_CACHE);
if (players[rankplayer[i]].mo->colorized)
colormap = R_GetTranslationColormap(TC_RAINBOW, players[rankplayer[i]].mo->color, GTC_CACHE);
else
colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE);
colormap = R_GetTranslationColormap(workingskin, players[rankplayer[i]].mo->color, GTC_CACHE);
V_DrawMappedPatch(FACE_X, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin][FACE_RANK], colormap);
V_DrawMappedPatch(FACE_X + xoff, Y + yoff, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT|flipflag, faceprefix[workingskin][FACE_RANK], colormap);
if (LUA_HudEnabled(hud_battlebumpers))
{

View file

@ -2717,6 +2717,47 @@ void K_SpawnBumpEffect(mobj_t *mo)
S_StartSound(mo, sfx_s3k49);
}
void K_SpawnMagicianParticles(mobj_t *mo, int spread)
{
INT32 i;
mobj_t *target = mo->target;
if (P_MobjWasRemoved(target))
target = mo;
for (i = 0; i < 16; i++)
{
fixed_t hmomentum = P_RandomRange(PR_DECORATION, spread * -1, spread) * mo->scale;
fixed_t vmomentum = P_RandomRange(PR_DECORATION, spread * -1, spread) * mo->scale;
UINT16 color = P_RandomKey(PR_DECORATION, numskincolors);
fixed_t ang = FixedAngle(P_RandomRange(PR_DECORATION, 0, 359)*FRACUNIT);
SINT8 flip = 1;
mobj_t *dust;
if (i & 1)
ang -= ANGLE_90;
else
ang += ANGLE_90;
dust = P_SpawnMobjFromMobj(mo,
FixedMul(mo->radius, FINECOSINE(ang >> ANGLETOFINESHIFT)),
FixedMul(mo->radius, FINESINE(ang >> ANGLETOFINESHIFT)),
target->height, (i%3 == 0) ? MT_SIGNSPARKLE : MT_SPINDASHDUST
);
flip = P_MobjFlip(dust);
dust->momx = target->momx + FixedMul(hmomentum, FINECOSINE(ang >> ANGLETOFINESHIFT));
dust->momy = target->momy + FixedMul(hmomentum, FINESINE(ang >> ANGLETOFINESHIFT));
dust->momz = vmomentum * flip;
dust->scale = dust->scale*4;
dust->frame |= FF_SUBTRACT|FF_TRANS90;
dust->color = color;
dust->colorized = true;
}
}
static SINT8 K_GlanceAtPlayers(player_t *glancePlayer)
{
const fixed_t maxdistance = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
@ -3445,6 +3486,8 @@ boolean K_WaterRun(mobj_t *mobj)
case MT_PLAYER:
{
fixed_t minspeed = 0;
if (mobj->player == NULL)
{
return false;
@ -3455,11 +3498,18 @@ boolean K_WaterRun(mobj_t *mobj)
return K_IsHoldingDownTop(mobj->player) == false;
}
minspeed = 2 * K_GetKartSpeed(mobj->player, false, false); // 200%
if (mobj->player->speed < minspeed / 5) // 40%
{
return false;
}
if (mobj->player->invincibilitytimer
|| mobj->player->sneakertimer
|| mobj->player->tiregrease
|| mobj->player->flamedash
|| mobj->player->speed > 2 * K_GetKartSpeed(mobj->player, false, false))
|| mobj->player->speed > minspeed)
{
return true;
}
@ -10362,6 +10412,9 @@ boolean K_FastFallBounce(player_t *player)
}
}
if (player->mo->eflags & MFE_UNDERWATER)
bounce = (117 * bounce) / 200;
S_StartSound(player->mo, sfx_ffbonc);
player->mo->momz = bounce * P_MobjFlip(player->mo);

View file

@ -110,6 +110,7 @@ void K_SpawnBoostTrail(player_t *player);
void K_SpawnSparkleTrail(mobj_t *mo);
void K_SpawnWipeoutTrail(mobj_t *mo);
void K_SpawnDraftDust(mobj_t *mo);
void K_SpawnMagicianParticles(mobj_t *mo, int spread);
void K_DriftDustHandling(mobj_t *spawner);
void K_Squish(mobj_t *mo);
mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow, angle_t angleOffset);

View file

@ -1250,7 +1250,7 @@ static boolean M_DrawCharacterSprite(INT16 x, INT16 y, INT16 skin, boolean charf
addflags ^= V_FLIP; // This sprite is left/right flipped!
}
if (skins[skin].flags & SF_HIRES)
if (skins[skin].highresscale != FRACUNIT)
{
V_DrawFixedPatch(x<<FRACBITS,
y<<FRACBITS,

View file

@ -999,108 +999,108 @@ static int lib_pRemoveFloorSpriteSlope(lua_State *L)
static int lib_pRailThinker(lua_State *L)
{
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
NOHUD
INLEVEL
if (!mobj)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_RailThinker(mobj));
P_SetTarget(&tmthing, ptmthing);
P_RestoreTMStruct(ptm);
return 1;
}
static int lib_pXYMovement(lua_State *L)
{
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
NOHUD
INLEVEL
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
P_XYMovement(actor);
P_SetTarget(&tmthing, ptmthing);
P_RestoreTMStruct(ptm);
return 0;
}
static int lib_pRingXYMovement(lua_State *L)
{
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
NOHUD
INLEVEL
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
P_RingXYMovement(actor);
P_SetTarget(&tmthing, ptmthing);
P_RestoreTMStruct(ptm);
return 0;
}
static int lib_pSceneryXYMovement(lua_State *L)
{
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
NOHUD
INLEVEL
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
P_SceneryXYMovement(actor);
P_SetTarget(&tmthing, ptmthing);
P_RestoreTMStruct(ptm);
return 0;
}
static int lib_pZMovement(lua_State *L)
{
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
NOHUD
INLEVEL
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_ZMovement(actor));
P_CheckPosition(actor, actor->x, actor->y);
P_SetTarget(&tmthing, ptmthing);
P_CheckPosition(actor, actor->x, actor->y, NULL);
P_RestoreTMStruct(ptm);
return 1;
}
static int lib_pRingZMovement(lua_State *L)
{
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
NOHUD
INLEVEL
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
P_RingZMovement(actor);
P_CheckPosition(actor, actor->x, actor->y);
P_SetTarget(&tmthing, ptmthing);
P_CheckPosition(actor, actor->x, actor->y, NULL);
P_RestoreTMStruct(ptm);
return 0;
}
static int lib_pSceneryZMovement(lua_State *L)
{
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
NOHUD
INLEVEL
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_SceneryZMovement(actor));
P_CheckPosition(actor, actor->x, actor->y);
P_SetTarget(&tmthing, ptmthing);
P_CheckPosition(actor, actor->x, actor->y, NULL);
P_RestoreTMStruct(ptm);
return 1;
}
static int lib_pPlayerZMovement(lua_State *L)
{
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
NOHUD
INLEVEL
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
P_PlayerZMovement(actor);
P_CheckPosition(actor, actor->x, actor->y);
P_SetTarget(&tmthing, ptmthing);
P_CheckPosition(actor, actor->x, actor->y, NULL);
P_RestoreTMStruct(ptm);
return 0;
}
@ -1302,13 +1302,13 @@ static int lib_pGivePlayerLives(lua_State *L)
static int lib_pMovePlayer(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
P_MovePlayer(player);
P_SetTarget(&tmthing, ptmthing);
P_RestoreTMStruct(ptm);
return 0;
}
@ -1380,7 +1380,7 @@ static int lib_pNukeEnemies(lua_State *L)
static int lib_pCheckPosition(lua_State *L)
{
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3);
@ -1388,15 +1388,15 @@ static int lib_pCheckPosition(lua_State *L)
INLEVEL
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_CheckPosition(thing, x, y));
LUA_PushUserdata(L, tmthing, META_MOBJ);
P_SetTarget(&tmthing, ptmthing);
lua_pushboolean(L, P_CheckPosition(thing, x, y, NULL));
LUA_PushUserdata(L, tm.thing, META_MOBJ);
P_RestoreTMStruct(ptm);
return 2;
}
static int lib_pTryMove(lua_State *L)
{
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3);
@ -1405,15 +1405,15 @@ static int lib_pTryMove(lua_State *L)
INLEVEL
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_TryMove(thing, x, y, allowdropoff));
LUA_PushUserdata(L, tmthing, META_MOBJ);
P_SetTarget(&tmthing, ptmthing);
lua_pushboolean(L, P_TryMove(thing, x, y, allowdropoff, NULL));
LUA_PushUserdata(L, tm.thing, META_MOBJ);
P_RestoreTMStruct(ptm);
return 2;
}
static int lib_pMove(lua_State *L)
{
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t speed = luaL_checkfixed(L, 2);
NOHUD
@ -1421,14 +1421,14 @@ static int lib_pMove(lua_State *L)
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_Move(actor, speed));
LUA_PushUserdata(L, tmthing, META_MOBJ);
P_SetTarget(&tmthing, ptmthing);
LUA_PushUserdata(L, tm.thing, META_MOBJ);
P_RestoreTMStruct(ptm);
return 2;
}
static int lib_pTeleportMove(lua_State *L)
{
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3);
@ -1439,14 +1439,14 @@ static int lib_pTeleportMove(lua_State *L)
return LUA_ErrInvalid(L, "mobj_t");
LUA_Deprecated(L, "P_TeleportMove", "P_SetOrigin\" or \"P_MoveOrigin");
lua_pushboolean(L, P_MoveOrigin(thing, x, y, z));
LUA_PushUserdata(L, tmthing, META_MOBJ);
P_SetTarget(&tmthing, ptmthing);
LUA_PushUserdata(L, tm.thing, META_MOBJ);
P_RestoreTMStruct(ptm);
return 2;
}
static int lib_pSetOrigin(lua_State *L)
{
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3);
@ -1456,14 +1456,14 @@ static int lib_pSetOrigin(lua_State *L)
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_SetOrigin(thing, x, y, z));
LUA_PushUserdata(L, tmthing, META_MOBJ);
P_SetTarget(&tmthing, ptmthing);
LUA_PushUserdata(L, tm.thing, META_MOBJ);
P_RestoreTMStruct(ptm);
return 2;
}
static int lib_pMoveOrigin(lua_State *L)
{
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3);
@ -1473,8 +1473,8 @@ static int lib_pMoveOrigin(lua_State *L)
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_MoveOrigin(thing, x, y, z));
LUA_PushUserdata(L, tmthing, META_MOBJ);
P_SetTarget(&tmthing, ptmthing);
LUA_PushUserdata(L, tm.thing, META_MOBJ);
P_RestoreTMStruct(ptm);
return 2;
}
@ -1520,23 +1520,31 @@ static int lib_pSetRoll(lua_State *L)
static int lib_pSlideMove(lua_State *L)
{
/*
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
P_SlideMove(mo);
*/
LUA_UsageWarning(L, "FIXME: P_SlideMove needs updated to use result from P_TryMove");
(void)L;
return 0;
}
static int lib_pBounceMove(lua_State *L)
{
/*
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
P_BounceMove(mo);
*/
LUA_UsageWarning(L, "FIXME: P_BounceMove needs updated to use result from P_TryMove");
(void)L;
return 0;
}

View file

@ -722,7 +722,7 @@ static int sector_set(lua_State *L)
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
case sector_floorheight: { // floorheight
boolean flag;
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
fixed_t lastpos = sector->floorheight;
sector->floorheight = luaL_checkfixed(L, 3);
flag = P_CheckSector(sector, true);
@ -731,12 +731,12 @@ static int sector_set(lua_State *L)
sector->floorheight = lastpos;
P_CheckSector(sector, true);
}
P_SetTarget(&tmthing, ptmthing);
P_RestoreTMStruct(ptm);
break;
}
case sector_ceilingheight: { // ceilingheight
boolean flag;
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
fixed_t lastpos = sector->ceilingheight;
sector->ceilingheight = luaL_checkfixed(L, 3);
flag = P_CheckSector(sector, true);
@ -745,7 +745,7 @@ static int sector_set(lua_State *L)
sector->ceilingheight = lastpos;
P_CheckSector(sector, true);
}
P_SetTarget(&tmthing, ptmthing);
P_RestoreTMStruct(ptm);
break;
}
case sector_floorpic:
@ -2127,7 +2127,7 @@ static int ffloor_set(lua_State *L)
case ffloor_topheight: { // topheight
boolean flag;
fixed_t lastpos = *ffloor->topheight;
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
sector_t *sector = &sectors[ffloor->secnum];
sector->ceilingheight = luaL_checkfixed(L, 3);
flag = P_CheckSector(sector, true);
@ -2136,7 +2136,7 @@ static int ffloor_set(lua_State *L)
*ffloor->topheight = lastpos;
P_CheckSector(sector, true);
}
P_SetTarget(&tmthing, ptmthing);
P_RestoreTMStruct(ptm);
break;
}
case ffloor_toppic:
@ -2148,7 +2148,7 @@ static int ffloor_set(lua_State *L)
case ffloor_bottomheight: { // bottomheight
boolean flag;
fixed_t lastpos = *ffloor->bottomheight;
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
sector_t *sector = &sectors[ffloor->secnum];
sector->floorheight = luaL_checkfixed(L, 3);
flag = P_CheckSector(sector, true);
@ -2157,7 +2157,7 @@ static int ffloor_set(lua_State *L)
*ffloor->bottomheight = lastpos;
P_CheckSector(sector, true);
}
P_SetTarget(&tmthing, ptmthing);
P_RestoreTMStruct(ptm);
break;
}
case ffloor_bottompic:

View file

@ -515,14 +515,14 @@ static int mobj_set(lua_State *L)
case mobj_z:
{
// z doesn't cross sector bounds so it's okay.
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
mo->z = luaL_checkfixed(L, 3);
P_CheckPosition(mo, mo->x, mo->y);
mo->floorz = tmfloorz;
mo->ceilingz = tmceilingz;
mo->floorrover = tmfloorrover;
mo->ceilingrover = tmceilingrover;
P_SetTarget(&tmthing, ptmthing);
P_CheckPosition(mo, mo->x, mo->y, NULL);
mo->floorz = tm.floorz;
mo->ceilingz = tm.ceilingz;
mo->floorrover = tm.floorrover;
mo->ceilingrover = tm.ceilingrover;
P_RestoreTMStruct(ptm);
break;
}
case mobj_snext:
@ -583,30 +583,30 @@ static int mobj_set(lua_State *L)
return NOSET;
case mobj_radius:
{
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
mo->radius = luaL_checkfixed(L, 3);
if (mo->radius < 0)
mo->radius = 0;
P_CheckPosition(mo, mo->x, mo->y);
mo->floorz = tmfloorz;
mo->ceilingz = tmceilingz;
mo->floorrover = tmfloorrover;
mo->ceilingrover = tmceilingrover;
P_SetTarget(&tmthing, ptmthing);
P_CheckPosition(mo, mo->x, mo->y, NULL);
mo->floorz = tm.floorz;
mo->ceilingz = tm.ceilingz;
mo->floorrover = tm.floorrover;
mo->ceilingrover = tm.ceilingrover;
P_RestoreTMStruct(ptm);
break;
}
case mobj_height:
{
mobj_t *ptmthing = tmthing;
tm_t ptm = tm;
mo->height = luaL_checkfixed(L, 3);
if (mo->height < 0)
mo->height = 0;
P_CheckPosition(mo, mo->x, mo->y);
mo->floorz = tmfloorz;
mo->ceilingz = tmceilingz;
mo->floorrover = tmfloorrover;
mo->ceilingrover = tmceilingrover;
P_SetTarget(&tmthing, ptmthing);
P_CheckPosition(mo, mo->x, mo->y, NULL);
mo->floorz = tm.floorz;
mo->ceilingz = tm.ceilingz;
mo->floorrover = tm.floorrover;
mo->ceilingrover = tm.ceilingrover;
P_RestoreTMStruct(ptm);
break;
}
case mobj_momx:

View file

@ -410,6 +410,10 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->skin);
else if (fastcmp(field,"availabilities"))
lua_pushinteger(L, plr->availabilities);
else if (fastcmp(field,"fakeskin"))
lua_pushinteger(L, plr->fakeskin);
else if (fastcmp(field,"lastfakeskin"))
lua_pushinteger(L, plr->lastfakeskin);
else if (fastcmp(field,"score"))
lua_pushinteger(L, plr->score);
// SRB2kart
@ -575,6 +579,10 @@ static int player_set(lua_State *L)
return NOSET;
else if (fastcmp(field,"availabilities"))
return NOSET;
else if (fastcmp(field,"fakeskin"))
return NOSET;
else if (fastcmp(field,"lastfakeskin"))
return NOSET;
else if (fastcmp(field,"score"))
plr->score = luaL_checkinteger(L, 3);
// SRB2kart

View file

@ -46,6 +46,7 @@ typedef enum
PR_PLAYERSTARTS, // Player starts
PR_VOICES, // Player voice sounds
PR_RANDOMSKIN, // Random skin select from Heavy Magician(?)
PR_RULESCRAMBLE, // Rule scrambing events

View file

@ -358,9 +358,9 @@ void Obj_OrbinautJawzMoveHeld(player_t *player)
cur->momy = FixedMul(FINESINE(cur->angle >> ANGLETOFINESHIFT), orbinaut_shield_dist(cur));
cur->flags &= ~MF_NOCLIPTHING;
if (!P_TryMove(cur, player->mo->x + cur->momx, player->mo->y + cur->momy, true))
if (!P_TryMove(cur, player->mo->x + cur->momx, player->mo->y + cur->momy, true, NULL))
{
P_SlideMove(cur);
P_SlideMove(cur, NULL);
}
if (P_IsObjectOnGround(player->mo))

View file

@ -541,12 +541,12 @@ boolean P_Move(mobj_t *actor, fixed_t speed)
if (actor->type == MT_SKIM && !P_WaterInSector(actor, tryx, tryy)) // bail out if sector lacks water
return false;
if (!P_TryMove(actor, tryx, tryy, false))
if (!P_TryMove(actor, tryx, tryy, false, NULL))
{
if (actor->flags & MF_FLOAT && floatok)
if (actor->flags & MF_FLOAT && tm.floatok)
{
// must adjust height
if (actor->z < tmfloorz)
if (actor->z < tm.floorz)
actor->z += FixedMul(FLOATSPEED, actor->scale);
else
actor->z -= FixedMul(FLOATSPEED, actor->scale);
@ -1074,7 +1074,7 @@ void A_FaceStabRev(mobj_t *actor)
}
else
{
P_TryMove(actor, actor->x - P_ReturnThrustX(actor, actor->angle, 2<<FRACBITS), actor->y - P_ReturnThrustY(actor, actor->angle, 2<<FRACBITS), false);
P_TryMove(actor, actor->x - P_ReturnThrustX(actor, actor->angle, 2<<FRACBITS), actor->y - P_ReturnThrustY(actor, actor->angle, 2<<FRACBITS), false, NULL);
P_FaceStabFlume(actor);
}
}
@ -1126,7 +1126,7 @@ void A_FaceStabHurl(mobj_t *actor)
if (P_TryMove(actor,
actor->x + P_ReturnThrustX(actor, dirang, actor->extravalue2<<FRACBITS),
actor->y + P_ReturnThrustY(actor, dirang, actor->extravalue2<<FRACBITS),
false))
false, NULL))
{
// Do the spear damage.
#define NUMSTEPS 3
@ -1196,7 +1196,7 @@ void A_FaceStabMiss(mobj_t *actor)
if (actor->extravalue2 <= 0 || !P_TryMove(actor,
actor->x + P_ReturnThrustX(actor, actor->angle, actor->extravalue2<<FRACBITS),
actor->y + P_ReturnThrustY(actor, actor->angle, actor->extravalue2<<FRACBITS),
false))
false, NULL))
{
actor->extravalue2 = 0;
P_SetMobjState(actor, locvar2);
@ -1821,7 +1821,7 @@ void A_CrushstaceanWalk(mobj_t *actor)
if (!P_TryMove(actor,
actor->x + P_ReturnThrustX(actor, ang, locvar1*actor->scale),
actor->y + P_ReturnThrustY(actor, ang, locvar1*actor->scale),
false)
false, NULL)
|| (actor->reactiontime-- <= 0))
{
actor->flags2 ^= MF2_AMBUSH;
@ -2000,7 +2000,7 @@ void A_CrushclawLaunch(mobj_t *actor)
if (!P_TryMove(actor,
actor->target->x + P_ReturnThrustX(actor, actor->target->angle, actor->extravalue2*actor->scale),
actor->target->y + P_ReturnThrustY(actor, actor->target->angle, actor->extravalue2*actor->scale),
true)
true, NULL)
&& !locvar1)
{
actor->extravalue1 = 0;
@ -2946,9 +2946,9 @@ void A_Boss1Laser(mobj_t *actor)
{
fixed_t distx = P_ReturnThrustX(point, point->angle, point->radius);
fixed_t disty = P_ReturnThrustY(point, point->angle, point->radius);
if (P_TryMove(point, point->x + distx, point->y + disty, false) // prevents the sprite from clipping into the wall or dangling off ledges
&& P_TryMove(point, point->x - 2*distx, point->y - 2*disty, false)
&& P_TryMove(point, point->x + distx, point->y + disty, false))
if (P_TryMove(point, point->x + distx, point->y + disty, false, NULL) // prevents the sprite from clipping into the wall or dangling off ledges
&& P_TryMove(point, point->x - 2*distx, point->y - 2*disty, false, NULL)
&& P_TryMove(point, point->x + distx, point->y + disty, false, NULL))
{
if (point->info->seesound)
S_StartSound(point, point->info->seesound);
@ -3012,7 +3012,7 @@ void A_FocusTarget(mobj_t *actor)
{
actor->momx = 0, actor->momy = 0, actor->momz = 0;
actor->z = actor->target->z + (actor->target->height>>1);
P_TryMove(actor, actor->target->x, actor->target->y, true);
P_TryMove(actor, actor->target->x, actor->target->y, true, NULL);
}
break;
default:
@ -3168,7 +3168,7 @@ void A_SkullAttack(mobj_t *actor)
if (P_CheckMove(actor,\
P_ReturnThrustX(actor, testang, dist + 2*actor->radius),\
P_ReturnThrustY(actor, testang, dist + 2*actor->radius),\
true)) break;
true, NULL)) break;
if (P_RandomChance(PR_UNDEFINED, FRACUNIT/2)) // port priority 2?
{
@ -4483,13 +4483,13 @@ void A_MinusDigging(mobj_t *actor)
par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT);
if (actor->eflags & MFE_VERTICALFLIP)
par->eflags |= MFE_VERTICALFLIP;
P_TryMove(par, x, y, false);
P_TryMove(par, x, y, false, NULL);
// If close enough, prepare to attack
if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2)
{
P_SetMobjState(actor, actor->info->meleestate);
P_TryMove(actor, actor->target->x, actor->target->y, false);
P_TryMove(actor, actor->target->x, actor->target->y, false, NULL);
S_StartSound(actor, actor->info->attacksound);
// Spawn growing dirt pile.
@ -4532,7 +4532,7 @@ void A_MinusDigging(mobj_t *actor)
}
else
{
if (P_TryMove(actor->tracer, actor->x, actor->y, false))
if (P_TryMove(actor->tracer, actor->x, actor->y, false, NULL))
actor->tracer->z = mz;
else
P_SetTarget(&actor->tracer, NULL);
@ -5702,7 +5702,7 @@ void A_MixUp(mobj_t *actor)
players[i].mo->floorz = P_GetFloorZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL);
players[i].mo->ceilingz = P_GetCeilingZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL);
P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y);
P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y, NULL);
}
}
}
@ -6470,7 +6470,7 @@ void A_GuardChase(mobj_t *actor)
&& !P_TryMove(actor,
actor->x + P_ReturnThrustX(actor, actor->angle, speed),
actor->y + P_ReturnThrustY(actor, actor->angle, speed),
false)
false, NULL)
&& speed > 0) // can't be the same check as previous so that P_TryMove gets to happen.
{
INT32 direction = actor->spawnpoint ? actor->spawnpoint->args[0] : TMGD_BACK;
@ -9273,7 +9273,7 @@ void A_SpikeRetract(mobj_t *actor)
actor->flags &= ~MF_NOCLIPTHING;
}
if (actor->flags & MF_SOLID)
P_CheckPosition(actor, actor->x, actor->y);
P_CheckPosition(actor, actor->x, actor->y, NULL);
}
// Function: A_InfoState
@ -10421,13 +10421,13 @@ void A_FlickyCenter(mobj_t *actor)
{
actor->extravalue2 = 1;
P_SetOrigin(actor, actor->target->x, actor->target->y, actor->target->z);
tmthing = NULL;
P_SetTarget(&tm.thing, NULL);
}
else if(actor->extravalue2)
{
actor->extravalue2 = 0;
P_SetOrigin(actor, originx, originy, originz);
tmthing = NULL;
P_SetTarget(&tm.thing, NULL);
}
}
}
@ -11511,7 +11511,7 @@ void A_DoNPCSkid(mobj_t *actor)
locvar2 = FRACUNIT/2;
if ((FixedHypot(actor->momx, actor->momy) < locvar2)
|| !P_TryMove(actor, actor->x + actor->momx, actor->y + actor->momy, false))
|| !P_TryMove(actor, actor->x + actor->momx, actor->y + actor->momy, false, NULL))
{
actor->momx = actor->momy = 0;
P_SetMobjState(actor, locvar1);
@ -12286,7 +12286,7 @@ static void P_SnapperLegPlace(mobj_t *mo)
INT32 necklen = (32*(mo->info->reactiontime - mo->reactiontime))/mo->info->reactiontime; // Not in FU
seg->z = mo->z + ((mo->eflags & MFE_VERTICALFLIP) ? (((mo->height<<1)/3) - seg->height) : mo->height/3);
P_TryMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, true);
P_TryMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, true, NULL);
seg->angle = a;
// Move as many legs as available.
@ -12307,7 +12307,7 @@ static void P_SnapperLegPlace(mobj_t *mo)
x = c*o2 + s*o1;
y = s*o2 - c*o1;
seg->z = mo->z + (((mo->eflags & MFE_VERTICALFLIP) ? (mo->height - seg->height) : 0));
P_TryMove(seg, mo->x + x, mo->y + y, true);
P_TryMove(seg, mo->x + x, mo->y + y, true, NULL);
P_SetMobjState(seg, seg->info->raisestate);
}
else
@ -12442,7 +12442,7 @@ void A_SnapperThinker(mobj_t *actor)
c = FINECOSINE(fa);
s = FINESINE(fa);
P_TryMove(actor, actor->x + c*speed, actor->y + s*speed, false);
P_TryMove(actor, actor->x + c*speed, actor->y + s*speed, false, NULL);
// The snapper spawns dust if going fast!
if (actor->reactiontime < 4)

View file

@ -381,25 +381,48 @@ void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angl
// P_MAP
//
// If "floatok" true, move would be ok
// if within "tmfloorz - tmceilingz".
extern boolean floatok;
extern fixed_t tmfloorz;
extern fixed_t tmceilingz;
extern ffloor_t *tmfloorrover, *tmceilingrover;
extern mobj_t *tmfloorthing, *tmhitthing, *tmthing;
typedef struct tm_s
{
mobj_t *thing;
fixed_t x, y;
fixed_t bbox[4];
INT32 flags;
precipmobj_t *precipthing;
fixed_t precipbbox[4];
// If "floatok" true, move would be ok
// if within "tm.floorz - tm.ceilingz".
boolean floatok;
fixed_t floorz, ceilingz;
fixed_t dropoffz, drpoffceilz; // drop-off floor/ceiling heights
mobj_t *floorthing; // the thing corresponding to tm.floorz or NULL if tm.floorz is from a sector
mobj_t *hitthing; // the solid thing you bumped into (for collisions)
ffloor_t *floorrover, *ceilingrover;
pslope_t *floorslope, *ceilingslope;
INT32 floorpic, ceilingpic;
fixed_t floorstep, ceilingstep;
// keep track of the line that lowers the ceiling,
// so missiles don't explode against sky hack walls
line_t *ceilingline;
// set by PIT_CheckLine() for any line that stopped the PIT_CheckLine()
// that is, for any line which is 'solid'
line_t *blockingline;
} tm_t;
extern tm_t tm;
void P_RestoreTMStruct(tm_t tmrestore);
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);
extern void P_MapEnd(void);
extern line_t *ceilingline;
extern line_t *blockingline;
extern msecnode_t *sector_list;
extern mprecipsecnode_t *precipsector_list;
@ -408,20 +431,28 @@ void P_UnsetThingPosition(mobj_t *thing);
void P_SetThingPosition(mobj_t *thing);
void P_SetUnderlayPosition(mobj_t *thing);
typedef struct TryMoveResult_s
{
boolean success;
line_t *line;
mobj_t *mo;
} TryMoveResult_t;
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *result);
boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff, TryMoveResult_t *result);
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff, TryMoveResult_t *result);
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *result);
boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing);
boolean P_IsLineTripWire(const line_t *ld);
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
fixed_t P_BaseStepUp(void);
fixed_t P_GetThingStepUp(mobj_t *thing, fixed_t destX, fixed_t destY);
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_SlideMove(mobj_t *mo);
void P_BouncePlayerMove(mobj_t *mo);
void P_BounceMove(mobj_t *mo);
void P_SlideMove(mobj_t *mo, TryMoveResult_t *result);
void P_BounceMove(mobj_t *mo, TryMoveResult_t *result);
boolean P_CheckSight(mobj_t *t1, mobj_t *t2);
boolean P_TraceBlockingLines(mobj_t *t1, mobj_t *t2);
boolean P_TraceBotTraversal(mobj_t *t1, mobj_t *t2);

File diff suppressed because it is too large Load diff

View file

@ -379,8 +379,8 @@ void P_CameraLineOpening(line_t *linedef)
}
else
{
frontfloor = P_CameraGetFloorZ (mapcampointer, front, tmx, tmy, linedef);
frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef);
frontfloor = P_CameraGetFloorZ (mapcampointer, front, tm.x, tm.y, linedef);
frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tm.x, tm.y, linedef);
}
if (back->camsec >= 0)
@ -397,8 +397,8 @@ void P_CameraLineOpening(line_t *linedef)
}
else
{
backfloor = P_CameraGetFloorZ(mapcampointer, back, tmx, tmy, linedef);
backceiling = P_CameraGetCeilingZ(mapcampointer, back, tmx, tmy, linedef);
backfloor = P_CameraGetFloorZ(mapcampointer, back, tm.x, tm.y, linedef);
backceiling = P_CameraGetCeilingZ(mapcampointer, back, tm.x, tm.y, linedef);
}
{
@ -440,8 +440,8 @@ void P_CameraLineOpening(line_t *linedef)
if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef);
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tm.x, tm.y, linedef);
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tm.x, tm.y, linedef);
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
@ -464,8 +464,8 @@ void P_CameraLineOpening(line_t *linedef)
if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef);
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tm.x, tm.y, linedef);
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tm.x, tm.y, linedef);
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
@ -614,7 +614,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
return;
}
P_ClosestPointOnLine(tmx, tmy, linedef, &cross);
P_ClosestPointOnLine(tm.x, tm.y, linedef, &cross);
// Treat polyobjects kind of like 3D Floors
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT))
@ -656,8 +656,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
fixed_t height[2];
const sector_t * sector[2] = { front, back };
height[FRONT] = P_GetCeilingZ(mobj, front, tmx, tmy, linedef);
height[BACK] = P_GetCeilingZ(mobj, back, tmx, tmy, linedef);
height[FRONT] = P_GetCeilingZ(mobj, front, tm.x, tm.y, linedef);
height[BACK] = P_GetCeilingZ(mobj, back, tm.x, tm.y, linedef);
hi = ( height[0] < height[1] );
lo = ! hi;
@ -676,8 +676,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
openceilingdrop = ( topedge[hi] - topedge[lo] );
}
height[FRONT] = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
height[BACK] = P_GetFloorZ(mobj, back, tmx, tmy, linedef);
height[FRONT] = P_GetFloorZ(mobj, front, tm.x, tm.y, linedef);
height[BACK] = P_GetFloorZ(mobj, back, tm.x, tm.y, linedef);
hi = ( height[0] < height[1] );
lo = ! hi;
@ -818,8 +818,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|| (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
topheight = P_GetFOFTopZ(mobj, front, rover, tm.x, tm.y, linedef);
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tm.x, tm.y, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
@ -862,8 +862,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|| (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
topheight = P_GetFOFTopZ(mobj, back, rover, tm.x, tm.y, linedef);
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tm.x, tm.y, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
@ -1596,16 +1596,16 @@ boolean P_RadiusLinesCheck(fixed_t radius, fixed_t x, fixed_t y,
INT32 xl, xh, yl, yh;
INT32 bx, by;
tmbbox[BOXTOP] = y + radius;
tmbbox[BOXBOTTOM] = y - radius;
tmbbox[BOXRIGHT] = x + radius;
tmbbox[BOXLEFT] = x - radius;
tm.bbox[BOXTOP] = y + radius;
tm.bbox[BOXBOTTOM] = y - radius;
tm.bbox[BOXRIGHT] = x + radius;
tm.bbox[BOXLEFT] = x - radius;
// check lines
xl = (unsigned)(tmbbox[BOXLEFT] - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
xl = (unsigned)(tm.bbox[BOXLEFT] - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)(tm.bbox[BOXRIGHT] - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)(tm.bbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(tm.bbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)

View file

@ -53,7 +53,6 @@ line_t * P_FindNearestLine(const fixed_t x, const fixed_t y, const sector_t *, c
void P_UnsetPrecipThingPosition(precipmobj_t *thing);
void P_SetPrecipitationThingPosition(precipmobj_t *thing);
void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y);
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y);
void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_t momy);
boolean P_GetMidtextureTopBottom(line_t *linedef, fixed_t x, fixed_t y, fixed_t *return_top, fixed_t *return_bottom);
@ -85,8 +84,6 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, BlockItReturn_t(*func)(mobj_t *)
extern divline_t trace;
extern fixed_t tmbbox[4]; // p_map.c
// call your user function for each line of the blockmap in the
// bbox defined by the radius
//boolean P_RadiusLinesCheck(fixed_t radius, fixed_t x, fixed_t y,

View file

@ -1491,12 +1491,12 @@ bustupdone:
//
static boolean P_CheckSkyHit(mobj_t *mo)
{
if (ceilingline && ceilingline->backsector
&& ceilingline->backsector->ceilingpic == skyflatnum
&& ceilingline->frontsector
&& ceilingline->frontsector->ceilingpic == skyflatnum
&& (mo->z >= ceilingline->frontsector->ceilingheight
|| mo->z >= ceilingline->backsector->ceilingheight))
if (tm.ceilingline && tm.ceilingline->backsector
&& tm.ceilingline->backsector->ceilingpic == skyflatnum
&& tm.ceilingline->frontsector
&& tm.ceilingline->frontsector->ceilingpic == skyflatnum
&& (mo->z >= tm.ceilingline->frontsector->ceilingheight
|| mo->z >= tm.ceilingline->backsector->ceilingheight))
return true;
return false;
}
@ -1513,6 +1513,7 @@ void P_XYMovement(mobj_t *mo)
pslope_t *oldslope = NULL;
vector3_t slopemom = {0,0,0};
fixed_t predictedz = 0;
TryMoveResult_t result = {0};
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
@ -1595,13 +1596,13 @@ void P_XYMovement(mobj_t *mo)
}
//}
if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true)
if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true, &result)
&& !(P_MobjWasRemoved(mo) || mo->eflags & MFE_SPRUNG))
{
// blocked move
moved = false;
if (LUA_HookMobjMoveBlocked(mo, tmhitthing, blockingline))
if (LUA_HookMobjMoveBlocked(mo, tm.hitthing, tm.blockingline))
{
if (P_MobjWasRemoved(mo))
return;
@ -1626,7 +1627,7 @@ void P_XYMovement(mobj_t *mo)
// draw damage on wall
//SPLAT TEST ----------------------------------------------------------
#ifdef WALLSPLATS
if (blockingline && mo->type != MT_REDRING && mo->type != MT_FIREBALL
if (tm.blockingline && mo->type != MT_REDRING && mo->type != MT_FIREBALL
&& !(mo->flags2 & (MF2_AUTOMATIC|MF2_RAILRING|MF2_BOUNCERING|MF2_EXPLOSION|MF2_SCATTER)))
// set by last P_TryMove() that failed
{
@ -1634,13 +1635,13 @@ void P_XYMovement(mobj_t *mo)
divline_t misl;
fixed_t frac;
P_MakeDivline(blockingline, &divl);
P_MakeDivline(tm.blockingline, &divl);
misl.x = mo->x;
misl.y = mo->y;
misl.dx = mo->momx;
misl.dy = mo->momy;
frac = P_InterceptVector(&divl, &misl);
R_AddWallSplat(blockingline, P_PointOnLineSide(mo->x,mo->y,blockingline),
R_AddWallSplat(tm.blockingline, P_PointOnLineSide(mo->x,mo->y,tm.blockingline),
"A_DMG3", mo->z, frac, SPLATDRAWMODE_SHADE);
}
#endif
@ -1691,7 +1692,7 @@ void P_XYMovement(mobj_t *mo)
walltransferred = true;
P_SlideMove(mo);
P_SlideMove(mo, &result);
xmove = ymove = 0;
@ -1726,14 +1727,14 @@ void P_XYMovement(mobj_t *mo)
}
else if (mo->flags & MF_SLIDEME)
{
P_SlideMove(mo);
P_SlideMove(mo, &result);
if (P_MobjWasRemoved(mo))
return;
xmove = ymove = 0;
}
else
{
P_BounceMove(mo);
P_BounceMove(mo, &result);
if (P_MobjWasRemoved(mo))
return;
xmove = ymove = 0;
@ -1895,16 +1896,19 @@ void P_XYMovement(mobj_t *mo)
void P_RingXYMovement(mobj_t *mo)
{
TryMoveResult_t result = {0};
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy))
P_BounceMove(mo);
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy, &result))
P_BounceMove(mo, &result);
}
void P_SceneryXYMovement(mobj_t *mo)
{
fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls
TryMoveResult_t result = {0};
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
@ -1912,8 +1916,8 @@ void P_SceneryXYMovement(mobj_t *mo)
oldx = mo->x;
oldy = mo->y;
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy))
P_BounceMove(mo);
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy, &result))
P_BounceMove(mo, &result);
if (P_MobjWasRemoved(mo))
return;
@ -2367,15 +2371,15 @@ boolean P_ZMovement(mobj_t *mo)
return true;
}
P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly
P_CheckPosition(mo, mo->x, mo->y, NULL); // Sets mo->standingslope correctly
if (P_MobjWasRemoved(mo)) // mobjs can be removed by P_CheckPosition -- Monster Iestyn 31/07/21
return false;
K_UpdateMobjTerrain(mo, ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingpic : tmfloorpic));
K_UpdateMobjTerrain(mo, ((mo->eflags & MFE_VERTICALFLIP) ? tm.ceilingpic : tm.floorpic));
if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
if (((mo->eflags & MFE_VERTICALFLIP) ? tm.ceilingslope : tm.floorslope) && (mo->type != MT_STEAM))
{
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tm.ceilingslope : tm.floorslope;
P_SetPitchRollFromSlope(mo, mo->standingslope);
P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
}
@ -2591,11 +2595,11 @@ boolean P_ZMovement(mobj_t *mo)
}
}
else
mom.z = (tmfloorthing ? tmfloorthing->momz : 0);
mom.z = (tm.floorthing ? tm.floorthing->momz : 0);
}
else if (tmfloorthing)
mom.z = tmfloorthing->momz;
else if (tm.floorthing)
mom.z = tm.floorthing->momz;
if (mo->standingslope) { // MT_STEAM will never have a standingslope, see above.
P_QuantizeMomentumToSlope(&mom, mo->standingslope);
@ -2834,7 +2838,7 @@ void P_PlayerZMovement(mobj_t *mo)
mo->z = mo->floorz;
}
K_UpdateMobjTerrain(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingpic : tmfloorpic));
K_UpdateMobjTerrain(mo, (mo->eflags & MFE_VERTICALFLIP ? tm.ceilingpic : tm.floorpic));
// Get up if you fell.
if (mo->player->panim == PA_HURT && mo->player->spinouttimer == 0 && mo->player->tumbleBounces == 0)
@ -2842,10 +2846,10 @@ void P_PlayerZMovement(mobj_t *mo)
P_SetPlayerMobjState(mo, S_KART_STILL);
}
if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope))
if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tm.ceilingslope : tm.floorslope))
{
// Handle landing on slope during Z movement
P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope));
P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tm.ceilingslope : tm.floorslope));
}
if (P_MobjFlip(mo) * mo->momz < 0) // falling
@ -2860,12 +2864,12 @@ void P_PlayerZMovement(mobj_t *mo)
if (clipmomz)
{
mo->momz = (tmfloorthing ? tmfloorthing->momz : 0);
mo->momz = (tm.floorthing ? tm.floorthing->momz : 0);
}
}
else if (tmfloorthing)
else if (tm.floorthing)
{
mo->momz = tmfloorthing->momz;
mo->momz = tm.floorthing->momz;
}
}
else
@ -2985,7 +2989,7 @@ boolean P_SceneryZMovement(mobj_t *mo)
if (!(mo->flags & MF_SLIDEME) && (mo->z <= mo->floorz || mo->z+mo->height >= mo->ceilingz))
{
// set standingslope
P_TryMove(mo, mo->x, mo->y, true);
P_TryMove(mo, mo->x, mo->y, true, NULL);
mo->momz = -mo->momz;
if (mo->standingslope)
{
@ -3083,9 +3087,9 @@ boolean P_SceneryZMovement(mobj_t *mo)
{
mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack
if (tmfloorthing)
mo->momz = tmfloorthing->momz;
else if (!tmfloorthing)
if (tm.floorthing)
mo->momz = tm.floorthing->momz;
else if (!tm.floorthing)
mo->momz = 0;
}
}
@ -3218,14 +3222,15 @@ boolean P_CanRunOnWater(mobj_t *mobj, ffloor_t *rover)
// We start water run IF we can step onto it!
if (surfDiff <= maxStep && surfDiff >= 0)
{
if (ourZAng < 0)
pslope_t *groundSlope = (flip ? mobj->subsector->sector->c_slope : mobj->subsector->sector->f_slope);
if (groundSlope != NULL && groundSlope->zangle != 0)
{
fixed_t floorheight = flip ? P_GetSectorCeilingZAt(mobj->subsector->sector, mobj->x, mobj->y) : P_GetSectorFloorZAt(mobj->subsector->sector, mobj->x, mobj->y);
fixed_t floorDiff = flip ? (floorheight - mobjbottom) : (mobjbottom - floorheight);
if (floorDiff <= maxStep && floorDiff >= -maxStep)
{
// ... but NOT if going down and real floor is in range.
// FIXME: Count solid FOFs in this check
// ... but NOT if downward-sloping real floor is in range.
// FIXME: Count solid FOFs in these checks
return false;
}
}
@ -3801,8 +3806,8 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
}
thiscam->subsector = R_PointInSubsector(thiscam->x, thiscam->y);
thiscam->floorz = tmfloorz;
thiscam->ceilingz = tmceilingz;
thiscam->floorz = tm.floorz;
thiscam->ceilingz = tm.ceilingz;
if (thiscam->momz || player->mo->pmomz)
{
@ -3959,9 +3964,9 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
mobj->y += mobj->momy;
mobj->z += mobj->momz;
P_SetThingPosition(mobj);
P_CheckPosition(mobj, mobj->x, mobj->y);
mobj->floorz = tmfloorz;
mobj->ceilingz = tmceilingz;
P_CheckPosition(mobj, mobj->x, mobj->y, NULL);
mobj->floorz = tm.floorz;
mobj->ceilingz = tm.ceilingz;
goto animonly;
}
@ -3976,7 +3981,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
return;
}
else
P_TryMove(mobj, mobj->x, mobj->y, true);
P_TryMove(mobj, mobj->x, mobj->y, true, NULL);
P_CheckCrumblingPlatforms(mobj);
@ -3991,7 +3996,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|| P_IsObjectInGoop(mobj))
{
P_PlayerZMovement(mobj);
P_CheckPosition(mobj, mobj->x, mobj->y); // Need this to pick up objects!
P_CheckPosition(mobj, mobj->x, mobj->y, NULL); // Need this to pick up objects!
if (P_MobjWasRemoved(mobj))
return;
@ -4181,7 +4186,7 @@ static void P_RingThinker(mobj_t *mobj)
if (mobj->momz)
{
P_RingZMovement(mobj);
P_CheckPosition(mobj, mobj->x, mobj->y); // Need this to pick up objects!
P_CheckPosition(mobj, mobj->x, mobj->y, NULL); // Need this to pick up objects!
if (P_MobjWasRemoved(mobj))
return;
@ -5330,7 +5335,7 @@ void P_RunOverlays(void)
P_SetUnderlayPosition(mo);
else
P_SetThingPosition(mo);
P_CheckPosition(mo, mo->x, mo->y);
P_CheckPosition(mo, mo->x, mo->y, NULL);
}
P_SetTarget(&overlaycap, NULL);
}
@ -7694,6 +7699,109 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->renderflags = (mobj->renderflags & ~RF_TRANSMASK)|(trans << RF_TRANSSHIFT);
}
break;
case MT_MAGICIANBOX:
{
fixed_t destx, desty;
fixed_t zoff = 0;
// EV1: rotation rate
// EV2: lifetime
// cusval: responsible for disappear FX (should only happen once)
// S_MAGICANBOX: sides, starting angle is set in the spawner (SetRandomFakePlayerSkin)
// S_MAGICIANBOX_TOP, S_MAGICIANBOX_BOTTOM: splats with their own offset sprite sets
mobj->extravalue2--;
if (mobj->extravalue2 == 0)
{
P_RemoveMobj(mobj);
break;
}
else if (mobj->extravalue2 < TICRATE/3)
{
P_SetTarget(&mobj->target, NULL);
if (mobj->extravalue2 & 1)
mobj->renderflags |= RF_DONTDRAW;
else
mobj->renderflags &= ~RF_DONTDRAW;
}
else if (mobj->extravalue2 == TICRATE/3 && !P_MobjWasRemoved(mobj->target))
{
mobj->momx = mobj->target->momx;
mobj->momy = mobj->target->momy;
mobj->momz = mobj->target->momz;
if (mobj->state == &states[S_MAGICIANBOX]) // sides
P_Thrust(mobj, mobj->angle + ANGLE_90, 32*mapobjectscale);
mobj->flags &= ~MF_NOGRAVITY;
mobj->momz += 10*mapobjectscale;
if (mobj->state == &states[S_MAGICIANBOX_BOTTOM])
mobj->momz *= -1;
if (!mobj->cusval) // Some stuff should only occur once per box
return true;
S_StartSound(mobj, sfx_kc2e);
S_StartSound(mobj, sfx_s3k9f);
if (mobj->target->player->hyudorotimer)
{
P_RemoveMobj(mobj);
break;
}
else
{
K_SpawnMagicianParticles(mobj, 5);
}
return true;
}
else if (mobj->target && !P_MobjWasRemoved(mobj->target))
{
mobj->renderflags &= ~RF_DONTDRAW;
mobj->renderflags |= (mobj->target->renderflags & RF_DONTDRAW);
// NB: This depends on order of thinker execution!
// SetRandomFakePlayerSkin (r_skins.c) sets cusval on the bottom (last) side (i=5).
// This writes to the player's visibility only after every other side has ticked and inherited it.
if (mobj->cusval)
mobj->target->renderflags |= RF_DONTDRAW;
}
if (P_MobjWasRemoved(mobj->target) || !mobj->target->health || !mobj->target->player) {
mobj->extravalue2 = min(mobj->extravalue2, TICRATE/3);
return true;
}
mobj->extravalue1 += 1;
mobj->angle += ANG1*mobj->extravalue1;
mobj->scale = mobj->target->scale;
destx = mobj->target->x;
desty = mobj->target->y;
if (mobj->state == &states[S_MAGICIANBOX]) // sides
{
destx += FixedMul(mobj->radius*2, FINECOSINE((mobj->angle+ANGLE_90) >> ANGLETOFINESHIFT));
desty += FixedMul(mobj->radius*2, FINESINE((mobj->angle+ANGLE_90) >> ANGLETOFINESHIFT));
}
else if (mobj->state == &states[S_MAGICIANBOX_TOP]) // top
{
zoff = mobj->radius*4;
}
if (mobj->flags2 & MF2_AMBUSH)
{
P_SetOrigin(mobj, destx, desty, mobj->target->z + zoff);
mobj->flags2 &= ~MF2_AMBUSH;
}
else
{
P_MoveOrigin(mobj, destx, desty, mobj->target->z + zoff);
}
break;
}
case MT_LIGHTNINGSHIELD:
{
fixed_t destx, desty;
@ -8408,7 +8516,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->movecount += mobj->lastlook;
if (!(P_TryMove(mobj->tracer, mobj->x + ((mobj->extravalue1<<FRACBITS) * mobj->movecount), mobj->y + ((mobj->extravalue2<<FRACBITS) * mobj->movecount), true))
if (!(P_TryMove(mobj->tracer, mobj->x + ((mobj->extravalue1<<FRACBITS) * mobj->movecount), mobj->y + ((mobj->extravalue2<<FRACBITS) * mobj->movecount), true, NULL))
|| (mobj->movecount >= 16) // maximum travel time
|| (mobj->tracer->z <= mobj->tracer->floorz) // Through the floor
|| ((mobj->tracer->z + mobj->tracer->height) >= mobj->tracer->ceilingz)) // Through the ceiling
@ -9451,7 +9559,9 @@ void P_MobjThinker(mobj_t *mobj)
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG|MFE_SLOPELAUNCHED);
tmfloorthing = tmhitthing = NULL;
// sal: what the hell? is there any reason this isn't done, like, literally ANYWHERE else?
P_SetTarget(&tm.floorthing, NULL);
P_SetTarget(&tm.hitthing, NULL);
// Sector flag MSF_TRIGGERLINE_MOBJ allows ANY mobj to trigger a linedef exec
P_CheckMobjTrigger(mobj, false);
@ -9607,7 +9717,7 @@ void P_MobjThinker(mobj_t *mobj)
{
if (!P_ZMovement(mobj))
return; // mobj was removed
P_CheckPosition(mobj, mobj->x, mobj->y); // Need this to pick up objects!
P_CheckPosition(mobj, mobj->x, mobj->y, NULL); // Need this to pick up objects!
if (P_MobjWasRemoved(mobj))
return;
}
@ -9631,7 +9741,7 @@ void P_MobjThinker(mobj_t *mobj)
|| mobj->type == MT_JAWZ
|| (mobj->type == MT_DROPTARGET && mobj->reactiontime))
{
P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly
P_TryMove(mobj, mobj->x, mobj->y, true, NULL); // Sets mo->standingslope correctly
if (P_MobjWasRemoved(mobj)) // anything that calls checkposition can be lethal
return;
@ -9729,7 +9839,7 @@ boolean P_RailThinker(mobj_t *mobj)
{
if (!P_ZMovement(mobj))
return true; // mobj was removed
//P_CheckPosition(mobj, mobj->x, mobj->y);
//P_CheckPosition(mobj, mobj->x, mobj->y, NULL);
}
return P_MobjWasRemoved(mobj) || (x == mobj->x && y == mobj->y && z == mobj->z);
@ -9745,7 +9855,7 @@ void P_PushableThinker(mobj_t *mobj)
// it has to be pushable RIGHT NOW for this part to happen
if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy))
P_TryMove(mobj, mobj->x, mobj->y, true);
P_TryMove(mobj, mobj->x, mobj->y, true, NULL);
if (mobj->fuse == 1) // it would explode in the MobjThinker code
{
@ -9806,13 +9916,13 @@ void P_SceneryThinker(mobj_t *mobj)
{
if (!P_SceneryZMovement(mobj))
return; // mobj was removed
P_CheckPosition(mobj, mobj->x, mobj->y); // Need this to pick up objects!
P_CheckPosition(mobj, mobj->x, mobj->y, NULL); // Need this to pick up objects!
if (P_MobjWasRemoved(mobj))
return;
mobj->floorz = tmfloorz;
mobj->ceilingz = tmceilingz;
mobj->floorrover = tmfloorrover;
mobj->ceilingrover = tmceilingrover;
mobj->floorz = tm.floorz;
mobj->ceilingz = tm.ceilingz;
mobj->floorrover = tm.floorrover;
mobj->ceilingrover = tm.ceilingrover;
}
else
{
@ -13348,7 +13458,7 @@ boolean P_CheckMissileSpawn(mobj_t *th)
th->z += th->momz>>1;
}
if (!P_TryMove(th, th->x, th->y, true))
if (!P_TryMove(th, th->x, th->y, true, NULL))
{
P_ExplodeMissile(th);
return false;

View file

@ -762,7 +762,7 @@ static void Polyobj_removeFromBlockmap(polyobj_t *po)
// Movement functions
// A version of Lee's routine from p_maputl.c that accepts an mobj pointer
// argument instead of using tmthing. Returns true if the line isn't contacted
// argument instead of using tm.thing. Returns true if the line isn't contacted
// and false otherwise.
static inline boolean Polyobj_untouched(line_t *ld, mobj_t *mo)
{
@ -805,11 +805,11 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo)
// if object doesn't fit at desired location, possibly hurt it
if (po->damage && (mo->flags & MF_SHOOTABLE))
{
P_CheckPosition(mo, mo->x + momx, mo->y + momy);
mo->floorz = tmfloorz;
mo->ceilingz = tmceilingz;
mo->floorrover = tmfloorrover;
mo->ceilingrover = tmceilingrover;
P_CheckPosition(mo, mo->x + momx, mo->y + momy, NULL);
mo->floorz = tm.floorz;
mo->ceilingz = tm.ceilingz;
mo->floorrover = tm.floorrover;
mo->ceilingrover = tm.ceilingrover;
}
}
@ -851,7 +851,7 @@ static void Polyobj_slideThing(mobj_t *mo, fixed_t dx, fixed_t dy)
mo->player->onconveyor = 1;
} else
P_TryMove(mo, mo->x+dx, mo->y+dy, true);
P_TryMove(mo, mo->x+dx, mo->y+dy, true, NULL);
}
// Causes objects resting on top of the polyobject to 'ride' with its movement.

View file

@ -151,6 +151,8 @@ static void P_NetArchivePlayers(void)
WRITEUINT8(save_p, players[i].skincolor);
WRITEINT32(save_p, players[i].skin);
WRITEUINT32(save_p, players[i].availabilities);
WRITEUINT8(save_p, players[i].fakeskin);
WRITEUINT8(save_p, players[i].lastfakeskin);
WRITEUINT32(save_p, players[i].score);
WRITESINT8(save_p, players[i].lives);
WRITESINT8(save_p, players[i].xtralife);
@ -470,6 +472,8 @@ static void P_NetUnArchivePlayers(void)
players[i].skincolor = READUINT8(save_p);
players[i].skin = READINT32(save_p);
players[i].availabilities = READUINT32(save_p);
players[i].fakeskin = READUINT8(save_p);
players[i].lastfakeskin = READUINT8(save_p);
players[i].score = READUINT32(save_p);
players[i].lives = READSINT8(save_p);
players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter

View file

@ -7465,7 +7465,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
P_ResetTubeWaypoints();
P_MapStart(); // tmthing can be used starting from this point
P_MapStart(); // tm.thing can be used starting from this point
// init anything that P_SpawnSlopes/P_LoadThings needs to know
P_InitSpecials();
@ -7570,7 +7570,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
P_RunCachedActions();
P_MapEnd(); // tmthing is no longer needed from this point onwards
P_MapEnd(); // tm.thing is no longer needed from this point onwards
// Took me 3 hours to figure out why my progression kept on getting overwritten with the titlemap...
if (!titlemapinaction)
@ -7629,9 +7629,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1);
}
P_PreTicker(2);
P_MapStart(); // just in case MapLoad modifies tmthing
P_MapStart(); // just in case MapLoad modifies tm.thing
LUA_HookInt(gamemap, HOOK(MapLoad));
P_MapEnd(); // just in case MapLoad modifies tmthing
P_MapEnd(); // just in case MapLoad modifies tm.thing
}
K_TimerReset();

View file

@ -749,10 +749,10 @@ static boolean P_CrossBotTraversalSubsector(size_t num, register traceblocking_t
}
// set openrange, opentop, openbottom
tmx = tb->compareThing->x;
tmy = tb->compareThing->y;
tm.x = tb->compareThing->x;
tm.y = tb->compareThing->y;
P_LineOpening(line, tb->compareThing);
maxstep = P_GetThingStepUp(tb->compareThing, tmx, tmy);
maxstep = P_GetThingStepUp(tb->compareThing, tm.x, tm.y);
if ((openrange < tb->compareThing->height) // doesn't fit
|| (opentop - tb->compareThing->z < tb->compareThing->height) // mobj is too high

View file

@ -1928,6 +1928,17 @@ static void K_HandleLapIncrement(player_t *player)
P_DoPlayerExit(player);
P_SetupSignExit(player);
}
else
{
UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[(player-players)]].flags
: skins[player->skin].flags;
if (skinflags & SF_IRONMAN)
{
SetRandomFakePlayerSkin(player, true);
}
}
if (player->laps > player->latestlap)
{

View file

@ -1264,6 +1264,8 @@ void P_DoPlayerExit(player_t *player)
if (!player->spectator)
{
ClearFakePlayerSkin(player);
if ((gametyperules & GTR_CIRCUIT)) // If in Race Mode, allow
{
K_KartUpdatePosition(player);
@ -4167,6 +4169,35 @@ void P_PlayerThink(player_t *player)
{
player->stairjank--;
}
// Random skin / "ironman"
{
UINT32 skinflags = (demo.playback)
? demo.skinlist[demo.currentskinid[playeri]].flags
: skins[player->skin].flags;
if (skinflags & SF_IRONMAN) // we are Heavy Magician
{
if (player->charflags & SF_IRONMAN) // no fakeskin yet
{
if (leveltime >= starttime && !player->exiting)
{
if (player->fakeskin != MAXSKINS)
{
SetFakePlayerSkin(player, player->fakeskin);
}
else if (!(gametyperules & GTR_CIRCUIT))
{
SetRandomFakePlayerSkin(player, false);
}
}
}
else if (player->exiting) // wearing a fakeskin, but need to display signpost postrace etc
{
ClearFakePlayerSkin(player);
}
}
}
K_KartPlayerThink(player, cmd); // SRB2kart

View file

@ -180,6 +180,8 @@ consvar_t cv_maxportals = CVAR_INIT ("maxportals", "2", CV_SAVE, maxportals_cons
consvar_t cv_renderstats = CVAR_INIT ("renderstats", "Off", 0, CV_OnOff, NULL);
consvar_t cv_drawpickups = CVAR_INIT ("drawpickups", "Yes", CV_CHEAT, CV_YesNo, NULL);
void SplitScreen_OnChange(void)
{
UINT8 i;
@ -1646,4 +1648,6 @@ void R_RegisterEngineStuff(void)
// Frame interpolation/uncapped
CV_RegisterVar(&cv_fpscap);
CV_RegisterVar(&cv_drawpickups);
}

View file

@ -117,6 +117,7 @@ extern consvar_t cv_drawdist, cv_drawdist_precip;
extern consvar_t cv_fov[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_skybox;
extern consvar_t cv_tailspickup;
extern consvar_t cv_drawpickups;
// Called by startup code.
void R_Init(void);

View file

@ -27,6 +27,8 @@
#include "p_local.h"
#include "dehacked.h" // get_number (for thok)
#include "m_cond.h"
#include "k_kart.h"
#include "m_random.h"
#if 0
#include "k_kart.h" // K_KartResetPlayerColor
#endif
@ -334,6 +336,136 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
SetPlayerSkinByNum(playernum, 0); // not found, put in the default skin
}
// Set mo skin but not player_t skin, for ironman
void SetFakePlayerSkin(player_t* player, INT32 skinid)
{
if (player->fakeskin != skinid)
{
if (player->fakeskin != MAXSKINS)
player->lastfakeskin = player->fakeskin;
player->fakeskin = skinid;
}
if (demo.playback)
{
player->kartspeed = demo.skinlist[skinid].kartspeed;
player->kartweight = demo.skinlist[skinid].kartweight;
player->charflags = demo.skinlist[skinid].flags;
skinid = demo.skinlist[skinid].mapping;
}
else
{
player->kartspeed = skins[skinid].kartspeed;
player->kartweight = skins[skinid].kartweight;
player->charflags = skins[skinid].flags;
}
player->mo->skin = &skins[skinid];
}
// Loudly rerandomize
void SetRandomFakePlayerSkin(player_t* player, boolean fast)
{
INT32 i;
UINT8 usableskins = 0, maxskinpick;
UINT8 grabskins[MAXSKINS];
maxskinpick = (demo.playback ? demo.numskins : numskins);
for (i = 0; i < maxskinpick; i++)
{
if (i == player->lastfakeskin)
continue;
if (demo.playback)
{
if (demo.skinlist[i].flags & SF_IRONMAN)
continue;
}
else if (skins[i].flags & SF_IRONMAN)
continue;
/*if (K_SkinLocked(i))
continue;*/
grabskins[usableskins++] = i;
}
i = grabskins[P_RandomKey(PR_RANDOMSKIN, usableskins)];
SetFakePlayerSkin(player, i);
if (player->mo)
{
S_StartSound(player->mo, sfx_kc33);
S_StartSound(player->mo, sfx_cdfm44);
mobj_t *parent = player->mo;
fixed_t baseangle = P_RandomRange(PR_DECORATION, 0, 359);
INT32 j;
for (j = 0; j < 6; j++) // 0-3 = sides, 4 = top, 5 = bottom
{
mobj_t *box = P_SpawnMobjFromMobj(parent, 0, 0, 0, MT_MAGICIANBOX);
P_SetTarget(&box->target, parent);
box->angle = FixedAngle((baseangle + j*90) * FRACUNIT);
box->flags2 |= MF2_AMBUSH;
if (fast)
{
box->extravalue1 = 10; // Rotation rate
box->extravalue2 = 5*TICRATE/4; // Lifetime
}
else
{
box->extravalue1 = 1;
box->extravalue2 = 3*TICRATE/2;
}
// cusval controls behavior that should run only once, like disappear FX and RF_DONTDRAW handling.
// NB: Order of thinker execution matters here!
// We want the other sides to inherit the player's "existing" RF_DONTDRAW before the last side writes to it.
// See the MT_MAGICIANBOX thinker in p_mobj.c.
if (j == 5)
box->cusval = 1;
else
box->cusval = 0;
if (j > 3)
{
P_SetMobjState(box, (j == 4) ? S_MAGICIANBOX_TOP : S_MAGICIANBOX_BOTTOM);
box->renderflags |= RF_NOSPLATBILLBOARD;
box->angle = FixedAngle(baseangle*FRACUNIT);
}
}
K_SpawnMagicianParticles(player->mo, 10);
}
}
// Return to base skin from an SF_IRONMAN randomization
void ClearFakePlayerSkin(player_t* player)
{
UINT8 skinid;
UINT32 flags;
if (demo.playback)
{
skinid = demo.currentskinid[(player-players)];
flags = demo.skinlist[skinid].flags;
}
else
{
skinid = player->skin;
flags = skins[player->skin].flags;
}
if ((flags & SF_IRONMAN) && !P_MobjWasRemoved(player->mo))
{
SetFakePlayerSkin(player, skinid);
S_StartSound(player->mo, sfx_s3k9f);
K_SpawnMagicianParticles(player->mo, 5);
}
player->fakeskin = MAXSKINS;
}
//
// Add skins from a pwad, each skin preceded by 'S_SKIN' marker
//
@ -482,8 +614,8 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
// parameters for individual character flags
// these are uppercase so they can be concatenated with SF_
// 1, true, yes are all valid values
GETFLAG(HIRES)
GETFLAG(MACHINE)
GETFLAG(IRONMAN)
#undef GETFLAG
else // let's check if it's a sound, otherwise error out

View file

@ -81,6 +81,9 @@ void R_InitSkins(void);
void SetPlayerSkin(INT32 playernum,const char *skinname);
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
void SetFakePlayerSkin(player_t* player, INT32 skinnum);
void SetRandomFakePlayerSkin(player_t* player, boolean fast);
void ClearFakePlayerSkin(player_t* player);
boolean R_SkinUsable(INT32 playernum, INT32 skinnum);
UINT32 R_GetSkinAvailabilities(void);
INT32 R_SkinAvailable(const char *name);

View file

@ -181,7 +181,7 @@ void R_DrawFloorSplat(vissprite_t *spr)
splat.height = spr->patch->height;
splat.scale = mobj->scale;
if (mobj->skin && ((skin_t *)mobj->skin)->flags & SF_HIRES)
if (mobj->skin && ((skin_t *)mobj->skin)->highresscale != FRACUNIT)
splat.scale = FixedMul(splat.scale, ((skin_t *)mobj->skin)->highresscale);
if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD)

View file

@ -945,7 +945,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
frac = vis->startfrac;
windowtop = windowbottom = sprbotscreen = INT32_MAX;
if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES)
if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->highresscale != FRACUNIT)
this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale);
if (this_scale <= 0)
@ -1410,7 +1410,7 @@ static void R_ProjectDropShadow(
shadow->gzt = groundz + patch->height * shadowyscale / 2;
shadow->gz = shadow->gzt - patch->height * shadowyscale;
shadow->texturemid = FixedMul(interp.scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
if (thing->skin && ((skin_t *)thing->skin)->highresscale != FRACUNIT)
shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale);
shadow->scalestep = 0;
shadow->shear.tan = shadowskew; // repurposed variable
@ -1797,7 +1797,7 @@ static void R_ProjectSprite(mobj_t *thing)
I_Assert(lump < max_spritelumps);
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
if (thing->skin && ((skin_t *)thing->skin)->highresscale != FRACUNIT)
this_scale = FixedMul(this_scale, ((skin_t *)thing->skin)->highresscale);
spr_width = spritecachedinfo[lump].width;
@ -3443,6 +3443,26 @@ boolean R_ThingVisible (mobj_t *thing)
if (thing->sprite == SPR_NULL)
return false;
if (!cv_drawpickups.value)
{
switch (thing->type)
{
case MT_RING:
case MT_FLINGRING:
case MT_BLUESPHERE:
case MT_RANDOMITEM:
case MT_SPHEREBOX:
case MT_ITEMCAPSULE:
case MT_ITEMCAPSULE_PART:
case MT_BATTLECAPSULE:
case MT_BATTLECAPSULE_PIECE:
return false;
default:
break;
}
}
if (r_viewmobj && (thing == r_viewmobj || (r_viewmobj->player && r_viewmobj->player->followmobj == thing)))
return false;

View file

@ -619,10 +619,6 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
colfrac = FixedDiv(FRACUNIT, fdup);
rowfrac = FixedDiv(FRACUNIT, vdup);
// So it turns out offsets aren't scaled in V_NOSCALESTART unless V_OFFSET is applied ...poo, that's terrible
// For now let's just at least give V_OFFSET the ability to support V_FLIP
// I'll probably make a better fix for 2.2 where I don't have to worry about breaking existing support for stuff
// -- Monster Iestyn 29/10/18
{
fixed_t offsetx = 0, offsety = 0;
@ -633,15 +629,17 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
offsetx = FixedMul(patch->leftoffset<<FRACBITS, pscale);
// top offset
// TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!?
offsety = FixedMul(patch->topoffset<<FRACBITS, vscale);
if (scrn & V_VFLIP)
offsety = FixedMul((patch->height - patch->topoffset)<<FRACBITS, vscale) + 1;
else
offsety = FixedMul(patch->topoffset<<FRACBITS, vscale);
// Subtract the offsets from x/y positions
x -= offsetx;
y -= offsety;
}
desttop = screens[scrn&V_PARAMMASK];
desttop = screens[scrn&V_SCREENMASK];
if (!desttop)
return;
@ -700,6 +698,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
if (x+offx >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
break;
}
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS]));
while (column->topdelta != 0xff)
@ -709,17 +708,31 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
topdelta += prevdelta;
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - desttop);
dest = deststart + (destend - dest);
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup))*vid.width;
for (ofs = 0; dest < deststop && (ofs>>FRACBITS) < column->length; ofs += rowfrac)
if (scrn & V_VFLIP)
{
if (dest >= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = patchdrawfunc(dest, source, ofs);
dest += vid.width;
for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac)
{
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = patchdrawfunc(dest, source, ofs);
dest += vid.width;
}
}
else
{
for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac)
{
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = patchdrawfunc(dest, source, ofs);
dest += vid.width;
}
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
}
@ -778,7 +791,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
y -= FixedMul(patch->topoffset<<FRACBITS, pscale);
x -= FixedMul(patch->leftoffset<<FRACBITS, pscale);
desttop = screens[scrn&V_PARAMMASK];
desttop = screens[scrn&V_SCREENMASK];
if (!desttop)
return;
@ -830,7 +843,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
for (; dest < deststop && (ofs>>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac)
{
if (dest >= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = patchdrawfunc(dest, source, ofs);
dest += vid.width;
}

View file

@ -82,11 +82,14 @@ void V_CubeApply(RGBA_t *input);
#define V_GetColor(color) (pLocalPalette[color&0xFF])
#define V_GetMasterColor(color) (pMasterPalette[color&0xFF])
// Bottom 8 bits are used for parameter (screen or character)
// Bottom 8 bits are used for parameter (character)
#define V_PARAMMASK 0x000000FF
// strings/characters only
#define V_STRINGDANCE 0x00000002
// Bottom bit is used for screen (patches)
#define V_SCREENMASK 0x0000000F
#define V_STRINGDANCE 0x00000002 // (strings/characters only) funny undertale
#define V_VFLIP 0x00000010 // (patches only) Vertical flip
// flags hacked in scrn (not supported by all functions (see src))
// patch scaling uses bits 9 and 10