Merge branch 'next' into gl-slopes

This commit is contained in:
Monster Iestyn 2016-05-02 22:51:51 +01:00
commit f0bea2cebf
39 changed files with 1073 additions and 510 deletions

View file

@ -15,6 +15,7 @@
#include "am_map.h" #include "am_map.h"
#include "g_input.h" #include "g_input.h"
#include "p_local.h" #include "p_local.h"
#include "p_slopes.h"
#include "v_video.h" #include "v_video.h"
#include "i_video.h" #include "i_video.h"
#include "r_state.h" #include "r_state.h"
@ -996,6 +997,10 @@ static inline void AM_drawWalls(void)
{ {
size_t i; size_t i;
static mline_t l; static mline_t l;
#ifdef ESLOPE
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
#endif
for (i = 0; i < numlines; i++) for (i = 0; i < numlines; i++)
{ {
@ -1003,6 +1008,22 @@ static inline void AM_drawWalls(void)
l.a.y = lines[i].v1->y; l.a.y = lines[i].v1->y;
l.b.x = lines[i].v2->x; l.b.x = lines[i].v2->x;
l.b.y = lines[i].v2->y; l.b.y = lines[i].v2->y;
#ifdef ESLOPE
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \
end1 = P_GetZAt(slope, l.a.x, l.a.y); \
end2 = P_GetZAt(slope, l.b.x, l.b.y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight)
SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight)
if (lines[i].backsector) {
SLOPEPARAMS(lines[i].backsector->f_slope, backf1, backf2, lines[i].backsector->floorheight)
SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight)
}
#undef SLOPEPARAMS
#endif
// AM_drawMline(&l, GRAYS + 3); // Old, everything-is-gray automap // AM_drawMline(&l, GRAYS + 3); // Old, everything-is-gray automap
if (!lines[i].backsector) // 1-sided if (!lines[i].backsector) // 1-sided
@ -1016,11 +1037,19 @@ static inline void AM_drawWalls(void)
AM_drawMline(&l, WALLCOLORS+lightlev); AM_drawMline(&l, WALLCOLORS+lightlev);
} }
} }
#ifdef ESLOPE
else if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier
|| (frontf1 == frontc1 && frontf2 == frontc2)) // Front is thok barrier
{
if (backf1 == backc1 && backf2 == backc2
&& frontf1 == frontc1 && frontf2 == frontc2) // BOTH are thok barriers
#else
else if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight // Back is thok barrier else if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight // Back is thok barrier
|| lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // Front is thok barrier || lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // Front is thok barrier
{ {
if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight if (lines[i].backsector->floorheight == lines[i].backsector->ceilingheight
&& lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // BOTH are thok barriers && lines[i].frontsector->floorheight == lines[i].frontsector->ceilingheight) // BOTH are thok barriers
#endif
{ {
if (lines[i].flags & ML_NOCLIMB) if (lines[i].flags & ML_NOCLIMB)
{ {
@ -1046,12 +1075,20 @@ static inline void AM_drawWalls(void)
else else
{ {
if (lines[i].flags & ML_NOCLIMB) { if (lines[i].flags & ML_NOCLIMB) {
#ifdef ESLOPE
if (backf1 != frontf1 || backf2 != frontf2) {
#else
if (lines[i].backsector->floorheight if (lines[i].backsector->floorheight
!= lines[i].frontsector->floorheight) { != lines[i].frontsector->floorheight) {
#endif
AM_drawMline(&l, NOCLIMBFDWALLCOLORS + lightlev); // floor level change AM_drawMline(&l, NOCLIMBFDWALLCOLORS + lightlev); // floor level change
} }
#ifdef ESLOPE
else if (backc1 != frontc1 || backc2 != frontc2) {
#else
else if (lines[i].backsector->ceilingheight else if (lines[i].backsector->ceilingheight
!= lines[i].frontsector->ceilingheight) { != lines[i].frontsector->ceilingheight) {
#endif
AM_drawMline(&l, NOCLIMBCDWALLCOLORS+lightlev); // ceiling level change AM_drawMline(&l, NOCLIMBCDWALLCOLORS+lightlev); // ceiling level change
} }
else { else {
@ -1060,12 +1097,20 @@ static inline void AM_drawWalls(void)
} }
else else
{ {
#ifdef ESLOPE
if (backf1 != frontf1 || backf2 != frontf2) {
#else
if (lines[i].backsector->floorheight if (lines[i].backsector->floorheight
!= lines[i].frontsector->floorheight) { != lines[i].frontsector->floorheight) {
#endif
AM_drawMline(&l, FDWALLCOLORS + lightlev); // floor level change AM_drawMline(&l, FDWALLCOLORS + lightlev); // floor level change
} }
#ifdef ESLOPE
else if (backc1 != frontc1 || backc2 != frontc2) {
#else
else if (lines[i].backsector->ceilingheight else if (lines[i].backsector->ceilingheight
!= lines[i].frontsector->ceilingheight) { != lines[i].frontsector->ceilingheight) {
#endif
AM_drawMline(&l, CDWALLCOLORS+lightlev); // ceiling level change AM_drawMline(&l, CDWALLCOLORS+lightlev); // ceiling level change
} }
else { else {

View file

@ -597,7 +597,9 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_gif_optimize); CV_RegisterVar(&cv_gif_optimize);
CV_RegisterVar(&cv_gif_downscale); CV_RegisterVar(&cv_gif_downscale);
#ifdef WALLSPLATS
CV_RegisterVar(&cv_splats); CV_RegisterVar(&cv_splats);
#endif
// register these so it is saved to config // register these so it is saved to config
if ((username = I_GetUserName())) if ((username = I_GetUserName()))
@ -808,7 +810,7 @@ static boolean IsNameGood(char *name, INT32 playernum)
else if (len == 1) // Agh! else if (len == 1) // Agh!
{ {
// Last ditch effort... // Last ditch effort...
sprintf(name, "%d", M_Random() & 7); sprintf(name, "%d", M_RandomKey(10));
if (!IsNameGood (name, playernum)) if (!IsNameGood (name, playernum))
return false; return false;
} }
@ -3583,7 +3585,7 @@ retryscramble:
for (i = 0; i < playercount; i++) for (i = 0; i < playercount; i++)
{ {
if (repick) if (repick)
newteam = (INT16)((M_Random() % 2) + 1); newteam = (INT16)((M_RandomByte() % 2) + 1);
// One team has the most players they can get, assign the rest to the other team. // One team has the most players they can get, assign the rest to the other team.
if (red == maxcomposition || blue == maxcomposition) if (red == maxcomposition || blue == maxcomposition)
@ -3628,7 +3630,7 @@ retryscramble:
{ {
if (repick) if (repick)
{ {
newteam = (INT16)((M_Random() % 2) + 1); newteam = (INT16)((M_RandomByte() % 2) + 1);
repick = false; repick = false;
} }
else else

View file

@ -81,7 +81,9 @@ extern consvar_t cv_useranalog, cv_useranalog2;
extern consvar_t cv_analog, cv_analog2; extern consvar_t cv_analog, cv_analog2;
extern consvar_t cv_netstat; extern consvar_t cv_netstat;
#ifdef WALLSPLATS
extern consvar_t cv_splats; extern consvar_t cv_splats;
#endif
extern consvar_t cv_countdowntime; extern consvar_t cv_countdowntime;
extern consvar_t cv_runscripts; extern consvar_t cv_runscripts;

View file

@ -2349,7 +2349,7 @@ mapthing_t *G_FindCTFStart(INT32 playernum)
return NULL; return NULL;
} }
if ((!players[playernum].ctfteam && numredctfstarts && (!numbluectfstarts || P_Random() & 1)) || players[playernum].ctfteam == 1) //red if ((!players[playernum].ctfteam && numredctfstarts && (!numbluectfstarts || P_RandomChance(FRACUNIT/2))) || players[playernum].ctfteam == 1) //red
{ {
if (!numredctfstarts) if (!numredctfstarts)
{ {
@ -5487,7 +5487,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void)
UINT8 i; UINT8 i;
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
for (i = 0; i < 16; i++, p++) for (i = 0; i < 16; i++, p++)
*p = P_Random(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
#else #else
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file.
@ -5569,7 +5569,7 @@ boolean G_CheckDemoStatus(void)
UINT8 i; UINT8 i;
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
for (i = 0; i < 16; i++, p++) for (i = 0; i < 16; i++, p++)
*p = P_Random(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
#else #else
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file.

View file

@ -384,12 +384,12 @@ INT32 HW3S_I_StartSound(const void *origin_p, source3D_data_t *source_parm, chan
/*if (gamemode != heretic) /*if (gamemode != heretic)
{ {
if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit) if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit)
pitch += 8 - (M_Random()&15); pitch += 8 - (M_RandomByte()&15);
else if (sfx_id != sfx_itemup && sfx_id != sfx_tink) else if (sfx_id != sfx_itemup && sfx_id != sfx_tink)
pitch += 16 - (M_Random()&31); pitch += 16 - (M_RandomByte()&31);
} }
else*/ else*/
pitch = 128 + (M_Random() & 7) - (M_Random() & 7); pitch = 128 + (M_RandomByte() & 7) - (M_RandomByte() & 7);
} }
#endif #endif

View file

@ -871,7 +871,7 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr)
size = p_lspr->corona_radius * ((outVerts[0].z+120.0f)/950.0f); // d'ou vienne ces constante ? size = p_lspr->corona_radius * ((outVerts[0].z+120.0f)/950.0f); // d'ou vienne ces constante ?
break; break;
case ROCKET_SPR: case ROCKET_SPR:
p_lspr->corona_color = (((M_Random()>>1)&0xff)<<24)|0x0040ff; p_lspr->corona_color = (((M_RandomByte()>>1)&0xff)<<24)|0x0040ff;
// don't need a break // don't need a break
case CORONA_SPR: case CORONA_SPR:
size = p_lspr->corona_radius * ((outVerts[0].z+60.0f)/100.0f); // d'ou vienne ces constante ? size = p_lspr->corona_radius * ((outVerts[0].z+60.0f)/100.0f); // d'ou vienne ces constante ?
@ -974,7 +974,7 @@ void HWR_DrawCoronas(void)
size = p_lspr->corona_radius * ((cz+120.0f)/950.0f); // d'ou vienne ces constante ? size = p_lspr->corona_radius * ((cz+120.0f)/950.0f); // d'ou vienne ces constante ?
break; break;
case ROCKET_SPR: case ROCKET_SPR:
Surf.FlatColor.s.alpha = (UINT8)((M_Random()>>1)&0xff); Surf.FlatColor.s.alpha = (UINT8)((M_RandomByte()>>1)&0xff);
// don't need a break // don't need a break
case CORONA_SPR: case CORONA_SPR:
size = p_lspr->corona_radius * ((cz+60.0f)/100.0f); // d'ou vienne ces constante ? size = p_lspr->corona_radius * ((cz+60.0f)/100.0f); // d'ou vienne ces constante ?

View file

@ -74,10 +74,12 @@ FUNCMATH UINT8 LightLevelToLum(INT32 l);
extern CV_PossibleValue_t granisotropicmode_cons_t[]; extern CV_PossibleValue_t granisotropicmode_cons_t[];
#ifdef ALAM_LIGHTING
extern consvar_t cv_grdynamiclighting; extern consvar_t cv_grdynamiclighting;
extern consvar_t cv_grstaticlighting; extern consvar_t cv_grstaticlighting;
extern consvar_t cv_grcoronas; extern consvar_t cv_grcoronas;
extern consvar_t cv_grcoronasize; extern consvar_t cv_grcoronasize;
#endif
extern consvar_t cv_grfov; extern consvar_t cv_grfov;
extern consvar_t cv_grmd2; extern consvar_t cv_grmd2;
extern consvar_t cv_grfog; extern consvar_t cv_grfog;

View file

@ -1470,6 +1470,26 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
else else
pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
} }
else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8)
{
//pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
if (MipMap)
{
pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
#ifdef GL_TEXTURE_MIN_LOD
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
#endif
#ifdef GL_TEXTURE_MAX_LOD
if (pTexInfo->flags & TF_TRANSPARENT)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
#endif
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
}
else
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
else else
{ {
if (MipMap) if (MipMap)
@ -2150,7 +2170,7 @@ EXPORT void HWRAPI(StartScreenWipe) (void)
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, texsize, texsize, 0); pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
@ -2179,7 +2199,7 @@ EXPORT void HWRAPI(EndScreenWipe)(void)
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, texsize, texsize, 0); pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
@ -2294,22 +2314,22 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
// Bottom left // Bottom left
pglMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f); pglMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f);
pglMultiTexCoord2f(GL_TEXTURE1, 0.0f, 0.0f); pglMultiTexCoord2f(GL_TEXTURE1, 0.0f, 1.0f);
pglVertex3f(-1.0f, -1.0f, 1.0f); pglVertex3f(-1.0f, -1.0f, 1.0f);
// Top left // Top left
pglMultiTexCoord2f(GL_TEXTURE0, 0.0f, yfix); pglMultiTexCoord2f(GL_TEXTURE0, 0.0f, yfix);
pglMultiTexCoord2f(GL_TEXTURE1, 0.0f, 1.0f); pglMultiTexCoord2f(GL_TEXTURE1, 0.0f, 0.0f);
pglVertex3f(-1.0f, 1.0f, 1.0f); pglVertex3f(-1.0f, 1.0f, 1.0f);
// Top right // Top right
pglMultiTexCoord2f(GL_TEXTURE0, xfix, yfix); pglMultiTexCoord2f(GL_TEXTURE0, xfix, yfix);
pglMultiTexCoord2f(GL_TEXTURE1, 1.0f, 1.0f); pglMultiTexCoord2f(GL_TEXTURE1, 1.0f, 0.0f);
pglVertex3f(1.0f, 1.0f, 1.0f); pglVertex3f(1.0f, 1.0f, 1.0f);
// Bottom right // Bottom right
pglMultiTexCoord2f(GL_TEXTURE0, xfix, 0.0f); pglMultiTexCoord2f(GL_TEXTURE0, xfix, 0.0f);
pglMultiTexCoord2f(GL_TEXTURE1, 1.0f, 0.0f); pglMultiTexCoord2f(GL_TEXTURE1, 1.0f, 1.0f);
pglVertex3f(1.0f, -1.0f, 1.0f); pglVertex3f(1.0f, -1.0f, 1.0f);
pglEnd(); pglEnd();

View file

@ -96,17 +96,17 @@ static int lib_evalMath(lua_State *L)
// M_RANDOM // M_RANDOM
////////////// //////////////
static int lib_pRandom(lua_State *L) static int lib_pRandomFixed(lua_State *L)
{ {
NOHUD NOHUD
lua_pushinteger(L, P_Random()); lua_pushfixed(L, P_RandomFixed());
return 1; return 1;
} }
static int lib_pSignedRandom(lua_State *L) static int lib_pRandomByte(lua_State *L)
{ {
NOHUD NOHUD
lua_pushinteger(L, P_SignedRandom()); lua_pushinteger(L, P_RandomByte());
return 1; return 1;
} }
@ -134,6 +134,30 @@ static int lib_pRandomRange(lua_State *L)
return 1; return 1;
} }
// Deprecated, macros, etc.
static int lib_pRandom(lua_State *L)
{
NOHUD
LUA_Deprecated(L, "P_Random", "P_RandomByte");
lua_pushinteger(L, P_RandomByte());
return 1;
}
static int lib_pSignedRandom(lua_State *L)
{
NOHUD
lua_pushinteger(L, P_SignedRandom());
return 1;
}
static int lib_pRandomChance(lua_State *L)
{
fixed_t p = luaL_checkfixed(L, 1);
NOHUD
lua_pushboolean(L, P_RandomChance(p));
return 1;
}
// P_MAPUTIL // P_MAPUTIL
/////////////// ///////////////
@ -271,8 +295,8 @@ static int lib_pSpawnMobj(lua_State *L)
fixed_t z = luaL_checkfixed(L, 3); fixed_t z = luaL_checkfixed(L, 3);
mobjtype_t type = luaL_checkinteger(L, 4); mobjtype_t type = luaL_checkinteger(L, 4);
NOHUD NOHUD
if (type > MT_LASTFREESLOT) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ); LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ);
return 1; return 1;
} }
@ -297,8 +321,8 @@ static int lib_pSpawnMissile(lua_State *L)
NOHUD NOHUD
if (!source || !dest) if (!source || !dest)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type > MT_LASTFREESLOT) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnMissile(source, dest, type), META_MOBJ); LUA_PushUserdata(L, P_SpawnMissile(source, dest, type), META_MOBJ);
return 1; return 1;
} }
@ -314,8 +338,8 @@ static int lib_pSpawnXYZMissile(lua_State *L)
NOHUD NOHUD
if (!source || !dest) if (!source || !dest)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type > MT_LASTFREESLOT) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnXYZMissile(source, dest, type, x, y, z), META_MOBJ); LUA_PushUserdata(L, P_SpawnXYZMissile(source, dest, type, x, y, z), META_MOBJ);
return 1; return 1;
} }
@ -333,8 +357,8 @@ static int lib_pSpawnPointMissile(lua_State *L)
NOHUD NOHUD
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type > MT_LASTFREESLOT) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnPointMissile(source, xa, ya, za, type, x, y, z), META_MOBJ); LUA_PushUserdata(L, P_SpawnPointMissile(source, xa, ya, za, type, x, y, z), META_MOBJ);
return 1; return 1;
} }
@ -350,8 +374,8 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L)
NOHUD NOHUD
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type > MT_LASTFREESLOT) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnAlteredDirectionMissile(source, type, x, y, z, shiftingAngle), META_MOBJ); LUA_PushUserdata(L, P_SpawnAlteredDirectionMissile(source, type, x, y, z, shiftingAngle), META_MOBJ);
return 1; return 1;
} }
@ -379,8 +403,8 @@ static int lib_pSPMAngle(lua_State *L)
NOHUD NOHUD
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type > MT_LASTFREESLOT) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SPMAngle(source, type, angle, allowaim, flags2), META_MOBJ); LUA_PushUserdata(L, P_SPMAngle(source, type, angle, allowaim, flags2), META_MOBJ);
return 1; return 1;
} }
@ -393,8 +417,8 @@ static int lib_pSpawnPlayerMissile(lua_State *L)
NOHUD NOHUD
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type > MT_LASTFREESLOT) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnPlayerMissile(source, type, flags2), META_MOBJ); LUA_PushUserdata(L, P_SpawnPlayerMissile(source, type, flags2), META_MOBJ);
return 1; return 1;
} }
@ -413,8 +437,8 @@ static int lib_pWeaponOrPanel(lua_State *L)
{ {
mobjtype_t type = luaL_checkinteger(L, 1); mobjtype_t type = luaL_checkinteger(L, 1);
//HUDSAFE //HUDSAFE
if (type > MT_LASTFREESLOT) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
lua_pushboolean(L, P_WeaponOrPanel(type)); lua_pushboolean(L, P_WeaponOrPanel(type));
return 1; return 1;
} }
@ -453,8 +477,10 @@ static int lib_pSpawnParaloop(lua_State *L)
statenum_t nstate = luaL_optinteger(L, 8, S_NULL); statenum_t nstate = luaL_optinteger(L, 8, S_NULL);
boolean spawncenter = lua_optboolean(L, 9); boolean spawncenter = lua_optboolean(L, 9);
NOHUD NOHUD
if (type > MT_LASTFREESLOT) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
if (nstate >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", nstate, NUMSTATES-1);
P_SpawnParaloop(x, y, z, radius, number, type, nstate, rotangle, spawncenter); P_SpawnParaloop(x, y, z, radius, number, type, nstate, rotangle, spawncenter);
return 0; return 0;
} }
@ -884,8 +910,8 @@ static int lib_pSpawnSpinMobj(lua_State *L)
NOHUD NOHUD
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
if (type > MT_LASTFREESLOT) if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
P_SpawnSpinMobj(player, type); P_SpawnSpinMobj(player, type);
return 0; return 0;
} }
@ -1250,6 +1276,8 @@ static int lib_pSetMobjStateNF(lua_State *L)
NOHUD NOHUD
if (!mobj) if (!mobj)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (state >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", state, NUMSTATES-1);
if (mobj->player && state == S_NULL) if (mobj->player && state == S_NULL)
return luaL_error(L, "Attempt to remove player mobj with S_NULL."); return luaL_error(L, "Attempt to remove player mobj with S_NULL.");
lua_pushboolean(L, P_SetMobjStateNF(mobj, state)); lua_pushboolean(L, P_SetMobjStateNF(mobj, state));
@ -1361,8 +1389,8 @@ static int lib_pIsFlagAtBase(lua_State *L)
{ {
mobjtype_t flag = luaL_checkinteger(L, 1); mobjtype_t flag = luaL_checkinteger(L, 1);
NOHUD NOHUD
if (flag > MT_LASTFREESLOT) if (flag >= NUMMOBJTYPES)
return luaL_error(L, "mobjtype_t out of bounds error!"); return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1);
lua_pushboolean(L, P_IsFlagAtBase(flag)); lua_pushboolean(L, P_IsFlagAtBase(flag));
return 1; return 1;
} }
@ -1595,7 +1623,7 @@ static int lib_rSetPlayerSkin(lua_State *L)
{ {
INT32 i = luaL_checkinteger(L, 2); INT32 i = luaL_checkinteger(L, 2);
if (i < 0 || i >= MAXSKINS) if (i < 0 || i >= MAXSKINS)
return luaL_error(L, "argument #2 cannot exceed MAXSKINS"); return luaL_error(L, "skin number (argument #2) %d out of range (0 - %d)", i, MAXSKINS-1);
SetPlayerSkinByNum(player-players, i); SetPlayerSkinByNum(player-players, i);
} }
else // skin name else // skin name
@ -1615,6 +1643,8 @@ static int lib_sStartSound(lua_State *L)
sfxenum_t sound_id = luaL_checkinteger(L, 2); sfxenum_t sound_id = luaL_checkinteger(L, 2);
player_t *player = NULL; player_t *player = NULL;
NOHUD NOHUD
if (sound_id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1);
if (!lua_isnil(L, 1)) if (!lua_isnil(L, 1))
{ {
origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -1639,12 +1669,15 @@ static int lib_sStartSoundAtVolume(lua_State *L)
INT32 volume = (INT32)luaL_checkinteger(L, 3); INT32 volume = (INT32)luaL_checkinteger(L, 3);
player_t *player = NULL; player_t *player = NULL;
NOHUD NOHUD
if (!lua_isnil(L, 1)) if (!lua_isnil(L, 1))
{ {
origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
if (!origin) if (!origin)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
} }
if (sound_id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1);
if (!lua_isnone(L, 4) && lua_isuserdata(L, 4)) if (!lua_isnone(L, 4) && lua_isuserdata(L, 4))
{ {
player = *((player_t **)luaL_checkudata(L, 4, META_PLAYER)); player = *((player_t **)luaL_checkudata(L, 4, META_PLAYER));
@ -1776,6 +1809,8 @@ static int lib_sIdPlaying(lua_State *L)
{ {
sfxenum_t id = luaL_checkinteger(L, 1); sfxenum_t id = luaL_checkinteger(L, 1);
NOHUD NOHUD
if (id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", id, NUMSFX-1);
lua_pushboolean(L, S_IdPlaying(id)); lua_pushboolean(L, S_IdPlaying(id));
return 1; return 1;
} }
@ -1787,6 +1822,8 @@ static int lib_sSoundPlaying(lua_State *L)
NOHUD NOHUD
if (!origin) if (!origin)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", id, NUMSFX-1);
lua_pushboolean(L, S_SoundPlaying(origin, id)); lua_pushboolean(L, S_SoundPlaying(origin, id));
return 1; return 1;
} }
@ -1807,7 +1844,7 @@ static int lib_gDoReborn(lua_State *L)
INT32 playernum = luaL_checkinteger(L, 1); INT32 playernum = luaL_checkinteger(L, 1);
NOHUD NOHUD
if (playernum >= MAXPLAYERS) if (playernum >= MAXPLAYERS)
return luaL_error(L, "playernum out of bounds error!"); return luaL_error(L, "playernum %d out of range (0 - %d)", playernum, MAXPLAYERS-1);
G_DoReborn(playernum); G_DoReborn(playernum);
return 0; return 0;
} }
@ -1934,10 +1971,13 @@ static luaL_Reg lib[] = {
{"EvalMath", lib_evalMath}, {"EvalMath", lib_evalMath},
// m_random // m_random
{"P_Random",lib_pRandom}, {"P_RandomFixed",lib_pRandomFixed},
{"P_SignedRandom",lib_pSignedRandom}, {"P_RandomByte",lib_pRandomByte},
{"P_RandomKey",lib_pRandomKey}, {"P_RandomKey",lib_pRandomKey},
{"P_RandomRange",lib_pRandomRange}, {"P_RandomRange",lib_pRandomRange},
{"P_Random",lib_pRandom}, // DEPRECATED
{"P_SignedRandom",lib_pSignedRandom}, // MACRO
{"P_RandomChance",lib_pRandomChance}, // MACRO
// p_maputil // p_maputil
{"P_AproxDistance",lib_pAproxDistance}, {"P_AproxDistance",lib_pAproxDistance},

View file

@ -166,6 +166,8 @@ static int lib_getHudInfo(lua_State *L)
lua_remove(L, 1); lua_remove(L, 1);
i = luaL_checkinteger(L, 1); i = luaL_checkinteger(L, 1);
if (i >= NUMHUDITEMS)
return luaL_error(L, "hudinfo[] index %d out of range (0 - %d)", i, NUMHUDITEMS-1);
LUA_PushUserdata(L, &hudinfo[i], META_HUDINFO); LUA_PushUserdata(L, &hudinfo[i], META_HUDINFO);
return 1; return 1;
} }

