mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-29 20:50:58 +00:00
Merge branch 'master' into linedef-153
This commit is contained in:
commit
a2f0f61d75
57 changed files with 7832 additions and 622 deletions
6428
extras/conf/SRB2-22.cfg
Normal file
6428
extras/conf/SRB2-22.cfg
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
# libopenmpt mingw-w64 binary info
|
||||
|
||||
Current built version as of 2019/05/23 is 0.4.4+r11531.pkg
|
||||
Current built version as of 2019/09/27 is 0.4.7+r12088.pkg
|
||||
|
||||
* mingw binaries (.dll): `bin/[x86 or x86_64]/mingw`
|
||||
* mingw import libraries (.dll.a): `lib/[x86 or x86_64]/mingw`
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -5,6 +5,44 @@ Changelog {#changelog}
|
|||
For fully detailed change log, please see the source repository directly. This
|
||||
is just a high-level summary.
|
||||
|
||||
### libopenmpt 0.4.7 (2019-09-23)
|
||||
|
||||
* [**Bug**] Compilation fix for various platforms that do not provide
|
||||
`std::aligned_alloc` in C++17 mode. The problematic dependency has been
|
||||
removed. This should fix build problems on MinGW, OpenBSD, Haiku, and others
|
||||
for good.
|
||||
|
||||
* J2B: Ignore notes with non-existing instrument (fixes Ending.j2b).
|
||||
|
||||
* mpg123: Update to v1.25.13 (2019-08-24).
|
||||
* ogg: Update to v1.3.4. (2019-08-31).
|
||||
* flac: Update to v1.3.3. (2019-08-04).
|
||||
|
||||
### libopenmpt 0.4.6 (2019-08-10)
|
||||
|
||||
* [**Bug**] Compilation fix for OpenBSD.
|
||||
* [**Bug**] Compilation fix for NO_PLUGINS being defined.
|
||||
|
||||
* in_openmpt: Correct documentation. `openmpt-mpg123.dll` must be placed into
|
||||
the Winamp directory.
|
||||
|
||||
* Detect IT files unpacked with early UNMO3 versions.
|
||||
|
||||
* mpg123: Update to v1.25.11 (2019-07-18).
|
||||
* minimp3: Update to commit 977514a6dfc4960d819a103f43b358e58ac6c28f
|
||||
(2019-07-24).
|
||||
* miniz: Update to v2.1.0 (2019-05-05).
|
||||
* stb_vorbis: Update to v1.17 (2019-08-09).
|
||||
|
||||
### libopenmpt 0.4.5 (2019-05-27)
|
||||
|
||||
* [**Sec**] Possible crash during playback due out-of-bounds read in XM and
|
||||
MT2 files (r11608).
|
||||
|
||||
* Breaking out of a sustain loop through Note-Off sometimes didn't continue in
|
||||
the regular sample loop.
|
||||
* Seeking did not stop notes playing with XM Key Off (Kxx) effect.
|
||||
|
||||
### libopenmpt 0.4.4 (2019-04-07)
|
||||
|
||||
* [**Bug**] Channel VU meters were swapped.
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
/*! \brief libopenmpt minor version number */
|
||||
#define OPENMPT_API_VERSION_MINOR 4
|
||||
/*! \brief libopenmpt patch version number */
|
||||
#define OPENMPT_API_VERSION_PATCH 4
|
||||
#define OPENMPT_API_VERSION_PATCH 7
|
||||
/*! \brief libopenmpt pre-release tag */
|
||||
#define OPENMPT_API_VERSION_PREREL ""
|
||||
/*! \brief libopenmpt pre-release flag */
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
14
src/b_bot.c
14
src/b_bot.c
|
@ -140,6 +140,9 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward, boolean left, boolean right, boolean strafeleft, boolean straferight, boolean jump, boolean spin)
|
||||
{
|
||||
// don't try to do stuff if your sonic is in a minecart or something
|
||||
if (players[consoleplayer].powers[pw_carry])
|
||||
return;
|
||||
// Turn the virtual keypresses into ticcmd_t.
|
||||
if (twodlevel || mo->flags2 & MF2_TWOD) {
|
||||
if (players[consoleplayer].climbing
|
||||
|
@ -218,7 +221,12 @@ boolean B_CheckRespawn(player_t *player)
|
|||
return false;
|
||||
|
||||
// Low ceiling, do not want!
|
||||
if (sonic->ceilingz - sonic->z < 2*sonic->height)
|
||||
if (sonic->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (sonic->z - sonic->floorz < (sonic->player->exiting ? 5 : 2)*sonic->height)
|
||||
return false;
|
||||
}
|
||||
else if (sonic->ceilingz - sonic->z < (sonic->player->exiting ? 6 : 3)*sonic->height)
|
||||
return false;
|
||||
|
||||
// If you're dead, wait a few seconds to respawn.
|
||||
|
@ -252,11 +260,11 @@ void B_RespawnBot(INT32 playernum)
|
|||
y = sonic->y;
|
||||
if (sonic->eflags & MFE_VERTICALFLIP) {
|
||||
tails->eflags |= MFE_VERTICALFLIP;
|
||||
z = sonic->z - FixedMul(512*FRACUNIT,sonic->scale);
|
||||
z = sonic->z - (512*sonic->scale);
|
||||
if (z < sonic->floorz)
|
||||
z = sonic->floorz;
|
||||
} else {
|
||||
z = sonic->z + sonic->height + FixedMul(512*FRACUNIT,sonic->scale);
|
||||
z = sonic->z + sonic->height + (512*sonic->scale);
|
||||
if (z > sonic->ceilingz - sonic->height)
|
||||
z = sonic->ceilingz - sonic->height;
|
||||
}
|
||||
|
|
|
@ -621,6 +621,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
rsp->friction = LONG(players[i].mo->friction);
|
||||
rsp->movefactor = LONG(players[i].mo->movefactor);
|
||||
|
||||
rsp->sprite = (spritenum_t)LONG(players[i].mo->sprite);
|
||||
rsp->frame = LONG(players[i].mo->frame);
|
||||
rsp->sprite2 = players[i].mo->sprite2;
|
||||
rsp->anim_duration = SHORT(players[i].mo->anim_duration);
|
||||
rsp->tics = LONG(players[i].mo->tics);
|
||||
rsp->statenum = (statenum_t)LONG(players[i].mo->state-states); // :(
|
||||
rsp->eflags = (UINT16)SHORT(players[i].mo->eflags);
|
||||
|
@ -767,8 +771,17 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
players[i].mo->momy = LONG(rsp->momy);
|
||||
players[i].mo->momz = LONG(rsp->momz);
|
||||
players[i].mo->movefactor = LONG(rsp->movefactor);
|
||||
|
||||
// Don't use P_SetMobjStateNF to restore state, write/read all the values manually!
|
||||
// This should stop those stupid console errors, hopefully.
|
||||
// -- Monster Iestyn
|
||||
players[i].mo->sprite = (spritenum_t)LONG(rsp->sprite);
|
||||
players[i].mo->frame = LONG(rsp->frame);
|
||||
players[i].mo->sprite2 = rsp->sprite2;
|
||||
players[i].mo->anim_duration = SHORT(rsp->anim_duration);
|
||||
players[i].mo->tics = LONG(rsp->tics);
|
||||
P_SetMobjStateNF(players[i].mo, LONG(rsp->statenum));
|
||||
players[i].mo->state = &states[LONG(rsp->statenum)];
|
||||
|
||||
players[i].mo->x = LONG(rsp->x);
|
||||
players[i].mo->y = LONG(rsp->y);
|
||||
players[i].mo->z = LONG(rsp->z);
|
||||
|
@ -3841,7 +3854,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
break;
|
||||
|
||||
// Ignore tics from those not synched
|
||||
if (resynch_inprogress[node])
|
||||
if (resynch_inprogress[node] && nettics[node] == gametic)
|
||||
break;
|
||||
|
||||
// To save bytes, only the low byte of tic numbers are sent
|
||||
|
@ -4699,7 +4712,7 @@ void TryRunTics(tic_t realtics)
|
|||
if (player_joining)
|
||||
return;
|
||||
|
||||
if (neededtic > gametic)
|
||||
if (neededtic > gametic && !resynch_local_inprogress)
|
||||
{
|
||||
if (advancedemo)
|
||||
D_StartTitle();
|
||||
|
@ -4853,8 +4866,13 @@ void NetUpdate(void)
|
|||
for (i = 0; i < MAXNETNODES; ++i)
|
||||
if (resynch_inprogress[i])
|
||||
{
|
||||
SV_SendResynch(i);
|
||||
counts = -666;
|
||||
if (!nodeingame[i] || nettics[i] == gametic)
|
||||
{
|
||||
SV_SendResynch(i);
|
||||
counts = -666;
|
||||
}
|
||||
else
|
||||
counts = 0; // Let the client catch up with the server
|
||||
}
|
||||
|
||||
// Do not make tics while resynching
|
||||
|
|
|
@ -265,6 +265,10 @@ typedef struct
|
|||
fixed_t friction;
|
||||
fixed_t movefactor;
|
||||
|
||||
spritenum_t sprite;
|
||||
UINT32 frame;
|
||||
UINT8 sprite2;
|
||||
UINT16 anim_duration;
|
||||
INT32 tics;
|
||||
statenum_t statenum;
|
||||
UINT32 flags;
|
||||
|
|
|
@ -363,7 +363,7 @@ consvar_t cv_runscripts = {"runscripts", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL
|
|||
consvar_t cv_pause = {"pausepermission", "Server", CV_NETVAR, pause_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_sleep = {"cpusleep", "1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
INT16 gametype = GT_COOP;
|
||||
boolean splitscreen = false;
|
||||
|
@ -1186,12 +1186,12 @@ static void SendNameAndColor(void)
|
|||
&& !strcmp(cv_skin.string, skins[players[consoleplayer].skin].name))
|
||||
return;
|
||||
|
||||
players[consoleplayer].availabilities = R_GetSkinAvailabilities();
|
||||
|
||||
// We'll handle it later if we're not playing.
|
||||
if (!Playing())
|
||||
return;
|
||||
|
||||
players[consoleplayer].availabilities = R_GetSkinAvailabilities();
|
||||
|
||||
// If you're not in a netgame, merely update the skin, color, and name.
|
||||
if (!netgame)
|
||||
{
|
||||
|
@ -1304,12 +1304,12 @@ static void SendNameAndColor2(void)
|
|||
CV_StealthSet(&cv_playercolor2, cv_playercolor2.defaultvalue);
|
||||
}
|
||||
|
||||
players[secondplaya].availabilities = R_GetSkinAvailabilities();
|
||||
|
||||
// We'll handle it later if we're not playing.
|
||||
if (!Playing())
|
||||
return;
|
||||
|
||||
players[secondplaya].availabilities = R_GetSkinAvailabilities();
|
||||
|
||||
// If you're not in a netgame, merely update the skin, color, and name.
|
||||
if (botingame)
|
||||
{
|
||||
|
|
|
@ -5885,7 +5885,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
|
||||
// Saloon door
|
||||
"S_SALOONDOOR",
|
||||
"S_SALOONDOORTHINKER",
|
||||
"S_SALOONDOORCENTER",
|
||||
|
||||
// Train cameo
|
||||
"S_TRAINCAMEOSPAWNER_1",
|
||||
|
@ -5991,6 +5991,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_LAMPPOST1", // normal
|
||||
"S_LAMPPOST2", // with snow
|
||||
"S_HANGSTAR",
|
||||
"S_MISTLETOE",
|
||||
// Xmas GFZ bushes
|
||||
"S_XMASBLUEBERRYBUSH",
|
||||
"S_XMASBERRYBUSH",
|
||||
|
@ -5998,6 +5999,16 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
// FHZ
|
||||
"S_FHZICE1",
|
||||
"S_FHZICE2",
|
||||
"S_ROSY_IDLE1",
|
||||
"S_ROSY_IDLE2",
|
||||
"S_ROSY_IDLE3",
|
||||
"S_ROSY_IDLE4",
|
||||
"S_ROSY_JUMP",
|
||||
"S_ROSY_WALK",
|
||||
"S_ROSY_HUG",
|
||||
"S_ROSY_PAIN",
|
||||
"S_ROSY_STND",
|
||||
"S_ROSY_UNHAPPY",
|
||||
|
||||
// Halloween Scenery
|
||||
// Pumpkins
|
||||
|
@ -7655,7 +7666,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_MINECARTSIDEMARK",
|
||||
"MT_MINECARTSPARK",
|
||||
"MT_SALOONDOOR",
|
||||
"MT_SALOONDOORTHINKER",
|
||||
"MT_SALOONDOORCENTER",
|
||||
"MT_TRAINCAMEOSPAWNER",
|
||||
"MT_TRAINSEG",
|
||||
"MT_TRAINDUSTSPAWNER",
|
||||
|
@ -7717,6 +7728,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_LAMPPOST1", // normal
|
||||
"MT_LAMPPOST2", // with snow
|
||||
"MT_HANGSTAR",
|
||||
"MT_MISTLETOE",
|
||||
// Xmas GFZ bushes
|
||||
"MT_XMASBLUEBERRYBUSH",
|
||||
"MT_XMASBERRYBUSH",
|
||||
|
@ -7724,6 +7736,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
// FHZ
|
||||
"MT_FHZICE1",
|
||||
"MT_FHZICE2",
|
||||
"MT_ROSY",
|
||||
"MT_CDLHRT",
|
||||
|
||||
// Halloween Scenery
|
||||
// Pumpkins
|
||||
|
|
|
@ -637,6 +637,7 @@ static void F_IntroDrawScene(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
menuanimtimer = animtimer; // Reusing this variable for the intro to fix the scrolling sky, better than changing the function around.
|
||||
F_SkyScroll(80*4, 0, "TITLESKY");
|
||||
if (timetonext == 6)
|
||||
{
|
||||
|
|
|
@ -709,8 +709,8 @@ void G_DefineDefaultControls(void)
|
|||
|
||||
for (i = 1; i < num_gamecontrolschemes; i++) // skip gcs_custom (0)
|
||||
{
|
||||
gamecontroldefault[i][gc_weaponnext ][0] = 'e';
|
||||
gamecontroldefault[i][gc_weaponprev ][0] = 'q';
|
||||
gamecontroldefault[i][gc_weaponnext ][0] = KEY_MOUSEWHEELUP+0;
|
||||
gamecontroldefault[i][gc_weaponprev ][0] = KEY_MOUSEWHEELDOWN+0;
|
||||
gamecontroldefault[i][gc_wepslot1 ][0] = '1';
|
||||
gamecontroldefault[i][gc_wepslot2 ][0] = '2';
|
||||
gamecontroldefault[i][gc_wepslot3 ][0] = '3';
|
||||
|
|
|
@ -47,6 +47,7 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal, RGBA_t *pgamma);
|
|||
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl);
|
||||
EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
|
||||
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
|
||||
EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform);
|
||||
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
|
||||
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor);
|
||||
EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo);
|
||||
|
@ -89,6 +90,7 @@ struct hwdriver_s
|
|||
FinishUpdate pfnFinishUpdate;
|
||||
Draw2DLine pfnDraw2DLine;
|
||||
DrawPolygon pfnDrawPolygon;
|
||||
RenderSkyDome pfnRenderSkyDome;
|
||||
SetBlend pfnSetBlend;
|
||||
ClearBuffer pfnClearBuffer;
|
||||
SetTexture pfnSetTexture;
|
||||
|
|
|
@ -395,7 +395,9 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_XMS3
|
||||
&lspr[NOLIGHT], // SPR_XMS4
|
||||
&lspr[NOLIGHT], // SPR_XMS5
|
||||
&lspr[NOLIGHT], // SPR_XMS6
|
||||
&lspr[NOLIGHT], // SPR_FHZI
|
||||
&lspr[NOLIGHT], // SPR_ROSY
|
||||
|
||||
// Halloween Scenery
|
||||
&lspr[RINGLIGHT_L], // SPR_PUMK
|
||||
|
|
|
@ -5454,7 +5454,7 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
#ifdef HWPRECIP
|
||||
precipmobj_t *precipthing;
|
||||
#endif
|
||||
fixed_t approx_dist, limit_dist;
|
||||
fixed_t approx_dist, limit_dist, hoop_limit_dist;
|
||||
|
||||
// BSP is traversed by subsector.
|
||||
// A sector might have been split into several
|
||||
|
@ -5471,7 +5471,9 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
|
||||
// Handle all things in sector.
|
||||
// If a limit exists, handle things a tiny bit different.
|
||||
if ((limit_dist = (fixed_t)((maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : cv_drawdist.value) << FRACBITS))
|
||||
limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
|
||||
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
||||
if (limit_dist || hoop_limit_dist)
|
||||
{
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
|
@ -5480,8 +5482,16 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
||||
if (approx_dist > limit_dist)
|
||||
continue;
|
||||
if (thing->sprite == SPR_HOOP)
|
||||
{
|
||||
if (hoop_limit_dist && approx_dist > hoop_limit_dist)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (limit_dist && approx_dist > limit_dist)
|
||||
continue;
|
||||
}
|
||||
|
||||
HWR_ProjectSprite(thing);
|
||||
}
|
||||
|
@ -5711,6 +5721,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer)
|
||||
{
|
||||
// bodge support - not nearly as comprehensive as r_things.c, but better than nothing
|
||||
if (thing->tracer->sprite == SPR_NULL || thing->tracer->flags2 & MF2_DONTDRAW)
|
||||
return;
|
||||
}
|
||||
|
||||
// store information in a vissprite
|
||||
vis = HWR_NewVisSprite();
|
||||
vis->x1 = x1;
|
||||
|
@ -5724,7 +5741,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
vis->z2 = z2;
|
||||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
|
||||
if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
|
||||
{
|
||||
if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized)
|
||||
vis->colormap = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
|
||||
|
@ -5869,86 +5886,122 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
// ==========================================================================
|
||||
//
|
||||
// ==========================================================================
|
||||
static void HWR_DrawSkyBackground(void)
|
||||
static void HWR_DrawSkyBackground(player_t *player)
|
||||
{
|
||||
FOutVector v[4];
|
||||
angle_t angle;
|
||||
float dimensionmultiply;
|
||||
float aspectratio;
|
||||
float angleturn;
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture]);
|
||||
aspectratio = (float)vid.width/(float)vid.height;
|
||||
|
||||
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
|
||||
// because it's called just after clearing the screen
|
||||
// and thus, the near clipping plane is set to 3.99
|
||||
// Sryder: Just use the near clipping plane value then
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
v[0].x = v[3].x = -ZCLIP_PLANE-1;
|
||||
v[1].x = v[2].x = ZCLIP_PLANE+1;
|
||||
v[0].y = v[1].y = -ZCLIP_PLANE-1;
|
||||
v[2].y = v[3].y = ZCLIP_PLANE+1;
|
||||
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1;
|
||||
|
||||
// X
|
||||
|
||||
// NOTE: This doesn't work right with texture widths greater than 1024
|
||||
// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
|
||||
// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
|
||||
|
||||
angle = (dup_viewangle + gr_xtoviewangle[0]);
|
||||
|
||||
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
|
||||
|
||||
v[0].sow = v[3].sow = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left
|
||||
v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f)
|
||||
// use +angle and -1.0f above instead if you wanted old backwards behavior
|
||||
|
||||
// Y
|
||||
angle = aimingangle;
|
||||
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio));
|
||||
|
||||
if (splitscreen)
|
||||
if (cv_grskydome.value)
|
||||
{
|
||||
dimensionmultiply *= 2;
|
||||
angle *= 2;
|
||||
}
|
||||
FTransform transform;
|
||||
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
|
||||
postimg_t *type;
|
||||
|
||||
// Middle of the sky should always be at angle 0
|
||||
// need to keep correct aspect ratio with X
|
||||
if (atransform.flip)
|
||||
{
|
||||
// During vertical flip the sky should be flipped and it's y movement should also be flipped obviously
|
||||
v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); // top
|
||||
v[0].tow = v[1].tow = v[3].tow - (1.0f/dimensionmultiply); // bottom (or top - 1.0f)
|
||||
if (splitscreen && player == &players[secondarydisplayplayer])
|
||||
type = &postimgtype2;
|
||||
else
|
||||
type = &postimgtype;
|
||||
|
||||
memset(&transform, 0x00, sizeof(FTransform));
|
||||
|
||||
//04/01/2000: Hurdler: added for T&L
|
||||
// It should replace all other gr_viewxxx when finished
|
||||
transform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
|
||||
transform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
|
||||
|
||||
if (*type == postimg_flip)
|
||||
transform.flip = true;
|
||||
else
|
||||
transform.flip = false;
|
||||
|
||||
transform.scalex = 1;
|
||||
transform.scaley = (float)vid.width/vid.height;
|
||||
transform.scalez = 1;
|
||||
transform.fovxangle = fpov; // Tails
|
||||
transform.fovyangle = fpov; // Tails
|
||||
transform.splitscreen = splitscreen;
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture]);
|
||||
HWD.pfnRenderSkyDome(skytexture, textures[skytexture]->width, textures[skytexture]->height, transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); // bottom
|
||||
v[3].tow = v[2].tow = v[0].tow - (1.0f/dimensionmultiply); // top (or bottom - 1.0f)
|
||||
}
|
||||
FOutVector v[4];
|
||||
angle_t angle;
|
||||
float dimensionmultiply;
|
||||
float aspectratio;
|
||||
float angleturn;
|
||||
|
||||
angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply;
|
||||
HWR_GetTexture(texturetranslation[skytexture]);
|
||||
aspectratio = (float)vid.width/(float)vid.height;
|
||||
|
||||
if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa
|
||||
{
|
||||
angle = InvAngle(angle);
|
||||
v[3].tow = v[2].tow += ((float) angle / angleturn);
|
||||
v[0].tow = v[1].tow += ((float) angle / angleturn);
|
||||
}
|
||||
else
|
||||
{
|
||||
v[3].tow = v[2].tow -= ((float) angle / angleturn);
|
||||
v[0].tow = v[1].tow -= ((float) angle / angleturn);
|
||||
}
|
||||
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
|
||||
// because it's called just after clearing the screen
|
||||
// and thus, the near clipping plane is set to 3.99
|
||||
// Sryder: Just use the near clipping plane value then
|
||||
|
||||
HWD.pfnDrawPolygon(NULL, v, 4, 0);
|
||||
// 3--2
|
||||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
v[0].x = v[3].x = -ZCLIP_PLANE-1;
|
||||
v[1].x = v[2].x = ZCLIP_PLANE+1;
|
||||
v[0].y = v[1].y = -ZCLIP_PLANE-1;
|
||||
v[2].y = v[3].y = ZCLIP_PLANE+1;
|
||||
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1;
|
||||
|
||||
// X
|
||||
|
||||
// NOTE: This doesn't work right with texture widths greater than 1024
|
||||
// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
|
||||
// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
|
||||
|
||||
angle = (dup_viewangle + gr_xtoviewangle[0]);
|
||||
|
||||
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
|
||||
|
||||
v[0].sow = v[3].sow = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left
|
||||
v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f)
|
||||
// use +angle and -1.0f above instead if you wanted old backwards behavior
|
||||
|
||||
// Y
|
||||
angle = aimingangle;
|
||||
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio));
|
||||
|
||||
if (splitscreen)
|
||||
{
|
||||
dimensionmultiply *= 2;
|
||||
angle *= 2;
|
||||
}
|
||||
|
||||
// Middle of the sky should always be at angle 0
|
||||
// need to keep correct aspect ratio with X
|
||||
if (atransform.flip)
|
||||
{
|
||||
// During vertical flip the sky should be flipped and it's y movement should also be flipped obviously
|
||||
v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); // top
|
||||
v[0].tow = v[1].tow = v[3].tow - (1.0f/dimensionmultiply); // bottom (or top - 1.0f)
|
||||
}
|
||||
else
|
||||
{
|
||||
v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); // bottom
|
||||
v[3].tow = v[2].tow = v[0].tow - (1.0f/dimensionmultiply); // top (or bottom - 1.0f)
|
||||
}
|
||||
|
||||
angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply;
|
||||
|
||||
if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa
|
||||
{
|
||||
angle = InvAngle(angle);
|
||||
v[3].tow = v[2].tow += ((float) angle / angleturn);
|
||||
v[0].tow = v[1].tow += ((float) angle / angleturn);
|
||||
}
|
||||
else
|
||||
{
|
||||
v[3].tow = v[2].tow -= ((float) angle / angleturn);
|
||||
v[0].tow = v[1].tow -= ((float) angle / angleturn);
|
||||
}
|
||||
|
||||
HWD.pfnDrawPolygon(NULL, v, 4, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -6100,7 +6153,7 @@ if (0)
|
|||
}
|
||||
|
||||
if (drawsky)
|
||||
HWR_DrawSkyBackground();
|
||||
HWR_DrawSkyBackground(player);
|
||||
|
||||
//Hurdler: it doesn't work in splitscreen mode
|
||||
drawsky = splitscreen;
|
||||
|
@ -6317,7 +6370,7 @@ if (0)
|
|||
}
|
||||
|
||||
if (!skybox && drawsky) // Don't draw the regular sky if there's a skybox
|
||||
HWR_DrawSkyBackground();
|
||||
HWR_DrawSkyBackground(player);
|
||||
|
||||
//Hurdler: it doesn't work in splitscreen mode
|
||||
drawsky = splitscreen;
|
||||
|
|
|
@ -98,6 +98,7 @@ extern consvar_t cv_voodoocompatibility;
|
|||
extern consvar_t cv_grfovchange;
|
||||
extern consvar_t cv_grsolvetjoin;
|
||||
extern consvar_t cv_grspritebillboarding;
|
||||
extern consvar_t cv_grskydome;
|
||||
|
||||
extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy;
|
||||
|
||||
|
|
|
@ -1277,6 +1277,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
|
||||
// MD2 colormap fix
|
||||
// colormap test
|
||||
if (spr->mobj->subsector)
|
||||
{
|
||||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
UINT8 lightlevel = 255;
|
||||
|
@ -1308,6 +1309,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
else
|
||||
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
|
||||
}
|
||||
else
|
||||
Surf.FlatColor.rgba = 0xFFFFFFFF;
|
||||
|
||||
// Look at HWR_ProjectSprite for more
|
||||
{
|
||||
|
|
|
@ -1427,6 +1427,219 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf,
|
|||
Clamp2D(GL_TEXTURE_WRAP_T);
|
||||
}
|
||||
|
||||
typedef struct vbo_vertex_s
|
||||
{
|
||||
float x, y, z;
|
||||
float u, v;
|
||||
unsigned char r, g, b, a;
|
||||
} vbo_vertex_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int mode;
|
||||
int vertexcount;
|
||||
int vertexindex;
|
||||
int use_texture;
|
||||
} GLSkyLoopDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int id;
|
||||
int rows, columns;
|
||||
int loopcount;
|
||||
GLSkyLoopDef *loops;
|
||||
vbo_vertex_t *data;
|
||||
} GLSkyVBO;
|
||||
|
||||
// The texture offset to be applied to the texture coordinates in SkyVertex().
|
||||
static int rows, columns;
|
||||
static boolean yflip;
|
||||
static int texw, texh;
|
||||
static boolean foglayer;
|
||||
static float delta = 0.0f;
|
||||
|
||||
static int gl_sky_detail = 16;
|
||||
|
||||
static INT32 lasttex = -1;
|
||||
|
||||
#define MAP_COEFF 128.0f
|
||||
|
||||
static void SkyVertex(vbo_vertex_t *vbo, int r, int c)
|
||||
{
|
||||
const float radians = (M_PIl / 180.0f);
|
||||
const float scale = 10000.0f;
|
||||
const float maxSideAngle = 60.0f;
|
||||
|
||||
float topAngle = (c / (float)columns * 360.0f);
|
||||
float sideAngle = (maxSideAngle * (rows - r) / rows);
|
||||
float height = sin(sideAngle * radians);
|
||||
float realRadius = scale * cos(sideAngle * radians);
|
||||
float x = realRadius * cos(topAngle * radians);
|
||||
float y = (!yflip) ? scale * height : -scale * height;
|
||||
float z = realRadius * sin(topAngle * radians);
|
||||
float timesRepeat = (4 * (256.0f / texw));
|
||||
if (fpclassify(timesRepeat) == FP_ZERO)
|
||||
timesRepeat = 1.0f;
|
||||
|
||||
if (!foglayer)
|
||||
{
|
||||
vbo->r = 255;
|
||||
vbo->g = 255;
|
||||
vbo->b = 255;
|
||||
vbo->a = (r == 0 ? 0 : 255);
|
||||
|
||||
// And the texture coordinates.
|
||||
vbo->u = (-timesRepeat * c / (float)columns);
|
||||
if (!yflip) // Flipped Y is for the lower hemisphere.
|
||||
vbo->v = (r / (float)rows) + 0.5f;
|
||||
else
|
||||
vbo->v = 1.0f + ((rows - r) / (float)rows) + 0.5f;
|
||||
}
|
||||
|
||||
if (r != 4)
|
||||
{
|
||||
y += 300.0f;
|
||||
}
|
||||
|
||||
// And finally the vertex.
|
||||
vbo->x = x;
|
||||
vbo->y = y + delta;
|
||||
vbo->z = z;
|
||||
}
|
||||
|
||||
static GLSkyVBO sky_vbo;
|
||||
|
||||
static void gld_BuildSky(int row_count, int col_count)
|
||||
{
|
||||
int c, r;
|
||||
vbo_vertex_t *vertex_p;
|
||||
int vertex_count = 2 * row_count * (col_count * 2 + 2) + col_count * 2;
|
||||
|
||||
GLSkyVBO *vbo = &sky_vbo;
|
||||
|
||||
if ((vbo->columns != col_count) || (vbo->rows != row_count))
|
||||
{
|
||||
free(vbo->loops);
|
||||
free(vbo->data);
|
||||
memset(vbo, 0, sizeof(&vbo));
|
||||
}
|
||||
|
||||
if (!vbo->data)
|
||||
{
|
||||
memset(vbo, 0, sizeof(&vbo));
|
||||
vbo->loops = malloc((row_count * 2 + 2) * sizeof(vbo->loops[0]));
|
||||
// create vertex array
|
||||
vbo->data = malloc(vertex_count * sizeof(vbo->data[0]));
|
||||
}
|
||||
|
||||
vbo->columns = col_count;
|
||||
vbo->rows = row_count;
|
||||
|
||||
vertex_p = &vbo->data[0];
|
||||
vbo->loopcount = 0;
|
||||
|
||||
for (yflip = 0; yflip < 2; yflip++)
|
||||
{
|
||||
vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN;
|
||||
vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0];
|
||||
vbo->loops[vbo->loopcount].vertexcount = col_count;
|
||||
vbo->loops[vbo->loopcount].use_texture = false;
|
||||
vbo->loopcount++;
|
||||
|
||||
delta = 0.0f;
|
||||
foglayer = true;
|
||||
for (c = 0; c < col_count; c++)
|
||||
{
|
||||
SkyVertex(vertex_p, 1, c);
|
||||
vertex_p->r = 255;
|
||||
vertex_p->g = 255;
|
||||
vertex_p->b = 255;
|
||||
vertex_p->a = 255;
|
||||
vertex_p++;
|
||||
}
|
||||
foglayer = false;
|
||||
|
||||
delta = (yflip ? 5.0f : -5.0f) / MAP_COEFF;
|
||||
|
||||
for (r = 0; r < row_count; r++)
|
||||
{
|
||||
vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_STRIP;
|
||||
vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0];
|
||||
vbo->loops[vbo->loopcount].vertexcount = 2 * col_count + 2;
|
||||
vbo->loops[vbo->loopcount].use_texture = true;
|
||||
vbo->loopcount++;
|
||||
|
||||
for (c = 0; c <= col_count; c++)
|
||||
{
|
||||
SkyVertex(vertex_p++, r + (yflip ? 1 : 0), (c ? c : 0));
|
||||
SkyVertex(vertex_p++, r + (yflip ? 0 : 1), (c ? c : 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void RenderDome(INT32 skytexture)
|
||||
{
|
||||
int i, j;
|
||||
GLSkyVBO *vbo = &sky_vbo;
|
||||
|
||||
pglRotatef(270.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
rows = 4;
|
||||
columns = 4 * gl_sky_detail;
|
||||
|
||||
if (lasttex != skytexture)
|
||||
{
|
||||
lasttex = skytexture;
|
||||
gld_BuildSky(rows, columns);
|
||||
}
|
||||
|
||||
pglScalef(1.0f, (float)texh / 230.0f, 1.0f);
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
for (i = 0; i < vbo->loopcount; i++)
|
||||
{
|
||||
GLSkyLoopDef *loop = &vbo->loops[i];
|
||||
|
||||
if (j == 0 ? loop->use_texture : !loop->use_texture)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
int k;
|
||||
pglBegin(loop->mode);
|
||||
for (k = loop->vertexindex; k < (loop->vertexindex + loop->vertexcount); k++)
|
||||
{
|
||||
vbo_vertex_t *v = &vbo->data[k];
|
||||
if (loop->use_texture)
|
||||
pglTexCoord2f(v->u, v->v);
|
||||
pglColor4f(v->r, v->g, v->b, v->a);
|
||||
pglVertex3f(v->x, v->y, v->z);
|
||||
}
|
||||
pglEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pglScalef(1.0f, 1.0f, 1.0f);
|
||||
pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform)
|
||||
{
|
||||
SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||
SetTransform(&transform);
|
||||
texw = texture_width;
|
||||
texh = texture_height;
|
||||
RenderDome(tex);
|
||||
SetBlend(0);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
//
|
||||
|
|
111
src/info.c
111
src/info.c
|
@ -266,7 +266,6 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"ADST", // Arid dust
|
||||
"MCRT", // Minecart
|
||||
"MCSP", // Minecart spark
|
||||
"NON2", // Saloon door thinker
|
||||
"SALD", // Saloon door
|
||||
"TRAE", // Train cameo locomotive
|
||||
"TRAI", // Train cameo wagon
|
||||
|
@ -290,7 +289,9 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"XMS3", // Snowman
|
||||
"XMS4", // Lamppost
|
||||
"XMS5", // Hanging Star
|
||||
"XMS6", // Mistletoe
|
||||
"FHZI", // FHZ ice
|
||||
"ROSY",
|
||||
|
||||
// Halloween Scenery
|
||||
"PUMK", // Pumpkins
|
||||
|
@ -2486,8 +2487,8 @@ state_t states[NUMSTATES] =
|
|||
{SPR_MCSP, FF_FULLBRIGHT, 1, {A_MinecartSparkThink}, 0, 0, S_MINECARTSPARK}, // S_MINECARTSPARK
|
||||
|
||||
// Saloon door
|
||||
{SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR
|
||||
{SPR_NON2, 0, -1, {A_SaloonDoorSpawn}, 0, 0, S_NULL}, // S_SALONDOORTHINKER
|
||||
{SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR
|
||||
{SPR_NULL, 0, -1, {A_SaloonDoorSpawn}, MT_SALOONDOOR, 48, S_NULL}, // S_SALOONDOORCENTER
|
||||
|
||||
// Train cameo
|
||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_TRAINCAMEOSPAWNER_2}, // S_TRAINCAMEOSPAWNER_1
|
||||
|
@ -2598,6 +2599,7 @@ state_t states[NUMSTATES] =
|
|||
{SPR_XMS4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LAMPPOST1
|
||||
{SPR_XMS4, 1, -1, {NULL}, 0, 0, S_NULL}, // S_LAMPPOST2
|
||||
{SPR_XMS5, 0, -1, {NULL}, 0, 0, S_NULL}, // S_HANGSTAR
|
||||
{SPR_XMS6, 0, -1, {NULL}, 0, 0, S_NULL}, // S_MISTLETOE
|
||||
// Xmas GFZ bushes
|
||||
{SPR_BUS3, 1, -1, {NULL}, 0, 0, S_NULL}, // S_XMASBLUEBERRYBUSH
|
||||
{SPR_BUS1, 1, -1, {NULL}, 0, 0, S_NULL}, // S_XMASBERRYBUSH
|
||||
|
@ -2605,6 +2607,16 @@ state_t states[NUMSTATES] =
|
|||
// FHZ
|
||||
{SPR_FHZI, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FHZICE1
|
||||
{SPR_FHZI, 1, -1, {NULL}, 0, 0, S_NULL}, // S_FHZICE2
|
||||
{SPR_ROSY, 16, 8, {NULL}, 0, 0, S_ROSY_IDLE2}, // S_ROSY_IDLE1
|
||||
{SPR_ROSY, 17, 4, {NULL}, 0, 0, S_ROSY_IDLE3}, // S_ROSY_IDLE2
|
||||
{SPR_ROSY, 18, 8, {NULL}, 0, 0, S_ROSY_IDLE4}, // S_ROSY_IDLE3
|
||||
{SPR_ROSY, 17, 4, {NULL}, 0, 0, S_ROSY_IDLE1}, // S_ROSY_IDLE4
|
||||
{SPR_ROSY, 14, -1, {NULL}, 1, 0, S_NULL}, // S_ROSY_JUMP
|
||||
{SPR_ROSY, 5, -1, {NULL}, 7, 0, S_NULL}, // S_ROSY_WALK
|
||||
{SPR_ROSY, 19, -1, {NULL}, 0, 0, S_NULL}, // S_ROSY_HUG
|
||||
{SPR_ROSY, 13, -1, {NULL}, 0, 0, S_NULL}, // S_ROSY_PAIN
|
||||
{SPR_ROSY, 1|FF_ANIMATE, -1, {NULL}, 3, 16, S_NULL}, // S_ROSY_STND
|
||||
{SPR_ROSY, 20|FF_ANIMATE, TICRATE, {NULL}, 3, 4, S_ROSY_WALK}, // S_ROSY_UNHAPPY
|
||||
|
||||
// Halloween Scenery
|
||||
// Pumpkins
|
||||
|
@ -4829,7 +4841,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SCENERY|MF_PAIN|MF_NOCLIPHEIGHT|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
|
||||
MF_SCENERY|MF_PAIN|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
|
||||
S_SNAPPER_LEGRAISE // raisestate
|
||||
},
|
||||
|
||||
|
@ -4856,7 +4868,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_PAIN|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
|
||||
MF_PAIN|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -12383,7 +12395,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SOLID|MF_SHOOTABLE|MF_ENEMY|MF_PUSHABLE, // flags
|
||||
MF_SOLID|MF_SHOOTABLE|MF_PUSHABLE, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -12711,9 +12723,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_SALOONDOORTHINKER
|
||||
{ // MT_SALOONDOORCENTER
|
||||
1221, // doomednum
|
||||
S_SALOONDOORTHINKER, // spawnstate
|
||||
S_SALOONDOORCENTER, // spawnstate
|
||||
1, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
@ -12734,7 +12746,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags
|
||||
MF_SOLID|MF_NOGRAVITY|MF_RUNSPAWNFUNC|MF_PAPERCOLLISION|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -13926,6 +13938,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_MISTLETOE
|
||||
2105, // doomednum
|
||||
S_MISTLETOE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
52*FRACUNIT, // radius
|
||||
106*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
1, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_XMASBLUEBERRYBUSH
|
||||
1859, // doomednum
|
||||
S_XMASBLUEBERRYBUSH, // spawnstate
|
||||
|
@ -14061,6 +14100,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_ROSY
|
||||
2104, // doomednum
|
||||
S_ROSY_IDLE1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
16*FRACUNIT, // radius
|
||||
48*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SCENERY|MF_ENEMY|MF_SLIDEME, // flags -- "enemy" may seem weird but it doesn't have any unintended consequences in context because no MF_SHOOTABLE|MF_SPECIAL
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_CDLHRT
|
||||
-1, // doomednum
|
||||
S_LHRT, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
4*FRACUNIT, // speed
|
||||
4*FRACUNIT, // radius
|
||||
4*FRACUNIT, // height
|
||||
1, // display offset
|
||||
4, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_JACKO1
|
||||
2006, // doomednum
|
||||
S_JACKO1, // spawnstate
|
||||
|
|
21
src/info.h
21
src/info.h
|
@ -522,7 +522,6 @@ typedef enum sprite
|
|||
SPR_ADST, // Arid dust
|
||||
SPR_MCRT, // Minecart
|
||||
SPR_MCSP, // Minecart spark
|
||||
SPR_NON2, // Saloon door thinker
|
||||
SPR_SALD, // Saloon door
|
||||
SPR_TRAE, // Train cameo locomotive
|
||||
SPR_TRAI, // Train cameo wagon
|
||||
|
@ -546,7 +545,9 @@ typedef enum sprite
|
|||
SPR_XMS3, // Snowman
|
||||
SPR_XMS4, // Lamppost
|
||||
SPR_XMS5, // Hanging Star
|
||||
SPR_XMS6, // Mistletoe
|
||||
SPR_FHZI, // FHZ Ice
|
||||
SPR_ROSY,
|
||||
|
||||
// Halloween Scenery
|
||||
SPR_PUMK, // Pumpkins
|
||||
|
@ -2608,7 +2609,7 @@ typedef enum state
|
|||
|
||||
// Saloon door
|
||||
S_SALOONDOOR,
|
||||
S_SALOONDOORTHINKER,
|
||||
S_SALOONDOORCENTER,
|
||||
|
||||
// Train cameo
|
||||
S_TRAINCAMEOSPAWNER_1,
|
||||
|
@ -2714,6 +2715,7 @@ typedef enum state
|
|||
S_LAMPPOST1, // normal
|
||||
S_LAMPPOST2, // with snow
|
||||
S_HANGSTAR,
|
||||
S_MISTLETOE,
|
||||
// Xmas GFZ bushes
|
||||
S_XMASBLUEBERRYBUSH,
|
||||
S_XMASBERRYBUSH,
|
||||
|
@ -2721,6 +2723,16 @@ typedef enum state
|
|||
// FHZ
|
||||
S_FHZICE1,
|
||||
S_FHZICE2,
|
||||
S_ROSY_IDLE1,
|
||||
S_ROSY_IDLE2,
|
||||
S_ROSY_IDLE3,
|
||||
S_ROSY_IDLE4,
|
||||
S_ROSY_JUMP,
|
||||
S_ROSY_WALK,
|
||||
S_ROSY_HUG,
|
||||
S_ROSY_PAIN,
|
||||
S_ROSY_STND,
|
||||
S_ROSY_UNHAPPY,
|
||||
|
||||
// Halloween Scenery
|
||||
// Pumpkins
|
||||
|
@ -4400,7 +4412,7 @@ typedef enum mobj_type
|
|||
MT_MINECARTSIDEMARK,
|
||||
MT_MINECARTSPARK,
|
||||
MT_SALOONDOOR,
|
||||
MT_SALOONDOORTHINKER,
|
||||
MT_SALOONDOORCENTER,
|
||||
MT_TRAINCAMEOSPAWNER,
|
||||
MT_TRAINSEG,
|
||||
MT_TRAINDUSTSPAWNER,
|
||||
|
@ -4462,6 +4474,7 @@ typedef enum mobj_type
|
|||
MT_LAMPPOST1, // normal
|
||||
MT_LAMPPOST2, // with snow
|
||||
MT_HANGSTAR,
|
||||
MT_MISTLETOE,
|
||||
// Xmas GFZ bushes
|
||||
MT_XMASBLUEBERRYBUSH,
|
||||
MT_XMASBERRYBUSH,
|
||||
|
@ -4469,6 +4482,8 @@ typedef enum mobj_type
|
|||
// FHZ
|
||||
MT_FHZICE1,
|
||||
MT_FHZICE2,
|
||||
MT_ROSY,
|
||||
MT_CDLHRT,
|
||||
|
||||
// Halloween Scenery
|
||||
// Pumpkins
|
||||
|
|
|
@ -1121,7 +1121,7 @@ void LUA_Archive(void)
|
|||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
if (!playeringame[i] && i > 0) // dedicated servers...
|
||||
continue;
|
||||
// all players in game will be archived, even if they just add a 0.
|
||||
ArchiveExtVars(&players[i], "player");
|
||||
|
@ -1157,7 +1157,7 @@ void LUA_UnArchive(void)
|
|||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
if (!playeringame[i] && i > 0) // dedicated servers...
|
||||
continue;
|
||||
UnArchiveExtVars(&players[i]);
|
||||
}
|
||||
|
|
111
src/m_menu.c
111
src/m_menu.c
|
@ -247,6 +247,7 @@ menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef;
|
|||
// Single Player
|
||||
static void M_StartTutorial(INT32 choice);
|
||||
static void M_LoadGame(INT32 choice);
|
||||
static void M_HandleTimeAttackLevelSelect(INT32 choice);
|
||||
static void M_TimeAttackLevelSelect(INT32 choice);
|
||||
static void M_TimeAttack(INT32 choice);
|
||||
static void M_NightsAttackLevelSelect(INT32 choice);
|
||||
|
@ -743,7 +744,7 @@ static menuitem_t SP_TimeAttackLevelSelectMenu[] =
|
|||
// Single Player Time Attack
|
||||
static menuitem_t SP_TimeAttackMenu[] =
|
||||
{
|
||||
{IT_STRING|IT_CALL, NULL, "Level Select...", &M_TimeAttackLevelSelect, 52},
|
||||
{IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", M_HandleTimeAttackLevelSelect, 52},
|
||||
{IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 62},
|
||||
|
||||
{IT_DISABLED, NULL, "Guest Option...", &SP_GuestReplayDef, 100},
|
||||
|
@ -1224,7 +1225,7 @@ static menuitem_t OP_VideoOptionsMenu[] =
|
|||
{IT_HEADER, NULL, "Level", NULL, 155},
|
||||
{IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 161},
|
||||
{IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 166},
|
||||
{IT_STRING | IT_CVAR, NULL, "NiGHTS mode Draw Dist.", &cv_drawdist_nights, 171},
|
||||
{IT_STRING | IT_CVAR, NULL, "NiGHTS Hoop Draw Dist.", &cv_drawdist_nights, 171},
|
||||
|
||||
{IT_HEADER, NULL, "Diagnostic", NULL, 180},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 186},
|
||||
|
@ -4894,13 +4895,25 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
{
|
||||
boolean exitmenu = false; // exit to previous menu
|
||||
INT32 selectval;
|
||||
UINT8 iter;
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_DOWNARROW:
|
||||
if (lsrow == levelselect.numrows-1)
|
||||
{
|
||||
if (levelselect.numrows < 3)
|
||||
{
|
||||
if (!lsoffs[0]) // prevent sound spam
|
||||
{
|
||||
lsoffs[0] = -8;
|
||||
S_StartSound(NULL,sfx_s3kb7);
|
||||
}
|
||||
return;
|
||||
}
|
||||
lsrow = UINT8_MAX;
|
||||
}
|
||||
lsrow++;
|
||||
if (lsrow == levelselect.numrows)
|
||||
lsrow = 0;
|
||||
|
||||
lsoffs[0] = lsvseperation(lsrow);
|
||||
|
||||
|
@ -4914,17 +4927,29 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
break;
|
||||
|
||||
case KEY_UPARROW:
|
||||
lsoffs[0] = -lsvseperation(lsrow);
|
||||
|
||||
iter = lsrow;
|
||||
if (!lsrow)
|
||||
{
|
||||
if (levelselect.numrows < 3)
|
||||
{
|
||||
if (!lsoffs[0]) // prevent sound spam
|
||||
{
|
||||
lsoffs[0] = 8;
|
||||
S_StartSound(NULL,sfx_s3kb7);
|
||||
}
|
||||
return;
|
||||
}
|
||||
lsrow = levelselect.numrows;
|
||||
}
|
||||
lsrow--;
|
||||
if (lsrow == UINT8_MAX)
|
||||
lsrow = levelselect.numrows-1;
|
||||
|
||||
lsoffs[0] = -lsvseperation(iter);
|
||||
|
||||
if (levelselect.rows[lsrow].header[0])
|
||||
lshli = lsrow;
|
||||
else
|
||||
{
|
||||
UINT8 iter = lsrow;
|
||||
iter = lsrow;
|
||||
do
|
||||
iter = ((iter == 0) ? levelselect.numrows-1 : iter-1);
|
||||
while ((iter != lsrow) && !(levelselect.rows[iter].header[0]));
|
||||
|
@ -4957,7 +4982,7 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
M_LevelSelectWarp(0);
|
||||
Nextmap_OnChange();
|
||||
}
|
||||
else if (!lsoffs[0]) // prevent sound spam
|
||||
else if (!lsoffs[0]) // prevent sound spam
|
||||
{
|
||||
lsoffs[0] = -8;
|
||||
S_StartSound(NULL,sfx_s3kb2);
|
||||
|
@ -4987,7 +5012,7 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
|
||||
ifselectvalnextmap(lscol) else ifselectvalnextmap(0)
|
||||
}
|
||||
else if (!lsoffs[1]) // prevent sound spam
|
||||
else if (!lsoffs[1]) // prevent sound spam
|
||||
{
|
||||
lsoffs[1] = 8;
|
||||
S_StartSound(NULL,sfx_s3kb7);
|
||||
|
@ -5016,7 +5041,7 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
|
||||
ifselectvalnextmap(lscol) else ifselectvalnextmap(0)
|
||||
}
|
||||
else if (!lsoffs[1]) // prevent sound spam
|
||||
else if (!lsoffs[1]) // prevent sound spam
|
||||
{
|
||||
lsoffs[1] = -8;
|
||||
S_StartSound(NULL,sfx_s3kb7);
|
||||
|
@ -5187,7 +5212,13 @@ static void M_DrawLevelPlatterMenu(void)
|
|||
// finds row at top of the screen
|
||||
while (y > -8)
|
||||
{
|
||||
iter = ((iter == 0) ? levelselect.numrows-1 : iter-1);
|
||||
if (iter == 0)
|
||||
{
|
||||
if (levelselect.numrows < 3)
|
||||
break;
|
||||
iter = levelselect.numrows;
|
||||
}
|
||||
iter--;
|
||||
y -= lsvseperation(iter);
|
||||
}
|
||||
|
||||
|
@ -5196,7 +5227,13 @@ static void M_DrawLevelPlatterMenu(void)
|
|||
{
|
||||
M_DrawLevelPlatterRow(iter, y);
|
||||
y += lsvseperation(iter);
|
||||
iter = ((iter == levelselect.numrows-1) ? 0 : iter+1);
|
||||
if (iter == levelselect.numrows-1)
|
||||
{
|
||||
if (levelselect.numrows < 3)
|
||||
break;
|
||||
iter = UINT8_MAX;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
// draw cursor box
|
||||
|
@ -8330,7 +8367,18 @@ void M_DrawTimeAttackMenu(void)
|
|||
else
|
||||
PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE);
|
||||
|
||||
V_DrawSmallScaledPatch(208, 32+lsheadingheight, 0, PictureOfLevel);
|
||||
y = 32+lsheadingheight;
|
||||
V_DrawSmallScaledPatch(208, y, 0, PictureOfLevel);
|
||||
|
||||
if (itemOn == talevel)
|
||||
{
|
||||
/* Draw arrows !! */
|
||||
y = y + 25 - 4;
|
||||
V_DrawCharacter(208 - 10 - (skullAnimCounter/5), y,
|
||||
'\x1C' | V_YELLOWMAP, false);
|
||||
V_DrawCharacter(208 + 80 + 2 + (skullAnimCounter/5), y,
|
||||
'\x1D' | V_YELLOWMAP, false);
|
||||
}
|
||||
|
||||
V_DrawString(104 - 72, 32+lsheadingheight/2, 0, "* LEVEL RECORDS *");
|
||||
|
||||
|
@ -8400,6 +8448,39 @@ void M_DrawTimeAttackMenu(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void M_HandleTimeAttackLevelSelect(INT32 choice)
|
||||
{
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_DOWNARROW:
|
||||
M_NextOpt();
|
||||
break;
|
||||
case KEY_UPARROW:
|
||||
M_PrevOpt();
|
||||
break;
|
||||
|
||||
case KEY_LEFTARROW:
|
||||
CV_AddValue(&cv_nextmap, -1);
|
||||
break;
|
||||
case KEY_RIGHTARROW:
|
||||
CV_AddValue(&cv_nextmap, 1);
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
M_TimeAttackLevelSelect(0);
|
||||
break;
|
||||
|
||||
case KEY_ESCAPE:
|
||||
noFurtherInput = true;
|
||||
M_GoBack(0);
|
||||
return;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
}
|
||||
|
||||
static void M_TimeAttackLevelSelect(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
|
140
src/p_enemy.c
140
src/p_enemy.c
|
@ -5351,20 +5351,22 @@ static mobj_t *minus;
|
|||
|
||||
static boolean PIT_MinusCarry(mobj_t *thing)
|
||||
{
|
||||
if (minus->tracer)
|
||||
return true;
|
||||
|
||||
if (minus->type == thing->type)
|
||||
return true;
|
||||
|
||||
if (!(thing->flags & MF_SHOOTABLE) || !(thing->flags & MF_ENEMY))
|
||||
if (!(thing->flags & (MF_PUSHABLE|MF_ENEMY)))
|
||||
return true;
|
||||
|
||||
if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius * 3)
|
||||
if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius*3)
|
||||
return true;
|
||||
|
||||
if (abs(thing->z - minus->z) > minus->height)
|
||||
return true;
|
||||
|
||||
P_SetTarget(&minus->tracer, thing);
|
||||
minus->tracer->flags &= ~MF_PUSHABLE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -5428,6 +5430,9 @@ void A_MinusDigging(mobj_t *actor)
|
|||
A_Chase(actor);
|
||||
|
||||
// Carry over shit, maybe
|
||||
if (P_MobjWasRemoved(actor->tracer) || !actor->tracer->health)
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
|
||||
if (!actor->tracer)
|
||||
{
|
||||
fixed_t radius = 3*actor->radius;
|
||||
|
@ -5477,7 +5482,6 @@ void A_MinusPopup(mobj_t *actor)
|
|||
else
|
||||
actor->momz = 10*FRACUNIT;
|
||||
|
||||
actor->flags |= MF_SPECIAL|MF_SHOOTABLE;
|
||||
S_StartSound(actor, sfx_s3k82);
|
||||
for (i = 1; i <= num; i++)
|
||||
{
|
||||
|
@ -5490,6 +5494,7 @@ void A_MinusPopup(mobj_t *actor)
|
|||
if (actor->tracer)
|
||||
P_DamageMobj(actor->tracer, actor, actor, 1, 0);
|
||||
|
||||
actor->flags = (actor->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE;
|
||||
}
|
||||
|
||||
// Function: A_MinusCheck
|
||||
|
@ -12248,7 +12253,6 @@ void A_ConnectToGround(mobj_t *actor)
|
|||
mobj_t *work;
|
||||
fixed_t workz;
|
||||
fixed_t workh;
|
||||
SINT8 dir;
|
||||
angle_t ang;
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
|
@ -12262,23 +12266,17 @@ void A_ConnectToGround(mobj_t *actor)
|
|||
P_AdjustMobjFloorZ_FFloors(actor, actor->subsector->sector, 2);
|
||||
|
||||
if (actor->flags2 & MF2_OBJECTFLIP)
|
||||
{
|
||||
workz = actor->ceilingz - (actor->z + actor->height);
|
||||
dir = -1;
|
||||
}
|
||||
workz = (actor->z + actor->height) - actor->ceilingz;
|
||||
else
|
||||
{
|
||||
workz = actor->floorz - actor->z;
|
||||
dir = 1;
|
||||
}
|
||||
|
||||
if (locvar2)
|
||||
{
|
||||
workh = FixedMul(mobjinfo[locvar2].height, actor->scale);
|
||||
if (actor->flags2 & MF2_OBJECTFLIP)
|
||||
workz -= workh;
|
||||
workz += workh;
|
||||
work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar2);
|
||||
workz += dir*workh;
|
||||
workz += workh;
|
||||
}
|
||||
|
||||
if (!locvar1)
|
||||
|
@ -12287,21 +12285,18 @@ void A_ConnectToGround(mobj_t *actor)
|
|||
if (!(workh = FixedMul(mobjinfo[locvar1].height, actor->scale)))
|
||||
return;
|
||||
|
||||
if (actor->flags2 & MF2_OBJECTFLIP)
|
||||
workz -= workh;
|
||||
|
||||
ang = actor->angle + ANGLE_45;
|
||||
while (dir*workz < 0)
|
||||
while (workz < 0)
|
||||
{
|
||||
work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar1);
|
||||
if (work)
|
||||
work->angle = ang;
|
||||
ang += ANGLE_90;
|
||||
workz += dir*workh;
|
||||
workz += workh;
|
||||
}
|
||||
|
||||
if (workz != 0)
|
||||
actor->z += workz;
|
||||
actor->z += P_MobjFlip(actor)*workz;
|
||||
}
|
||||
|
||||
// Function: A_SpawnParticleRelative
|
||||
|
@ -13466,6 +13461,13 @@ void A_TNTExplode(mobj_t *actor)
|
|||
if (LUA_CallAction("A_TNTExplode", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (actor->tracer)
|
||||
{
|
||||
P_SetTarget(&actor->tracer->tracer, NULL);
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
}
|
||||
|
||||
P_UnsetThingPosition(actor);
|
||||
if (sector_list)
|
||||
{
|
||||
|
@ -13679,8 +13681,6 @@ void A_KillSegments(mobj_t *actor)
|
|||
static void P_SnapperLegPlace(mobj_t *mo)
|
||||
{
|
||||
mobj_t *seg = mo->tracer;
|
||||
fixed_t x0 = mo->x;
|
||||
fixed_t y0 = mo->y;
|
||||
angle_t a = mo->angle;
|
||||
angle_t fa = (a >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t c = FINECOSINE(fa);
|
||||
|
@ -13695,7 +13695,8 @@ static void P_SnapperLegPlace(mobj_t *mo)
|
|||
fixed_t rad = mo->radius;
|
||||
INT32 necklen = (32*(mo->info->reactiontime - mo->reactiontime))/mo->info->reactiontime; // Not in FU
|
||||
|
||||
P_TeleportMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, mo->z + mo->height/3);
|
||||
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);
|
||||
seg->angle = a;
|
||||
|
||||
// Move as many legs as available.
|
||||
|
@ -13715,13 +13716,14 @@ static void P_SnapperLegPlace(mobj_t *mo)
|
|||
{
|
||||
x = c*o2 + s*o1;
|
||||
y = s*o2 - c*o1;
|
||||
P_TryMove(seg, x0 + x, y0 + y, true);
|
||||
seg->z = mo->z + (((mo->eflags & MFE_VERTICALFLIP) ? (mo->height - seg->height) : 0));
|
||||
P_TryMove(seg, mo->x + x, mo->y + y, true);
|
||||
P_SetMobjState(seg, seg->info->raisestate);
|
||||
}
|
||||
else
|
||||
P_SetMobjState(seg, seg->info->spawnstate);
|
||||
|
||||
seg->angle = R_PointToAngle2(x0, y0, seg->x, seg->y);
|
||||
seg->angle = R_PointToAngle2(mo->x, mo->y, seg->x, seg->y);
|
||||
|
||||
seg = seg->tracer;
|
||||
} while (seg);
|
||||
|
@ -13749,14 +13751,14 @@ void A_SnapperSpawn(mobj_t *actor)
|
|||
#endif
|
||||
|
||||
// It spawns 1 head.
|
||||
seg = P_SpawnMobj(actor->x, actor->y, actor->z, headtype);
|
||||
seg = P_SpawnMobjFromMobj(actor, 0, 0, 0, headtype);
|
||||
P_SetTarget(&ptr->tracer, seg);
|
||||
ptr = seg;
|
||||
|
||||
// It spawns 4 legs which will be handled in the thinker function.
|
||||
for (i = 1; i <= 4; i++)
|
||||
{
|
||||
seg = P_SpawnMobj(actor->x, actor->y, actor->z, legtype);
|
||||
seg = P_SpawnMobjFromMobj(actor, 0, 0, 0, legtype);
|
||||
P_SetTarget(&ptr->tracer, seg);
|
||||
ptr = seg;
|
||||
|
||||
|
@ -13904,51 +13906,43 @@ void A_SnapperThinker(mobj_t *actor)
|
|||
//
|
||||
// Description: Spawns a saloon door.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
// var1 = mobjtype for sides
|
||||
// var2 = distance sides should be placed apart
|
||||
//
|
||||
void A_SaloonDoorSpawn(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
angle_t ang = actor->angle;
|
||||
angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t c = FINECOSINE(fa);
|
||||
fixed_t s = FINESINE(fa);
|
||||
INT32 d = 48;
|
||||
fixed_t x = actor->x;
|
||||
fixed_t y = actor->y;
|
||||
fixed_t z = actor->z;
|
||||
fixed_t c = FINECOSINE(fa)*locvar2;
|
||||
fixed_t s = FINESINE(fa)*locvar2;
|
||||
mobj_t *door;
|
||||
mobjflag2_t ambush = (actor->flags & MF2_AMBUSH);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_SaloonDoorSpawn", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
//Front
|
||||
door = P_SpawnMobj(x + c*d, y + s*d, z, MT_SALOONDOOR);
|
||||
if (!locvar1)
|
||||
return;
|
||||
|
||||
// One door...
|
||||
if (!(door = P_SpawnMobjFromMobj(actor, c, s, 0, locvar1))) return;
|
||||
door->angle = ang + ANGLE_180;
|
||||
door->extravalue1 = AngleFixed(door->angle); // Origin angle
|
||||
door->extravalue2 = 0; // Angular speed
|
||||
P_SetTarget(&door->tracer, actor); // Origin door
|
||||
door->flags2 |= ambush; // Can be opened by normal players?
|
||||
|
||||
// Origin angle
|
||||
door->extravalue1 = AngleFixed(door->angle);
|
||||
|
||||
// Angular speed
|
||||
door->extravalue2 = 0;
|
||||
|
||||
// Origin door
|
||||
P_SetTarget(&door->tracer, actor);
|
||||
|
||||
//Back
|
||||
door = P_SpawnMobj(x - c*d, y - s*d, z, MT_SALOONDOOR);
|
||||
// ...two door!
|
||||
if (!(door = P_SpawnMobjFromMobj(actor, -c, -s, 0, locvar1))) return;
|
||||
door->angle = ang;
|
||||
|
||||
// Origin angle
|
||||
door->extravalue1 = AngleFixed(door->angle);
|
||||
|
||||
// Angular speed
|
||||
door->extravalue2 = 0;
|
||||
|
||||
// Origin door
|
||||
P_SetTarget(&door->tracer, actor);
|
||||
door->extravalue1 = AngleFixed(door->angle); // Origin angle
|
||||
door->extravalue2 = 0; // Angular speed
|
||||
P_SetTarget(&door->tracer, actor); // Origin door
|
||||
door->flags2 |= ambush; // Can be opened by normal players?
|
||||
}
|
||||
|
||||
// Function: A_MinecartSparkThink
|
||||
|
@ -14200,7 +14194,7 @@ void A_RolloutSpawn(mobj_t *actor)
|
|||
actor->target = P_SpawnMobj(actor->x, actor->y, actor->z, locvar2);
|
||||
actor->target->flags2 |= (actor->flags2 & (MF2_AMBUSH | MF2_OBJECTFLIP)) | MF2_SLIDEPUSH;
|
||||
actor->target->eflags |= (actor->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
|
||||
if (actor->target->flags2 & MF2_AMBUSH)
|
||||
{
|
||||
actor->target->color = SKINCOLOR_SUPERRUST3;
|
||||
|
@ -14220,37 +14214,35 @@ void A_RolloutRock(mobj_t *actor)
|
|||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_RolloutRock", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
UINT8 maxframes = actor->info->reactiontime; // number of frames the mobj cycles through
|
||||
fixed_t pi = (22*FRACUNIT/7);
|
||||
fixed_t circumference = FixedMul(2 * pi, actor->radius); // used to calculate when to change frame
|
||||
fixed_t speed = P_AproxDistance(actor->momx, actor->momy), topspeed = FixedMul(actor->info->speed, actor->scale);
|
||||
boolean inwater = actor->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_RolloutRock", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
actor->friction = FRACUNIT; // turns out riding on solids sucks, so let's just make it easier on ourselves
|
||||
|
||||
if (actor->threshold)
|
||||
actor->threshold--;
|
||||
|
||||
if (inwater && !(actor->flags2 & MF2_AMBUSH)) // buoyancy in water (or lava)
|
||||
{
|
||||
UINT8 flip = P_MobjFlip(actor);
|
||||
fixed_t prevmomz = actor->momz;
|
||||
actor->momz = FixedMul(actor->momz, locvar2);
|
||||
actor->momz += flip * FixedMul(locvar2, actor->scale);
|
||||
if (actor->threshold)
|
||||
actor->threshold--;
|
||||
if (flip*prevmomz < 0 && flip*actor->momz >= 0)
|
||||
if (flip*prevmomz < 0 && flip*actor->momz >= 0 && !actor->threshold)
|
||||
{
|
||||
if (actor->eflags & MFE_UNDERWATER)
|
||||
S_StartSound(actor, sfx_splash);
|
||||
else if (!actor->threshold)
|
||||
{
|
||||
S_StartSound(actor, sfx_splish);
|
||||
actor->threshold = max((topspeed - speed) >> FRACBITS, 0);
|
||||
}
|
||||
actor->threshold = max((topspeed - speed) >> FRACBITS, 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14259,7 +14251,7 @@ void A_RolloutRock(mobj_t *actor)
|
|||
actor->momx = FixedMul(FixedDiv(actor->momx, speed), topspeed);
|
||||
actor->momy = FixedMul(FixedDiv(actor->momy, speed), topspeed);
|
||||
}
|
||||
|
||||
|
||||
if (P_IsObjectOnGround(actor) || inwater) // apply drag to speed (compensates for lack of friction but also works in liquids)
|
||||
{
|
||||
actor->momx = FixedMul(actor->momx, locvar1);
|
||||
|
@ -14287,13 +14279,13 @@ void A_RolloutRock(mobj_t *actor)
|
|||
}
|
||||
|
||||
actor->frame = actor->reactiontime % maxframes; // set frame
|
||||
|
||||
|
||||
if (!(actor->flags & MF_PUSHABLE)) // if being ridden, don't disappear
|
||||
actor->fuse = 0;
|
||||
else if (!actor->fuse && actor->movecount == 1) // otherwise if rock has moved, set its fuse
|
||||
actor->fuse = actor->info->painchance;
|
||||
|
||||
|
||||
if (actor->fuse && actor->fuse < 2*TICRATE)
|
||||
actor->flags2 ^= MF2_DONTDRAW;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -428,7 +428,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|| special->state == &states[S_FANG_BOUNCE4]
|
||||
|| special->state == &states[S_FANG_PINCHBOUNCE3]
|
||||
|| special->state == &states[S_FANG_PINCHBOUNCE4])
|
||||
&& P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z - toucher->height/2)) > -(special->height/4))
|
||||
&& P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z - toucher->height/2)) > (special->height/4))
|
||||
{
|
||||
P_DamageMobj(toucher, special, special, 1, 0);
|
||||
P_SetTarget(&special->tracer, toucher);
|
||||
|
@ -1085,7 +1085,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (player->exiting)
|
||||
return;
|
||||
|
||||
if (player->bumpertime < TICRATE/4)
|
||||
if (player->bumpertime <= (TICRATE/2)-5)
|
||||
{
|
||||
S_StartSound(toucher, special->info->seesound);
|
||||
if (player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
|
@ -1776,7 +1776,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
|
||||
case MT_MINECARTSPAWNER:
|
||||
if (!special->fuse || player->powers[pw_carry] != CR_MINECART)
|
||||
if (!player->bot && (special->fuse < TICRATE || player->powers[pw_carry] != CR_MINECART))
|
||||
{
|
||||
mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART);
|
||||
P_SetTarget(&mcart->target, toucher);
|
||||
|
@ -1786,7 +1786,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
P_ResetPlayer(player);
|
||||
player->pflags |= PF_JUMPDOWN;
|
||||
player->powers[pw_carry] = CR_MINECART;
|
||||
toucher->player->pflags &= ~PF_APPLYAUTOBRAKE;
|
||||
player->pflags &= ~PF_APPLYAUTOBRAKE;
|
||||
P_SetTarget(&toucher->tracer, mcart);
|
||||
toucher->momx = toucher->momy = toucher->momz = 0;
|
||||
|
||||
|
|
83
src/p_map.c
83
src/p_map.c
|
@ -208,7 +208,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
{
|
||||
angle_t nightsangle = 0;
|
||||
|
||||
if (object->player->bumpertime >= TICRATE/4)
|
||||
if (object->player->bumpertime > (TICRATE/2)-5)
|
||||
return false;
|
||||
|
||||
if ((object->player->pflags & PF_TRANSFERTOCLOSEST) && object->player->axis1 && object->player->axis2)
|
||||
|
@ -640,6 +640,34 @@ static void P_SlapStick(mobj_t *fang, mobj_t *pole)
|
|||
P_SetTarget(&pole->tracer, NULL);
|
||||
}
|
||||
|
||||
static void P_PlayerBarrelCollide(mobj_t *toucher, mobj_t *barrel)
|
||||
{
|
||||
if (toucher->momz < 0)
|
||||
{
|
||||
if (toucher->z + toucher->momz > barrel->z + barrel->height)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (toucher->z > barrel->z + barrel->height)
|
||||
return;
|
||||
}
|
||||
|
||||
if (toucher->momz > 0)
|
||||
{
|
||||
if (toucher->z + toucher->height + toucher->momz < barrel->z)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (toucher->z + toucher->height < barrel->z)
|
||||
return;
|
||||
}
|
||||
|
||||
if (P_PlayerCanDamage(toucher->player, barrel))
|
||||
P_DamageMobj(barrel, toucher, toucher, 1, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// PIT_CheckThing
|
||||
//
|
||||
|
@ -917,12 +945,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
if (thing->type == MT_SALOONDOOR && tmthing->player)
|
||||
{
|
||||
if (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer) && tmthing->tracer->health)
|
||||
mobj_t *ref = (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)) ? tmthing->tracer : tmthing;
|
||||
if ((thing->flags & MF2_AMBUSH) || ref != tmthing)
|
||||
{
|
||||
fixed_t dx = tmthing->tracer->momx;
|
||||
fixed_t dy = tmthing->tracer->momy;
|
||||
fixed_t dm = min(FixedHypot(dx, dy), 16*FRACUNIT);
|
||||
angle_t ang = R_PointToAngle2(0, 0, dx, dy) - thing->angle;
|
||||
fixed_t dm = min(FixedHypot(ref->momx, ref->momy), 16*FRACUNIT);
|
||||
angle_t ang = R_PointToAngle2(0, 0, ref->momx, ref->momy) - thing->angle;
|
||||
fixed_t s = FINESINE((ang >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
S_StartSound(tmthing, thing->info->activesound);
|
||||
thing->extravalue2 += 2*FixedMul(s, dm)/3;
|
||||
|
@ -930,39 +957,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
}
|
||||
}
|
||||
|
||||
if (thing->type == MT_TNTBARREL && tmthing->player)
|
||||
if (thing->type == MT_SALOONDOORCENTER && tmthing->player)
|
||||
{
|
||||
if (tmthing->momz < 0)
|
||||
{
|
||||
if (tmthing->z + tmthing->momz > thing->z + thing->height)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmthing->z > thing->z + thing->height)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tmthing->momz > 0)
|
||||
{
|
||||
if (tmthing->z + tmthing->height + tmthing->momz < thing->z)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmthing->z + tmthing->height < thing->z)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((tmthing->player->pflags & (PF_SPINNING | PF_GLIDING))
|
||||
|| ((tmthing->player->pflags & PF_JUMPED)
|
||||
&& (!(tmthing->player->pflags & PF_NOJUMPDAMAGE)
|
||||
|| (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|
||||
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|
||||
|| ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING)
|
||||
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height / 2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))
|
||||
|| (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (tmthing->player->pflags & PF_SHIELDABILITY)))
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
||||
if ((thing->flags & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (thing->type == MT_ROLLOUTROCK && tmthing->player && tmthing->health)
|
||||
|
@ -1023,6 +1021,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (thing->type == MT_PTERABYTE && tmthing->player)
|
||||
P_DoPterabyteCarry(tmthing->player, thing);
|
||||
|
||||
if (thing->type == MT_TNTBARREL && tmthing->player)
|
||||
P_PlayerBarrelCollide(tmthing, thing);
|
||||
|
||||
if (thing->type == MT_VULTURE && tmthing->type == MT_VULTURE)
|
||||
{
|
||||
fixed_t dx = thing->x - tmthing->x;
|
||||
|
@ -2732,8 +2733,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
// HACK TO FIX DSZ2: apply only if slopes are involved
|
||||
else if (tmceilingslope && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
|
||||
else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
|
||||
{
|
||||
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
|
||||
thing->ceilingrover = tmceilingrover;
|
||||
|
@ -2748,8 +2748,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
// HACK TO FIX DSZ2: apply only if slopes are involved
|
||||
else if (tmfloorslope && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
|
||||
else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
|
||||
{
|
||||
thing->z = thing->floorz = tmfloorz;
|
||||
thing->floorrover = tmfloorrover;
|
||||
|
|
278
src/p_mobj.c
278
src/p_mobj.c
|
@ -1578,7 +1578,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
|
||||
// Goop has slower, reversed gravity
|
||||
if (goopgravity)
|
||||
gravityadd = -gravityadd/5;
|
||||
gravityadd = -((gravityadd/5) + (gravityadd/8));
|
||||
|
||||
gravityadd = FixedMul(gravityadd, mo->scale);
|
||||
|
||||
|
@ -2369,9 +2369,9 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
|
|||
return false;
|
||||
|
||||
if (((mo->z <= mo->subsector->sector->floorheight
|
||||
&& !(mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR))
|
||||
&& ((mo->subsector->sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR))
|
||||
|| (mo->z + mo->height >= mo->subsector->sector->ceilingheight
|
||||
&& (mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING)))
|
||||
&& ((mo->subsector->sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING)))
|
||||
&& (GETSECSPECIAL(mo->subsector->sector->special, 1) == 6
|
||||
|| GETSECSPECIAL(mo->subsector->sector->special, 1) == 7))
|
||||
return true;
|
||||
|
@ -3434,9 +3434,18 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= height>>1))
|
||||
return;
|
||||
|
||||
if (!wasgroundpounding && (mobj->eflags & MFE_GOOWATER || wasingoo)) { // Decide what happens to your momentum when you enter/leave goopy water.
|
||||
if (P_MobjFlip(mobj)*mobj->momz < 0) // You are entering the goo?
|
||||
mobj->momz = FixedMul(mobj->momz, FixedDiv(2*FRACUNIT, 5*FRACUNIT)); // kill momentum significantly, to make the goo feel thick.
|
||||
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");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!wasgroundpounding)
|
||||
mobj->momz >>= 1; // kill momentum significantly, to make the goo feel thick.
|
||||
//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.
|
||||
|
@ -7642,6 +7651,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
case MT_ROCKCRUMBLE16:
|
||||
case MT_WOODDEBRIS:
|
||||
case MT_BRICKDEBRIS:
|
||||
case MT_BROKENROBOT:
|
||||
if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height)
|
||||
&& mobj->state != &states[mobj->info->deathstate])
|
||||
{
|
||||
|
@ -7706,6 +7716,237 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (mobj->movedir)
|
||||
mobj->angle += mobj->movedir;
|
||||
break;
|
||||
case MT_ROSY:
|
||||
{
|
||||
UINT8 i;
|
||||
fixed_t pdist = 1700*mobj->scale, work, actualwork;
|
||||
player_t *player = NULL;
|
||||
statenum_t stat = (mobj->state-states);
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
if (!players[i].mo)
|
||||
continue;
|
||||
if (players[i].bot)
|
||||
continue;
|
||||
if (!players[i].mo->health)
|
||||
continue;
|
||||
actualwork = work = FixedHypot(mobj->x-players[i].mo->x, mobj->y-players[i].mo->y);
|
||||
if (player)
|
||||
{
|
||||
if (players[i].skin == 0 || players[i].skin == 3)
|
||||
work = (2*work)/3;
|
||||
if (work >= pdist)
|
||||
continue;
|
||||
}
|
||||
pdist = actualwork;
|
||||
player = &players[i];
|
||||
}
|
||||
|
||||
if (stat == S_ROSY_JUMP || stat == S_ROSY_PAIN)
|
||||
{
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
mobj->momx = mobj->momy = 0;
|
||||
if (player && mobj->cvmem < (-2*TICRATE))
|
||||
stat = S_ROSY_UNHAPPY;
|
||||
else
|
||||
stat = S_ROSY_WALK;
|
||||
P_SetMobjState(mobj, stat);
|
||||
}
|
||||
else if (P_MobjFlip(mobj)*mobj->momz < 0)
|
||||
mobj->frame = mobj->state->frame+mobj->state->var1;
|
||||
}
|
||||
|
||||
if (!player)
|
||||
{
|
||||
if ((stat < S_ROSY_IDLE1 || stat > S_ROSY_IDLE4) && stat != S_ROSY_JUMP)
|
||||
{
|
||||
mobj->momx = mobj->momy = 0;
|
||||
P_SetMobjState(mobj, S_ROSY_IDLE1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean dojump = false, targonground, love, makeheart = false;
|
||||
if (mobj->target != player->mo)
|
||||
P_SetTarget(&mobj->target, player->mo);
|
||||
targonground = (P_IsObjectOnGround(mobj->target) && (player->panim == PA_IDLE || player->panim == PA_WALK || player->panim == PA_RUN));
|
||||
love = (player->skin == 0 || player->skin == 3);
|
||||
|
||||
switch (stat)
|
||||
{
|
||||
case S_ROSY_IDLE1:
|
||||
case S_ROSY_IDLE2:
|
||||
case S_ROSY_IDLE3:
|
||||
case S_ROSY_IDLE4:
|
||||
dojump = true;
|
||||
break;
|
||||
case S_ROSY_JUMP:
|
||||
case S_ROSY_PAIN:
|
||||
// handled above
|
||||
break;
|
||||
case S_ROSY_WALK:
|
||||
{
|
||||
fixed_t x = mobj->x, y = mobj->y, z = mobj->z;
|
||||
angle_t angletoplayer = R_PointToAngle2(x, y, mobj->target->x, mobj->target->y);
|
||||
boolean allowed = P_TryMove(mobj, mobj->target->x, mobj->target->y, false);
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = x;
|
||||
mobj->y = y;
|
||||
mobj->z = z;
|
||||
P_SetThingPosition(mobj);
|
||||
|
||||
if (allowed)
|
||||
{
|
||||
fixed_t mom, max;
|
||||
P_Thrust(mobj, angletoplayer, (3*FRACUNIT)>>1);
|
||||
mom = FixedHypot(mobj->momx, mobj->momy);
|
||||
max = pdist;
|
||||
if ((--mobj->extravalue1) <= 0)
|
||||
{
|
||||
if (++mobj->frame > mobj->state->frame+mobj->state->var1)
|
||||
mobj->frame = mobj->state->frame;
|
||||
if (mom > 12*mobj->scale)
|
||||
mobj->extravalue1 = 2;
|
||||
else if (mom > 6*mobj->scale)
|
||||
mobj->extravalue1 = 3;
|
||||
else
|
||||
mobj->extravalue1 = 4;
|
||||
}
|
||||
if (max < (mobj->radius + mobj->target->radius))
|
||||
{
|
||||
mobj->momx = mobj->target->player->cmomx;
|
||||
mobj->momy = mobj->target->player->cmomy;
|
||||
if ((mobj->cvmem > TICRATE && !player->exiting) || !targonground)
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_STND));
|
||||
else
|
||||
{
|
||||
mobj->target->momx = mobj->momx;
|
||||
mobj->target->momy = mobj->momy;
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_HUG));
|
||||
S_StartSound(mobj, sfx_cdpcm6);
|
||||
mobj->angle = angletoplayer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
max /= 3;
|
||||
if (max > 30*mobj->scale)
|
||||
max = 30*mobj->scale;
|
||||
if (mom > max && max > mobj->scale)
|
||||
{
|
||||
max = FixedDiv(max, mom);
|
||||
mobj->momx = FixedMul(mobj->momx, max);
|
||||
mobj->momy = FixedMul(mobj->momy, max);
|
||||
}
|
||||
if (abs(mobj->momx) > mobj->scale || abs(mobj->momy) > mobj->scale)
|
||||
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
|
||||
}
|
||||
}
|
||||
else
|
||||
dojump = true;
|
||||
}
|
||||
break;
|
||||
case S_ROSY_HUG:
|
||||
if (targonground)
|
||||
{
|
||||
player->pflags |= PF_STASIS;
|
||||
if (mobj->cvmem < 5*TICRATE)
|
||||
mobj->cvmem++;
|
||||
if (love && !(leveltime & 7))
|
||||
makeheart = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mobj->cvmem < (love ? 5*TICRATE : 0))
|
||||
{
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_PAIN));
|
||||
S_StartSound(mobj, sfx_cdpcm7);
|
||||
}
|
||||
else
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_JUMP));
|
||||
var1 = var2 = 0;
|
||||
A_DoNPCPain(mobj);
|
||||
mobj->cvmem -= TICRATE;
|
||||
}
|
||||
break;
|
||||
case S_ROSY_STND:
|
||||
if ((pdist > (mobj->radius + mobj->target->radius + 3*(mobj->scale + mobj->target->scale))))
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_WALK));
|
||||
else if (!targonground)
|
||||
;
|
||||
else
|
||||
{
|
||||
if (love && !(leveltime & 15))
|
||||
makeheart = true;
|
||||
if (player->exiting || --mobj->cvmem < TICRATE)
|
||||
{
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_HUG));
|
||||
S_StartSound(mobj, sfx_cdpcm6);
|
||||
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y);
|
||||
mobj->target->momx = mobj->momx;
|
||||
mobj->target->momy = mobj->momy;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case S_ROSY_UNHAPPY:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (stat == S_ROSY_HUG)
|
||||
{
|
||||
if (player->panim != PA_IDLE)
|
||||
P_SetPlayerMobjState(mobj->target, S_PLAY_STND);
|
||||
player->pflags |= PF_STASIS;
|
||||
}
|
||||
|
||||
if (dojump)
|
||||
{
|
||||
P_SetMobjState(mobj, S_ROSY_JUMP);
|
||||
mobj->z += P_MobjFlip(mobj);
|
||||
mobj->momx = mobj->momy = 0;
|
||||
P_SetObjectMomZ(mobj, 6<<FRACBITS, false);
|
||||
S_StartSound(mobj, sfx_cdfm02);
|
||||
}
|
||||
|
||||
if (makeheart)
|
||||
{
|
||||
mobj_t *cdlhrt = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_CDLHRT);
|
||||
cdlhrt->destscale = (5*mobj->scale)>>4;
|
||||
P_SetScale(cdlhrt, cdlhrt->destscale);
|
||||
cdlhrt->fuse = (5*TICRATE)>>1;
|
||||
cdlhrt->momz = mobj->scale;
|
||||
P_SetTarget(&cdlhrt->target, mobj);
|
||||
cdlhrt->extravalue1 = mobj->x;
|
||||
cdlhrt->extravalue2 = mobj->y;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MT_CDLHRT:
|
||||
{
|
||||
if (mobj->cvmem < 24)
|
||||
mobj->cvmem++;
|
||||
mobj->movedir += ANG10;
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = mobj->extravalue1 + P_ReturnThrustX(mobj, mobj->movedir, mobj->cvmem*mobj->scale);
|
||||
mobj->y = mobj->extravalue2 + P_ReturnThrustY(mobj, mobj->movedir, mobj->cvmem*mobj->scale);
|
||||
P_SetThingPosition(mobj);
|
||||
if ((--mobj->fuse) < 6)
|
||||
{
|
||||
if (!mobj->fuse)
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
mobj->frame = (mobj->frame & ~FF_TRANSMASK)|((10-(mobj->fuse*2))<<(FF_TRANSSHIFT));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MT_VWREF:
|
||||
case MT_VWREB:
|
||||
{
|
||||
|
@ -10130,6 +10371,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
case MT_FANG:
|
||||
sc = 4;
|
||||
break;
|
||||
case MT_ROSY:
|
||||
sc = 5;
|
||||
break;
|
||||
case MT_CORK:
|
||||
mobj->flags2 |= MF2_SUPERFIRE;
|
||||
break;
|
||||
|
@ -10145,6 +10389,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
}
|
||||
case MT_TNTBARREL:
|
||||
mobj->momx = 1; //stack hack
|
||||
mobj->flags2 |= MF2_INVERTAIMABLE;
|
||||
break;
|
||||
case MT_MINECARTEND:
|
||||
P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID));
|
||||
|
@ -10478,7 +10723,7 @@ void P_SpawnPrecipitation(void)
|
|||
if (curWeather == PRECIP_SNOW)
|
||||
{
|
||||
// Not in a sector with visible sky -- exception for NiGHTS.
|
||||
if (!(maptol & TOL_NIGHTS) && precipsector->sector->ceilingpic != skyflatnum)
|
||||
if ((!(maptol & TOL_NIGHTS) && (precipsector->sector->ceilingpic != skyflatnum)) == !(precipsector->sector->flags & SF_INVERTPRECIP))
|
||||
continue;
|
||||
|
||||
rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE);
|
||||
|
@ -10491,7 +10736,7 @@ void P_SpawnPrecipitation(void)
|
|||
else // everything else.
|
||||
{
|
||||
// Not in a sector with visible sky.
|
||||
if (precipsector->sector->ceilingpic != skyflatnum)
|
||||
if ((precipsector->sector->ceilingpic != skyflatnum) == !(precipsector->sector->flags & SF_INVERTPRECIP))
|
||||
continue;
|
||||
|
||||
rainmo = P_SpawnRainMobj(x, y, height, MT_RAIN);
|
||||
|
@ -11311,6 +11556,16 @@ You should think about modifying the deathmatch starts to take full advantage of
|
|||
// They're likely facets of the level's design and therefore required to progress.
|
||||
}
|
||||
|
||||
if (i == MT_ROSY)
|
||||
{
|
||||
if (!(gametype == GT_COOP || (mthing->options & MTF_EXTRA)))
|
||||
return; // she doesn't hang out here
|
||||
else if (mariomode)
|
||||
i = MT_TOAD; // don't remove on penalty of death
|
||||
else if (!(netgame || multiplayer) && players[consoleplayer].skin == 5)
|
||||
return; // no doubles
|
||||
}
|
||||
|
||||
if (i == MT_TOKEN && ((gametype != GT_COOP && gametype != GT_COMPETITION) || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++)))
|
||||
return; // you already got this token, or there are too many, or the gametype's not right
|
||||
|
||||
|
@ -11524,9 +11779,10 @@ You should think about modifying the deathmatch starts to take full advantage of
|
|||
else
|
||||
mobj->health = FixedMul(ss->sector->ceilingheight-ss->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS;
|
||||
break;
|
||||
case MT_FANG:
|
||||
case MT_METALSONIC_RACE:
|
||||
case MT_METALSONIC_BATTLE:
|
||||
case MT_FANG:
|
||||
case MT_ROSY:
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj->color = SKINCOLOR_SILVER;
|
||||
|
@ -12428,7 +12684,7 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
{
|
||||
if (mthing->options & MTF_AMBUSH)
|
||||
{
|
||||
if (i == MT_YELLOWDIAG || i == MT_REDDIAG)
|
||||
if (i == MT_YELLOWDIAG || i == MT_REDDIAG || i == MT_BLUEDIAG)
|
||||
mobj->angle += ANGLE_22h;
|
||||
|
||||
if (i == MT_YELLOWHORIZ || i == MT_REDHORIZ || i == MT_BLUEHORIZ)
|
||||
|
@ -12467,7 +12723,7 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
{
|
||||
if (i == MT_YELLOWDIAG || i == MT_REDDIAG)
|
||||
if (i == MT_YELLOWDIAG || i == MT_REDDIAG || i == MT_BLUEDIAG)
|
||||
mobj->flags |= MF_NOGRAVITY;
|
||||
|
||||
if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0)
|
||||
|
|
|
@ -3618,7 +3618,7 @@ static void P_NetUnArchiveThinkers(void)
|
|||
{
|
||||
executor_t *delay = NULL;
|
||||
UINT32 mobjnum;
|
||||
for (currentthinker = thlist[i].next; currentthinker != &thlist[i];
|
||||
for (currentthinker = thlist[THINK_MAIN].next; currentthinker != &thlist[THINK_MAIN];
|
||||
currentthinker = currentthinker->next)
|
||||
{
|
||||
if (currentthinker->function.acp1 != (actionf_p1)T_ExecutorDelay)
|
||||
|
|
186
src/p_spec.c
186
src/p_spec.c
|
@ -4174,26 +4174,11 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
|
|||
// Check the 3D floor's type...
|
||||
if (rover->flags & FF_BLOCKPLAYER)
|
||||
{
|
||||
boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == topheight));
|
||||
boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == bottomheight));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight)
|
||||
continue;
|
||||
}
|
||||
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
|
||||
{
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP)
|
||||
|| player->mo->z + player->mo->height != bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight)
|
||||
|| (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight)))
|
||||
continue;
|
||||
}
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4234,26 +4219,11 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
|
|||
// Check the 3D floor's type...
|
||||
if (rover->flags & FF_BLOCKPLAYER)
|
||||
{
|
||||
boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == topheight));
|
||||
boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == bottomheight));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight)
|
||||
continue;
|
||||
}
|
||||
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
|
||||
{
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP)
|
||||
|| player->mo->z + player->mo->height != bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight)
|
||||
|| (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight)))
|
||||
continue;
|
||||
}
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4304,26 +4274,11 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
|
|||
// Check the 3D floor's type...
|
||||
if (rover->flags & FF_BLOCKPLAYER)
|
||||
{
|
||||
boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == top));
|
||||
boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == bottom));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != top)
|
||||
return false;
|
||||
}
|
||||
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
|
||||
{
|
||||
if (!(mo->eflags & MFE_VERTICALFLIP)
|
||||
|| mo->z + mo->height != bottom)
|
||||
return false;
|
||||
}
|
||||
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottom)
|
||||
|| (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == top)))
|
||||
return false;
|
||||
}
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4345,10 +4300,10 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
|
|||
//
|
||||
static boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
|
||||
{
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING);
|
||||
else
|
||||
return (mo->z == P_GetSpecialBottomZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_FLOOR);
|
||||
boolean floorallowed = ((sec->flags & SF_FLIPSPECIAL_FLOOR) && ((sec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == P_GetSpecialBottomZ(mo, sec, sec)));
|
||||
boolean ceilingallowed = ((sec->flags & SF_FLIPSPECIAL_CEILING) && ((sec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == P_GetSpecialTopZ(mo, sec, sec)));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
return (floorallowed || ceilingallowed);
|
||||
}
|
||||
|
||||
/** Applies a sector special to a player.
|
||||
|
@ -5312,26 +5267,11 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
|||
if (((rover->flags & FF_BLOCKPLAYER) && mo->player)
|
||||
|| ((rover->flags & FF_BLOCKOTHERS) && !mo->player))
|
||||
{
|
||||
boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == topheight));
|
||||
boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == bottomheight));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != topheight)
|
||||
continue;
|
||||
}
|
||||
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
|
||||
{
|
||||
if (!(mo->eflags & MFE_VERTICALFLIP)
|
||||
|| mo->z + mo->height != bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottomheight)
|
||||
|| (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == topheight)))
|
||||
continue;
|
||||
}
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5374,26 +5314,11 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
|||
// Check the 3D floor's type...
|
||||
if (rover->flags & FF_BLOCKPLAYER)
|
||||
{
|
||||
boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == topheight));
|
||||
boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == bottomheight));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
|
||||
{
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight)
|
||||
continue;
|
||||
}
|
||||
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
|
||||
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
|
||||
{
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP)
|
||||
|| player->mo->z + player->mo->height != bottomheight)
|
||||
continue;
|
||||
}
|
||||
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight)
|
||||
|| (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight)))
|
||||
continue;
|
||||
}
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5450,38 +5375,16 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
|||
}
|
||||
|
||||
if (!(po->flags & POF_TESTHEIGHT)) // Don't do height checking
|
||||
{
|
||||
}
|
||||
;
|
||||
else if (po->flags & POF_SOLID)
|
||||
{
|
||||
boolean floorallowed = ((polysec->flags & SF_FLIPSPECIAL_FLOOR) && ((polysec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == polysec->ceilingheight));
|
||||
boolean ceilingallowed = ((polysec->flags & SF_FLIPSPECIAL_CEILING) && ((polysec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == polysec->floorheight));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if ((polysec->flags & SF_FLIPSPECIAL_FLOOR)
|
||||
&& !(polysec->flags & SF_FLIPSPECIAL_CEILING))
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
{
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != polysec->ceilingheight)
|
||||
{
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ((polysec->flags & SF_FLIPSPECIAL_CEILING)
|
||||
&& !(polysec->flags & SF_FLIPSPECIAL_FLOOR))
|
||||
{
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP)
|
||||
|| player->mo->z + player->mo->height != polysec->floorheight)
|
||||
{
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (polysec->flags & SF_FLIPSPECIAL_BOTH)
|
||||
{
|
||||
if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == polysec->floorheight)
|
||||
|| (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == polysec->ceilingheight)))
|
||||
{
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
continue;
|
||||
}
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5580,17 +5483,13 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
|
|||
f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector);
|
||||
c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector);
|
||||
|
||||
// Only go further if on the ground
|
||||
if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint)
|
||||
return;
|
||||
|
||||
if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != c_affectpoint)
|
||||
return;
|
||||
|
||||
if ((sector->flags & SF_FLIPSPECIAL_BOTH)
|
||||
&& player->mo->z != f_affectpoint
|
||||
&& player->mo->z + player->mo->height != c_affectpoint)
|
||||
return;
|
||||
{
|
||||
boolean floorallowed = ((sector->flags & SF_FLIPSPECIAL_FLOOR) && ((sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == f_affectpoint));
|
||||
boolean ceilingallowed = ((sector->flags & SF_FLIPSPECIAL_CEILING) && ((sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == c_affectpoint));
|
||||
// Thing must be on top of the floor to be affected...
|
||||
if (!(floorallowed || ceilingallowed))
|
||||
return;
|
||||
}
|
||||
|
||||
P_ProcessSpecialSector(player, sector, NULL);
|
||||
}
|
||||
|
@ -6685,6 +6584,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
|
||||
if (lines[i].flags & ML_EFFECT3)
|
||||
sectors[s].flags |= SF_TRIGGERSPECIAL_TOUCH;
|
||||
if (lines[i].flags & ML_EFFECT2)
|
||||
sectors[s].flags |= SF_TRIGGERSPECIAL_HEADBUMP;
|
||||
|
||||
if (lines[i].flags & ML_EFFECT1)
|
||||
sectors[s].flags |= SF_INVERTPRECIP;
|
||||
|
||||
if (lines[i].frontsector && GETSECSPECIAL(lines[i].frontsector->special, 4) == 12)
|
||||
sectors[s].camsec = sides[*lines[i].sidenum].sector-sectors;
|
||||
|
@ -7178,15 +7082,15 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
break;
|
||||
|
||||
case 252: // Shatter block (breaks when touched)
|
||||
ffloorflags = FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER;
|
||||
ffloorflags = FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER;
|
||||
if (lines[i].flags & ML_NOCLIMB)
|
||||
ffloorflags |= FF_SOLID|FF_SHATTERBOTTOM;
|
||||
ffloorflags |= FF_BLOCKPLAYER|FF_SHATTERBOTTOM;
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
break;
|
||||
|
||||
case 253: // Translucent shatter block (see 76)
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER|FF_TRANSLUCENT, secthinkers);
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER|FF_TRANSLUCENT, secthinkers);
|
||||
break;
|
||||
|
||||
case 254: // Bustable block
|
||||
|
|
|
@ -482,7 +482,7 @@ static inline void P_DoSpecialStageStuff(void)
|
|||
countspheres += players[i].spheres;
|
||||
|
||||
// If in water, deplete timer 6x as fast.
|
||||
if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER))
|
||||
if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER) && !(players[i].powers[pw_shield] & SH_PROTECTWATER))
|
||||
players[i].nightstime -= 5;
|
||||
if (--players[i].nightstime > 6)
|
||||
{
|
||||
|
|
52
src/p_user.c
52
src/p_user.c
|
@ -898,7 +898,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
if (player->mo->target)
|
||||
{
|
||||
player->angle_pos = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y);
|
||||
player->drawangle = player->mo->angle = player->angle_pos
|
||||
player->drawangle = player->angle_pos
|
||||
+ ((player->mo->target->flags2 & MF2_AMBUSH) ? // if axis is invert, take the opposite right angle
|
||||
-ANGLE_90 : ANGLE_90); // flyangle is always 0 here, below is kept for posterity
|
||||
/*(player->flyangle > 90 && player->flyangle < 270 ? ANGLE_90 : -ANGLE_90)
|
||||
|
@ -2260,7 +2260,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
else if (!player->skidtime)
|
||||
player->pflags &= ~PF_GLIDING;
|
||||
}
|
||||
else if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
|
||||
else if (player->charability2 == CA2_MELEE && ((player->panim == PA_ABILITY2) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|
||||
{
|
||||
if (player->mo->state-states != S_PLAY_MELEE_LANDING)
|
||||
{
|
||||
|
@ -4674,8 +4674,9 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
|
|||
if (player->speed < FixedMul(player->maxdash, player->mo->scale))
|
||||
#endif
|
||||
{
|
||||
player->drawangle = player->mo->angle;
|
||||
P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->maxdash, player->mo->scale));
|
||||
if (player->panim == PA_IDLE)
|
||||
player->drawangle = player->mo->angle;
|
||||
P_InstaThrust(player->mo, player->drawangle, FixedMul(player->maxdash, player->mo->scale));
|
||||
}
|
||||
player->mo->momx += player->cmomx;
|
||||
player->mo->momy += player->cmomy;
|
||||
|
@ -5873,35 +5874,28 @@ static void P_3dMovement(player_t *player)
|
|||
else
|
||||
topspeed = normalspd;
|
||||
}
|
||||
else if (player->powers[pw_super] || player->powers[pw_sneakers])
|
||||
{
|
||||
thrustfactor = player->thrustfactor*2;
|
||||
acceleration = player->accelstart/2 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration/2;
|
||||
|
||||
if (player->powers[pw_tailsfly])
|
||||
topspeed = normalspd;
|
||||
else if (player->mo->eflags & (MFE_UNDERWATER|MFE_GOOWATER))
|
||||
{
|
||||
topspeed = normalspd;
|
||||
acceleration = 2*acceleration/3;
|
||||
}
|
||||
else
|
||||
topspeed = normalspd * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
thrustfactor = player->thrustfactor;
|
||||
acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration;
|
||||
|
||||
if (player->powers[pw_tailsfly])
|
||||
topspeed = normalspd/2;
|
||||
else if (player->mo->eflags & (MFE_UNDERWATER|MFE_GOOWATER))
|
||||
if (player->powers[pw_super] || player->powers[pw_sneakers])
|
||||
{
|
||||
topspeed = normalspd/2;
|
||||
acceleration = 2*acceleration/3;
|
||||
topspeed = 5 * normalspd / 3; // 1.67x
|
||||
thrustfactor = player->thrustfactor*2;
|
||||
acceleration = player->accelstart/2 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
topspeed = normalspd;
|
||||
thrustfactor = player->thrustfactor;
|
||||
acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration;
|
||||
}
|
||||
|
||||
if (player->powers[pw_tailsfly])
|
||||
topspeed >>= 1;
|
||||
else if (player->mo->eflags & (MFE_UNDERWATER|MFE_GOOWATER))
|
||||
{
|
||||
topspeed >>= 1;
|
||||
acceleration = 2*acceleration/3;
|
||||
}
|
||||
}
|
||||
|
||||
if (spin) // Prevent gaining speed whilst rolling!
|
||||
|
@ -8892,7 +8886,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
|
|||
continue;
|
||||
|
||||
if (mo->type == MT_MINUS && !(mo->flags & (MF_SPECIAL|MF_SHOOTABLE)))
|
||||
mo->flags |= MF_SPECIAL|MF_SHOOTABLE;
|
||||
mo->flags = (mo->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE;
|
||||
|
||||
if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield!
|
||||
P_KillMobj(mo->tracer, inflictor, source, DMG_NUKE);
|
||||
|
@ -10291,7 +10285,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n
|
|||
ffloor_t *rover;
|
||||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
if (!(rover->flags & (FF_EXISTS|FF_BLOCKOTHERS)))
|
||||
continue;
|
||||
|
||||
*nz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight;
|
||||
|
|
358
src/r_data.c
358
src/r_data.c
|
@ -483,7 +483,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
wadnum = patch->wad;
|
||||
lumpnum = patch->lump;
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); // can't use W_CachePatchNumPwad because OpenGL
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
|
||||
|
@ -557,7 +557,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
|
|||
texturememory += blocksize;
|
||||
block = Z_Malloc(blocksize+1, PU_STATIC, &texturecache[texnum]);
|
||||
|
||||
memset(block, 0xFF, blocksize+1); // Transparency hack
|
||||
memset(block, TRANSPARENTPIXEL, blocksize+1); // Transparency hack
|
||||
|
||||
// columns lookup table
|
||||
colofs = (UINT32 *)(void *)block;
|
||||
|
@ -2520,7 +2520,11 @@ void R_PrecacheLevel(void)
|
|||
"spritememory: %s k\n", sizeu1(flatmemory>>10), sizeu2(texturememory>>10), sizeu3(spritememory>>10));
|
||||
}
|
||||
|
||||
// https://github.com/coelckers/prboom-plus/blob/master/prboom2/src/r_patch.c#L350
|
||||
//
|
||||
// R_CheckIfPatch
|
||||
//
|
||||
// Returns true if the lump is a valid patch.
|
||||
//
|
||||
boolean R_CheckIfPatch(lumpnum_t lump)
|
||||
{
|
||||
size_t size;
|
||||
|
@ -2565,6 +2569,71 @@ boolean R_CheckIfPatch(lumpnum_t lump)
|
|||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// R_TextureToFlat
|
||||
//
|
||||
// Convert a texture to a flat.
|
||||
//
|
||||
void R_TextureToFlat(size_t tex, UINT8 *flat)
|
||||
{
|
||||
texture_t *texture = textures[tex];
|
||||
|
||||
fixed_t col, ofs;
|
||||
column_t *column;
|
||||
UINT8 *desttop, *dest, *deststop;
|
||||
UINT8 *source;
|
||||
|
||||
// yea
|
||||
R_CheckTextureCache(tex);
|
||||
|
||||
desttop = flat;
|
||||
deststop = desttop + (texture->width * texture->height);
|
||||
|
||||
for (col = 0; col < texture->width; col++, desttop++)
|
||||
{
|
||||
// no post_t info
|
||||
if (!texture->holes)
|
||||
{
|
||||
column = (column_t *)(R_GetColumn(tex, col));
|
||||
source = (UINT8 *)(column);
|
||||
dest = desttop;
|
||||
for (ofs = 0; dest < deststop && ofs < texture->height; ofs++)
|
||||
{
|
||||
if (source[ofs] != TRANSPARENTPIXEL)
|
||||
*dest = source[ofs];
|
||||
dest += texture->width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
column = (column_t *)((UINT8 *)R_GetColumn(tex, col) - 3);
|
||||
while (column->topdelta != 0xff)
|
||||
{
|
||||
topdelta = column->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
|
||||
dest = desttop + (topdelta * texture->width);
|
||||
source = (UINT8 *)column + 3;
|
||||
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
|
||||
{
|
||||
if (source[ofs] != TRANSPARENTPIXEL)
|
||||
*dest = source[ofs];
|
||||
dest += texture->width;
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_PatchToFlat
|
||||
//
|
||||
// Convert a patch to a flat.
|
||||
//
|
||||
void R_PatchToFlat(patch_t *patch, UINT8 *flat)
|
||||
{
|
||||
fixed_t col, ofs;
|
||||
|
@ -2599,7 +2668,124 @@ void R_PatchToFlat(patch_t *patch, UINT8 *flat)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_FlatToPatch
|
||||
//
|
||||
// Convert a flat to a patch.
|
||||
//
|
||||
static unsigned char imgbuf[1<<26];
|
||||
patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency)
|
||||
{
|
||||
UINT32 x, y;
|
||||
UINT8 *img;
|
||||
UINT8 *imgptr = imgbuf;
|
||||
UINT8 *colpointers, *startofspan;
|
||||
size_t size = 0;
|
||||
|
||||
// Write image size and offset
|
||||
WRITEINT16(imgptr, width);
|
||||
WRITEINT16(imgptr, height);
|
||||
WRITEINT16(imgptr, leftoffset);
|
||||
WRITEINT16(imgptr, topoffset);
|
||||
|
||||
// Leave placeholder to column pointers
|
||||
colpointers = imgptr;
|
||||
imgptr += width*4;
|
||||
|
||||
// Write columns
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
int lastStartY = 0;
|
||||
int spanSize = 0;
|
||||
startofspan = NULL;
|
||||
|
||||
// Write column pointer
|
||||
WRITEINT32(colpointers, imgptr - imgbuf);
|
||||
|
||||
// Write pixels
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
UINT8 paletteIndex = raw[((y * width) + x)];
|
||||
boolean opaque = transparency ? (paletteIndex != TRANSPARENTPIXEL) : true;
|
||||
|
||||
// End span if we have a transparent pixel
|
||||
if (!opaque)
|
||||
{
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
startofspan = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start new column if we need to
|
||||
if (!startofspan || spanSize == 255)
|
||||
{
|
||||
int writeY = y;
|
||||
|
||||
// If we reached the span size limit, finish the previous span
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
|
||||
if (y > 254)
|
||||
{
|
||||
// Make sure we're aligned to 254
|
||||
if (lastStartY < 254)
|
||||
{
|
||||
WRITEUINT8(imgptr, 254);
|
||||
WRITEUINT8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
lastStartY = 254;
|
||||
}
|
||||
|
||||
// Write stopgap empty spans if needed
|
||||
writeY = y - lastStartY;
|
||||
|
||||
while (writeY > 254)
|
||||
{
|
||||
WRITEUINT8(imgptr, 254);
|
||||
WRITEUINT8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
writeY -= 254;
|
||||
}
|
||||
}
|
||||
|
||||
startofspan = imgptr;
|
||||
WRITEUINT8(imgptr, writeY);
|
||||
imgptr += 2;
|
||||
spanSize = 0;
|
||||
|
||||
lastStartY = y;
|
||||
}
|
||||
|
||||
// Write the pixel
|
||||
WRITEUINT8(imgptr, paletteIndex);
|
||||
spanSize++;
|
||||
startofspan[1] = spanSize;
|
||||
}
|
||||
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
|
||||
WRITEUINT8(imgptr, 0xFF);
|
||||
}
|
||||
|
||||
size = imgptr-imgbuf;
|
||||
img = Z_Malloc(size, PU_STATIC, NULL);
|
||||
memcpy(img, imgbuf, size);
|
||||
|
||||
Z_Free(raw);
|
||||
|
||||
if (destsize != NULL)
|
||||
*destsize = size;
|
||||
return (patch_t *)img;
|
||||
}
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
//
|
||||
// R_IsLumpPNG
|
||||
//
|
||||
// Returns true if the lump is a valid PNG.
|
||||
//
|
||||
boolean R_IsLumpPNG(const UINT8 *d, size_t s)
|
||||
{
|
||||
if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/
|
||||
|
@ -2812,125 +2998,31 @@ static UINT8 *PNG_RawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topo
|
|||
return flat;
|
||||
}
|
||||
|
||||
//
|
||||
// R_PNGToFlat
|
||||
//
|
||||
// Convert a PNG to a flat.
|
||||
UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t size)
|
||||
//
|
||||
UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size)
|
||||
{
|
||||
return PNG_RawConvert(png, &levelflat->width, &levelflat->height, NULL, NULL, size);
|
||||
return PNG_RawConvert(png, width, height, NULL, NULL, size);
|
||||
}
|
||||
|
||||
//
|
||||
// R_PNGToPatch
|
||||
//
|
||||
// Convert a PNG to a patch.
|
||||
static unsigned char imgbuf[1<<26];
|
||||
//
|
||||
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency)
|
||||
{
|
||||
UINT16 width, height;
|
||||
INT16 topoffset = 0, leftoffset = 0;
|
||||
UINT8 *raw = PNG_RawConvert(png, &width, &height, &topoffset, &leftoffset, size);
|
||||
|
||||
UINT32 x, y;
|
||||
UINT8 *img;
|
||||
UINT8 *imgptr = imgbuf;
|
||||
UINT8 *colpointers, *startofspan;
|
||||
|
||||
if (!raw)
|
||||
I_Error("R_PNGToPatch: conversion failed");
|
||||
|
||||
// Write image size and offset
|
||||
WRITEINT16(imgptr, width);
|
||||
WRITEINT16(imgptr, height);
|
||||
WRITEINT16(imgptr, leftoffset);
|
||||
WRITEINT16(imgptr, topoffset);
|
||||
|
||||
// Leave placeholder to column pointers
|
||||
colpointers = imgptr;
|
||||
imgptr += width*4;
|
||||
|
||||
// Write columns
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
int lastStartY = 0;
|
||||
int spanSize = 0;
|
||||
startofspan = NULL;
|
||||
|
||||
//printf("%d ", x);
|
||||
// Write column pointer (@TODO may be wrong)
|
||||
WRITEINT32(colpointers, imgptr - imgbuf);
|
||||
|
||||
// Write pixels
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
UINT8 paletteIndex = raw[((y * width) + x)];
|
||||
boolean opaque = transparency ? (paletteIndex != TRANSPARENTPIXEL) : true;
|
||||
|
||||
// End span if we have a transparent pixel
|
||||
if (!opaque)
|
||||
{
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
startofspan = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start new column if we need to
|
||||
if (!startofspan || spanSize == 255)
|
||||
{
|
||||
int writeY = y;
|
||||
|
||||
// If we reached the span size limit, finish the previous span
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
|
||||
if (y > 254)
|
||||
{
|
||||
// Make sure we're aligned to 254
|
||||
if (lastStartY < 254)
|
||||
{
|
||||
WRITEUINT8(imgptr, 254);
|
||||
WRITEUINT8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
lastStartY = 254;
|
||||
}
|
||||
|
||||
// Write stopgap empty spans if needed
|
||||
writeY = y - lastStartY;
|
||||
|
||||
while (writeY > 254)
|
||||
{
|
||||
WRITEUINT8(imgptr, 254);
|
||||
WRITEUINT8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
writeY -= 254;
|
||||
}
|
||||
}
|
||||
|
||||
startofspan = imgptr;
|
||||
WRITEUINT8(imgptr, writeY);///@TODO calculate starting y pos
|
||||
imgptr += 2;
|
||||
spanSize = 0;
|
||||
|
||||
lastStartY = y;
|
||||
}
|
||||
|
||||
// Write the pixel
|
||||
WRITEUINT8(imgptr, paletteIndex);
|
||||
spanSize++;
|
||||
startofspan[1] = spanSize;
|
||||
}
|
||||
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
|
||||
WRITEUINT8(imgptr, 0xFF);
|
||||
}
|
||||
|
||||
size = imgptr-imgbuf;
|
||||
img = Z_Malloc(size, PU_STATIC, NULL);
|
||||
memcpy(img, imgbuf, size);
|
||||
|
||||
Z_Free(raw);
|
||||
|
||||
if (destsize != NULL)
|
||||
*destsize = size;
|
||||
return (patch_t *)img;
|
||||
return R_FlatToPatch(raw, width, height, leftoffset, topoffset, destsize, transparency);
|
||||
}
|
||||
|
||||
boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size)
|
||||
|
@ -3001,53 +3093,3 @@ boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size)
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void R_TextureToFlat(size_t tex, UINT8 *flat)
|
||||
{
|
||||
texture_t *texture = textures[tex];
|
||||
|
||||
fixed_t col, ofs;
|
||||
column_t *column;
|
||||
UINT8 *desttop, *dest, *deststop;
|
||||
UINT8 *source;
|
||||
|
||||
desttop = flat;
|
||||
deststop = desttop + (texture->width * texture->height);
|
||||
|
||||
for (col = 0; col < texture->width; col++, desttop++)
|
||||
{
|
||||
column = (column_t *)R_GetColumn(tex, col);
|
||||
if (!texture->holes)
|
||||
{
|
||||
dest = desttop;
|
||||
source = (UINT8 *)(column);
|
||||
for (ofs = 0; dest < deststop && ofs < texture->height; ofs++)
|
||||
{
|
||||
if (source[ofs] != TRANSPARENTPIXEL)
|
||||
*dest = source[ofs];
|
||||
dest += texture->width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
while (column->topdelta != 0xff)
|
||||
{
|
||||
topdelta = column->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
|
||||
dest = desttop + (topdelta * texture->width);
|
||||
source = (UINT8 *)(column) + 3;
|
||||
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
|
||||
{
|
||||
if (source[ofs] != TRANSPARENTPIXEL)
|
||||
*dest = source[ofs];
|
||||
dest += texture->width;
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,15 +159,14 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap);
|
|||
#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
|
||||
|
||||
boolean R_CheckIfPatch(lumpnum_t lump);
|
||||
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||
|
||||
void R_PatchToFlat(patch_t *patch, UINT8 *flat);
|
||||
void R_TextureToFlat(size_t tex, UINT8 *flat);
|
||||
void R_PatchToFlat(patch_t *patch, UINT8 *flat);
|
||||
patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
boolean R_IsLumpPNG(const UINT8 *d, size_t s);
|
||||
|
||||
UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t size);
|
||||
UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size);
|
||||
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency);
|
||||
boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size);
|
||||
#endif
|
||||
|
|
13
src/r_defs.h
13
src/r_defs.h
|
@ -263,10 +263,15 @@ typedef struct pslope_s
|
|||
|
||||
typedef enum
|
||||
{
|
||||
SF_FLIPSPECIAL_FLOOR = 1,
|
||||
SF_FLIPSPECIAL_CEILING = 2,
|
||||
SF_FLIPSPECIAL_BOTH = 3,
|
||||
SF_TRIGGERSPECIAL_TOUCH = 4,
|
||||
// flipspecial - planes with effect
|
||||
SF_FLIPSPECIAL_FLOOR = 1,
|
||||
SF_FLIPSPECIAL_CEILING = 1<<1,
|
||||
SF_FLIPSPECIAL_BOTH = (SF_FLIPSPECIAL_FLOOR|SF_FLIPSPECIAL_CEILING),
|
||||
// triggerspecial - conditions under which plane touch causes effect
|
||||
SF_TRIGGERSPECIAL_TOUCH = 1<<2,
|
||||
SF_TRIGGERSPECIAL_HEADBUMP = 1<<3,
|
||||
// invertprecip - inverts presence of precipitation
|
||||
SF_INVERTPRECIP = 1<<4,
|
||||
} sectorflags_t;
|
||||
|
||||
//
|
||||
|
|
|
@ -1219,6 +1219,7 @@ void R_RegisterEngineStuff(void)
|
|||
#endif
|
||||
CV_RegisterVar(&cv_grmd2);
|
||||
CV_RegisterVar(&cv_grspritebillboarding);
|
||||
CV_RegisterVar(&cv_grskydome);
|
||||
#endif
|
||||
|
||||
#ifdef HWRENDER
|
||||
|
|
|
@ -650,6 +650,11 @@ static void R_DrawSkyPlane(visplane_t *pl)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_CheckPowersOfTwo
|
||||
//
|
||||
// Self-explanatory?
|
||||
//
|
||||
boolean R_CheckPowersOfTwo(void)
|
||||
{
|
||||
boolean wpow2 = (!(ds_flatwidth & (ds_flatwidth - 1)));
|
||||
|
@ -667,6 +672,11 @@ boolean R_CheckPowersOfTwo(void)
|
|||
return ds_powersoftwo;
|
||||
}
|
||||
|
||||
//
|
||||
// R_CheckFlatLength
|
||||
//
|
||||
// Determine the flat's dimensions from the lump length.
|
||||
//
|
||||
void R_CheckFlatLength(size_t size)
|
||||
{
|
||||
switch (size)
|
||||
|
@ -723,7 +733,24 @@ void R_CheckFlatLength(size_t size)
|
|||
}
|
||||
}
|
||||
|
||||
static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng)
|
||||
//
|
||||
// R_GenerateFlat
|
||||
//
|
||||
// Generate a flat from specified width and height.
|
||||
//
|
||||
static UINT8 *R_GenerateFlat(UINT16 width, UINT16 height)
|
||||
{
|
||||
UINT8 *flat = Z_Malloc(width * height, PU_LEVEL, NULL);
|
||||
memset(flat, TRANSPARENTPIXEL, width * height);
|
||||
return flat;
|
||||
}
|
||||
|
||||
//
|
||||
// R_GetTextureFlat
|
||||
//
|
||||
// Convert a texture or patch to a flat.
|
||||
//
|
||||
static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng)
|
||||
{
|
||||
UINT8 *flat;
|
||||
textureflat_t *texflat = &texflats[levelflat->texturenum];
|
||||
|
@ -747,14 +774,14 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
|
|||
// If the texture changed, or the patch doesn't exist, convert either of them to a flat.
|
||||
if (levelflat->flatpatch == NULL || texturechanged)
|
||||
{
|
||||
// Level texture
|
||||
if (leveltexture)
|
||||
{
|
||||
texture_t *texture = textures[levelflat->texturenum];
|
||||
texflat->width = ds_flatwidth = texture->width;
|
||||
texflat->height = ds_flatheight = texture->height;
|
||||
|
||||
texflat->flat = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL);
|
||||
memset(texflat->flat, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight);
|
||||
texflat->flat = R_GenerateFlat(ds_flatwidth, ds_flatheight);
|
||||
R_TextureToFlat(levelflat->texturenum, texflat->flat);
|
||||
flat = texflat->flat;
|
||||
|
||||
|
@ -762,13 +789,14 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
|
|||
levelflat->width = ds_flatwidth;
|
||||
levelflat->height = ds_flatheight;
|
||||
}
|
||||
// Patch (never happens yet)
|
||||
else
|
||||
{
|
||||
patch = (patch_t *)ds_source;
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (ispng)
|
||||
{
|
||||
levelflat->flatpatch = R_PNGToFlat(levelflat, ds_source, W_LumpLength(levelflat->lumpnum));
|
||||
levelflat->flatpatch = R_PNGToFlat(&levelflat->width, &levelflat->height, ds_source, W_LumpLength(levelflat->lumpnum));
|
||||
levelflat->topoffset = levelflat->leftoffset = 0;
|
||||
ds_flatwidth = levelflat->width;
|
||||
ds_flatheight = levelflat->height;
|
||||
|
@ -782,8 +810,7 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
|
|||
levelflat->topoffset = patch->topoffset * FRACUNIT;
|
||||
levelflat->leftoffset = patch->leftoffset * FRACUNIT;
|
||||
|
||||
levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL);
|
||||
memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight);
|
||||
levelflat->flatpatch = R_GenerateFlat(ds_flatwidth, ds_flatheight);
|
||||
R_PatchToFlat(patch, levelflat->flatpatch);
|
||||
}
|
||||
flat = levelflat->flatpatch;
|
||||
|
@ -794,11 +821,11 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
|
|||
flat = levelflat->flatpatch;
|
||||
ds_flatwidth = levelflat->width;
|
||||
ds_flatheight = levelflat->height;
|
||||
|
||||
xoffs += levelflat->leftoffset;
|
||||
yoffs += levelflat->topoffset;
|
||||
}
|
||||
|
||||
xoffs += levelflat->leftoffset;
|
||||
yoffs += levelflat->topoffset;
|
||||
|
||||
levelflat->lasttexturenum = levelflat->texturenum;
|
||||
return flat;
|
||||
}
|
||||
|
@ -963,15 +990,15 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
|
||||
// Check if the flat is actually a wall texture.
|
||||
if (levelflat->texturenum != 0 && levelflat->texturenum != -1)
|
||||
flat = R_GetPatchFlat(levelflat, true, false);
|
||||
flat = R_GetTextureFlat(levelflat, true, false);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
// Maybe it's a PNG?!
|
||||
else if (R_IsLumpPNG(ds_source, size))
|
||||
flat = R_GetPatchFlat(levelflat, false, true);
|
||||
flat = R_GetTextureFlat(levelflat, false, true);
|
||||
#endif
|
||||
// Maybe it's just a patch, then?
|
||||
else if (R_CheckIfPatch(levelflat->lumpnum))
|
||||
flat = R_GetPatchFlat(levelflat, false, false);
|
||||
flat = R_GetTextureFlat(levelflat, false, false);
|
||||
// It's a raw flat.
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1230,7 +1230,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
range = 1;
|
||||
|
||||
scalestep = (yscale2 - yscale)/range;
|
||||
scalestep = (yscale2 - yscale)/range ?: 1;
|
||||
|
||||
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
|
||||
// sortscale = max(yscale, yscale2);
|
||||
|
@ -1637,7 +1637,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
mobj_t *thing;
|
||||
precipmobj_t *precipthing; // Tails 08-25-2002
|
||||
INT32 lightnum;
|
||||
fixed_t approx_dist, limit_dist;
|
||||
fixed_t approx_dist, limit_dist, hoop_limit_dist;
|
||||
|
||||
if (rendermode != render_soft)
|
||||
return;
|
||||
|
@ -1668,7 +1668,9 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
|
||||
// Handle all things in sector.
|
||||
// If a limit exists, handle things a tiny bit different.
|
||||
if ((limit_dist = (fixed_t)((maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : cv_drawdist.value) << FRACBITS))
|
||||
limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
|
||||
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
||||
if (limit_dist || hoop_limit_dist)
|
||||
{
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
|
@ -1677,8 +1679,16 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
||||
if (approx_dist > limit_dist)
|
||||
continue;
|
||||
if (thing->sprite == SPR_HOOP)
|
||||
{
|
||||
if (hoop_limit_dist && approx_dist > hoop_limit_dist)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (limit_dist && approx_dist > limit_dist)
|
||||
continue;
|
||||
}
|
||||
|
||||
R_ProjectSprite(thing);
|
||||
}
|
||||
|
@ -2786,9 +2796,9 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
|||
}
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Requested skin not found\n"));
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum);
|
||||
else if(server || IsPlayerAdmin(consoleplayer))
|
||||
CONS_Alert(CONS_WARNING, "Player %d (%s) skin not found\n", playernum, player_names[playernum]);
|
||||
CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum);
|
||||
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ void *hwSym(const char *funcName,void *handle)
|
|||
GETFUNC(Init);
|
||||
GETFUNC(Draw2DLine);
|
||||
GETFUNC(DrawPolygon);
|
||||
GETFUNC(RenderSkyDome);
|
||||
GETFUNC(SetBlend);
|
||||
GETFUNC(ClearBuffer);
|
||||
GETFUNC(SetTexture);
|
||||
|
|
|
@ -1629,6 +1629,7 @@ void I_StartupGraphics(void)
|
|||
HWD.pfnFinishUpdate = NULL;
|
||||
HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL);
|
||||
HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL);
|
||||
HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",NULL);
|
||||
HWD.pfnSetBlend = hwSym("SetBlend",NULL);
|
||||
HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL);
|
||||
HWD.pfnSetTexture = hwSym("SetTexture",NULL);
|
||||
|
|
|
@ -878,7 +878,11 @@ boolean I_SetSongSpeed(float speed)
|
|||
#ifdef HAVE_OPENMPT
|
||||
if (openmpt_mhandle)
|
||||
{
|
||||
char modspd[16];
|
||||
char modspd[13];
|
||||
|
||||
if (speed > 4.0f)
|
||||
speed = 4.0f; // Limit this to 4x to prevent crashing, stupid fix but... ~SteelT 27/9/19
|
||||
|
||||
sprintf(modspd, "%g", speed);
|
||||
openmpt_module_ctl_set(openmpt_mhandle, "play.tempo_factor", modspd);
|
||||
return true;
|
||||
|
|
|
@ -1474,12 +1474,9 @@ static void ST_drawNightsRecords(void)
|
|||
|
||||
if (P_HasGrades(gamemap, stplyr->lastmare + 1))
|
||||
{
|
||||
if (aflag)
|
||||
V_DrawTranslucentPatch(BASEVIDWIDTH/2 + 60, 160, aflag,
|
||||
ngradeletters[P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare)]);
|
||||
else
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2 + 60, 160, 0,
|
||||
ngradeletters[P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare)]);
|
||||
UINT8 grade = P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare);
|
||||
if (modeattacking || grade >= GRADE_A)
|
||||
V_DrawTranslucentPatch(BASEVIDWIDTH/2 + 60, 160, aflag, ngradeletters[grade]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1857,7 +1854,8 @@ static void ST_drawNiGHTSHUD(void)
|
|||
numbersize = 48/2;
|
||||
|
||||
if ((oldspecialstage && leveltime & 2)
|
||||
&& (stplyr->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)))
|
||||
&& (stplyr->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER))
|
||||
&& !(stplyr->powers[pw_shield] & SH_PROTECTWATER))
|
||||
col = SKINCOLOR_ORANGE;
|
||||
|
||||
ST_DrawNightsOverlayNum((160 + numbersize)<<FRACBITS, 14<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP, realnightstime, nightsnum, col);
|
||||
|
|
|
@ -112,6 +112,7 @@ static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NUL
|
|||
// console variables in development
|
||||
consvar_t cv_grmd2 = {"gr_md2", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif
|
||||
|
||||
// local copy of the palette for V_GetColor()
|
||||
|
|
|
@ -102,6 +102,7 @@ static loadfunc_t hwdFuncTable[] = {
|
|||
{"FinishUpdate@4", &hwdriver.pfnFinishUpdate},
|
||||
{"Draw2DLine@12", &hwdriver.pfnDraw2DLine},
|
||||
{"DrawPolygon@16", &hwdriver.pfnDrawPolygon},
|
||||
{"RenderSkyDome@16", &hwdriver.pfnRenderSkyDome},
|
||||
{"SetBlend@4", &hwdriver.pfnSetBlend},
|
||||
{"ClearBuffer@12", &hwdriver.pfnClearBuffer},
|
||||
{"SetTexture@4", &hwdriver.pfnSetTexture},
|
||||
|
@ -133,6 +134,7 @@ static loadfunc_t hwdFuncTable[] = {
|
|||
{"FinishUpdate", &hwdriver.pfnFinishUpdate},
|
||||
{"Draw2DLine", &hwdriver.pfnDraw2DLine},
|
||||
{"DrawPolygon", &hwdriver.pfnDrawPolygon},
|
||||
{"RenderSkyDome", &hwdriver.pfnRenderSkyDome},
|
||||
{"SetBlend", &hwdriver.pfnSetBlend},
|
||||
{"ClearBuffer", &hwdriver.pfnClearBuffer},
|
||||
{"SetTexture", &hwdriver.pfnSetTexture},
|
||||
|
|
Loading…
Reference in a new issue