Merge branch 'master' into snaptoground-fix

This commit is contained in:
Monster Iestyn 2019-08-03 18:23:09 +01:00
commit dff544404d
22 changed files with 266 additions and 184 deletions

View File

@ -82,7 +82,6 @@ typedef enum
// Current menu parameters
extern UINT8 titlemapinaction;
extern mobj_t *titlemapcameraref;
extern char curbgname[8];
extern SINT8 curfadevalue;

View File

@ -4366,7 +4366,7 @@ void G_WriteGhostTic(mobj_t *ghost)
ghostext.flags = 0;
}
if (ghost->player && ghost->player->followmobj)
if (ghost->player && ghost->player->followmobj) // bloats tails runs but what can ya do
{
INT16 temp;
@ -4592,6 +4592,9 @@ void G_GhostTicker(void)
switch(g->color)
{
default:
case GHC_RETURNSKIN:
g->mo->skin = g->oldmo.skin;
// fallthru
case GHC_NORMAL: // Go back to skin color
g->mo->color = g->oldmo.color;
break;
@ -4602,6 +4605,9 @@ void G_GhostTicker(void)
case GHC_FIREFLOWER: // Fireflower
g->mo->color = SKINCOLOR_WHITE;
break;
case GHC_NIGHTSSKIN: // not actually a colour
g->mo->skin = &skins[DEFAULTNIGHTSSKIN];
break;
}
}
if (xziptic & EZT_FLIP)

View File

@ -140,7 +140,9 @@ typedef enum
GHC_NORMAL = 0,
GHC_SUPER,
GHC_FIREFLOWER,
GHC_INVINCIBLE
GHC_INVINCIBLE,
GHC_NIGHTSSKIN, // not actually a colour
GHC_RETURNSKIN // ditto
} ghostcolor_t;
// Record/playback tics

View File

@ -50,6 +50,7 @@ typedef enum
} gameaction_t;
extern gamestate_t gamestate;
extern UINT8 titlemapinaction;
extern UINT8 ultimatemode; // was sk_insane
extern gameaction_t gameaction;

View File

@ -1791,7 +1791,11 @@ state_t states[NUMSTATES] =
// Blue Sphere for special stages
{SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERE
{SPR_SPHR, FF_FULLBRIGHT|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS
{SPR_SPHR, FF_FULLBRIGHT
#ifdef MANIASPHERES
|FF_ANIMATE|FF_RANDOMANIM
#endif
, -1, {NULL}, 1, 4, S_NULL}, // S_BLUESPHEREBONUS
{SPR_SPHR, 0, 20, {NULL}, 0, 0, S_NULL}, // S_BLUESPHERESPARK
// Bomb Sphere

View File

@ -33,8 +33,6 @@
#define NOHUD if (hud_running)\
return luaL_error(L, "HUD rendering code should not call this function!");
#define INLEVEL if (gamestate != GS_LEVEL)\
return luaL_error(L, "This function can only be used in a level!");
boolean luaL_checkboolean(lua_State *L, int narg) {
luaL_checktype(L, narg, LUA_TBOOLEAN);
@ -2047,12 +2045,22 @@ static int lib_pStartQuake(lua_State *L)
static int lib_evCrumbleChain(lua_State *L)
{
sector_t *sec = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR));
sector_t *sec = NULL;
ffloor_t *rover = NULL;
NOHUD
INLEVEL
if (!sec)
return LUA_ErrInvalid(L, "sector_t");
if (!lua_isnone(L, 2))
{
if (!lua_isnil(L, 1))
{
sec = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
if (!sec)
return LUA_ErrInvalid(L, "sector_t");
}
rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR));
}
else
rover = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
if (!rover)
return LUA_ErrInvalid(L, "ffloor_t");
EV_CrumbleChain(sec, rover);

View File

@ -28,9 +28,6 @@ return luaL_error(L, "HUD rendering code should not call this function!");
// for functions not allowed in hooks or coroutines (supercedes above)
#define NOHOOK if (!lua_lumploading)\
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
// for functions only allowed within a level
#define INLEVEL if (gamestate != GS_LEVEL)\
return luaL_error(L, "This function can only be used in a level!");
static const char *cvname = NULL;

View File