View file

@ -146,6 +146,8 @@ static int lib_getState(lua_State *L)
lua_remove(L, 1); lua_remove(L, 1);
i = luaL_checkinteger(L, 1); i = luaL_checkinteger(L, 1);
if (i >= NUMSTATES)
return luaL_error(L, "states[] index %d out of range (0 - %d)", i, NUMSTATES-1);
LUA_PushUserdata(L, &states[i], META_STATE); LUA_PushUserdata(L, &states[i], META_STATE);
return 1; return 1;
} }
@ -155,7 +157,12 @@ static int lib_setState(lua_State *L)
{ {
state_t *state; state_t *state;
lua_remove(L, 1); // don't care about states[] userdata. lua_remove(L, 1); // don't care about states[] userdata.
state = &states[luaL_checkinteger(L, 1)]; // get the state to assign to. {
UINT32 i = luaL_checkinteger(L, 1);
if (i >= NUMSTATES)
return luaL_error(L, "states[] index %d out of range (0 - %d)", i, NUMSTATES-1);
state = &states[i]; // get the state to assign to.
}
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table. luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
lua_remove(L, 1); // pop state num, don't need it any more. lua_remove(L, 1); // pop state num, don't need it any more.
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the state. lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the state.
@ -436,6 +443,8 @@ static int lib_getMobjInfo(lua_State *L)
lua_remove(L, 1); lua_remove(L, 1);
i = luaL_checkinteger(L, 1); i = luaL_checkinteger(L, 1);
if (i >= NUMMOBJTYPES)
return luaL_error(L, "mobjinfo[] index %d out of range (0 - %d)", i, NUMMOBJTYPES-1);
LUA_PushUserdata(L, &mobjinfo[i], META_MOBJINFO); LUA_PushUserdata(L, &mobjinfo[i], META_MOBJINFO);
return 1; return 1;
} }
@ -445,7 +454,12 @@ static int lib_setMobjInfo(lua_State *L)
{ {
mobjinfo_t *info; mobjinfo_t *info;
lua_remove(L, 1); // don't care about mobjinfo[] userdata. lua_remove(L, 1); // don't care about mobjinfo[] userdata.
info = &mobjinfo[luaL_checkinteger(L, 1)]; // get the mobjinfo to assign to. {
UINT32 i = luaL_checkinteger(L, 1);
if (i >= NUMMOBJTYPES)
return luaL_error(L, "mobjinfo[] index %d out of range (0 - %d)", i, NUMMOBJTYPES-1);
info = &mobjinfo[i]; // get the mobjinfo to assign to.
}
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table. luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
lua_remove(L, 1); // pop mobjtype num, don't need it any more. lua_remove(L, 1); // pop mobjtype num, don't need it any more.
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the mobjinfo. lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the mobjinfo.
@ -717,6 +731,8 @@ static int lib_getSfxInfo(lua_State *L)
lua_remove(L, 1); lua_remove(L, 1);
i = luaL_checkinteger(L, 1); i = luaL_checkinteger(L, 1);
if (i >= NUMSFX)
return luaL_error(L, "sfxinfo[] index %d out of range (0 - %d)", i, NUMSFX-1);
LUA_PushUserdata(L, &S_sfx[i], META_SFXINFO); LUA_PushUserdata(L, &S_sfx[i], META_SFXINFO);
return 1; return 1;
} }
@ -727,7 +743,12 @@ static int lib_setSfxInfo(lua_State *L)
sfxinfo_t *info; sfxinfo_t *info;
lua_remove(L, 1); lua_remove(L, 1);
info = &S_sfx[luaL_checkinteger(L, 1)]; // get the mobjinfo to assign to. {
UINT32 i = luaL_checkinteger(L, 1);
if (i >= NUMSFX)
return luaL_error(L, "sfxinfo[] index %d out of range (0 - %d)", i, NUMSFX-1);
info = &S_sfx[i]; // get the mobjinfo to assign to.
}
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table. luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
lua_remove(L, 1); // pop mobjtype num, don't need it any more. lua_remove(L, 1); // pop mobjtype num, don't need it any more.
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the mobjinfo. lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the mobjinfo.

View file

@ -55,7 +55,7 @@ static int lib_getPlayer(lua_State *L)
{ {
lua_Integer i = luaL_checkinteger(L, 2); lua_Integer i = luaL_checkinteger(L, 2);
if (i < 0 || i >= MAXPLAYERS) if (i < 0 || i >= MAXPLAYERS)
return luaL_error(L, "players[] index cannot exceed MAXPLAYERS"); return luaL_error(L, "players[] index %d out of range (0 - %d)", i, MAXPLAYERS-1);
if (!playeringame[i]) if (!playeringame[i])
return 0; return 0;
if (!players[i].mo) if (!players[i].mo)
@ -298,6 +298,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->lastlinehit); lua_pushinteger(L, plr->lastlinehit);
else if (fastcmp(field,"losstime")) else if (fastcmp(field,"losstime"))
lua_pushinteger(L, plr->losstime); lua_pushinteger(L, plr->losstime);
else if (fastcmp(field,"timeshit"))
lua_pushinteger(L, plr->timeshit);
else if (fastcmp(field,"onconveyor")) else if (fastcmp(field,"onconveyor"))
lua_pushinteger(L, plr->onconveyor); lua_pushinteger(L, plr->onconveyor);
else if (fastcmp(field,"awayviewmobj")) else if (fastcmp(field,"awayviewmobj"))
@ -553,6 +555,8 @@ static int player_set(lua_State *L)
plr->lastlinehit = (INT16)luaL_checkinteger(L, 3); plr->lastlinehit = (INT16)luaL_checkinteger(L, 3);
else if (fastcmp(field,"losstime")) else if (fastcmp(field,"losstime"))
plr->losstime = (tic_t)luaL_checkinteger(L, 3); plr->losstime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"timeshit"))
plr->timeshit = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"onconveyor")) else if (fastcmp(field,"onconveyor"))
plr->onconveyor = (INT32)luaL_checkinteger(L, 3); plr->onconveyor = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"awayviewmobj")) else if (fastcmp(field,"awayviewmobj"))

View file

@ -244,7 +244,7 @@ static int lib_getSkin(lua_State *L)
{ {
i = luaL_checkinteger(L, 2); i = luaL_checkinteger(L, 2);
if (i < 0 || i >= MAXSKINS) if (i < 0 || i >= MAXSKINS)
return luaL_error(L, "skins[] index cannot exceed MAXSKINS"); return luaL_error(L, "skins[] index %d out of range (0 - %d)", i, MAXSKINS-1);
if (i >= numskins) if (i >= numskins)
return 0; return 0;
LUA_PushUserdata(L, &skins[i], META_SKIN); LUA_PushUserdata(L, &skins[i], META_SKIN);

View file

@ -31,6 +31,7 @@
#include "v_video.h" #include "v_video.h"
#include "z_zone.h" #include "z_zone.h"
#include "p_slopes.h"
#include "lua_script.h" #include "lua_script.h"
#include "lua_hook.h" #include "lua_hook.h"
@ -598,9 +599,9 @@ void Command_CauseCfail_f(void)
} }
P_UnsetThingPosition(players[consoleplayer].mo); P_UnsetThingPosition(players[consoleplayer].mo);
P_Random(); P_RandomFixed();
P_Random(); P_RandomByte();
P_Random(); P_RandomFixed();
players[consoleplayer].mo->x = 0; players[consoleplayer].mo->x = 0;
players[consoleplayer].mo->y = 123311; //cfail cansuled kthxbye players[consoleplayer].mo->y = 123311; //cfail cansuled kthxbye
players[consoleplayer].mo->z = 123311; players[consoleplayer].mo->z = 123311;
@ -837,9 +838,19 @@ static void OP_CycleThings(INT32 amt)
static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) static boolean OP_HeightOkay(player_t *player, UINT8 ceiling)
{ {
sector_t *sec = player->mo->subsector->sector;
if (ceiling) if (ceiling)
{ {
if (((player->mo->subsector->sector->ceilingheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT))) #ifdef ESLOPE
// Truncate position to match where mapthing would be when spawned
// (this applies to every further P_GetZAt call as well)
fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight;
#else
fixed_t cheight = sec->ceilingheight;
#endif
if (((cheight - player->mo->z - player->mo->height)>>FRACBITS) >= (1 << (16-ZSHIFT)))
{ {
CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("low"), CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("low"),
(1 << (16-ZSHIFT)), M_GetText("below top ceiling")); (1 << (16-ZSHIFT)), M_GetText("below top ceiling"));
@ -848,7 +859,12 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling)
} }
else else
{ {
if (((player->mo->z - player->mo->subsector->sector->floorheight)>>FRACBITS) >= (1 << (16-ZSHIFT))) #ifdef ESLOPE
fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight;
#else
fixed_t fheight = sec->floorheight;
#endif
if (((player->mo->z - fheight)>>FRACBITS) >= (1 << (16-ZSHIFT)))
{ {
CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("high"), CONS_Printf(M_GetText("Sorry, you're too %s to place this object (max: %d %s).\n"), M_GetText("high"),
(1 << (16-ZSHIFT)), M_GetText("above bottom floor")); (1 << (16-ZSHIFT)), M_GetText("above bottom floor"));
@ -861,6 +877,7 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling)
static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean ceiling) static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean ceiling)
{ {
mapthing_t *mt = mapthings; mapthing_t *mt = mapthings;
sector_t *sec = player->mo->subsector->sector;
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
LUA_InvalidateMapthings(); LUA_InvalidateMapthings();
@ -893,9 +910,23 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
mt->x = (INT16)(player->mo->x>>FRACBITS); mt->x = (INT16)(player->mo->x>>FRACBITS);
mt->y = (INT16)(player->mo->y>>FRACBITS); mt->y = (INT16)(player->mo->y>>FRACBITS);
if (ceiling) if (ceiling)
mt->options = (UINT16)((player->mo->subsector->sector->ceilingheight - player->mo->z - player->mo->height)>>FRACBITS); {
#ifdef ESLOPE
fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->ceilingheight;
#else
fixed_t cheight = sec->ceilingheight;
#endif
mt->options = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS);
}
else else
mt->options = (UINT16)((player->mo->z - player->mo->subsector->sector->floorheight)>>FRACBITS); {
#ifdef ESLOPE
fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : sec->floorheight;
#else
fixed_t fheight = sec->floorheight;
#endif
mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS);
}
mt->options <<= ZSHIFT; mt->options <<= ZSHIFT;
mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle))); mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle)));
@ -949,6 +980,13 @@ void OP_NightsObjectplace(player_t *player)
{ {
UINT16 angle = (UINT16)(player->anotherflyangle % 360); UINT16 angle = (UINT16)(player->anotherflyangle % 360);
INT16 temp = (INT16)FixedInt(AngleFixed(player->mo->angle)); // Traditional 2D Angle INT16 temp = (INT16)FixedInt(AngleFixed(player->mo->angle)); // Traditional 2D Angle
sector_t *sec = player->mo->subsector->sector;
#ifdef ESLOPE
fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight;
#else
fixed_t fheight = sec->floorheight;
#endif
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
@ -963,7 +1001,7 @@ void OP_NightsObjectplace(player_t *player)
temp += 90; temp += 90;
temp %= 360; temp %= 360;
mt->options = (UINT16)((player->mo->z - player->mo->subsector->sector->floorheight)>>FRACBITS); mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS);
mt->angle = (INT16)(mt->angle+(INT16)((FixedInt(FixedDiv(temp*FRACUNIT, 360*(FRACUNIT/256))))<<8)); mt->angle = (INT16)(mt->angle+(INT16)((FixedInt(FixedDiv(temp*FRACUNIT, 360*(FRACUNIT/256))))<<8));
P_SpawnHoopsAndRings(mt); P_SpawnHoopsAndRings(mt);
@ -1097,6 +1135,33 @@ void OP_ObjectplaceMovement(player_t *player)
else else
player->viewz = player->mo->z + player->viewheight; player->viewz = player->mo->z + player->viewheight;
// Display flag information
// Moved up so it always updates.
{
sector_t *sec = player->mo->subsector->sector;
if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP))
{
#ifdef ESLOPE
fixed_t cheight = sec->c_slope ? P_GetZAt(sec->c_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->ceilingheight;
#else
fixed_t cheight = sec->ceilingheight;
#endif
op_displayflags = (UINT16)((cheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS);
}
else
{
#ifdef ESLOPE
fixed_t fheight = sec->f_slope ? P_GetZAt(sec->f_slope, player->mo->x & 0xFFFF0000, player->mo->y & 0xFFFF0000) : sec->floorheight;
#else
fixed_t fheight = sec->floorheight;
#endif
op_displayflags = (UINT16)((player->mo->z - fheight)>>FRACBITS);
}
op_displayflags <<= ZSHIFT;
op_displayflags |= (UINT16)cv_opflags.value;
}
if (player->pflags & PF_ATTACKDOWN) if (player->pflags & PF_ATTACKDOWN)
{ {
// Are ANY objectplace buttons pressed? If no, remove flag. // Are ANY objectplace buttons pressed? If no, remove flag.
@ -1162,16 +1227,6 @@ void OP_ObjectplaceMovement(player_t *player)
CONS_Printf(M_GetText("Placed object type %d at %d, %d, %d, %d\n"), mt->type, mt->x, mt->y, mt->options>>ZSHIFT, mt->angle); CONS_Printf(M_GetText("Placed object type %d at %d, %d, %d, %d\n"), mt->type, mt->x, mt->y, mt->options>>ZSHIFT, mt->angle);
} }
// Display flag information
{
if (!!(mobjinfo[op_currentthing].flags & MF_SPAWNCEILING) ^ !!(cv_opflags.value & MTF_OBJECTFLIP))
op_displayflags = (UINT16)((player->mo->subsector->sector->ceilingheight - player->mo->z - mobjinfo[op_currentthing].height)>>FRACBITS);
else
op_displayflags = (UINT16)((player->mo->z - player->mo->subsector->sector->floorheight)>>FRACBITS);
op_displayflags <<= ZSHIFT;
op_displayflags |= (UINT16)cv_opflags.value;
}
} }
// //

View file

@ -1787,17 +1787,6 @@ UINT8 M_CountBits(UINT32 num, UINT8 size)
return sum; return sum;
} }
/** Get the most significant bit in a number.
* (integer log2)
*/
UINT8 M_HighestBit(UINT32 num)
{
UINT8 i = 0;
while (num >>= 1) ++i;
return i;
}
const char *GetRevisionString(void) const char *GetRevisionString(void)
{ {
static char rev[9] = {0}; static char rev[9] = {0};

View file

@ -95,7 +95,6 @@ void M_SetupMemcpy(void);
// counting bits, for weapon ammo code, usually // counting bits, for weapon ammo code, usually
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size); FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
FUNCMATH UINT8 M_HighestBit(UINT32 num);
// Flags for AA trees. // Flags for AA trees.
#define AATREE_ZUSER 1 // Treat values as z_zone-allocated blocks and set their user fields #define AATREE_ZUSER 1 // Treat values as z_zone-allocated blocks and set their user fields

View file

@ -10,7 +10,7 @@
// See the 'LICENSE' file for more details. // See the 'LICENSE' file for more details.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file m_random.c /// \file m_random.c
/// \brief LCG PRNG originally created for XMOD /// \brief RNG for client effects and PRNG for game actions
#include "doomdef.h" #include "doomdef.h"
#include "doomtype.h" #include "doomtype.h"
@ -19,48 +19,57 @@
#include "m_random.h" #include "m_random.h"
#include "m_fixed.h" #include "m_fixed.h"
// --------------------------- // ---------------------------
// RNG functions (not synched) // RNG functions (not synched)
// --------------------------- // ---------------------------
/** Provides a random byte. /** Provides a random fixed point number. Distribution is uniform.
* Used outside the p_xxx game code and not synchronized in netgames. This is * As with all M_Random functions, not synched in netgames.
* for anything that doesn't need to be synced, e.g. precipitation.
* *
* \return A random byte, 0 to 255. * \return A random fixed point number from [0,1).
*/ */
UINT8 M_Random(void) fixed_t M_RandomFixed(void)
{ {
return (rand() & 255); #if RAND_MAX < 65535
// Compensate for insufficient randomness.
fixed_t rndv = (rand()&1)<<15;
return rand()^rndv;
#else
return (rand() & 0xFFFF);
#endif
} }
/** Provides a random signed byte. Distribution is uniform. /** Provides a random byte. Distribution is uniform.
* As with all M_*Random functions, not synched in netgames. * As with all M_Random functions, not synched in netgames.
* *
* \return A random byte, -128 to 127. * \return A random integer from [0, 255].
* \sa M_Random
*/ */
INT32 M_SignedRandom(void) UINT8 M_RandomByte(void)
{ {
return M_Random() - 128; return (rand() & 0xFF);
} }
/** Provides a random number in between 0 and the given number - 1. /** Provides a random integer for picking random elements from an array.
* Distribution is uniform. Use for picking random elements from an array. * Distribution is uniform.
* As with all M_*Random functions, not synched in netgames. * As with all M_Random functions, not synched in netgames.
* *
* \return A random number, 0 to arg1-1. * \param a Number of items in array.
* \return A random integer from [0,a).
*/ */
INT32 M_RandomKey(INT32 a) INT32 M_RandomKey(INT32 a)
{ {
return (INT32)((rand()/((unsigned)RAND_MAX+1.0f))*a); return (INT32)((rand()/((unsigned)RAND_MAX+1.0f))*a);
} }
/** Provides a random number in between a specific range. /** Provides a random integer in a given range.
* Distribution is uniform. * Distribution is uniform.
* As with all M_*Random functions, not synched in netgames. * As with all M_Random functions, not synched in netgames.
* *
* \return A random number, arg1 to arg2. * \param a Lower bound.
* \param b Upper bound.
* \return A random integer from [a,b].
*/ */
INT32 M_RandomRange(INT32 a, INT32 b) INT32 M_RandomRange(INT32 a, INT32 b)
{ {
@ -74,54 +83,65 @@ INT32 M_RandomRange(INT32 a, INT32 b)
// ------------------------ // ------------------------
// Holds the current seed. // Holds the current seed.
static UINT32 randomseed = 0; static UINT32 randomseed = 0xBADE4404;
// Holds the INITIAL seed value. Used for demos, possibly other debugging. // Holds the INITIAL seed value. Used for demos, possibly other debugging.
static UINT32 initialseed = 0; static UINT32 initialseed = 0xBADE4404;
/** /** Provides a random fixed point number.
* Provides a random byte and sets the seed appropriately. * This is a variant of an xorshift PRNG; state fits in a 32 bit integer structure.
* The nature of this PRNG allows it to cycle through about two million numbers
* before it finally starts repeating numeric sequences.
* That's more than good enough for our purposes.
* *
* \return A random byte, 0 to 255. * \return A random fixed point number from [0,1).
*/ */
#ifndef DEBUGRANDOM ATTRINLINE static fixed_t FUNCINLINE __internal_prng__(void)
UINT8 P_Random(void)
{ {
#else randomseed ^= randomseed >> 13;
UINT8 P_RandomD(const char *rfile, INT32 rline) randomseed ^= randomseed >> 11;
{ randomseed ^= randomseed << 21;
CONS_Printf("P_Random() at: %sp %d\n", rfile, rline); return ( (randomseed*36548569) >> 4) & (FRACUNIT-1);
#endif
randomseed = (randomseed*746151647)+48205429;
return (UINT8)((randomseed >> 17)&255);
} }
/** Provides a random number from -128 to 127. /** Provides a random fixed point number. Distribution is uniform.
* Literally a wrapper for the internal PRNG function.
*
* \return A random fixed point number from [0,1).
*/
#ifndef DEBUGRANDOM
fixed_t P_RandomFixed(void)
{
#else
fixed_t P_RandomFixedD(const char *rfile, INT32 rline)
{
CONS_Printf("P_RandomFixed() at: %sp %d\n", rfile, rline);
#endif
return __internal_prng__();
}
/** Provides a random byte. Distribution is uniform.
* If you're curious, (&0xFF00) >> 8 gives the same result
* as a fixed point multiplication by 256.
*
* \return Random integer from [0, 255].
* \sa __internal_prng__
*/
#ifndef DEBUGRANDOM
UINT8 P_RandomByte(void)
{
#else
UINT8 P_RandomByteD(const char *rfile, INT32 rline)
{
CONS_Printf("P_RandomByte() at: %sp %d\n", rfile, rline);
#endif
return (UINT8)((__internal_prng__()&0xFF00)>>8);
}
/** Provides a random integer for picking random elements from an array.
* Distribution is uniform. * Distribution is uniform.
* NOTE: Maximum range is 65536.
* *
* \return Random number from -128 to 127. * \param a Number of items in array.
* \sa P_Random * \return A random integer from [0,a).
*/ * \sa __internal_prng__
#ifndef DEBUGRANDOM
INT32 P_SignedRandom(void)
{
#else
INT32 P_SignedRandomD(const char *rfile, INT32 rline)
{
CONS_Printf("P_SignedRandom() at: %sp %d\n", rfile, rline);
#endif
return P_Random() - 128;
}
/** Provides a random number in between 0 and the given number - 1.
* Distribution is uniform, also calls for two numbers for bigger output range.
* Use for picking random elements from an array.
*
* \return A random number, 0 to arg1-1.
* \sa P_Random
*/ */
#ifndef DEBUGRANDOM #ifndef DEBUGRANDOM
INT32 P_RandomKey(INT32 a) INT32 P_RandomKey(INT32 a)
@ -131,16 +151,17 @@ INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a)
{ {
CONS_Printf("P_RandomKey() at: %sp %d\n", rfile, rline); CONS_Printf("P_RandomKey() at: %sp %d\n", rfile, rline);
#endif #endif
INT32 prandom = P_Random(); // note: forcing explicit function call order return (INT32)((__internal_prng__() * a) >> FRACBITS);
prandom |= P_Random() << 8; // (function call order is not strictly defined)
return (INT32)((prandom/65536.0f)*a);
} }
/** Provides a random number in between a specific range. /** Provides a random integer in a given range.
* Distribution is uniform, also calls for two numbers for bigger output range. * Distribution is uniform.
* NOTE: Maximum range is 65536.
* *
* \return A random number, arg1 to arg2. * \param a Lower bound.
* \sa P_Random * \param b Upper bound.
* \return A random integer from [a,b].
* \sa __internal_prng__
*/ */
#ifndef DEBUGRANDOM #ifndef DEBUGRANDOM
INT32 P_RandomRange(INT32 a, INT32 b) INT32 P_RandomRange(INT32 a, INT32 b)
@ -150,21 +171,27 @@ INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b)
{ {
CONS_Printf("P_RandomRange() at: %sp %d\n", rfile, rline); CONS_Printf("P_RandomRange() at: %sp %d\n", rfile, rline);
#endif #endif
INT32 prandom = P_Random(); // note: forcing explicit function call order return (INT32)((__internal_prng__() * (b-a+1)) >> FRACBITS) + a;
prandom |= P_Random() << 8; // (function call order is not strictly defined)
return (INT32)((prandom/65536.0f)*(b-a+1))+a;
} }
/** Provides a random byte without saving what the seed would be.
* Used just to debug the PRNG.
// ----------------------
// PRNG seeds & debugging
// ----------------------
/** Peeks to see what the next result from the PRNG will be.
* Used for debugging.
* *
* \return A 'random' byte, 0 to 255. * \return A 'random' fixed point number from [0,1).
* \sa P_Random * \sa __internal_prng__
*/ */
UINT8 P_RandomPeek(void) fixed_t P_RandomPeek(void)
{ {
UINT32 r = (randomseed*746151647)+48205429; UINT32 r = randomseed;
return (UINT8)((r >> 17)&255); fixed_t ret = __internal_prng__();
randomseed = r;
return ret;
} }
/** Gets the current random seed. Used by netgame savegames. /** Gets the current random seed. Used by netgame savegames.
@ -213,6 +240,9 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, UINT32 seed)
{ {
CONS_Printf("P_SetRandSeed() at: %sp %d\n", rfile, rline); CONS_Printf("P_SetRandSeed() at: %sp %d\n", rfile, rline);
#endif #endif
// xorshift requires a nonzero seed
// this should never happen, but just in case it DOES, we check
if (!seed) seed = 0xBADE4404;
randomseed = initialseed = seed; randomseed = initialseed = seed;
} }
@ -222,5 +252,5 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, UINT32 seed)
*/ */
UINT32 M_RandomizedSeed(void) UINT32 M_RandomizedSeed(void)
{ {
return ((totalplaytime & 0xFFFF) << 16)|(rand() & 0xFFFF); return ((totalplaytime & 0xFFFF) << 16)|M_RandomFixed();
} }

View file

@ -20,32 +20,42 @@
//#define DEBUGRANDOM //#define DEBUGRANDOM
// M_Random functions pull random numbers of various types that aren't network synced. // M_Random functions pull random numbers of various types that aren't network synced.
// P_Random functions pulls random bytes from a LCG PRNG that is network synced. // P_Random functions pulls random bytes from a PRNG that is network synced.
// RNG functions // RNG functions
UINT8 M_Random(void); fixed_t M_RandomFixed(void);
INT32 M_SignedRandom(void); UINT8 M_RandomByte(void);
INT32 M_RandomKey(INT32 a); INT32 M_RandomKey(INT32 a);
INT32 M_RandomRange(INT32 a, INT32 b); INT32 M_RandomRange(INT32 a, INT32 b);
// PRNG functions // PRNG functions
#ifdef DEBUGRANDOM #ifdef DEBUGRANDOM
#define P_Random() P_RandomD(__FILE__, __LINE__) #define P_RandomFixed() P_RandomFixedD(__FILE__, __LINE__)
#define P_SignedRandom() P_SignedRandomD(__FILE__, __LINE__) #define P_RandomByte() P_RandomByteD(__FILE__, __LINE__)
#define P_RandomKey(c) P_RandomKeyD(__FILE__, __LINE__, c) #define P_RandomKey(c) P_RandomKeyD(__FILE__, __LINE__, c)
#define P_RandomRange(c, d) P_RandomRangeD(__FILE__, __LINE__, c, d) #define P_RandomRange(c, d) P_RandomRangeD(__FILE__, __LINE__, c, d)
UINT8 P_RandomD(const char *rfile, INT32 rline); fixed_t P_RandomFixedD(const char *rfile, INT32 rline);
INT32 P_SignedRandomD(const char *rfile, INT32 rline); UINT8 P_RandomByteD(const char *rfile, INT32 rline);
INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a); INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a);
INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b); INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b);
#else #else
UINT8 P_Random(void); fixed_t P_RandomFixed(void);
INT32 P_SignedRandom(void); UINT8 P_RandomByte(void);
INT32 P_RandomKey(INT32 a); INT32 P_RandomKey(INT32 a);
INT32 P_RandomRange(INT32 a, INT32 b); INT32 P_RandomRange(INT32 a, INT32 b);
#endif #endif
UINT8 P_RandomPeek(void);
// Macros for other functions
#define M_SignedRandom() ((INT32)M_RandomByte() - 128) // [-128, 127] signed byte, originally a
#define P_SignedRandom() ((INT32)P_RandomByte() - 128) // function of its own, moved to a macro
#define M_RandomChance(p) (M_RandomFixed() < p) // given fixed point probability, p, between 0 (0%)
#define P_RandomChance(p) (P_RandomFixed() < p) // and FRACUNIT (100%), returns true p% of the time
// Debugging
fixed_t P_RandomPeek(void);
// Working with the seed for PRNG // Working with the seed for PRNG
#ifdef DEBUGRANDOM #ifdef DEBUGRANDOM

View file

@ -386,7 +386,7 @@ boolean P_CheckMissileRange(mobj_t *actor)
if (actor->type == MT_EGGMOBILE && dist > 160) if (actor->type == MT_EGGMOBILE && dist > 160)
dist = 160; dist = 160;
if (P_Random() < dist) if (P_RandomByte() < dist)
return false; return false;
return true; return true;
@ -486,7 +486,7 @@ static boolean P_TryWalk(mobj_t *actor)
{ {
if (!P_Move(actor, actor->info->speed)) if (!P_Move(actor, actor->info->speed))
return false; return false;
actor->movecount = P_Random() & 15; actor->movecount = P_RandomByte() & 15;
return true; return true;
} }
@ -539,7 +539,7 @@ void P_NewChaseDir(mobj_t *actor)
} }
// try other directions // try other directions
if (P_Random() > 200 || abs(deltay) > abs(deltax)) if (P_RandomChance(25*FRACUNIT/32) || abs(deltay) > abs(deltax))
{ {
tdir = d[1]; tdir = d[1];
d[1] = d[2]; d[1] = d[2];
@ -577,7 +577,7 @@ void P_NewChaseDir(mobj_t *actor)
} }
// randomly determine direction of search // randomly determine direction of search
if (P_Random() & 1) if (P_RandomChance(FRACUNIT/2))
{ {
for (tdir = DI_EAST; tdir <= DI_SOUTHEAST; tdir++) for (tdir = DI_EAST; tdir <= DI_SOUTHEAST; tdir++)
{ {
@ -632,7 +632,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
// BP: first time init, this allow minimum lastlook changes // BP: first time init, this allow minimum lastlook changes
if (actor->lastlook < 0) if (actor->lastlook < 0)
actor->lastlook = P_Random(); actor->lastlook = P_RandomByte();
actor->lastlook %= MAXPLAYERS; actor->lastlook %= MAXPLAYERS;
@ -707,7 +707,7 @@ static boolean P_LookForShield(mobj_t *actor)
// BP: first time init, this allow minimum lastlook changes // BP: first time init, this allow minimum lastlook changes
if (actor->lastlook < 0) if (actor->lastlook < 0)
actor->lastlook = P_Random(); actor->lastlook = P_RandomByte();
actor->lastlook %= MAXPLAYERS; actor->lastlook %= MAXPLAYERS;
@ -2293,12 +2293,7 @@ void A_SkullAttack(mobj_t *actor)
if (locvar1 == 1) if (locvar1 == 1)
actor->angle += ANGLE_180; actor->angle += ANGLE_180;
else if (locvar1 == 2) else if (locvar1 == 2)
{ actor->angle += (P_RandomChance(FRACUNIT/2)) ? ANGLE_90 : -ANGLE_90;
if (P_Random() & 1)
actor->angle += ANGLE_90;
else
actor->angle -= ANGLE_90;
}
an = actor->angle >> ANGLETOFINESHIFT; an = actor->angle >> ANGLETOFINESHIFT;
@ -2398,9 +2393,9 @@ void A_BossScream(mobj_t *actor)
explodetype = (mobjtype_t)locvar2; explodetype = (mobjtype_t)locvar2;
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
z = actor->z + actor->height - mobjinfo[explodetype].height - FixedMul((P_Random()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); z = actor->z + actor->height - mobjinfo[explodetype].height - FixedMul((P_RandomByte()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale);
else else
z = actor->z + FixedMul((P_Random()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); z = actor->z + FixedMul((P_RandomByte()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale);
mo = P_SpawnMobj(x, y, z, explodetype); mo = P_SpawnMobj(x, y, z, explodetype);
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
@ -3461,7 +3456,7 @@ void A_BubbleSpawn(mobj_t *actor)
return; // don't make bubble! return; // don't make bubble!
} }
prandom = P_Random(); prandom = P_RandomByte();
if (leveltime % (3*TICRATE) < 8) if (leveltime % (3*TICRATE) < 8)
bubble = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2), MT_EXTRALARGEBUBBLE); bubble = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2), MT_EXTRALARGEBUBBLE);
@ -3509,7 +3504,7 @@ void A_FanBubbleSpawn(mobj_t *actor)
return; // don't make bubble! return; // don't make bubble!
} }
prandom = P_Random(); prandom = P_RandomByte();
if ((prandom & 0x7) == 0x7) if ((prandom & 0x7) == 0x7)
bubble = P_SpawnMobj(actor->x, actor->y, hz, MT_SMALLBUBBLE); bubble = P_SpawnMobj(actor->x, actor->y, hz, MT_SMALLBUBBLE);
@ -3550,7 +3545,7 @@ void A_BubbleRise(mobj_t *actor)
// Move around slightly to make it look like it's bending around the water // Move around slightly to make it look like it's bending around the water
if (!locvar1) if (!locvar1)
{ {
UINT8 prandom = P_Random(); UINT8 prandom = P_RandomByte();
if (!(prandom & 0x7)) // *****000 if (!(prandom & 0x7)) // *****000
{ {
P_InstaThrust(actor, prandom & 0x70 ? actor->angle + ANGLE_90 : actor->angle, P_InstaThrust(actor, prandom & 0x70 ? actor->angle + ANGLE_90 : actor->angle,
@ -3833,7 +3828,7 @@ void A_ThrownRing(mobj_t *actor)
// first time init, this allow minimum lastlook changes // first time init, this allow minimum lastlook changes
if (actor->lastlook < 0) if (actor->lastlook < 0)
actor->lastlook = P_Random(); actor->lastlook = P_RandomByte();
actor->lastlook %= MAXPLAYERS; actor->lastlook %= MAXPLAYERS;
@ -3913,7 +3908,7 @@ void A_SetSolidSteam(mobj_t *actor)
#endif #endif
actor->flags &= ~MF_NOCLIP; actor->flags &= ~MF_NOCLIP;
actor->flags |= MF_SOLID; actor->flags |= MF_SOLID;
if (!(P_Random() & 7)) if (P_RandomChance(FRACUNIT/8))
{ {
if (actor->info->deathsound) if (actor->info->deathsound)
S_StartSound(actor, actor->info->deathsound); // Hiss! S_StartSound(actor, actor->info->deathsound); // Hiss!
@ -4055,7 +4050,7 @@ void A_JetChase(mobj_t *actor)
if (actor->reactiontime) if (actor->reactiontime)
actor->reactiontime--; actor->reactiontime--;
if (P_Random() % 32 == 1) if (P_RandomChance(FRACUNIT/32))
{ {
actor->momx = actor->momx / 2; actor->momx = actor->momx / 2;
actor->momy = actor->momy / 2; actor->momy = actor->momy / 2;
@ -4416,7 +4411,7 @@ void A_JetgThink(mobj_t *actor)
if (actor->target) if (actor->target)
{ {
if (P_Random() <= 32 && !actor->reactiontime) if (P_RandomChance(FRACUNIT/8) && !actor->reactiontime)
P_SetMobjState(actor, actor->info->missilestate); P_SetMobjState(actor, actor->info->missilestate);
else else
A_JetChase (actor); A_JetChase (actor);
@ -4469,10 +4464,10 @@ void A_MouseThink(mobj_t *actor)
{ {
if (twodlevel || actor->flags2 & MF2_TWOD) if (twodlevel || actor->flags2 & MF2_TWOD)
{ {
if (P_Random() & 1) if (P_RandomChance(FRACUNIT/2))
actor->angle += ANGLE_180; actor->angle += ANGLE_180;
} }
else if (P_Random() & 1) else if (P_RandomChance(FRACUNIT/2))
actor->angle += ANGLE_90; actor->angle += ANGLE_90;
else else
actor->angle -= ANGLE_90; actor->angle -= ANGLE_90;
@ -4878,7 +4873,7 @@ void A_RockSpawn(mobj_t *actor)
type = MT_ROCKCRUMBLE1 + (sides[line->sidenum[0]].rowoffset >> FRACBITS); type = MT_ROCKCRUMBLE1 + (sides[line->sidenum[0]].rowoffset >> FRACBITS);
if (line->flags & ML_NOCLIMB) if (line->flags & ML_NOCLIMB)
randomoomph = P_Random() * (FRACUNIT/32); randomoomph = P_RandomByte() * (FRACUNIT/32);
else else
randomoomph = 0; randomoomph = 0;
@ -5172,7 +5167,7 @@ void A_CrawlaCommanderThink(mobj_t *actor)
if (locvar1) if (locvar1)
{ {
if (actor->health < 2 && P_Random() < 2) if (actor->health < 2 && P_RandomChance(FRACUNIT/128))
P_SpawnMissile(actor, actor->target, locvar1); P_SpawnMissile(actor, actor->target, locvar1);
} }
@ -5187,8 +5182,8 @@ void A_CrawlaCommanderThink(mobj_t *actor)
actor->threshold = 0; actor->threshold = 0;
// Roam around, somewhat in the player's direction. // Roam around, somewhat in the player's direction.
actor->angle += (P_Random()<<10); actor->angle += (P_RandomByte()<<10);
actor->angle -= (P_Random()<<10); actor->angle -= (P_RandomByte()<<10);
if (actor->health > 1) if (actor->health > 1)
P_InstaThrust(actor, actor->angle, FixedMul(10*FRACUNIT, actor->scale)); P_InstaThrust(actor, actor->angle, FixedMul(10*FRACUNIT, actor->scale));
@ -5204,7 +5199,7 @@ void A_CrawlaCommanderThink(mobj_t *actor)
actor->threshold = 1; actor->threshold = 1;
} }
} }
actor->reactiontime = 2*TICRATE + P_Random()/2; actor->reactiontime = 2*TICRATE + P_RandomByte()/2;
} }
if (actor->health == 1) if (actor->health == 1)
@ -5222,8 +5217,8 @@ void A_CrawlaCommanderThink(mobj_t *actor)
} }
else else
{ {
UINT8 prandom = P_Random(); UINT8 prandom = P_RandomByte();
actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom);
P_InstaThrust(actor, actor->angle, FixedDiv(FixedMul(locvar2, actor->scale), 3*FRACUNIT/2)); P_InstaThrust(actor, actor->angle, FixedDiv(FixedMul(locvar2, actor->scale), 3*FRACUNIT/2));
actor->momz = FixedMul(locvar2, actor->scale); // Bounce up in air actor->momz = FixedMul(locvar2, actor->scale); // Bounce up in air
} }
@ -5552,7 +5547,7 @@ void A_MixUp(mobj_t *actor)
{ {
if (counter > 255) // fail-safe to avoid endless loop if (counter > 255) // fail-safe to avoid endless loop
break; break;
prandom = P_Random(); prandom = P_RandomByte();
prandom %= numplayers; // I love modular arithmetic, don't you? prandom %= numplayers; // I love modular arithmetic, don't you?
if (prandom) // Make sure it's not a useless mix if (prandom) // Make sure it's not a useless mix
break; break;
@ -5701,7 +5696,7 @@ void A_RecyclePowers(mobj_t *actor)
{ {
UINT8 tempint; UINT8 tempint;
i = j + ((P_Random() + leveltime) % (numplayers - j)); i = j + ((P_RandomByte() + leveltime) % (numplayers - j));
tempint = postscramble[j]; tempint = postscramble[j];
postscramble[j] = postscramble[i]; postscramble[j] = postscramble[i];
postscramble[i] = tempint; postscramble[i] = tempint;
@ -5814,7 +5809,7 @@ void A_Boss1Chase(mobj_t *actor)
{ {
if (actor->health > actor->info->damage) if (actor->health > actor->info->damage)
{ {
if (P_Random() & 1) if (P_RandomChance(FRACUNIT/2))
P_SetMobjState(actor, actor->info->missilestate); P_SetMobjState(actor, actor->info->missilestate);
else else
P_SetMobjState(actor, actor->info->meleestate); P_SetMobjState(actor, actor->info->meleestate);
@ -5833,7 +5828,7 @@ void A_Boss1Chase(mobj_t *actor)
// ? // ?
nomissile: nomissile:
// possibly choose another target // possibly choose another target
if (multiplayer && P_Random() < 2) if (multiplayer && P_RandomChance(FRACUNIT/128))
{ {
if (P_LookForPlayers(actor, true, false, 0)) if (P_LookForPlayers(actor, true, false, 0))
return; // got a new target return; // got a new target
@ -5871,7 +5866,7 @@ nomissile:
deltay = actor->target->y - actor->y; deltay = actor->target->y - actor->y;
actor->movedir = diags[((deltay < 0)<<1) + (deltax > 0)]; actor->movedir = diags[((deltay < 0)<<1) + (deltax > 0)];
actor->movecount = P_Random() & 15; actor->movecount = P_RandomByte() & 15;
} }
} }
@ -5897,13 +5892,13 @@ void A_Boss2Chase(mobj_t *actor)
// Startup randomness // Startup randomness
if (actor->reactiontime <= -666) if (actor->reactiontime <= -666)
actor->reactiontime = 2*TICRATE + P_Random(); actor->reactiontime = 2*TICRATE + P_RandomByte();
// When reactiontime hits zero, he will go the other way // When reactiontime hits zero, he will go the other way
if (--actor->reactiontime <= 0) if (--actor->reactiontime <= 0)
{ {
reverse = true; reverse = true;
actor->reactiontime = 2*TICRATE + P_Random(); actor->reactiontime = 2*TICRATE + P_RandomByte();
} }
P_SetTarget(&actor->target, P_GetClosestAxis(actor)); P_SetTarget(&actor->target, P_GetClosestAxis(actor));
@ -5990,12 +5985,12 @@ void A_Boss2Chase(mobj_t *actor)
if (actor->info->attacksound) if (actor->info->attacksound)
S_StartAttackSound(actor, actor->info->attacksound); S_StartAttackSound(actor, actor->info->attacksound);
if (P_Random() & 1) if (P_RandomChance(FRACUNIT/2))
{ {
goop->momx *= 2; goop->momx *= 2;
goop->momy *= 2; goop->momy *= 2;
} }
else if (P_Random() > 128) else if (P_RandomChance(129*FRACUNIT/256))
{ {
goop->momx *= 3; goop->momx *= 3;
goop->momy *= 3; goop->momy *= 3;
@ -6153,7 +6148,7 @@ void A_Boss7Chase(mobj_t *actor)
{ {
A_FaceTarget(actor); A_FaceTarget(actor);
P_SetMobjState(actor, S_BLACKEGG_SHOOT1); P_SetMobjState(actor, S_BLACKEGG_SHOOT1);
actor->movecount = TICRATE + P_Random()/2; actor->movecount = TICRATE + P_RandomByte()/2;
return; return;
} }
@ -6162,7 +6157,7 @@ void A_Boss7Chase(mobj_t *actor)
if (actor->reactiontime <= 0 && actor->z == actor->floorz) if (actor->reactiontime <= 0 && actor->z == actor->floorz)
{ {
// Here, we'll call P_Random() and decide what kind of attack to do // Here, we'll call P_RandomByte() and decide what kind of attack to do
switch(actor->threshold) switch(actor->threshold)
{ {
case 0: // Lob cannon balls case 0: // Lob cannon balls
@ -6170,7 +6165,7 @@ void A_Boss7Chase(mobj_t *actor)
{ {
A_FaceTarget(actor); A_FaceTarget(actor);
P_SetMobjState(actor, actor->info->xdeathstate); P_SetMobjState(actor, actor->info->xdeathstate);
actor->movecount = 7*TICRATE + P_Random(); actor->movecount = 7*TICRATE + P_RandomByte();
break; break;
} }
actor->threshold++; actor->threshold++;
@ -6180,9 +6175,9 @@ void A_Boss7Chase(mobj_t *actor)
P_SetMobjState(actor, S_BLACKEGG_SHOOT1); P_SetMobjState(actor, S_BLACKEGG_SHOOT1);
if (actor->health > actor->info->damage) if (actor->health > actor->info->damage)
actor->movecount = TICRATE + P_Random()/3; actor->movecount = TICRATE + P_RandomByte()/3;
else else
actor->movecount = TICRATE + P_Random()/2; actor->movecount = TICRATE + P_RandomByte()/2;
break; break;
case 2: // Homing Missile case 2: // Homing Missile
A_FaceTarget(actor); A_FaceTarget(actor);
@ -6266,8 +6261,8 @@ void A_Boss2PogoSFX(mobj_t *actor)
} }
else else
{ {
UINT8 prandom = P_Random(); UINT8 prandom = P_RandomByte();
actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom);
P_InstaThrust(actor, actor->angle, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); P_InstaThrust(actor, actor->angle, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale));
} }
if (actor->info->activesound) S_StartSound(actor, actor->info->activesound); if (actor->info->activesound) S_StartSound(actor, actor->info->activesound);
@ -6307,10 +6302,10 @@ void A_Boss2PogoTarget(mobj_t *actor)
// Target hit, retreat! // Target hit, retreat!
if (actor->target->player->powers[pw_flashing] > TICRATE || actor->flags2 & MF2_FRET) if (actor->target->player->powers[pw_flashing] > TICRATE || actor->flags2 & MF2_FRET)
{ {
UINT8 prandom = P_Random(); UINT8 prandom = P_RandomByte();
actor->z++; // unstick from the floor actor->z++; // unstick from the floor
actor->momz = FixedMul(locvar1, actor->scale); // Bounce up in air actor->momz = FixedMul(locvar1, actor->scale); // Bounce up in air
actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); // Pick a direction, and randomize it. actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); // Pick a direction, and randomize it.
P_InstaThrust(actor, actor->angle+ANGLE_180, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed P_InstaThrust(actor, actor->angle+ANGLE_180, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed
} }
// Try to land on top of the player. // Try to land on top of the player.
@ -6347,10 +6342,10 @@ void A_Boss2PogoTarget(mobj_t *actor)
// Wander semi-randomly towards the player to get closer. // Wander semi-randomly towards the player to get closer.
else else
{ {
UINT8 prandom = P_Random(); UINT8 prandom = P_RandomByte();
actor->z++; // unstick from the floor actor->z++; // unstick from the floor
actor->momz = FixedMul(locvar1, actor->scale); // Bounce up in air actor->momz = FixedMul(locvar1, actor->scale); // Bounce up in air
actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); // Pick a direction, and randomize it. actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); // Pick a direction, and randomize it.
P_InstaThrust(actor, actor->angle, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed P_InstaThrust(actor, actor->angle, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed
} }
// Boing! // Boing!
@ -7084,7 +7079,7 @@ void A_SmokeTrailer(mobj_t *actor)
P_SetObjectMomZ(th, FRACUNIT, false); P_SetObjectMomZ(th, FRACUNIT, false);
th->destscale = actor->scale; th->destscale = actor->scale;
P_SetScale(th, actor->scale); P_SetScale(th, actor->scale);
th->tics -= P_Random() & 3; th->tics -= P_RandomByte() & 3;
if (th->tics < 1) if (th->tics < 1)
th->tics = 1; th->tics = 1;
} }
@ -7183,7 +7178,7 @@ void A_ChangeAngleRelative(mobj_t *actor)
// rather than the ranges, so <0 and >360 work as possible values. -Red // rather than the ranges, so <0 and >360 work as possible values. -Red
INT32 locvar1 = var1; INT32 locvar1 = var1;
INT32 locvar2 = var2; INT32 locvar2 = var2;
//angle_t angle = (P_Random()+1)<<24; //angle_t angle = (P_RandomByte()+1)<<24;
const fixed_t amin = locvar1*FRACUNIT; const fixed_t amin = locvar1*FRACUNIT;
const fixed_t amax = locvar2*FRACUNIT; const fixed_t amax = locvar2*FRACUNIT;
//const angle_t amin = FixedAngle(locvar1*FRACUNIT); //const angle_t amin = FixedAngle(locvar1*FRACUNIT);
@ -7217,7 +7212,7 @@ void A_ChangeAngleAbsolute(mobj_t *actor)
{ {
INT32 locvar1 = var1; INT32 locvar1 = var1;
INT32 locvar2 = var2; INT32 locvar2 = var2;
//angle_t angle = (P_Random()+1)<<24; //angle_t angle = (P_RandomByte()+1)<<24;
const fixed_t amin = locvar1*FRACUNIT; const fixed_t amin = locvar1*FRACUNIT;
const fixed_t amax = locvar2*FRACUNIT; const fixed_t amax = locvar2*FRACUNIT;
//const angle_t amin = FixedAngle(locvar1*FRACUNIT); //const angle_t amin = FixedAngle(locvar1*FRACUNIT);
@ -7825,7 +7820,7 @@ void A_RandomState(mobj_t *actor)
return; return;
#endif #endif
P_SetMobjState(actor, P_Random()&1 ? locvar1 : locvar2); P_SetMobjState(actor, P_RandomChance(FRACUNIT/2) ? locvar1 : locvar2);
} }
// Function: A_RandomStateRange // Function: A_RandomStateRange
@ -8516,34 +8511,32 @@ void A_SearchForPlayers(mobj_t *actor)
// Function: A_CheckRandom // Function: A_CheckRandom
// //
// Description: Calls a state by chance (around 1/var1). // Description: Calls a state by chance.
// //
// var1 = denominator (can't exceed 100) // var1:
// lower 16 bits = denominator
// upper 16 bits = numerator (defaults to 1 if zero)
// var2 = state number // var2 = state number
// //
void A_CheckRandom(mobj_t *actor) void A_CheckRandom(mobj_t *actor)
{ {
INT32 locvar1 = var1; INT32 locvar1 = var1;
INT32 locvar2 = var2; INT32 locvar2 = var2;
INT32 i, chance; fixed_t chance = FRACUNIT;
INT32 rndadd = 0;
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (LUA_CallAction("A_CheckRandom", actor)) if (LUA_CallAction("A_CheckRandom", actor))
return; return;
#endif #endif
if ((locvar1 & 0xFFFF) == 0)
return;
if(locvar1 > 100) // The PRNG doesn't suck anymore, OK?
locvar1 = 100; if (locvar1 >> 16)
chance *= (locvar1 >> 16);
chance /= (locvar1 & 0xFFFF);
for (i = 0; i < MAXPLAYERS; i++) if (P_RandomChance(chance))
if (playeringame[i])
rndadd += abs((int)players[i].mo->x) + abs((int)players[i].mo->y) + abs((int)players[i].mo->z);
rndadd = rndadd % 10000; //additional component to enlarge random number
chance = (P_Random() + rndadd) % locvar1;
if (chance == 0)
P_SetMobjState(actor, locvar2); P_SetMobjState(actor, locvar2);
} }
@ -9890,7 +9883,7 @@ void A_BrakChase(mobj_t *actor)
S_StartSound(actor, (sfxenum_t)locvar2); S_StartSound(actor, (sfxenum_t)locvar2);
// make active sound // make active sound
if (actor->type != MT_CYBRAKDEMON && actor->info->activesound && P_Random() < 3) if (actor->type != MT_CYBRAKDEMON && actor->info->activesound && P_RandomChance(3*FRACUNIT/256))
{ {
S_StartSound(actor, actor->info->activesound); S_StartSound(actor, actor->info->activesound);
} }

View file

@ -1253,7 +1253,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->target && special->target->state == &states[S_BLACKEGG_SHOOT1]) if (special->target && special->target->state == &states[S_BLACKEGG_SHOOT1])
{ {
if (special->target->health <= 2 && (P_Random() & 1)) if (special->target->health <= 2 && P_RandomChance(FRACUNIT/2))
P_SetMobjState(special->target, special->target->info->missilestate); P_SetMobjState(special->target, special->target->info->missilestate);
else else
P_SetMobjState(special->target, special->target->info->raisestate); P_SetMobjState(special->target, special->target->info->raisestate);
@ -2203,29 +2203,17 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
default: default:
if (target->info->doomednum) if (target->info->doomednum)
prandom = target->info->doomednum%5; // "Random" animal for new enemies.
else
prandom = P_RandomKey(5); // No placable object, just use a random number.
switch(prandom)
{ {
switch(target->info->doomednum%5)
{
default: item = MT_BUNNY; break; default: item = MT_BUNNY; break;
case 1: item = MT_BIRD; break; case 1: item = MT_BIRD; break;
case 2: item = MT_MOUSE; break; case 2: item = MT_MOUSE; break;
case 3: item = MT_COW; break; case 3: item = MT_COW; break;
case 4: item = MT_CHICKEN; break; case 4: item = MT_CHICKEN; break;
}
}
else
{
prandom = P_Random();
if (prandom < 51)
item = MT_BUNNY;
else if (prandom < 102)
item = MT_BIRD;
else if (prandom < 153)
item = MT_MOUSE;
else if (prandom < 204)
item = MT_COW;
else
item = MT_CHICKEN;
} }
break; break;
} }
@ -3103,7 +3091,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// Killing dead. Just for kicks. // Killing dead. Just for kicks.
// Require source and inflictor be player. Don't hurt for firing rings. // Require source and inflictor be player. Don't hurt for firing rings.
if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_Random() < 80) if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_RandomChance(5*FRACUNIT/16))
P_DamageMobj(source, target, target, 1); P_DamageMobj(source, target, target, 1);
// do the damage // do the damage
@ -3617,7 +3605,7 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
P_InstaThrust(flag, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale)); P_InstaThrust(flag, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale));
else else
{ {
angle_t fa = P_Random()*FINEANGLES/256; angle_t fa = P_RandomByte()*FINEANGLES/256;
flag->momx = FixedMul(FINECOSINE(fa), FixedMul(6*FRACUNIT, player->mo->scale)); flag->momx = FixedMul(FINECOSINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale)); flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));

View file

@ -51,7 +51,7 @@ void T_FireFlicker(fireflicker_t *flick)
if (--flick->count) if (--flick->count)
return; return;
amount = (INT16)((UINT8)(P_Random() & 3) * 16); amount = (INT16)((UINT8)(P_RandomByte() & 3) * 16);
if (flick->sector->lightlevel - amount < flick->minlight) if (flick->sector->lightlevel - amount < flick->minlight)
flick->sector->lightlevel = (INT16)flick->minlight; flick->sector->lightlevel = (INT16)flick->minlight;
@ -235,7 +235,7 @@ strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector,
flash->minlight = 0; flash->minlight = 0;
if (!inSync) if (!inSync)
flash->count = (P_Random() & 7) + 1; flash->count = (P_RandomByte() & 7) + 1;
else else
flash->count = 1; flash->count = 1;

View file

@ -1146,13 +1146,17 @@ static boolean PIT_CheckLine(line_t *ld)
{ {
tmceilingz = opentop; tmceilingz = opentop;
ceilingline = ld; ceilingline = ld;
#ifdef ESLOPE
tmceilingslope = opentopslope; tmceilingslope = opentopslope;
#endif
} }
if (openbottom > tmfloorz) if (openbottom > tmfloorz)
{ {
tmfloorz = openbottom; tmfloorz = openbottom;
#ifdef ESLOPE
tmfloorslope = openbottomslope; tmfloorslope = openbottomslope;
#endif
} }
if (highceiling > tmdrpoffceilz) if (highceiling > tmdrpoffceilz)
@ -1965,22 +1969,28 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) #ifdef ESLOPE
// HACK TO FIX DSZ2: apply only if slopes are involved
else if (tmceilingslope && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
{ {
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
#endif
} }
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep) else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
{ {
thing->z = thing->floorz = tmfloorz; thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) #ifdef ESLOPE
// HACK TO FIX DSZ2: apply only if slopes are involved
else if (tmfloorslope && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
{ {
thing->z = thing->floorz = tmfloorz; thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
#endif
} }
if (thing->eflags & MFE_VERTICALFLIP) if (thing->eflags & MFE_VERTICALFLIP)
@ -2051,21 +2061,26 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->ceilingz = tmceilingz; thing->ceilingz = tmceilingz;
#ifdef ESLOPE #ifdef ESLOPE
// Assign thing's standingslope if needed if (!(thing->flags & MF_NOCLIPHEIGHT))
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) { {
if (!startingonground && tmfloorslope) // Assign thing's standingslope if needed
P_HandleSlopeLanding(thing, tmfloorslope); if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) {
if (!startingonground && tmfloorslope)
P_HandleSlopeLanding(thing, tmfloorslope);
if (thing->momz <= 0) if (thing->momz <= 0)
thing->standingslope = tmfloorslope; thing->standingslope = tmfloorslope;
} }
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
if (!startingonground && tmceilingslope) if (!startingonground && tmceilingslope)
P_HandleSlopeLanding(thing, tmceilingslope); P_HandleSlopeLanding(thing, tmceilingslope);
if (thing->momz >= 0) if (thing->momz >= 0)
thing->standingslope = tmceilingslope; thing->standingslope = tmceilingslope;
}
} }
else // don't set standingslope if you're not going to clip against it
thing->standingslope = NULL;
#endif #endif
thing->x = x; thing->x = x;

View file

@ -527,13 +527,17 @@ void P_LineOpening(line_t *linedef)
{ {
opentop = frontheight; opentop = frontheight;
highceiling = backheight; highceiling = backheight;
#ifdef ESLOPE
opentopslope = front->c_slope; opentopslope = front->c_slope;
#endif
} }
else else
{ {
opentop = backheight; opentop = backheight;
highceiling = frontheight; highceiling = frontheight;
#ifdef ESLOPE
opentopslope = back->c_slope; opentopslope = back->c_slope;
#endif
} }
frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef); frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef);
@ -543,13 +547,17 @@ void P_LineOpening(line_t *linedef)
{ {
openbottom = frontheight; openbottom = frontheight;
lowfloor = backheight; lowfloor = backheight;
#ifdef ESLOPE
openbottomslope = front->f_slope; openbottomslope = front->f_slope;
#endif
} }
else else
{ {
openbottom = backheight; openbottom = backheight;
lowfloor = frontheight; lowfloor = frontheight;
#ifdef ESLOPE
openbottomslope = back->f_slope; openbottomslope = back->f_slope;
#endif
} }
} }