@ -333,8 +333,7 @@ static int lib_iterateSectorThinglist(lua_State *L)
mobj_t *state = NULL;
mobj_t *thing = NULL;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
return luaL_error(L, "Don't call sector.thinglist() directly, use it as 'for rover in sector.thinglist do <block> end'.");
@ -369,8 +368,7 @@ static int lib_iterateSectorFFloors(lua_State *L)
ffloor_t *state = NULL;
ffloor_t *ffloor = NULL;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
return luaL_error(L, "Don't call sector.ffloors() directly, use it as 'for rover in sector.ffloors do <block> end'.");
@ -1251,8 +1249,7 @@ static int bbox_get(lua_State *L)
static int lib_iterateSectors(lua_State *L)
{
size_t i = 0;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
return luaL_error(L, "Don't call sectors.iterate() directly, use it as 'for sector in sectors.iterate do <block> end'.");
lua_settop(L, 2);
@ -1270,8 +1267,7 @@ static int lib_iterateSectors(lua_State *L)
static int lib_getSector(lua_State *L)
{
int field;
if (gamestate != GS_LEVEL)
return luaL_error(L, "You cannot access this outside of a level!");
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))
@ -1305,8 +1301,7 @@ static int lib_numsectors(lua_State *L)
static int lib_iterateSubsectors(lua_State *L)
{
size_t i = 0;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
return luaL_error(L, "Don't call subsectors.iterate() directly, use it as 'for subsector in subsectors.iterate do <block> end'.");
lua_settop(L, 2);
@ -1324,8 +1319,7 @@ static int lib_iterateSubsectors(lua_State *L)
static int lib_getSubsector(lua_State *L)
{
int field;
if (gamestate != GS_LEVEL)
return luaL_error(L, "You cannot access this outside of a level!");
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))
@ -1359,8 +1353,7 @@ static int lib_numsubsectors(lua_State *L)
static int lib_iterateLines(lua_State *L)
{
size_t i = 0;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
return luaL_error(L, "Don't call lines.iterate() directly, use it as 'for line in lines.iterate do <block> end'.");
lua_settop(L, 2);
@ -1378,8 +1371,7 @@ static int lib_iterateLines(lua_State *L)
static int lib_getLine(lua_State *L)
{
int field;
if (gamestate != GS_LEVEL)
return luaL_error(L, "You cannot access this outside of a level!");
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))
@ -1413,8 +1405,7 @@ static int lib_numlines(lua_State *L)
static int lib_iterateSides(lua_State *L)
{
size_t i = 0;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
return luaL_error(L, "Don't call sides.iterate() directly, use it as 'for side in sides.iterate do <block> end'.");
lua_settop(L, 2);
@ -1432,8 +1423,7 @@ static int lib_iterateSides(lua_State *L)
static int lib_getSide(lua_State *L)
{
int field;
if (gamestate != GS_LEVEL)
return luaL_error(L, "You cannot access this outside of a level!");
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))
@ -1467,8 +1457,7 @@ static int lib_numsides(lua_State *L)
static int lib_iterateVertexes(lua_State *L)
{
size_t i = 0;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
return luaL_error(L, "Don't call vertexes.iterate() directly, use it as 'for vertex in vertexes.iterate do <block> end'.");
lua_settop(L, 2);
@ -1486,8 +1475,7 @@ static int lib_iterateVertexes(lua_State *L)
static int lib_getVertex(lua_State *L)
{
int field;
if (gamestate != GS_LEVEL)
return luaL_error(L, "You cannot access this outside of a level!");
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))
@ -1523,8 +1511,7 @@ static int lib_numvertexes(lua_State *L)
static int lib_iterateSegs(lua_State *L)
{
size_t i = 0;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
return luaL_error(L, "Don't call segs.iterate() directly, use it as 'for seg in segs.iterate do <block> end'.");
lua_settop(L, 2);
@ -1542,8 +1529,7 @@ static int lib_iterateSegs(lua_State *L)
static int lib_getSeg(lua_State *L)
{
int field;
if (gamestate != GS_LEVEL)
return luaL_error(L, "You cannot access this outside of a level!");
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))
@ -1577,8 +1563,7 @@ static int lib_numsegs(lua_State *L)
static int lib_iterateNodes(lua_State *L)
{
size_t i = 0;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
return luaL_error(L, "Don't call nodes.iterate() directly, use it as 'for node in nodes.iterate do <block> end'.");
lua_settop(L, 2);
@ -1596,8 +1581,7 @@ static int lib_iterateNodes(lua_State *L)
static int lib_getNode(lua_State *L)
{
int field;
if (gamestate != GS_LEVEL)
return luaL_error(L, "You cannot access this outside of a level!");
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))