View file

@ -38,7 +38,9 @@
// protos. // protos.
static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}}; static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}};
consvar_t cv_viewheight = {"viewheight", VIEWHEIGHTS, 0, viewheight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_viewheight = {"viewheight", VIEWHEIGHTS, 0, viewheight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#ifdef WALLSPLATS
consvar_t cv_splats = {"splats", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_splats = {"splats", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
actioncache_t actioncachehead; actioncache_t actioncachehead;
@ -652,9 +654,9 @@ void P_EmeraldManager(void)
break; break;
if (leveltime < TICRATE) // Start of map if (leveltime < TICRATE) // Start of map
spawnpoints[j]->threshold = 60*TICRATE + P_Random() * (TICRATE/5); spawnpoints[j]->threshold = 60*TICRATE + P_RandomByte() * (TICRATE/5);
else else
spawnpoints[j]->threshold = P_Random() * (TICRATE/5); spawnpoints[j]->threshold = P_RandomByte() * (TICRATE/5);
break; break;
} }
@ -683,26 +685,26 @@ void P_ExplodeMissile(mobj_t *mo)
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx += (P_Random() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy += (P_Random() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_pop); S_StartSound(explodemo, sfx_pop);
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx += (P_Random() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_Random() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_dmpain); S_StartSound(explodemo, sfx_dmpain);
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx -= (P_Random() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy += (P_Random() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_pop); S_StartSound(explodemo, sfx_pop);
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
P_SetScale(explodemo, mo->scale); P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale; explodemo->destscale = mo->destscale;
explodemo->momx -= (P_Random() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_Random() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_cybdth); S_StartSound(explodemo, sfx_cybdth);
// Hack: Release an animal. // Hack: Release an animal.
@ -752,6 +754,7 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover)
return true; return true;
} }
#ifdef ESLOPE
// P_GetFloorZ (and its ceiling counterpart) // P_GetFloorZ (and its ceiling counterpart)
// Gets the floor height (or ceiling height) of the mobj's contact point in sector, assuming object's center if moved to [x, y] // Gets the floor height (or ceiling height) of the mobj's contact point in sector, assuming object's center if moved to [x, y]
// If line is supplied, it's a divider line on the sector. Set it to NULL if you're not checking for collision with a line // If line is supplied, it's a divider line on the sector. Set it to NULL if you're not checking for collision with a line
@ -855,10 +858,13 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line,
P_GetZAt(slope, v2.x, v2.y) P_GetZAt(slope, v2.x, v2.y)
); );
} }
#endif
fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
{ {
#ifdef ESLOPE
I_Assert(mobj != NULL); I_Assert(mobj != NULL);
#endif
I_Assert(sector != NULL); I_Assert(sector != NULL);
#ifdef ESLOPE #ifdef ESLOPE
if (sector->f_slope) { if (sector->f_slope) {
@ -930,13 +936,23 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
return HighestOnLine(mobj->radius, x, y, line, slope, lowest); return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
} else // Well, that makes it easy. Just get the floor height } else // Well, that makes it easy. Just get the floor height
#else
(void)mobj;
(void)boundsec;
(void)x;
(void)y;
(void)line;
(void)lowest;
(void)perfect;
#endif #endif
return sector->floorheight; return sector->floorheight;
} }
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
{ {
#ifdef ESLOPE
I_Assert(mobj != NULL); I_Assert(mobj != NULL);
#endif
I_Assert(sector != NULL); I_Assert(sector != NULL);
#ifdef ESLOPE #ifdef ESLOPE
if (sector->c_slope) { if (sector->c_slope) {
@ -1008,6 +1024,14 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
return HighestOnLine(mobj->radius, x, y, line, slope, lowest); return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
} else // Well, that makes it easy. Just get the ceiling height } else // Well, that makes it easy. Just get the ceiling height
#else
(void)mobj;
(void)boundsec;
(void)x;
(void)y;
(void)line;
(void)lowest;
(void)perfect;
#endif #endif
return sector->ceilingheight; return sector->ceilingheight;
} }
@ -1015,7 +1039,9 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed
// Now do the same as all above, but for cameras because apparently cameras are special? // Now do the same as all above, but for cameras because apparently cameras are special?
fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
{ {
#ifdef ESLOPE
I_Assert(mobj != NULL); I_Assert(mobj != NULL);
#endif
I_Assert(sector != NULL); I_Assert(sector != NULL);
#ifdef ESLOPE #ifdef ESLOPE
if (sector->f_slope) { if (sector->f_slope) {
@ -1087,13 +1113,23 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix
return HighestOnLine(mobj->radius, x, y, line, slope, lowest); return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
} else // Well, that makes it easy. Just get the floor height } else // Well, that makes it easy. Just get the floor height
#else
(void)mobj;
(void)boundsec;
(void)x;
(void)y;
(void)line;
(void)lowest;
(void)perfect;
#endif #endif
return sector->floorheight; return sector->floorheight;
} }
fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
{ {
#ifdef ESLOPE
I_Assert(mobj != NULL); I_Assert(mobj != NULL);
#endif
I_Assert(sector != NULL); I_Assert(sector != NULL);
#ifdef ESLOPE #ifdef ESLOPE
if (sector->c_slope) { if (sector->c_slope) {
@ -1165,6 +1201,14 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
return HighestOnLine(mobj->radius, x, y, line, slope, lowest); return HighestOnLine(mobj->radius, x, y, line, slope, lowest);
} else // Well, that makes it easy. Just get the ceiling height } else // Well, that makes it easy. Just get the ceiling height
#else
(void)mobj;
(void)boundsec;
(void)x;
(void)y;
(void)line;
(void)lowest;
(void)perfect;
#endif #endif
return sector->ceilingheight; return sector->ceilingheight;
} }
@ -2106,8 +2150,13 @@ static boolean P_ZMovement(mobj_t *mo)
I_Assert(!P_MobjWasRemoved(mo)); I_Assert(!P_MobjWasRemoved(mo));
#ifdef ESLOPE #ifdef ESLOPE
if (mo->standingslope && !P_IsObjectOnGround(mo)) if (mo->standingslope)
{
if (mo->flags & MF_NOCLIPHEIGHT)
mo->standingslope = NULL;
else if (!P_IsObjectOnGround(mo))
P_SlopeLaunch(mo); P_SlopeLaunch(mo);
}
#endif #endif
// Intercept the stupid 'fall through 3dfloors' bug // Intercept the stupid 'fall through 3dfloors' bug
@ -2405,12 +2454,12 @@ static boolean P_ZMovement(mobj_t *mo)
// If deafed, give the tumbleweed another random kick if it runs out of steam. // If deafed, give the tumbleweed another random kick if it runs out of steam.
mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale);
if (P_Random() & 1) if (P_RandomChance(FRACUNIT/2))
mom.x += FixedMul(6*FRACUNIT, mo->scale); mom.x += FixedMul(6*FRACUNIT, mo->scale);
else else
mom.x -= FixedMul(6*FRACUNIT, mo->scale); mom.x -= FixedMul(6*FRACUNIT, mo->scale);
if (P_Random() & 1) if (P_RandomChance(FRACUNIT/2))
mom.y += FixedMul(6*FRACUNIT, mo->scale); mom.y += FixedMul(6*FRACUNIT, mo->scale);
else else
mom.y -= FixedMul(6*FRACUNIT, mo->scale); mom.y -= FixedMul(6*FRACUNIT, mo->scale);
@ -2588,8 +2637,13 @@ static void P_PlayerZMovement(mobj_t *mo)
return; return;
#ifdef ESLOPE #ifdef ESLOPE
if (mo->standingslope && !P_IsObjectOnGround(mo)) if (mo->standingslope)
{
if (mo->flags & MF_NOCLIPHEIGHT)
mo->standingslope = NULL;
else if (!P_IsObjectOnGround(mo))
P_SlopeLaunch(mo); P_SlopeLaunch(mo);
}
#endif #endif
// clip movement // clip movement
@ -2886,7 +2940,7 @@ static boolean P_SceneryZMovement(mobj_t *mo)
for (i = 0; i < 4; ++i) // split into four for (i = 0; i < 4; ++i) // split into four
{ {
prandom = P_Random(); prandom = P_RandomByte();
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_SMALLBUBBLE); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_SMALLBUBBLE);
explodemo->momx += ((prandom & 0x0F) << (FRACBITS-2)) * (i & 2 ? -1 : 1); explodemo->momx += ((prandom & 0x0F) << (FRACBITS-2)) * (i & 2 ? -1 : 1);
explodemo->momy += ((prandom & 0xF0) << (FRACBITS-6)) * (i & 1 ? -1 : 1); explodemo->momy += ((prandom & 0xF0) << (FRACBITS-6)) * (i & 1 ? -1 : 1);
@ -3218,13 +3272,13 @@ void P_MobjCheckWater(mobj_t *mobj)
// Create tons of bubbles // Create tons of bubbles
for (i = 0; i < bubblecount; i++) for (i = 0; i < bubblecount; i++)
{ {
// P_Random()s are called individually to allow consistency // P_RandomByte()s are called individually to allow consistency
// across various compilers, since the order of function calls // across various compilers, since the order of function calls
// in C is not part of the ANSI specification. // in C is not part of the ANSI specification.
prandom[0] = P_Random(); prandom[0] = P_RandomByte();
prandom[1] = P_Random(); prandom[1] = P_RandomByte();
prandom[2] = P_Random(); prandom[2] = P_RandomByte();
prandom[3] = P_Random(); prandom[3] = P_RandomByte();
bubbletype = MT_SMALLBUBBLE; bubbletype = MT_SMALLBUBBLE;
if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32 if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32
@ -3698,10 +3752,15 @@ static void CalculatePrecipFloor(precipmobj_t *mobj)
mobjsecsubsec = mobj->subsector->sector; mobjsecsubsec = mobj->subsector->sector;
else else
return; return;
mobj->floorz = mobjsecsubsec->floorheight; mobj->floorz =
#ifdef ESLOPE
mobjsecsubsec->f_slope ? P_GetZAt(mobjsecsubsec->f_slope, mobj->x, mobj->y) :
#endif
mobjsecsubsec->floorheight;
if (mobjsecsubsec->ffloors) if (mobjsecsubsec->ffloors)
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t topheight;
for (rover = mobjsecsubsec->ffloors; rover; rover = rover->next) for (rover = mobjsecsubsec->ffloors; rover; rover = rover->next)
{ {
@ -3712,8 +3771,15 @@ static void CalculatePrecipFloor(precipmobj_t *mobj)
if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE)) if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE))
continue; continue;
if (*rover->topheight > mobj->floorz) #ifdef ESLOPE
mobj->floorz = *rover->topheight; if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y);
else
#endif
topheight = *rover->topheight;
if (topheight > mobj->floorz)
mobj->floorz = topheight;
} }
} }
} }
@ -3826,7 +3892,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest)
// first time init, this allow minimum lastlook changes // first time init, this allow minimum lastlook changes
if (actor->lastlook < 0) if (actor->lastlook < 0)
actor->lastlook = P_Random(); actor->lastlook = P_RandomByte();
actor->lastlook &= PLAYERSMASK; actor->lastlook &= PLAYERSMASK;
for( ; ; actor->lastlook = (actor->lastlook+1) & PLAYERSMASK) for( ; ; actor->lastlook = (actor->lastlook+1) & PLAYERSMASK)
@ -4707,7 +4773,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
if (mobj->state == &states[S_BLACKEGG_STND] && mobj->tics == mobj->state->tics) if (mobj->state == &states[S_BLACKEGG_STND] && mobj->tics == mobj->state->tics)
{ {
mobj->reactiontime += P_Random(); mobj->reactiontime += P_RandomByte();
if (mobj->health <= mobj->info->damage) if (mobj->health <= mobj->info->damage)
mobj->reactiontime /= 4; mobj->reactiontime /= 4;
@ -4901,7 +4967,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
if (mobj->tracer && mobj->tracer->type == MT_BOSS3WAYPOINT if (mobj->tracer && mobj->tracer->type == MT_BOSS3WAYPOINT
&& mobj->tracer->spawnpoint && (mobj->tracer->spawnpoint->options & 7) == waypointNum) && mobj->tracer->spawnpoint && (mobj->tracer->spawnpoint->options & 7) == waypointNum)
{ {
if (P_Random() & 1) if (P_RandomChance(FRACUNIT/2))
waypointNum++; waypointNum++;
else else
waypointNum--; waypointNum--;
@ -4913,7 +4979,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
} }
if (waypointNum == 0 && mobj->health <= mobj->info->damage) if (waypointNum == 0 && mobj->health <= mobj->info->damage)
waypointNum = 1 + (P_Random() & 1); waypointNum = 1 + (P_RandomFixed() & 1);
// scan the thinkers to find // scan the thinkers to find
// the waypoint to use // the waypoint to use
@ -5013,7 +5079,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
P_SetMobjState(mobj, mobj->info->spawnstate); P_SetMobjState(mobj, mobj->info->spawnstate);
} }
else if (mobj->state == &states[mobj->info->deathstate] && mobj->tics == mobj->state->tics) else if (mobj->state == &states[mobj->info->deathstate] && mobj->tics == mobj->state->tics)
S_StartSound(0, sfx_bedie1 + (P_Random() & 1)); S_StartSound(0, sfx_bedie1 + (P_RandomFixed() & 1));
} }
@ -5440,7 +5506,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
// An incoming attack is detected! What should we do?! // An incoming attack is detected! What should we do?!
// Go into vector form! // Go into vector form!
mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))); mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS)));
if (P_Random()&1) if (P_RandomChance(FRACUNIT/2))
mobj->movedir = InvAngle(mobj->movedir); mobj->movedir = InvAngle(mobj->movedir);
mobj->threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))>>FRACBITS); mobj->threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))>>FRACBITS);
if (mobj->info->activesound) if (mobj->info->activesound)
@ -6042,20 +6108,20 @@ static void P_KoopaThinker(mobj_t *koopa)
P_XYMovement(koopa); P_XYMovement(koopa);
if (P_Random() < 8 && koopa->z <= koopa->floorz) if (P_RandomChance(FRACUNIT/32) && koopa->z <= koopa->floorz)
koopa->momz = FixedMul(5*FRACUNIT, koopa->scale); koopa->momz = FixedMul(5*FRACUNIT, koopa->scale);
if (koopa->z > koopa->floorz) if (koopa->z > koopa->floorz)
koopa->momz += FixedMul(FRACUNIT/4, koopa->scale); koopa->momz += FixedMul(FRACUNIT/4, koopa->scale);
if (P_Random() < 4) if (P_RandomChance(FRACUNIT/64))
{ {
mobj_t *flame; mobj_t *flame;
flame = P_SpawnMobj(koopa->x - koopa->radius + FixedMul(5*FRACUNIT, koopa->scale), koopa->y, koopa->z + (P_Random()<<(FRACBITS-2)), MT_KOOPAFLAME); flame = P_SpawnMobj(koopa->x - koopa->radius + FixedMul(5*FRACUNIT, koopa->scale), koopa->y, koopa->z + (P_RandomByte()<<(FRACBITS-2)), MT_KOOPAFLAME);
flame->momx = -FixedMul(flame->info->speed, flame->scale); flame->momx = -FixedMul(flame->info->speed, flame->scale);
S_StartSound(flame, sfx_koopfr); S_StartSound(flame, sfx_koopfr);
} }
else if (P_Random() > 250) else if (P_RandomChance(5*FRACUNIT/256))
{ {
mobj_t *hammer; mobj_t *hammer;
hammer = P_SpawnMobj(koopa->x - koopa->radius, koopa->y, koopa->z + koopa->height, MT_HAMMER); hammer = P_SpawnMobj(koopa->x - koopa->radius, koopa->y, koopa->z + koopa->height, MT_HAMMER);
@ -6499,11 +6565,11 @@ void P_MobjThinker(mobj_t *mobj)
fixed_t ns; fixed_t ns;
mobj_t *mo2; mobj_t *mo2;
i = P_Random(); i = P_RandomByte();
z = mobj->subsector->sector->floorheight + ((P_Random()&63)*FRACUNIT); z = mobj->subsector->sector->floorheight + ((P_RandomByte()&63)*FRACUNIT);
for (j = 0; j < 2; j++) for (j = 0; j < 2; j++)
{ {
const angle_t fa = (P_Random()*FINEANGLES/16) & FINEMASK; const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK;
ns = 64 * FRACUNIT; ns = 64 * FRACUNIT;
x = mobj->x + FixedMul(FINESINE(fa),ns); x = mobj->x + FixedMul(FINESINE(fa),ns);
y = mobj->y + FixedMul(FINECOSINE(fa),ns); y = mobj->y + FixedMul(FINECOSINE(fa),ns);
@ -6513,7 +6579,7 @@ void P_MobjThinker(mobj_t *mobj)
mo2->momx = FixedMul(FINESINE(fa),ns); mo2->momx = FixedMul(FINESINE(fa),ns);
mo2->momy = FixedMul(FINECOSINE(fa),ns); mo2->momy = FixedMul(FINECOSINE(fa),ns);
i = P_Random(); i = P_RandomByte();
if (i % 5 == 0) if (i % 5 == 0)
P_SpawnMobj(x, y, z, MT_CHICKEN); P_SpawnMobj(x, y, z, MT_CHICKEN);
@ -7753,6 +7819,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
{ {
state_t *st; state_t *st;
precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
fixed_t starting_floorz;
mobj->x = x; mobj->x = x;
mobj->y = y; mobj->y = y;
@ -7771,8 +7838,16 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
// set subsector and/or block links // set subsector and/or block links
P_SetPrecipitationThingPosition(mobj); P_SetPrecipitationThingPosition(mobj);
mobj->floorz = mobj->subsector->sector->floorheight; mobj->floorz = starting_floorz =
mobj->ceilingz = mobj->subsector->sector->ceilingheight; #ifdef ESLOPE
mobj->subsector->sector->f_slope ? P_GetZAt(mobj->subsector->sector->f_slope, x, y) :
#endif
mobj->subsector->sector->floorheight;
mobj->ceilingz =
#ifdef ESLOPE
mobj->subsector->sector->c_slope ? P_GetZAt(mobj->subsector->sector->c_slope, x, y) :
#endif
mobj->subsector->sector->ceilingheight;
mobj->z = z; mobj->z = z;
mobj->momz = mobjinfo[type].speed; mobj->momz = mobjinfo[type].speed;
@ -7782,7 +7857,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
CalculatePrecipFloor(mobj); CalculatePrecipFloor(mobj);
if (mobj->floorz != mobj->subsector->sector->floorheight) if (mobj->floorz != starting_floorz)
mobj->precipflags |= PCF_FOF; mobj->precipflags |= PCF_FOF;
else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7 else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7
|| GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6 || GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6
@ -7999,7 +8074,7 @@ void P_SpawnPrecipitation(void)
continue; continue;
rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE); rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE);
mrand = M_Random(); mrand = M_RandomByte();
if (mrand < 64) if (mrand < 64)
P_SetPrecipMobjState(rainmo, S_SNOW3); P_SetPrecipMobjState(rainmo, S_SNOW3);
else if (mrand < 144) else if (mrand < 144)
@ -8209,7 +8284,11 @@ void P_RespawnSpecials(void)
if (mthing->options & MTF_OBJECTFLIP) if (mthing->options & MTF_OBJECTFLIP)
{ {
z = ss->sector->ceilingheight - (mthing->options >> ZSHIFT) * FRACUNIT; z = (
#ifdef ESLOPE
ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) :
#endif
ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT;
if (mthing->options & MTF_AMBUSH if (mthing->options & MTF_AMBUSH
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i)))
z -= 24*FRACUNIT; z -= 24*FRACUNIT;
@ -8217,7 +8296,11 @@ void P_RespawnSpecials(void)
} }
else else
{ {
z = ss->sector->floorheight + (mthing->options >> ZSHIFT) * FRACUNIT; z = (
#ifdef ESLOPE
ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) :
#endif
ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT;
if (mthing->options & MTF_AMBUSH if (mthing->options & MTF_AMBUSH
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i)))
z += 24*FRACUNIT; z += 24*FRACUNIT;
@ -8387,7 +8470,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
fixed_t z; fixed_t z;
sector_t *sector; sector_t *sector;
fixed_t floor, ceiling;
player_t *p = &players[playernum]; player_t *p = &players[playernum];
mobj_t *mobj = p->mo; mobj_t *mobj = p->mo;
@ -8403,19 +8486,31 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
// set Z height // set Z height
sector = R_PointInSubsector(x, y)->sector; sector = R_PointInSubsector(x, y)->sector;
floor =
#ifdef ESLOPE
sector->f_slope ? P_GetZAt(sector->f_slope, x, y) :
#endif
sector->floorheight;
ceiling =
#ifdef ESLOPE
sector->c_slope ? P_GetZAt(sector->c_slope, x, y) :
#endif
sector->ceilingheight;
if (mthing) if (mthing)
{ {
// Flagging a player's ambush will make them start on the ceiling // Flagging a player's ambush will make them start on the ceiling
// Objectflip inverts // Objectflip inverts
if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP)) if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP))
{ {
z = sector->ceilingheight - mobjinfo[MT_PLAYER].height; z = ceiling - mobjinfo[MT_PLAYER].height;
if (mthing->options >> ZSHIFT) if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS); z -= ((mthing->options >> ZSHIFT) << FRACBITS);
} }
else else
{ {
z = sector->floorheight; z = floor;
if (mthing->options >> ZSHIFT) if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS); z += ((mthing->options >> ZSHIFT) << FRACBITS);
} }
@ -8427,15 +8522,15 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
} }
} }
else else
z = sector->floorheight; z = floor;
if (z < sector->floorheight) if (z < floor)
z = sector->floorheight; z = floor;
else if (z > sector->ceilingheight - mobjinfo[MT_PLAYER].height) else if (z > ceiling - mobjinfo[MT_PLAYER].height)
z = sector->ceilingheight - mobjinfo[MT_PLAYER].height; z = ceiling - mobjinfo[MT_PLAYER].height;
mobj->floorz = sector->floorheight; mobj->floorz = floor;
mobj->ceilingz = sector->ceilingheight; mobj->ceilingz = ceiling;
P_UnsetThingPosition(mobj); P_UnsetThingPosition(mobj);
mobj->x = x; mobj->x = x;
@ -8443,7 +8538,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
mobj->z = z; mobj->z = z;
if (mobj->z == sector->floorheight) if (mobj->z == mobj->floorz)
mobj->eflags |= MFE_ONGROUND; mobj->eflags |= MFE_ONGROUND;
mobj->angle = angle; mobj->angle = angle;
@ -8455,6 +8550,7 @@ void P_MovePlayerToStarpost(INT32 playernum)
{ {
fixed_t z; fixed_t z;
sector_t *sector; sector_t *sector;
fixed_t floor, ceiling;
player_t *p = &players[playernum]; player_t *p = &players[playernum];
mobj_t *mobj = p->mo; mobj_t *mobj = p->mo;
@ -8466,14 +8562,25 @@ void P_MovePlayerToStarpost(INT32 playernum)
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
sector = R_PointInSubsector(mobj->x, mobj->y)->sector; sector = R_PointInSubsector(mobj->x, mobj->y)->sector;
z = p->starpostz << FRACBITS; floor =
if (z < sector->floorheight) #ifdef ESLOPE
z = sector->floorheight; sector->f_slope ? P_GetZAt(sector->f_slope, mobj->x, mobj->y) :
else if (z > sector->ceilingheight - mobjinfo[MT_PLAYER].height) #endif
z = sector->ceilingheight - mobjinfo[MT_PLAYER].height; sector->floorheight;
ceiling =
#ifdef ESLOPE
sector->c_slope ? P_GetZAt(sector->c_slope, mobj->x, mobj->y) :
#endif
sector->ceilingheight;
mobj->floorz = sector->floorheight; z = p->starpostz << FRACBITS;
mobj->ceilingz = sector->ceilingheight; if (z < floor)
z = floor;
else if (z > ceiling - mobjinfo[MT_PLAYER].height)
z = ceiling - mobjinfo[MT_PLAYER].height;
mobj->floorz = floor;
mobj->ceilingz = ceiling;
mobj->z = z; mobj->z = z;
if (mobj->z == mobj->floorz) if (mobj->z == mobj->floorz)
@ -9167,12 +9274,12 @@ ML_NOCLIMB : Direction not controllable
{ {
mobj->momz += FixedMul(16*FRACUNIT, mobj->scale); mobj->momz += FixedMul(16*FRACUNIT, mobj->scale);
if (P_Random() & 1) if (P_RandomChance(FRACUNIT/2))
mobj->momx += FixedMul(16*FRACUNIT, mobj->scale); mobj->momx += FixedMul(16*FRACUNIT, mobj->scale);
else else
mobj->momx -= FixedMul(16*FRACUNIT, mobj->scale); mobj->momx -= FixedMul(16*FRACUNIT, mobj->scale);
if (P_Random() & 1) if (P_RandomChance(FRACUNIT/2))
mobj->momy += FixedMul(16*FRACUNIT, mobj->scale); mobj->momy += FixedMul(16*FRACUNIT, mobj->scale);
else else
mobj->momy -= FixedMul(16*FRACUNIT,mobj->scale); mobj->momy -= FixedMul(16*FRACUNIT,mobj->scale);

View file

@ -924,8 +924,12 @@ typedef enum
MD2_EXTVAL1 = 1<<5, MD2_EXTVAL1 = 1<<5,
MD2_EXTVAL2 = 1<<6, MD2_EXTVAL2 = 1<<6,
MD2_HNEXT = 1<<7, MD2_HNEXT = 1<<7,
#ifdef ESLOPE
MD2_HPREV = 1<<8, MD2_HPREV = 1<<8,
MD2_SLOPE = 1<<9 MD2_SLOPE = 1<<9
#else
MD2_HPREV = 1<<8
#endif
} mobj_diff2_t; } mobj_diff2_t;
typedef enum typedef enum
@ -1115,8 +1119,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_HNEXT; diff2 |= MD2_HNEXT;
if (mobj->hprev) if (mobj->hprev)
diff2 |= MD2_HPREV; diff2 |= MD2_HPREV;
#ifdef ESLOPE
if (mobj->standingslope) if (mobj->standingslope)
diff2 |= MD2_SLOPE; diff2 |= MD2_SLOPE;
#endif
if (diff2 != 0) if (diff2 != 0)
diff |= MD_MORE; diff |= MD_MORE;
@ -1232,8 +1238,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT32(save_p, mobj->hnext->mobjnum); WRITEUINT32(save_p, mobj->hnext->mobjnum);
if (diff2 & MD2_HPREV) if (diff2 & MD2_HPREV)
WRITEUINT32(save_p, mobj->hprev->mobjnum); WRITEUINT32(save_p, mobj->hprev->mobjnum);
#ifdef ESLOPE
if (diff2 & MD2_SLOPE) if (diff2 & MD2_SLOPE)
WRITEUINT16(save_p, mobj->standingslope->id); WRITEUINT16(save_p, mobj->standingslope->id);
#endif
WRITEUINT32(save_p, mobj->mobjnum); WRITEUINT32(save_p, mobj->mobjnum);
} }
@ -2087,8 +2095,10 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p); mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_HPREV) if (diff2 & MD2_HPREV)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
#ifdef ESLOPE
if (diff2 & MD2_SLOPE) if (diff2 & MD2_SLOPE)
mobj->standingslope = P_SlopeById(READUINT16(save_p)); mobj->standingslope = P_SlopeById(READUINT16(save_p));
#endif
if (diff & MD_REDFLAG) if (diff & MD_REDFLAG)

View file

@ -1099,6 +1099,9 @@ void P_ButteredSlope(mobj_t *mo)
if (!mo->standingslope) if (!mo->standingslope)
return; return;
if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY))
return; // don't slide down slopes if you can't touch them or you're not affected by gravity
if (mo->player) { if (mo->player) {
if (abs(mo->standingslope->zdelta) < FRACUNIT/4 && !(mo->player->pflags & PF_SPINNING)) if (abs(mo->standingslope->zdelta) < FRACUNIT/4 && !(mo->player->pflags & PF_SPINNING))
return; // Don't slide on non-steep slopes unless spinning return; // Don't slide on non-steep slopes unless spinning

View file

@ -2059,7 +2059,7 @@ void P_SwitchWeather(INT32 weathernum)
precipmobj = (precipmobj_t *)think; precipmobj = (precipmobj_t *)think;
precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags; precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags;
z = M_Random(); z = M_RandomByte();
if (z < 64) if (z < 64)
z = 2; z = 2;
@ -4672,8 +4672,10 @@ void P_UpdateSpecials(void)
// POINT LIMIT // POINT LIMIT
P_CheckPointLimit(); P_CheckPointLimit();
#ifdef ESLOPE
// Dynamic slopeness // Dynamic slopeness
P_RunDynamicSlopes(); P_RunDynamicSlopes();
#endif
// ANIMATE TEXTURES // ANIMATE TEXTURES
for (anim = anims; anim < lastanim; anim++) for (anim = anims; anim < lastanim; anim++)

View file

@ -363,7 +363,7 @@ static void P_DoAutobalanceTeams(void)
{ {
if (totalred > totalblue) if (totalred > totalblue)
{ {
i = M_Random() % red; i = M_RandomKey(red);
NetPacket.packet.newteam = 2; NetPacket.packet.newteam = 2;
NetPacket.packet.playernum = redarray[i]; NetPacket.packet.playernum = redarray[i];
NetPacket.packet.verification = true; NetPacket.packet.verification = true;
@ -375,7 +375,7 @@ static void P_DoAutobalanceTeams(void)
if (totalblue > totalred) if (totalblue > totalred)
{ {
i = M_Random() % blue; i = M_RandomKey(blue);
NetPacket.packet.newteam = 1; NetPacket.packet.newteam = 1;
NetPacket.packet.playernum = bluearray[i]; NetPacket.packet.playernum = bluearray[i];
NetPacket.packet.verification = true; NetPacket.packet.verification = true;

View file

@ -2172,9 +2172,9 @@ static void P_DoBubbleBreath(player_t *player)
if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !(player->pflags & PF_NIGHTSMODE)) || player->spectator) if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !(player->pflags & PF_NIGHTSMODE)) || player->spectator)
return; return;
if (!(P_Random() % 16)) if (P_RandomChance(FRACUNIT/16))
bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_SMALLBUBBLE); bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_SMALLBUBBLE);
else if (!(P_Random() % 96)) else if (P_RandomChance(3*FRACUNIT/256))
bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_MEDIUMBUBBLE); bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_MEDIUMBUBBLE);
if (bubble) if (bubble)
{ {
@ -6180,6 +6180,14 @@ void P_ElementalFireTrail(player_t *player)
{ {
newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale));
newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); newy = player->mo->y + P_ReturnThrustY(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale));
#ifdef ESLOPE
if (player->mo->standingslope)
{
ground = P_GetZAt(player->mo->standingslope, newx, newy);
if (player->mo->eflags & MFE_VERTICALFLIP)
ground -= FixedMul(mobjinfo[MT_SPINFIRE].height, player->mo->scale);
}
#endif
flame = P_SpawnMobj(newx, newy, ground, MT_SPINFIRE); flame = P_SpawnMobj(newx, newy, ground, MT_SPINFIRE);
P_SetTarget(&flame->target, player->mo); P_SetTarget(&flame->target, player->mo);
flame->angle = travelangle; flame->angle = travelangle;
@ -6620,7 +6628,7 @@ static void P_MovePlayer(player_t *player)
// Little water sound while touching water - just a nicety. // Little water sound while touching water - just a nicety.
if ((player->mo->eflags & MFE_TOUCHWATER) && !(player->mo->eflags & MFE_UNDERWATER) && !player->spectator) if ((player->mo->eflags & MFE_TOUCHWATER) && !(player->mo->eflags & MFE_UNDERWATER) && !player->spectator)
{ {
if (P_Random() & 1 && leveltime % TICRATE == 0) if (P_RandomChance(FRACUNIT/2) && leveltime % TICRATE == 0)
S_StartSound(player->mo, sfx_floush); S_StartSound(player->mo, sfx_floush);
} }
@ -6834,7 +6842,7 @@ static void P_MovePlayer(player_t *player)
} }
} }
// Super Sonic move // Super Sonic move
if (player->charflags & SF_SUPER && player->powers[pw_super] && player->speed > FixedMul(5<<FRACBITS, player->mo->scale) if (player->skin == 0 && player->powers[pw_super] && player->speed > FixedMul(5<<FRACBITS, player->mo->scale)
&& P_MobjFlip(player->mo)*player->mo->momz <= 0) && P_MobjFlip(player->mo)*player->mo->momz <= 0)
{ {
if (player->panim == PA_ROLL || player->mo->state == &states[S_PLAY_PAIN]) if (player->panim == PA_ROLL || player->mo->state == &states[S_PLAY_PAIN])
@ -7512,8 +7520,6 @@ boolean P_LookForEnemies(player_t *player)
if (an > ANGLE_90 && an < ANGLE_270) if (an > ANGLE_90 && an < ANGLE_270)
continue; // behind back continue; // behind back
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, mo->x, mo->y);
if (!P_CheckSight(player->mo, mo)) if (!P_CheckSight(player->mo, mo))
continue; // out of sight continue; // out of sight
@ -7524,6 +7530,7 @@ boolean P_LookForEnemies(player_t *player)
{ {
// Found a target monster // Found a target monster
P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, closestmo)); P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, closestmo));
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, closestmo->x, closestmo->y);
return true; return true;
} }
@ -8440,7 +8447,7 @@ static boolean P_SpectatorJoinGame(player_t *player)
else if (redscore > bluescore) else if (redscore > bluescore)
changeto = 2; changeto = 2;
else else
changeto = (P_Random() & 1) + 1; changeto = (P_RandomFixed() & 1) + 1;
if (player->mo) if (player->mo)
{ {
@ -8691,7 +8698,7 @@ void P_PlayerThink(player_t *player)
// Add some extra randomization. // Add some extra randomization.
if (cmd->forwardmove) if (cmd->forwardmove)
P_Random(); P_RandomFixed();
#ifdef PARANOIA #ifdef PARANOIA
if (player->playerstate == PST_REBORN) if (player->playerstate == PST_REBORN)

View file

@ -462,26 +462,64 @@ static void R_AddLine(seg_t *line)
// Closed door. // Closed door.
#ifdef ESLOPE #ifdef ESLOPE
// Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)
// random renderer stopping around slopes...
if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope))
#endif
if (backsector->ceilingheight <= frontsector->floorheight
|| backsector->floorheight >= frontsector->ceilingheight)
{ {
goto clipsolid; fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \
end1 = P_GetZAt(slope, line->v1->x, line->v1->y); \
end2 = P_GetZAt(slope, line->v2->x, line->v2->y); \
} else \
end1 = end2 = normalheight;
SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector->floorheight)
SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight)
SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector->floorheight)
SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight)
#undef SLOPEPARAMS
if ((backc1 <= frontf1 && backc2 <= frontf2)
|| (backf1 >= frontc1 && backf2 >= frontc2))
{
goto clipsolid;
}
// Check for automap fix. Store in doorclosed for r_segs.c
doorclosed = (backc1 <= backf1 && backc2 <= backf2
&& ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture)
&& ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture)
&& (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum));
if (doorclosed)
goto clipsolid;
// Window.
if (backc1 != frontc1 || backc2 != frontc2
|| backf1 != frontf1 || backf2 != frontf2)
{
goto clippass;
}
} }
else
// Check for automap fix. Store in doorclosed for r_segs.c #endif
doorclosed = R_DoorClosed();
if (doorclosed)
goto clipsolid;
// Window.
if (backsector->ceilingheight != frontsector->ceilingheight
|| backsector->floorheight != frontsector->floorheight)
{ {
goto clippass; if (backsector->ceilingheight <= frontsector->floorheight
|| backsector->floorheight >= frontsector->ceilingheight)
{
goto clipsolid;
}
// Check for automap fix. Store in doorclosed for r_segs.c
doorclosed = R_DoorClosed();
if (doorclosed)
goto clipsolid;
// Window.
if (backsector->ceilingheight != frontsector->ceilingheight
|| backsector->floorheight != frontsector->floorheight)
{
goto clippass;
}
} }
// Reject empty lines used for triggers and special events. // Reject empty lines used for triggers and special events.
@ -966,7 +1004,7 @@ static void R_Subsector(size_t num)
|| (viewz > heightcheck && (rover->flags & FF_BOTHPLANES)))) || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES))))
{ {
light = R_GetPlaneLight(frontsector, planecenterz, light = R_GetPlaneLight(frontsector, planecenterz,
viewz < *rover->bottomheight); viewz < heightcheck);
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
@ -984,12 +1022,7 @@ static void R_Subsector(size_t num)
frontsector->hasslope = true; frontsector->hasslope = true;
#endif #endif
ffloor[numffloors].height = ffloor[numffloors].height = heightcheck;
#ifdef ESLOPE
*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) :
#endif
*rover->bottomheight;
ffloor[numffloors].ffloor = rover; ffloor[numffloors].ffloor = rover;
numffloors++; numffloors++;
} }
@ -1014,7 +1047,7 @@ static void R_Subsector(size_t num)
&& ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES)) && ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES))
|| (viewz < heightcheck && (rover->flags & FF_BOTHPLANES)))) || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES))))
{ {
light = R_GetPlaneLight(frontsector, planecenterz, viewz < *rover->topheight); light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
@ -1032,12 +1065,7 @@ static void R_Subsector(size_t num)
frontsector->hasslope = true; frontsector->hasslope = true;
#endif #endif
ffloor[numffloors].height = ffloor[numffloors].height = heightcheck;
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) :
#endif
*rover->topheight;
ffloor[numffloors].ffloor = rover; ffloor[numffloors].ffloor = rover;
numffloors++; numffloors++;
} }