View File

@ -816,8 +816,7 @@ static int mapthing_set(lua_State *L)
static int lib_iterateMapthings(lua_State *L)
{
size_t i = 0;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
return luaL_error(L, "Don't call mapthings.iterate() directly, use it as 'for mapthing in mapthings.iterate do <block> end'.");
lua_settop(L, 2);
@ -835,8 +834,7 @@ static int lib_iterateMapthings(lua_State *L)
static int lib_getMapthing(lua_State *L)
{
int field;
if (gamestate != GS_LEVEL)
return luaL_error(L, "You cannot access this outside of a level!");
INLEVEL
lua_settop(L, 2);
lua_remove(L, 1); // dummy userdata table is unused.
if (lua_isnumber(L, 1))

View File

@ -25,8 +25,7 @@
static int lib_iteratePlayers(lua_State *L)
{
INT32 i = -1;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
if (lua_gettop(L) < 2)
{
//return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do <block> end'.");
@ -53,8 +52,7 @@ static int lib_getPlayer(lua_State *L)
{
const char *field;
// i -> players[i]
if (gamestate != GS_LEVEL)
return luaL_error(L, "You cannot access this outside of a level!");
INLEVEL
if (lua_type(L, 2) == LUA_TNUMBER)
{
lua_Integer i = luaL_checkinteger(L, 2);

View File

@ -15,6 +15,7 @@
#include "m_fixed.h"
#include "doomtype.h"
#include "d_player.h"
#include "g_state.h"
#include "blua/lua.h"
#include "blua/lualib.h"
@ -97,4 +98,7 @@ void COM_Lua_f(void);
// uncomment if you want seg_t/node_t in Lua
// #define HAVE_LUA_SEGS
#define INLEVEL if (gamestate != GS_LEVEL && !titlemapinaction)\
return luaL_error(L, "This can only be used in a level!");
#endif

View File

@ -56,8 +56,7 @@ static int lib_iterateThinkers(lua_State *L)
thinker_t *th = NULL, *next = NULL;
struct iterationState *it;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
it = luaL_checkudata(L, 1, META_ITERATIONSTATE);
@ -112,8 +111,7 @@ static int lib_startIterate(lua_State *L)
{
struct iterationState *it;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
INLEVEL
lua_pushvalue(L, lua_upvalueindex(1));
it = lua_newuserdata(L, sizeof(struct iterationState));

View File

@ -719,6 +719,8 @@ void T_ContinuousFalling(levelspecthink_t *faller)
}
}
P_CheckSector(faller->sector, false); // you might think this is irrelevant. you would be wrong
faller->sector->floorspeed = faller->speed*faller->direction;
faller->sector->ceilspeed = 42;
faller->sector->moved = true;
@ -3029,20 +3031,40 @@ INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed)
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
{
size_t i;
size_t leftmostvertex = 0, rightmostvertex = 0;
size_t topmostvertex = 0, bottommostvertex = 0;
fixed_t leftx, rightx;
fixed_t topy, bottomy;
fixed_t topz, bottomz;
fixed_t widthfactor = FRACUNIT, heightfactor = FRACUNIT;
fixed_t a, b, c;
mobjtype_t type = MT_ROCKCRUMBLE1;
fixed_t spacing = (32<<FRACBITS);
tic_t lifetime = 3*TICRATE;
INT16 flags = 0;
size_t i, leftmostvertex, rightmostvertex, topmostvertex, bottommostvertex;
fixed_t leftx, rightx, topy, bottomy, topz, bottomz, widthfactor, heightfactor, a, b, c, spacing;
mobjtype_t type;
tic_t lifetime;
INT16 flags;
#define controlsec rover->master->frontsector
sector_t *controlsec = rover->master->frontsector;
if (sec == NULL)
{
if (controlsec->numattached)
{
for (i = 0; i < controlsec->numattached; i++)
{
sec = &sectors[controlsec->attached[i]];
if (!sec->ffloors)
continue;
for (rover = sec->ffloors; rover; rover = rover->next)
{
if (rover->master->frontsector == controlsec)
EV_CrumbleChain(sec, rover);
}
}
}
return;
}
leftmostvertex = rightmostvertex = topmostvertex = bottommostvertex = 0;
widthfactor = heightfactor = FRACUNIT;
spacing = (32<<FRACBITS);
type = MT_ROCKCRUMBLE1;
lifetime = 3*TICRATE;
flags = 0;
if (controlsec->tag != 0)
{

View File

@ -670,7 +670,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_DoMatchSuper(player);
}
else
{
emeralds |= special->info->speed;
stagefailed = false;
}
if (special->target && special->target->type == MT_EMERALDSPAWN)
{
@ -3652,7 +3655,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
{
INT32 i;
mobj_t *mo;
angle_t fa;
angle_t fa, va;
fixed_t ns;
fixed_t z;
boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap));
@ -3674,6 +3677,11 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
// Spill weapons first
P_PlayerWeaponPanelOrAmmoBurst(player);
if (abs(player->mo->momx) > player->mo->scale || abs(player->mo->momy) > player->mo->scale)
va = R_PointToAngle2(player->mo->momx, player->mo->momy, 0, 0)>>ANGLETOFINESHIFT;
else
va = player->mo->angle>>ANGLETOFINESHIFT;
for (i = 0; i < num_rings; i++)
{
INT32 objType = mobjinfo[MT_RING].reactiontime;
@ -3695,7 +3703,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
P_SetScale(mo, player->mo->scale);
// Angle offset by player angle, then slightly offset by amount of rings
fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT) - ((num_rings-1)*FINEANGLES/32)) & FINEMASK;
fa = ((i*FINEANGLES/16) + va - ((num_rings-1)*FINEANGLES/32)) & FINEMASK;
// Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2.
// Technically a non-SA way of spilling rings. They just so happen to be a little similar.

View File

@ -142,7 +142,7 @@ boolean P_IsObjectOnGround(mobj_t *mo);
boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
boolean P_InSpaceSector(mobj_t *mo);
boolean P_InQuicksand(mobj_t *mo);
boolean P_PlayerHitFloor(player_t *player);
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff);
void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
void P_RestoreMusic(player_t *player);

View File

@ -342,7 +342,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (horizspeed)
{
object->player->drawangle = spring->angle;
if (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0)
if (vertispeed || (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0))
{
object->angle = spring->angle;
@ -2822,7 +2822,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
static boolean P_ThingHeightClip(mobj_t *thing)
{
boolean floormoved;
fixed_t oldfloorz = thing->floorz;
fixed_t oldfloorz = thing->floorz, oldz = thing->z;
ffloor_t *oldfloorrover = thing->floorrover;
ffloor_t *oldceilingrover = thing->ceilingrover;
boolean onfloor = P_IsObjectOnGround(thing);//(thing->z <= thing->floorz);
@ -2881,6 +2881,12 @@ static boolean P_ThingHeightClip(mobj_t *thing)
thing->z = thing->ceilingz - thing->height;
}
if (thing->z != oldz)
{
if (thing->player)
P_PlayerHitFloor(thing->player, false);
}
// debug: be sure it falls to the floor
thing->eflags &= ~MFE_ONGROUND;

View File

@ -1784,7 +1784,7 @@ static void P_PushableCheckBustables(mobj_t *mo)
continue;
}
EV_CrumbleChain(node->m_sector, rover);
EV_CrumbleChain(NULL, rover); // node->m_sector
// Run a linedef executor??
if (rover->master->flags & ML_EFFECT5)
@ -3047,7 +3047,7 @@ static void P_PlayerZMovement(mobj_t *mo)
}
}
clipmomz = P_PlayerHitFloor(mo->player);
clipmomz = P_PlayerHitFloor(mo->player, true);
if (!(mo->player->pflags & PF_SPINNING) && mo->player->powers[pw_carry] != CR_NIGHTSMODE)
mo->player->pflags &= ~PF_STARTDASH;
@ -3129,7 +3129,7 @@ nightsdone:
{
// DO THE MARIO!
if (rover->flags & FF_SHATTERBOTTOM) // Brick block!
EV_CrumbleChain(node->m_sector, rover);
EV_CrumbleChain(NULL, rover); // node->m_sector
else // Question block!
EV_MarioBlock(rover, node->m_sector, mo);
}
@ -11985,6 +11985,15 @@ ML_EFFECT5 : Don't stop thinking when too far away
if (i == MT_YELLOWDIAG || i == MT_REDDIAG)
mobj->angle += ANGLE_22h;
if (i == MT_YELLOWHORIZ || i == MT_REDHORIZ || i == MT_BLUEHORIZ)
{
if (mthing->options & MTF_OBJECTFLIP)
mobj->z -= 16*FRACUNIT;
else
mobj->z += 16*FRACUNIT;
}
if (mobj->flags & MF_NIGHTSITEM)
{
// Spawn already displayed
@ -12012,6 +12021,9 @@ ML_EFFECT5 : Don't stop thinking when too far away
if (mthing->options & MTF_OBJECTSPECIAL)
{
if (i == MT_YELLOWDIAG || i == MT_REDDIAG)
mobj->flags |= MF_NOGRAVITY;
if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0)
{
// flag for strong/weak random boxes
@ -12355,28 +12367,33 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
if (nightsreplace)
ringthing = MT_NIGHTSSTAR;
if (mthing->options & MTF_OBJECTFLIP)
{
z = (
#ifdef ESLOPE
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
#endif
sec->ceilingheight) - mobjinfo[ringthing].height;
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
}
else
{
z = (
#ifdef ESLOPE
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
#endif
sec->floorheight);
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
}
for (r = 1; r <= 5; r++)
{
if (mthing->options & MTF_OBJECTFLIP)
{
z = (
#ifdef ESLOPE
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
#endif
sec->ceilingheight) - mobjinfo[ringthing].height - dist*r;
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
}
z -= dist;
else
{
z = (
#ifdef ESLOPE
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
#endif
sec->floorheight) + dist*r;
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
}
z += dist;
mobj = P_SpawnMobj(x, y, z, ringthing);
@ -12410,31 +12427,36 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime)
closestangle = FixedAngle(mthing->angle*FRACUNIT);
fa = (closestangle >> ANGLETOFINESHIFT);
if (mthing->options & MTF_OBJECTFLIP)
{
z = (
#ifdef ESLOPE
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
#endif
sec->ceilingheight) - mobjinfo[ringthing].height;
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
}
else
{
z = (
#ifdef ESLOPE
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
#endif
sec->floorheight);
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
}
for (r = 1; r <= iterations; r++)
{
x += FixedMul(64*FRACUNIT, FINECOSINE(fa));
y += FixedMul(64*FRACUNIT, FINESINE(fa));
if (mthing->options & MTF_OBJECTFLIP)
{
z = (
#ifdef ESLOPE
sec->c_slope ? P_GetZAt(sec->c_slope, x, y) :
#endif
sec->ceilingheight) - mobjinfo[ringthing].height - 64*FRACUNIT*r;
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
}
z -= 64*FRACUNIT;
else
{
z = (
#ifdef ESLOPE
sec->f_slope ? P_GetZAt(sec->f_slope, x, y) :
#endif
sec->floorheight) + 64*FRACUNIT*r;
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
}
z += 64*FRACUNIT;
mobj = P_SpawnMobj(x, y, z, ringthing);

View File

@ -859,12 +859,7 @@ void P_ReloadRings(void)
mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)
->sector->floorheight>>FRACBITS);
P_SpawnHoopsAndRings(mt,
#ifdef MANIASPHERES
true);
#else
!G_IsSpecialStage(gamemap)); // prevent flashing spheres in special stages
#endif
P_SpawnHoopsAndRings(mt, true);
}
}
for (i = 0; i < numHoops; i++)
@ -878,11 +873,6 @@ void P_SwitchSpheresBonusMode(boolean bonustime)
mobj_t *mo;
thinker_t *th;
#ifndef MANIASPHERES
if (G_IsSpecialStage(gamemap)) // prevent flashing spheres in special stages
return;
#endif
// scan the thinkers to find spheres to switch
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
@ -2215,7 +2205,7 @@ static void P_LevelInitStuff(void)
ssspheres = timeinmap = 0;
// special stage
stagefailed = false;
stagefailed = true; // assume failed unless proven otherwise - P_GiveEmerald or emerald touchspecial
// Reset temporary record data
memset(&ntemprecords, 0, sizeof(nightsdata_t));