View file

@ -801,4 +801,6 @@ void R_DrawViewBorder(void)
// INCLUDE 16bpp DRAWING CODE HERE // INCLUDE 16bpp DRAWING CODE HERE
// ========================================================================== // ==========================================================================
#ifdef HIGHCOLOR
#include "r_draw16.c" #include "r_draw16.c"
#endif

View file

@ -169,11 +169,13 @@ void R_DrawColumnShadowed_8(void);
// 16bpp DRAWING CODE // 16bpp DRAWING CODE
// ------------------ // ------------------
#ifdef HIGHCOLOR
void R_DrawColumn_16(void); void R_DrawColumn_16(void);
void R_DrawWallColumn_16(void); void R_DrawWallColumn_16(void);
void R_DrawTranslucentColumn_16(void); void R_DrawTranslucentColumn_16(void);
void R_DrawTranslatedColumn_16(void); void R_DrawTranslatedColumn_16(void);
void R_DrawSpan_16(void); void R_DrawSpan_16(void);
#endif
// ========================================================================= // =========================================================================
#endif // __R_DRAW__ #endif // __R_DRAW__

View file

@ -517,7 +517,9 @@ static void R_InitTextureMapping(void)
focallength = FixedDiv(centerxfrac, focallength = FixedDiv(centerxfrac,
FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2));
#ifdef ESLOPE
focallengthf = FIXED_TO_FLOAT(focallength); focallengthf = FIXED_TO_FLOAT(focallength);
#endif
for (i = 0; i < FINEANGLES/2; i++) for (i = 0; i < FINEANGLES/2; i++)
{ {
@ -971,14 +973,42 @@ void R_SkyboxFrame(player_t *player)
{ {
if (skyboxmo[1]) if (skyboxmo[1])
{ {
fixed_t x = 0, y = 0;
if (mh->skybox_scalex > 0) if (mh->skybox_scalex > 0)
viewx += (player->mo->x - skyboxmo[1]->x) / mh->skybox_scalex; x = (player->mo->x - skyboxmo[1]->x) / mh->skybox_scalex;
else if (mh->skybox_scalex < 0) else if (mh->skybox_scalex < 0)
viewx += (player->mo->x - skyboxmo[1]->x) * -mh->skybox_scalex; x = (player->mo->x - skyboxmo[1]->x) * -mh->skybox_scalex;
if (mh->skybox_scaley > 0) if (mh->skybox_scaley > 0)
viewy += (player->mo->y - skyboxmo[1]->y) / mh->skybox_scaley; y = (player->mo->y - skyboxmo[1]->y) / mh->skybox_scaley;
else if (mh->skybox_scaley < 0) else if (mh->skybox_scaley < 0)
viewy += (player->mo->y - skyboxmo[1]->y) * -mh->skybox_scaley; y = (player->mo->y - skyboxmo[1]->y) * -mh->skybox_scaley;
if (viewmobj->angle == 0)
{
viewx += x;
viewy += y;
}
else if (viewmobj->angle == ANGLE_90)
{
viewx -= y;
viewy += x;
}
else if (viewmobj->angle == ANGLE_180)
{
viewx -= x;
viewy -= y;
}
else if (viewmobj->angle == ANGLE_270)
{
viewx += y;
viewy -= x;
}
else
{
angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT;
viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
}
} }
if (mh->skybox_scalez > 0) if (mh->skybox_scalez > 0)
viewz += player->viewz / mh->skybox_scalez; viewz += player->viewz / mh->skybox_scalez;
@ -1433,10 +1463,12 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_voodoocompatibility); CV_RegisterVar(&cv_voodoocompatibility);
CV_RegisterVar(&cv_grfogcolor); CV_RegisterVar(&cv_grfogcolor);
CV_RegisterVar(&cv_grsoftwarefog); CV_RegisterVar(&cv_grsoftwarefog);
#ifdef ALAM_LIGHTING
CV_RegisterVar(&cv_grstaticlighting); CV_RegisterVar(&cv_grstaticlighting);
CV_RegisterVar(&cv_grdynamiclighting); CV_RegisterVar(&cv_grdynamiclighting);
CV_RegisterVar(&cv_grcoronas); CV_RegisterVar(&cv_grcoronas);
CV_RegisterVar(&cv_grcoronasize); CV_RegisterVar(&cv_grcoronasize);
#endif
CV_RegisterVar(&cv_grmd2); CV_RegisterVar(&cv_grmd2);
#endif #endif

View file

@ -299,7 +299,7 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
} }
length = FixedMul (distance,distscale[x1]); length = FixedMul (distance,distscale[x1]);
angle = (currentplane->viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT; angle = (currentplane->viewangle + currentplane->plangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
/// \note Wouldn't it be faster just to add viewx and viewy /// \note Wouldn't it be faster just to add viewx and viewy
// to the plane's x/yoffs anyway?? // to the plane's x/yoffs anyway??
@ -475,7 +475,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
&& lightlevel == check->lightlevel && lightlevel == check->lightlevel
&& xoff == check->xoffs && yoff == check->yoffs && xoff == check->xoffs && yoff == check->yoffs
&& planecolormap == check->extra_colormap && planecolormap == check->extra_colormap
&& !pfloor && !check->ffloor && check->viewz == viewz && !pfloor && !check->ffloor
&& check->viewx == viewx && check->viewy == viewy && check->viewz == viewz
&& check->viewangle == viewangle && check->viewangle == viewangle
#ifdef ESLOPE #ifdef ESLOPE
&& check->slope == slope && check->slope == slope
@ -497,8 +498,10 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
check->yoffs = yoff; check->yoffs = yoff;
check->extra_colormap = planecolormap; check->extra_colormap = planecolormap;
check->ffloor = pfloor; check->ffloor = pfloor;
check->viewx = viewx;
check->viewy = viewy;
check->viewz = viewz; check->viewz = viewz;
check->viewangle = viewangle + plangle; check->viewangle = viewangle;
check->plangle = plangle; check->plangle = plangle;
#ifdef POLYOBJECTS_PLANES #ifdef POLYOBJECTS_PLANES
check->polyobj = NULL; check->polyobj = NULL;
@ -567,6 +570,8 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
new_pl->yoffs = pl->yoffs; new_pl->yoffs = pl->yoffs;
new_pl->extra_colormap = pl->extra_colormap; new_pl->extra_colormap = pl->extra_colormap;
new_pl->ffloor = pl->ffloor; new_pl->ffloor = pl->ffloor;
new_pl->viewx = pl->viewx;
new_pl->viewy = pl->viewy;
new_pl->viewz = pl->viewz; new_pl->viewz = pl->viewz;
new_pl->viewangle = pl->viewangle; new_pl->viewangle = pl->viewangle;
new_pl->plangle = pl->plangle; new_pl->plangle = pl->plangle;
@ -665,7 +670,6 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
void R_DrawPlanes(void) void R_DrawPlanes(void)
{ {
visplane_t *pl; visplane_t *pl;
angle_t skyviewangle = viewangle; // the flat angle itself can mess with viewangle, so do your own angle instead!
INT32 x; INT32 x;
INT32 angle; INT32 angle;
INT32 i; INT32 i;
@ -704,7 +708,7 @@ void R_DrawPlanes(void)
if (dc_yl <= dc_yh) if (dc_yl <= dc_yh)
{ {
angle = (skyviewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
dc_x = x; dc_x = x;
dc_source = dc_source =
R_GetColumn(skytexture, R_GetColumn(skytexture,
@ -857,13 +861,13 @@ void R_DrawSinglePlane(visplane_t *pl)
#ifdef ESLOPE #ifdef ESLOPE
if (!pl->slope) // Don't mess with angle on slopes! We'll handle this ourselves later if (!pl->slope) // Don't mess with angle on slopes! We'll handle this ourselves later
#endif #endif
if (viewangle != pl->viewangle) if (viewangle != pl->viewangle+pl->plangle)
{ {
memset(cachedheight, 0, sizeof (cachedheight)); memset(cachedheight, 0, sizeof (cachedheight));
angle = (pl->viewangle-ANGLE_90)>>ANGLETOFINESHIFT; angle = (pl->viewangle+pl->plangle-ANGLE_90)>>ANGLETOFINESHIFT;
basexscale = FixedDiv(FINECOSINE(angle),centerxfrac); basexscale = FixedDiv(FINECOSINE(angle),centerxfrac);
baseyscale = -FixedDiv(FINESINE(angle),centerxfrac); baseyscale = -FixedDiv(FINESINE(angle),centerxfrac);
viewangle = pl->viewangle; viewangle = pl->viewangle+pl->plangle;
} }
currentplane = pl; currentplane = pl;
@ -954,11 +958,11 @@ void R_DrawSinglePlane(visplane_t *pl)
xoffs *= fudge; xoffs *= fudge;
yoffs /= fudge; yoffs /= fudge;
vx = FIXED_TO_FLOAT(viewx+xoffs); vx = FIXED_TO_FLOAT(pl->viewx+xoffs);
vy = FIXED_TO_FLOAT(viewy-yoffs); vy = FIXED_TO_FLOAT(pl->viewy-yoffs);
vz = FIXED_TO_FLOAT(viewz); vz = FIXED_TO_FLOAT(pl->viewz);
temp = P_GetZAt(pl->slope, viewx, viewy); temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy);
zeroheight = FIXED_TO_FLOAT(temp); zeroheight = FIXED_TO_FLOAT(temp);
#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180) #define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180)
@ -966,14 +970,14 @@ void R_DrawSinglePlane(visplane_t *pl)
// p is the texture origin in view space // p is the texture origin in view space
// Don't add in the offsets at this stage, because doing so can result in // Don't add in the offsets at this stage, because doing so can result in
// errors if the flat is rotated. // errors if the flat is rotated.
ang = ANG2RAD(ANGLE_270 - viewangle); ang = ANG2RAD(ANGLE_270 - pl->viewangle);
p.x = vx * cos(ang) - vy * sin(ang); p.x = vx * cos(ang) - vy * sin(ang);
p.z = vx * sin(ang) + vy * cos(ang); p.z = vx * sin(ang) + vy * cos(ang);
temp = P_GetZAt(pl->slope, -xoffs, yoffs); temp = P_GetZAt(pl->slope, -xoffs, yoffs);
p.y = FIXED_TO_FLOAT(temp) - vz; p.y = FIXED_TO_FLOAT(temp) - vz;
// m is the v direction vector in view space // m is the v direction vector in view space
ang = ANG2RAD(ANGLE_180 - viewangle - pl->plangle); ang = ANG2RAD(ANGLE_180 - (pl->viewangle + pl->plangle));
m.x = cos(ang); m.x = cos(ang);
m.z = sin(ang); m.z = sin(ang);
@ -982,9 +986,9 @@ void R_DrawSinglePlane(visplane_t *pl)
n.z = -cos(ang); n.z = -cos(ang);
ang = ANG2RAD(pl->plangle); ang = ANG2RAD(pl->plangle);
temp = P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(sin(ang)), viewy + FLOAT_TO_FIXED(cos(ang))); temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang)));
m.y = FIXED_TO_FLOAT(temp) - zeroheight; m.y = FIXED_TO_FLOAT(temp) - zeroheight;
temp = P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(cos(ang)), viewy - FLOAT_TO_FIXED(sin(ang))); temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang)));
n.y = FIXED_TO_FLOAT(temp) - zeroheight; n.y = FIXED_TO_FLOAT(temp) - zeroheight;
m.x /= fudge; m.x /= fudge;
@ -1040,6 +1044,14 @@ void R_DrawSinglePlane(visplane_t *pl)
stop = pl->maxx + 1; stop = pl->maxx + 1;
if (viewx != pl->viewx || viewy != pl->viewy)
{
viewx = pl->viewx;
viewy = pl->viewy;
}
if (viewz != pl->viewz)
viewz = pl->viewz;
for (x = pl->minx; x <= stop; x++) for (x = pl->minx; x <= stop; x++)
{ {
R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1], R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1],

View file

@ -27,7 +27,8 @@ typedef struct visplane_s
{ {
struct visplane_s *next; struct visplane_s *next;
fixed_t height, viewz; fixed_t height;
fixed_t viewx, viewy, viewz;
angle_t viewangle; angle_t viewangle;
angle_t plangle; angle_t plangle;
INT32 picnum; INT32 picnum;

View file

@ -288,6 +288,10 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
line_t *ldef; line_t *ldef;
sector_t *front, *back; sector_t *front, *back;
INT32 times, repeats; INT32 times, repeats;
INT64 overflow_test;
#ifdef ESLOPE
INT32 range;
#endif
// Calculate light table. // Calculate light table.
// Use different light tables // Use different light tables
@ -334,6 +338,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
colfunc = fuzzcolfunc; colfunc = fuzzcolfunc;
} }
#ifdef ESLOPE
range = max(ds->x2-ds->x1, 1);
#endif
rw_scalestep = ds->scalestep; rw_scalestep = ds->scalestep;
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
@ -360,10 +367,30 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
for (i = 0; i < dc_numlights; i++) for (i = 0; i < dc_numlights; i++)
{ {
#ifdef ESLOPE
fixed_t leftheight, rightheight;
#endif
light = &frontsector->lightlist[i]; light = &frontsector->lightlist[i];
rlight = &dc_lightlist[i]; rlight = &dc_lightlist[i];
#ifdef ESLOPE
if (light->slope) {
leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y);
rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y);
} else
leftheight = rightheight = light->height;
leftheight -= viewz;
rightheight -= viewz;
rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1);
rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
//if (x1 > ds->x1)
//rlight->height -= (x1 - ds->x1)*rlight->heightstep;
#else
rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale);
rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz)); rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz));
#endif
rlight->lightlevel = *light->lightlevel; rlight->lightlevel = *light->lightlevel;
rlight->extra_colormap = light->extra_colormap; rlight->extra_colormap = light->extra_colormap;
rlight->flags = light->flags; rlight->flags = light->flags;
@ -459,7 +486,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
} }
#ifndef ESLOPE #ifndef ESLOPE
if (curline->linedef->flags & ML_DONTPEGBOTTOM) if (curline->linedef->flags & ML_DONTPEGBOTTOM)
{ {
@ -497,6 +523,16 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
// calculate lighting // calculate lighting
if (maskedtexturecol[dc_x] != INT16_MAX) if (maskedtexturecol[dc_x] != INT16_MAX)
{ {
// Check for overflows first
overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL)
{
// Eh, no, go away, don't waste our time
spryscale += rw_scalestep;
continue;
}
if (dc_numlights) if (dc_numlights)
{ {
lighttable_t **xwalllights; lighttable_t **xwalllights;
@ -673,7 +709,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
fixed_t offsetvalue = 0; fixed_t offsetvalue = 0;
lightlist_t *light; lightlist_t *light;
r_lightlist_t *rlight; r_lightlist_t *rlight;
#ifdef ESLOPE
INT32 range;
#endif
#ifndef ESLOPE
fixed_t lheight; fixed_t lheight;
#endif
line_t *newline = NULL; line_t *newline = NULL;
#ifdef ESLOPE #ifdef ESLOPE
// Render FOF sides kinda like normal sides, with the frac and step and everything // Render FOF sides kinda like normal sides, with the frac and step and everything
@ -735,6 +776,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
else if (pfloor->flags & FF_FOG) else if (pfloor->flags & FF_FOG)
colfunc = R_DrawFogColumn_8; colfunc = R_DrawFogColumn_8;
#ifdef ESLOPE
range = max(ds->x2-ds->x1, 1);
#endif
//SoM: Moved these up here so they are available for my lightlist calculations //SoM: Moved these up here so they are available for my lightlist calculations
rw_scalestep = ds->scalestep; rw_scalestep = ds->scalestep;
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
@ -751,9 +795,49 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
for (i = p = 0; i < dc_numlights; i++) for (i = p = 0; i < dc_numlights; i++)
{ {
#ifdef ESLOPE
fixed_t leftheight, rightheight;
fixed_t pfloorleft, pfloorright;
#endif
light = &frontsector->lightlist[i]; light = &frontsector->lightlist[i];
rlight = &dc_lightlist[p]; rlight = &dc_lightlist[p];
#ifdef ESLOPE
if (light->slope) {
leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y);
rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y);
} else
leftheight = rightheight = light->height;
if (*pfloor->b_slope) {
pfloorleft = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y);
pfloorright = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y);
} else
pfloorleft = pfloorright = *pfloor->bottomheight;
if (leftheight < pfloorleft && rightheight < pfloorright)
continue;
if (*pfloor->t_slope) {
pfloorleft = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y);
pfloorright = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y);
} else
pfloorleft = pfloorright = *pfloor->topheight;
if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights)
{
lightlist_t *nextlight = &frontsector->lightlist[i+1];
if (nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height > pfloorleft
&& nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height > pfloorright)
continue;
}
leftheight -= viewz;
rightheight -= viewz;
rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1);
rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
rlight->height -= rlight->heightstep;
#else
if (light->height < *pfloor->bottomheight) if (light->height < *pfloor->bottomheight)
continue; continue;
@ -763,13 +847,29 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height;
rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz)); rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz));
rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->heightstep; rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->heightstep;
#endif
rlight->flags = light->flags; rlight->flags = light->flags;
if (light->flags & FF_CUTLEVEL) if (light->flags & FF_CUTLEVEL)
{ {
#ifdef ESLOPE
if (*light->caster->b_slope) {
leftheight = P_GetZAt(*light->caster->b_slope, ds->leftpos.x, ds->leftpos.y);
rightheight = P_GetZAt(*light->caster->b_slope, ds->rightpos.x, ds->rightpos.y);
} else
leftheight = rightheight = *light->caster->bottomheight;
leftheight -= viewz;
rightheight -= viewz;
rlight->botheight = (centeryfrac) - FixedMul(leftheight, ds->scale1);
rlight->botheightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range);
rlight->botheight -= rlight->botheightstep;
#else
lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight;
rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz)); rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz));
rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->botheightstep; rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->botheightstep;
#endif
} }
rlight->lightlevel = *light->lightlevel; rlight->lightlevel = *light->lightlevel;
@ -857,24 +957,46 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// Set heights according to plane, or slope, whichever // Set heights according to plane, or slope, whichever
{ {
fixed_t left_top, right_top, left_bottom, right_bottom; fixed_t left_top, right_top, left_bottom, right_bottom;
INT64 overflow_test;
left_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->topheight; if (*pfloor->t_slope)
right_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->topheight; {
left_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->bottomheight; left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
right_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->bottomheight; right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz;
}
else
left_top = right_top = *pfloor->topheight - viewz;
left_top -= viewz; if (*pfloor->b_slope)
right_top -= viewz; {
left_bottom -= viewz; left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
right_bottom -= viewz; right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz;
}
else
left_bottom = right_bottom = *pfloor->bottomheight - viewz;
// overflow tests
// if any of these fail, abandon. likely we're too high up to see anything anyway
overflow_test = (INT64)centeryfrac - (((INT64)left_top*ds->scale1)>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return;
overflow_test = (INT64)centeryfrac - (((INT64)left_bottom*ds->scale1)>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return;
overflow_test = (INT64)centeryfrac - (((INT64)right_top*ds->scale2)>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return;
overflow_test = (INT64)centeryfrac - (((INT64)right_bottom*ds->scale2)>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return;
top_frac = centeryfrac - FixedMul(left_top, ds->scale1); top_frac = centeryfrac - FixedMul(left_top, ds->scale1);
bottom_frac = centeryfrac - FixedMul(left_bottom, ds->scale1); bottom_frac = centeryfrac - FixedMul(left_bottom, ds->scale1);
top_step = centeryfrac - FixedMul(right_top, ds->scale2); top_step = centeryfrac - FixedMul(right_top, ds->scale2);
bottom_step = centeryfrac - FixedMul(right_bottom, ds->scale2); bottom_step = centeryfrac - FixedMul(right_bottom, ds->scale2);
top_step = (top_step-top_frac)/(ds->x2-ds->x1+1); top_step = (top_step-top_frac)/(range);
bottom_step = (bottom_step-bottom_frac)/(ds->x2-ds->x1+1); bottom_step = (bottom_step-bottom_frac)/(range);
top_frac += top_step * (x1 - ds->x1); top_frac += top_step * (x1 - ds->x1);
bottom_frac += bottom_step * (x1 - ds->x1); bottom_frac += bottom_step * (x1 - ds->x1);
@ -1043,19 +1165,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap)
dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
//Handle over/underflows before they happen. This fixes the textures part of the FOF rendering bug.
//...for the most part, anyway.
if (((signed)dc_texturemid > 0 && (spryscale>>FRACBITS > INT32_MAX / (signed)dc_texturemid))
|| ((signed)dc_texturemid < 0 && (spryscale) && (signed)(dc_texturemid)>>FRACBITS < (INT32_MIN / spryscale)))
{
spryscale += rw_scalestep;
#ifdef ESLOPE
top_frac += top_step;
bottom_frac += bottom_step;
#endif
continue;
}
#ifdef ESLOPE #ifdef ESLOPE
sprtopscreen = windowtop = top_frac; sprtopscreen = windowtop = top_frac;
sprbotscreen = windowbottom = bottom_frac; sprbotscreen = windowbottom = bottom_frac;
@ -1112,7 +1221,9 @@ static void R_RenderSegLoop (void)
INT32 mid; INT32 mid;
fixed_t texturecolumn = 0; fixed_t texturecolumn = 0;
#ifdef ESLOPE
fixed_t oldtexturecolumn = -1; fixed_t oldtexturecolumn = -1;
#endif
INT32 top; INT32 top;
INT32 bottom; INT32 bottom;
INT32 i; INT32 i;
@ -1468,22 +1579,26 @@ void R_StoreWallRange(INT32 start, INT32 stop)
fixed_t hyp; fixed_t hyp;
fixed_t sineval; fixed_t sineval;
angle_t distangle, offsetangle; angle_t distangle, offsetangle;
//fixed_t vtop; #ifndef ESLOPE
fixed_t vtop;
#endif
INT32 lightnum; INT32 lightnum;
INT32 i, p; INT32 i, p;
lightlist_t *light; lightlist_t *light;
r_lightlist_t *rlight; r_lightlist_t *rlight;
INT32 range;
#ifdef ESLOPE #ifdef ESLOPE
vertex_t segleft, segright; vertex_t segleft, segright;
fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide;
#endif #endif
static size_t maxdrawsegs = 0; static size_t maxdrawsegs = 0;
#ifdef ESLOPE
maskedtextureheight = NULL; maskedtextureheight = NULL;
//initialize segleft and segright //initialize segleft and segright
memset(&segleft, 0x00, sizeof(segleft)); memset(&segleft, 0x00, sizeof(segleft));
memset(&segright, 0x00, sizeof(segright)); memset(&segright, 0x00, sizeof(segright));
#endif
if (ds_p == drawsegs+maxdrawsegs) if (ds_p == drawsegs+maxdrawsegs)
{ {
@ -1556,7 +1671,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (stop > start) if (stop > start)
{ {
ds_p->scale2 = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[stop]); ds_p->scale2 = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[stop]);
ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (stop-start); range = stop-start;
} }
else else
{ {
@ -1577,8 +1692,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} }
#endif #endif
ds_p->scale2 = ds_p->scale1; ds_p->scale2 = ds_p->scale1;
range = 1;
} }
ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (range);
// calculate texture boundaries // calculate texture boundaries
// and decide if floor / ceiling marks are needed // and decide if floor / ceiling marks are needed
#ifdef ESLOPE #ifdef ESLOPE
@ -1785,9 +1903,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
&& backsector->ceilingpic == skyflatnum) && backsector->ceilingpic == skyflatnum)
{ {
#ifdef ESLOPE #ifdef ESLOPE
worldtopslope = worldhighslope = worldtopslope = max(worldtopslope, worldhighslope);
worldhighslope = worldtopslope;
#endif #endif
worldtop = worldhigh; worldtop = max(worldtop, worldhigh);
worldhigh = worldtop;
} }
ds_p->sprtopclip = ds_p->sprbottomclip = NULL; ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
@ -1801,7 +1921,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{ {
ds_p->silhouette = SIL_BOTTOM; ds_p->silhouette = SIL_BOTTOM;
#ifdef ESLOPE #ifdef ESLOPE
ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz)
ds_p->bsilheight = INT32_MAX;
else
ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight);
#else #else
ds_p->bsilheight = frontsector->floorheight; ds_p->bsilheight = frontsector->floorheight;
#endif #endif
@ -1825,7 +1948,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{ {
ds_p->silhouette |= SIL_TOP; ds_p->silhouette |= SIL_TOP;
#ifdef ESLOPE #ifdef ESLOPE
ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz)
ds_p->tsilheight = INT32_MIN;
else
ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight);
#else #else
ds_p->tsilheight = frontsector->ceilingheight; ds_p->tsilheight = frontsector->ceilingheight;
#endif #endif
@ -1863,21 +1989,25 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->silhouette |= SIL_TOP; ds_p->silhouette |= SIL_TOP;
} }
#ifdef ESLOPE
// This causes issues with slopes.
if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope))
#endif
//SoM: 3/25/2000: This code fixes an automap bug that didn't check //SoM: 3/25/2000: This code fixes an automap bug that didn't check
// frontsector->ceiling and backsector->floor to see if a door was closed. // frontsector->ceiling and backsector->floor to see if a door was closed.
// Without the following code, sprites get displayed behind closed doors. // Without the following code, sprites get displayed behind closed doors.
{ {
#ifdef ESLOPE
if (doorclosed || (worldhigh <= worldbottom && worldhighslope <= worldbottomslope))
#else
if (doorclosed || backsector->ceilingheight <= frontsector->floorheight) if (doorclosed || backsector->ceilingheight <= frontsector->floorheight)
#endif
{ {
ds_p->sprbottomclip = negonearray; ds_p->sprbottomclip = negonearray;
ds_p->bsilheight = INT32_MAX; ds_p->bsilheight = INT32_MAX;
ds_p->silhouette |= SIL_BOTTOM; ds_p->silhouette |= SIL_BOTTOM;
} }
#ifdef ESLOPE
if (doorclosed || (worldlow >= worldtop && worldlowslope >= worldtopslope))
#else
if (doorclosed || backsector->floorheight >= frontsector->ceilingheight) if (doorclosed || backsector->floorheight >= frontsector->ceilingheight)
#endif
{ // killough 1/17/98, 2/8/98 { // killough 1/17/98, 2/8/98
ds_p->sprtopclip = screenheightarray; ds_p->sprtopclip = screenheightarray;
ds_p->tsilheight = INT32_MIN; ds_p->tsilheight = INT32_MIN;
@ -1937,8 +2067,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
markceiling = false; markceiling = false;
} }
#ifdef ESLOPE
if ((worldhigh <= worldbottom && worldhighslope <= worldbottomslope) ||
(worldlow >= worldtop && worldlowslope >= worldtopslope))
#else
if (backsector->ceilingheight <= frontsector->floorheight || if (backsector->ceilingheight <= frontsector->floorheight ||
backsector->floorheight >= frontsector->ceilingheight) backsector->floorheight >= frontsector->ceilingheight)
#endif
{ {
// closed door // closed door
markceiling = markfloor = true; markceiling = markfloor = true;
@ -2121,8 +2256,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
for (r2 = frontsector->ffloors; r2; r2 = r2->next) for (r2 = frontsector->ffloors; r2; r2 = r2->next)
{ {
if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES) if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES))
|| *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red
continue; continue;
if (r2->norender == leveltime) if (r2->norender == leveltime)
@ -2154,9 +2288,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} else } else
low2 = lowslope2 = *r2->bottomheight; low2 = lowslope2 = *r2->bottomheight;
if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope))
continue;
if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2))
continue; continue;
#else #else
if (*r2->topheight < lowcut || *r2->bottomheight > highcut)
continue;
if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight)
continue; continue;
#endif #endif
@ -2201,8 +2339,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
for (r2 = backsector->ffloors; r2; r2 = r2->next) for (r2 = backsector->ffloors; r2; r2 = r2->next)
{ {
if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES) if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES))
|| *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red
continue; continue;
if (r2->norender == leveltime) if (r2->norender == leveltime)
@ -2234,9 +2371,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} else } else
low2 = lowslope2 = *r2->bottomheight; low2 = lowslope2 = *r2->bottomheight;
if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope))
continue;
if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2))
continue; continue;
#else #else
if (*r2->topheight < lowcut || *r2->bottomheight > highcut)
continue;
if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight)
continue; continue;
#endif #endif
@ -2438,11 +2579,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
#ifdef ESLOPE #ifdef ESLOPE
if (frontsector->c_slope) { if (frontsector->c_slope) {
fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2);
topstep = (topfracend-topfrac)/(stop-start+1); topstep = (topfracend-topfrac)/(range);
} }
if (frontsector->f_slope) { if (frontsector->f_slope) {
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2);
bottomstep = (bottomfracend-bottomfrac)/(stop-start+1); bottomstep = (bottomfracend-bottomfrac)/(range);
} }
#endif #endif
@ -2503,7 +2644,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
#ifdef ESLOPE #ifdef ESLOPE
rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale);
rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2);
rlight->heightstep = (rlight->heightstep-rlight->height)/(stop-start+1); rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
#else #else
rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale); rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale);
rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4); rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4);
@ -2530,7 +2671,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale);
rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2);
rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(stop-start+1); rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range);
#else #else
rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale); rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale);
@ -2559,7 +2700,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
#ifdef ESLOPE #ifdef ESLOPE
ffloor[i].f_pos_slope >>= 4; ffloor[i].f_pos_slope >>= 4;
ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale);
ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(stop-start+1); ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range);
#else #else
ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos);
ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale);
@ -2576,11 +2717,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
worldlowslope >>= 4; worldlowslope >>= 4;
#endif #endif
if (worldhigh < worldtop if (toptexture)
#ifdef ESLOPE
|| worldhighslope <= worldtopslope
#endif
)
{ {
pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
pixhighstep = -FixedMul (rw_scalestep,worldhigh); pixhighstep = -FixedMul (rw_scalestep,worldhigh);
@ -2588,23 +2725,19 @@ void R_StoreWallRange(INT32 start, INT32 stop)
#ifdef ESLOPE #ifdef ESLOPE
if (backsector->c_slope) { if (backsector->c_slope) {
fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2);
pixhighstep = (topfracend-pixhigh)/(stop-start+1); pixhighstep = (topfracend-pixhigh)/(range);
} }
#endif #endif
} }
if (worldlow > worldbottom if (bottomtexture)
#ifdef ESLOPE
|| worldlowslope >= worldbottomslope
#endif
)
{ {
pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
pixlowstep = -FixedMul (rw_scalestep,worldlow); pixlowstep = -FixedMul (rw_scalestep,worldlow);
#ifdef ESLOPE #ifdef ESLOPE
if (backsector->f_slope) { if (backsector->f_slope) {
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2);
pixlowstep = (bottomfracend-pixlow)/(stop-start+1); pixlowstep = (bottomfracend-pixlow)/(range);
} }
#endif #endif
} }
@ -2612,7 +2745,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{ {
ffloor_t * rover; ffloor_t * rover;
#ifdef ESLOPE #ifdef ESLOPE
fixed_t rovertest; fixed_t roverleft, roverright;
fixed_t planevistest; fixed_t planevistest;
#endif #endif
i = 0; i = 0;
@ -2631,44 +2764,46 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (*rover->b_slope || *rover->t_slope) if (*rover->b_slope || *rover->t_slope)
backsector->hasslope = true; backsector->hasslope = true;
rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->bottomheight) - viewz; roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz;
roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz;
planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight);
if (rovertest>>4 <= worldhigh && if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
rovertest>>4 >= worldlow && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) (viewz > planevistest && (rover->flags & FF_BOTHPLANES))))
{ {
//ffloor[i].slope = *rover->b_slope; //ffloor[i].slope = *rover->b_slope;
ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; ffloor[i].b_pos = roverleft;
ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; ffloor[i].b_pos_slope = roverright;
ffloor[i].b_pos >>= 4; ffloor[i].b_pos >>= 4;
ffloor[i].b_pos_slope >>= 4; ffloor[i].b_pos_slope >>= 4;
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2);
ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range);
i++; i++;
} }
if (i >= MAXFFLOORS) if (i >= MAXFFLOORS)
break; break;
rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->topheight) - viewz; roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz;
roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz;
planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight);
if (rovertest>>4 <= worldhigh && if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
rovertest>>4 >= worldlow && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) (viewz < planevistest && (rover->flags & FF_BOTHPLANES))))
{ {
//ffloor[i].slope = *rover->t_slope; //ffloor[i].slope = *rover->t_slope;
ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; ffloor[i].b_pos = roverleft;
ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; ffloor[i].b_pos_slope = roverright;
ffloor[i].b_pos >>= 4; ffloor[i].b_pos >>= 4;
ffloor[i].b_pos_slope >>= 4; ffloor[i].b_pos_slope >>= 4;
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2);
ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range);
i++; i++;
} }
#else #else
@ -2716,44 +2851,46 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (*rover->b_slope || *rover->t_slope) if (*rover->b_slope || *rover->t_slope)
frontsector->hasslope = true; frontsector->hasslope = true;
rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight) - viewz; roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz;
roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz;
planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight);
if (rovertest>>4 <= worldtop && if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
rovertest>>4 >= worldbottom && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) (viewz > planevistest && (rover->flags & FF_BOTHPLANES))))
{ {
//ffloor[i].slope = *rover->b_slope; //ffloor[i].slope = *rover->b_slope;
ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; ffloor[i].b_pos = roverleft;
ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; ffloor[i].b_pos_slope = roverright;
ffloor[i].b_pos >>= 4; ffloor[i].b_pos >>= 4;
ffloor[i].b_pos_slope >>= 4; ffloor[i].b_pos_slope >>= 4;
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2);
ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range);
i++; i++;
} }
if (i >= MAXFFLOORS) if (i >= MAXFFLOORS)
break; break;
rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight) - viewz; roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz;
roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz;
planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight);
if (rovertest>>4 <= worldtop && if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
rovertest>>4 >= worldbottom && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) (viewz < planevistest && (rover->flags & FF_BOTHPLANES))))
{ {
//ffloor[i].slope = *rover->t_slope; //ffloor[i].slope = *rover->t_slope;
ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; ffloor[i].b_pos = roverleft;
ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; ffloor[i].b_pos_slope = roverright;
ffloor[i].b_pos >>= 4; ffloor[i].b_pos >>= 4;
ffloor[i].b_pos_slope >>= 4; ffloor[i].b_pos_slope >>= 4;
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2);
ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range);
i++; i++;
} }
#else #else

View file

@ -744,10 +744,16 @@ static void R_DrawVisSprite(vissprite_t *vis)
patch_t *patch = W_CacheLumpNum(vis->patch, PU_CACHE); patch_t *patch = W_CacheLumpNum(vis->patch, PU_CACHE);
fixed_t this_scale = vis->mobj->scale; fixed_t this_scale = vis->mobj->scale;
INT32 x1, x2; INT32 x1, x2;
INT64 overflow_test;
if (!patch) if (!patch)
return; return;
// Check for overflow
overflow_test = (INT64)centeryfrac - (((INT64)vis->texturemid*vis->scale)>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test;
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // fixed point mult would overflow
colfunc = basecolfunc; // hack: this isn't resetting properly somewhere. colfunc = basecolfunc; // hack: this isn't resetting properly somewhere.
dc_colormap = vis->colormap; dc_colormap = vis->colormap;
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
@ -1239,15 +1245,6 @@ static void R_ProjectSprite(mobj_t *thing)
return; return;
} }
// quick check for possible overflows
// if either of these triggers then there's a possibility that drawing is unsafe
if (M_HighestBit(abs(gzt - viewz)) + M_HighestBit(abs(yscale)) > 47 // 31 bits + 16 from the division by FRACUNIT
|| M_HighestBit(abs(gz - viewz)) + M_HighestBit(abs(yscale)) > 47)
{
CONS_Debug(DBG_RENDER, "Suspected overflow in ProjectSprite (sprite %s), ignoring\n", sprnames[thing->sprite]);
return;
}
// store information in a vissprite // store information in a vissprite
vis = R_NewVisSprite(); vis = R_NewVisSprite();
vis->heightsec = heightsec; //SoM: 3/17/2000 vis->heightsec = heightsec; //SoM: 3/17/2000
@ -1458,14 +1455,6 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
return; return;
} }
// quick check for possible overflows
// if either of these triggers then there's a possibility that drawing is unsafe
if (M_HighestBit(abs(gzt - viewz)) + M_HighestBit(abs(yscale)) > 47) // 31 bits + 16 from the division by FRACUNIT
{
CONS_Debug(DBG_RENDER, "Suspected overflow in ProjectPrecipitationSprite (sprite %s), ignoring\n", sprnames[thing->sprite]);
return;
}
// store information in a vissprite // store information in a vissprite
vis = R_NewVisSprite(); vis = R_NewVisSprite();
vis->scale = yscale; //<<detailshift; vis->scale = yscale; //<<detailshift;