View File

@ -4601,7 +4601,10 @@ DoneSection2:
if (player->bot)
break;
if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && player->nightstime > 6)
{
player->nightstime = 6; // Just let P_Ticker take care of the rest.
return;
}
// Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c)
{

View File

@ -518,10 +518,7 @@ static inline void P_DoSpecialStageStuff(void)
}
}
else
{
sstimer = 0;
stagefailed = true;
}
}
}

View File

@ -302,15 +302,39 @@ void P_GiveEmerald(boolean spawnObj)
S_StartSound(NULL, sfx_cgot); // Got the emerald!
emeralds |= (1 << em);
stagefailed = false;
if (spawnObj && playeringame[consoleplayer])
if (spawnObj)
{
// The Chaos Emerald begins to orbit us!
// Only give it to ONE person!
mobj_t *emmo = P_SpawnMobjFromMobj(players[consoleplayer].mo, 0, 0, players[consoleplayer].mo->height, MT_GOTEMERALD);
P_SetTarget(&emmo->target, players[consoleplayer].mo);
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
P_SetTarget(&players[consoleplayer].mo->tracer, emmo);
// Only visibly give it to ONE person!
UINT8 i, pnum = ((playeringame[consoleplayer]) && (!players[consoleplayer].spectator) && (players[consoleplayer].mo)) ? consoleplayer : 255;
for (i = 0; i < MAXPLAYERS; i++)
{
mobj_t *emmo;
if (!playeringame[i])
continue;
if (players[i].spectator)
continue;
if (!players[i].mo)
continue;
emmo = P_SpawnMobjFromMobj(players[i].mo, 0, 0, players[i].mo->height, MT_GOTEMERALD);
P_SetTarget(&emmo->target, players[i].mo);
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
P_SetTarget(&players[i].mo->tracer, emmo);
if (pnum == 255)
{
i = pnum;
continue;
}
if (i == pnum)
continue;
emmo->flags2 |= MF2_DONTDRAW;
}
}
}
@ -597,7 +621,7 @@ static void P_DeNightserizePlayer(player_t *player)
player->mo->skin = &skins[player->skin];
player->followitem = skins[player->skin].followitem;
player->mo->color = player->skincolor;
G_GhostAddColor(GHC_NORMAL);
G_GhostAddColor(GHC_RETURNSKIN);
// Restore aiming angle
if (player == &players[consoleplayer])
@ -615,7 +639,6 @@ static void P_DeNightserizePlayer(player_t *player)
if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE)
players[i].nightstime = 1; // force everyone else to fall too.
player->exiting = 3*TICRATE;
stagefailed = true; // NIGHT OVER
// If you screwed up, kiss your score and ring bonus goodbye.
// But only do this in special stage (and instakill!) In regular stages, wait til we hit the ground.
@ -716,6 +739,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
player->mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor;
player->followitem = skins[DEFAULTNIGHTSSKIN].followitem;
G_GhostAddColor(GHC_NIGHTSSKIN);
}
player->nightstime = player->startedtime = player->lapstartedtime = nighttime*TICRATE;
@ -2007,7 +2031,7 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
//
// Handles player hitting floor surface.
// Returns whether to clip momz.
boolean P_PlayerHitFloor(player_t *player)
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
{
boolean clipmomz;
@ -2015,22 +2039,31 @@ boolean P_PlayerHitFloor(player_t *player)
if ((clipmomz = !(P_CheckDeathPitCollide(player->mo))) && player->mo->health && !player->spectator)
{
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale)))
if (dorollstuff)
{
player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_spin);
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale)))
{
player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_spin);
}
else
player->pflags &= ~PF_SPINNING;
}
else
{
player->pflags &= ~PF_SPINNING;
if (player->pflags & PF_GLIDING) // ground gliding
if (player->pflags & PF_GLIDING) // ground gliding
{
if (dorollstuff)
{
player->skidtime = TICRATE;
player->mo->tics = -1;
}
else if (player->charability2 == CA2_MELEE && (player->panim == PA_ABILITY2 && player->mo->state-states != S_PLAY_MELEE_LANDING))
else
player->pflags &= ~PF_GLIDING;
}
else if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
{
if (player->mo->state-states != S_PLAY_MELEE_LANDING)
{
mobjtype_t type = player->revitem;
P_SetPlayerMobjState(player->mo, S_PLAY_MELEE_LANDING);
@ -2062,45 +2095,48 @@ boolean P_PlayerHitFloor(player_t *player)
P_ReturnThrustY(missile, throwang, mu)); // side to side component
P_Thrust(missile, player->drawangle, mu2); // forward component
P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true);
missile->momz += player->mo->pmomz;
missile->fuse = TICRATE/2;
missile->extravalue2 = ev;
i++;
throwang += ANG30;
}
if (mobjinfo[type].seesound)
if (mobjinfo[type].seesound && missile)
S_StartSound(missile, missile->info->seesound);
}
}
else if (player->pflags & PF_JUMPED || !(player->pflags & PF_SPINNING)
}
else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2)
;
else if (player->pflags & PF_JUMPED || !(player->pflags & PF_SPINNING)
|| player->powers[pw_tailsfly] || player->mo->state-states == S_PLAY_FLY_TIRED)
{
if (player->cmomx || player->cmomy)
{
if (player->cmomx || player->cmomy)
{
if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH)
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
else if ((player->rmomx || player->rmomy)
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
}
else
{
if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH)
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
else if ((player->mo->momx || player->mo->momy)
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
}
if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH)
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
else if ((player->rmomx || player->rmomy)
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
}
else
{
if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH)
P_SetPlayerMobjState(player->mo, S_PLAY_DASH);
else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
else if ((player->mo->momx || player->mo->momy)
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
}
}
@ -2320,7 +2356,7 @@ static void P_CheckBustableBlocks(player_t *player)
//if (metalrecording)
// G_RecordBustup(rover);
EV_CrumbleChain(node->m_sector, rover);
EV_CrumbleChain(NULL, rover); // node->m_sector
// Run a linedef executor??
if (rover->master->flags & ML_EFFECT5)
@ -2537,7 +2573,7 @@ static void P_CheckQuicksand(player_t *player)
player->mo->z = ceilingheight - player->mo->height;
if (player->mo->momz <= 0)
P_PlayerHitFloor(player);
P_PlayerHitFloor(player, false);
}
else
{
@ -2549,7 +2585,7 @@ static void P_CheckQuicksand(player_t *player)
player->mo->z = floorheight;
if (player->mo->momz >= 0)
P_PlayerHitFloor(player);
P_PlayerHitFloor(player, false);
}
friction = abs(rover->master->v1->y - rover->master->v2->y)>>6;
@ -4410,6 +4446,10 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
{
player->mo->z += P_MobjFlip(player->mo);
P_SetObjectMomZ(player->mo, player->mindash, false);
if (P_MobjFlip(player->mo)*player->mo->pmomz > 0)
player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump.
else
player->mo->pmomz = 0;
if (player->mo->eflags & MFE_UNDERWATER)
player->mo->momz >>= 1;
#if 0
@ -11641,7 +11681,6 @@ void P_PlayerAfterThink(player_t *player)
player->followmobj->threshold = player->mo->z;
player->followmobj->movecount = player->panim;
player->followmobj->angle = horizangle;
player->followmobj->scale = player->mo->scale;
P_SetScale(player->followmobj, player->mo->scale);
player->followmobj->destscale = player->mo->destscale;
player->followmobj->radius = player->mo->radius;

View File

@ -1617,12 +1617,8 @@ static void ST_drawNiGHTSHUD(void)
#endif
ST_DrawTopLeftOverlayPatch(16, 8, nbracket);
if (G_IsSpecialStage(gamemap))
#ifdef MANIASPHERES
ST_DrawTopLeftOverlayPatch(24, 16, (
(stplyr->bonustime && (leveltime & 4)) ? nssbon : nsshud));
#else
ST_DrawTopLeftOverlayPatch(24, 16, (nsshud));
#endif
(stplyr->bonustime && (leveltime & 4) && (states[S_BLUESPHEREBONUS].frame & FF_ANIMATE)) ? nssbon : nsshud));
else
ST_DrawTopLeftOverlayPatch(24, 16, *(((stplyr->bonustime) ? nbon : nhud)+((leveltime/2)%12)));