View file

@ -592,9 +592,13 @@ static void ST_drawDebugInfo(void)
if (cv_debug & DBG_RANDOMIZER) // randomizer testing if (cv_debug & DBG_RANDOMIZER) // randomizer testing
{ {
fixed_t peekres = P_RandomPeek();
peekres *= 10000; // Change from fixed point
peekres >>= FRACBITS; // to displayable decimal
V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Init: %08x", P_GetInitSeed())); V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Init: %08x", P_GetInitSeed()));
V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Seed: %08x", P_GetRandSeed())); V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Seed: %08x", P_GetRandSeed()));
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("== : %8d", P_RandomPeek())); V_DrawRightAlignedString(320, height, V_MONOSPACE, va("== : .%04d", peekres));
height -= 32; height -= 32;
} }

View file

@ -71,10 +71,12 @@ consvar_t cv_grgammagreen = {"gr_gammagreen", "127", CV_SAVE|CV_CALL, grgamma_co
CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL}; CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grgammablue = {"gr_gammablue", "127", CV_SAVE|CV_CALL, grgamma_cons_t, consvar_t cv_grgammablue = {"gr_gammablue", "127", CV_SAVE|CV_CALL, grgamma_cons_t,
CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL}; CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL};
#ifdef ALAM_LIGHTING
consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grstaticlighting = {"gr_staticlighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grstaticlighting = {"gr_staticlighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}}; static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}};
// console variables in development // console variables in development
@ -1989,7 +1991,7 @@ Unoptimized version
for (y = 0; y < height; y++) for (y = 0; y < height; y++)
{ {
if (M_Random() < 32) if (M_RandomChance(FRACUNIT/8)) // 12.5%
heatshifter[y] = true; heatshifter[y] = true;
} }