mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 17:22:12 +00:00
Merge branch 'master' of http://git.magicalgirl.moe/STJr/SRB2Internal.git into patch_hardcode
This commit is contained in:
commit
91cbeb5e1a
9 changed files with 560 additions and 225 deletions
32
src/info.c
32
src/info.c
|
@ -14426,7 +14426,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14453,7 +14453,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14480,7 +14480,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14507,7 +14507,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14534,7 +14534,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14561,7 +14561,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14588,7 +14588,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14615,7 +14615,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14642,7 +14642,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14669,7 +14669,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14696,7 +14696,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14723,7 +14723,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14750,7 +14750,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14777,7 +14777,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14804,7 +14804,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
@ -14831,7 +14831,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
sfx_crumbl, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
|
|
@ -2135,13 +2135,15 @@ void A_Boss1Laser(mobj_t *actor)
|
|||
if (!(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH))
|
||||
{
|
||||
point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET);
|
||||
point->angle = actor->angle;
|
||||
point->fuse = actor->tics+1;
|
||||
P_SetTarget(&point->target, actor->target);
|
||||
P_SetTarget(&actor->target, point);
|
||||
}
|
||||
}
|
||||
/* -- the following was relevant when the MT_EGGMOBILE_TARGET was allowed to move left and right from its path
|
||||
else if (actor->target && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH))
|
||||
actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);
|
||||
actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);*/
|
||||
|
||||
if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)
|
||||
angle = FixedAngle(FixedDiv(actor->tics*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT);
|
||||
|
@ -2191,11 +2193,16 @@ void A_Boss1Laser(mobj_t *actor)
|
|||
// var1:
|
||||
// 0 - accelerative focus with friction
|
||||
// 1 - steady focus with fixed movement speed
|
||||
// var2 = unused
|
||||
// anything else - don't move
|
||||
// var2:
|
||||
// 0 - don't trace target, just move forwards
|
||||
// & 1 - change horizontal angle
|
||||
// & 2 - change vertical angle
|
||||
//
|
||||
void A_FocusTarget(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_FocusTarget", actor))
|
||||
return;
|
||||
|
@ -2204,9 +2211,9 @@ void A_FocusTarget(mobj_t *actor)
|
|||
if (actor->target)
|
||||
{
|
||||
fixed_t speed = FixedMul(actor->info->speed, actor->scale);
|
||||
fixed_t dist = R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y);
|
||||
angle_t vangle = R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist);
|
||||
angle_t hangle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y);
|
||||
fixed_t dist = (locvar2 ? R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y) : speed+1);
|
||||
angle_t hangle = ((locvar2 & 1) ? R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) : actor->angle);
|
||||
angle_t vangle = ((locvar2 & 2) ? R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist) : ANGLE_90);
|
||||
switch(locvar1)
|
||||
{
|
||||
case 0:
|
||||
|
@ -3535,41 +3542,49 @@ void A_ScoreRise(mobj_t *actor)
|
|||
|
||||
// Function: A_ParticleSpawn
|
||||
//
|
||||
// Description: Spawns a particle at a specified interval
|
||||
// Description: Hyper-specialised function for spawning a particle for MT_PARTICLEGEN.
|
||||
//
|
||||
// var1 = type (if 0, defaults to MT_PARTICLE)
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_ParticleSpawn(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
fixed_t speed;
|
||||
mobjtype_t type;
|
||||
INT32 i = 0;
|
||||
mobj_t *spawn;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_ParticleSpawn", actor))
|
||||
return;
|
||||
#endif
|
||||
if (!actor->spawnpoint)
|
||||
{
|
||||
P_RemoveMobj(actor);
|
||||
if (!actor->health)
|
||||
return;
|
||||
|
||||
if (!actor->lastlook)
|
||||
return;
|
||||
|
||||
if (!actor->threshold)
|
||||
return;
|
||||
|
||||
for (i = 0; i < actor->lastlook; i++)
|
||||
{
|
||||
spawn = P_SpawnMobj(
|
||||
actor->x + FixedMul(FixedMul(actor->friction, actor->scale), FINECOSINE(actor->angle>>ANGLETOFINESHIFT)),
|
||||
actor->y + FixedMul(FixedMul(actor->friction, actor->scale), FINESINE(actor->angle>>ANGLETOFINESHIFT)),
|
||||
actor->z,
|
||||
(mobjtype_t)actor->threshold);
|
||||
P_SetScale(spawn, actor->scale);
|
||||
spawn->momz = FixedMul(actor->movefactor, spawn->scale);
|
||||
spawn->destscale = spawn->scale/100;
|
||||
spawn->scalespeed = spawn->scale/actor->health;
|
||||
spawn->tics = (tic_t)actor->health;
|
||||
spawn->flags2 |= (actor->flags2 & MF2_OBJECTFLIP);
|
||||
spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
|
||||
if (spawn->frame & FF_ANIMATE)
|
||||
spawn->frame += P_RandomKey(spawn->state->var1);
|
||||
|
||||
actor->angle += actor->movedir;
|
||||
}
|
||||
|
||||
if (locvar1)
|
||||
type = (mobjtype_t)locvar1;
|
||||
else
|
||||
type = MT_PARTICLE;
|
||||
|
||||
speed = FixedMul((actor->spawnpoint->angle >> 12)<<FRACBITS, actor->scale);
|
||||
|
||||
spawn = P_SpawnMobj(actor->x, actor->y, actor->z, type);
|
||||
P_SetScale(spawn, actor->scale);
|
||||
spawn->momz = speed;
|
||||
spawn->destscale = FixedDiv(spawn->scale<<FRACBITS, 100<<FRACBITS);
|
||||
spawn->scalespeed = FixedDiv(((actor->spawnpoint->angle >> 8) & 63) << FRACBITS, 100<<FRACBITS);
|
||||
actor->tics = actor->spawnpoint->extrainfo + 1;
|
||||
actor->angle += (angle_t)actor->movecount;
|
||||
}
|
||||
|
||||
// Function: A_BunnyHop
|
||||
|
|
141
src/p_floor.c
141
src/p_floor.c
|
@ -13,7 +13,11 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "m_random.h"
|
||||
#include "p_local.h"
|
||||
#ifdef ESLOPE
|
||||
#include "p_slopes.h"
|
||||
#endif
|
||||
#include "r_state.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
|
@ -1141,6 +1145,7 @@ void T_MarioBlock(levelspecthink_t *block)
|
|||
block->sector->ceilingdata = NULL;
|
||||
block->sector->floorspeed = 0;
|
||||
block->sector->ceilspeed = 0;
|
||||
block->direction = 0;
|
||||
}
|
||||
|
||||
for (i = -1; (i = P_FindSectorFromTag((INT16)block->vars[0], i)) >= 0 ;)
|
||||
|
@ -1800,10 +1805,24 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
|
|||
void T_MarioBlockChecker(levelspecthink_t *block)
|
||||
{
|
||||
line_t *masterline = block->sourceline;
|
||||
if (block->vars[2] == 1) // Don't update the textures when the block's being bumped upwards.
|
||||
return;
|
||||
if (SearchMarioNode(block->sector->touching_thinglist))
|
||||
sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture;
|
||||
{
|
||||
sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; // Update textures
|
||||
if (masterline->backsector)
|
||||
{
|
||||
block->sector->ceilingpic = block->sector->floorpic = masterline->backsector->ceilingpic; // Update flats to be backside's ceiling
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture;
|
||||
if (masterline->backsector)
|
||||
{
|
||||
block->sector->ceilingpic = block->sector->floorpic = masterline->backsector->floorpic; // Update flats to be backside's floor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is the Thwomp's 'brain'. It looks around for players nearby, and if
|
||||
|
@ -2523,6 +2542,29 @@ void T_CameraScanner(elevator_t *elevator)
|
|||
}
|
||||
}
|
||||
|
||||
void T_PlaneDisplace(planedisplace_t *pd)
|
||||
{
|
||||
sector_t *control, *target;
|
||||
INT32 direction;
|
||||
fixed_t diff;
|
||||
|
||||
control = §ors[pd->control];
|
||||
target = §ors[pd->affectee];
|
||||
|
||||
if (control->floorheight == pd->last_height)
|
||||
return; // no change, no movement
|
||||
|
||||
direction = (control->floorheight > pd->last_height) ? 1 : -1;
|
||||
diff = FixedMul(control->floorheight-pd->last_height, pd->speed);
|
||||
|
||||
if (pd->type == pd_floor || pd->type == pd_both)
|
||||
T_MovePlane(target, INT32_MAX/2, target->floorheight+diff, 0, 0, direction); // move floor
|
||||
if (pd->type == pd_ceiling || pd->type == pd_both)
|
||||
T_MovePlane(target, INT32_MAX/2, target->ceilingheight+diff, 0, 1, direction); // move ceiling
|
||||
|
||||
pd->last_height = control->floorheight;
|
||||
}
|
||||
|
||||
//
|
||||
// EV_DoFloor
|
||||
//
|
||||
|
@ -2880,18 +2922,41 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
|
|||
size_t topmostvertex = 0, bottommostvertex = 0;
|
||||
fixed_t leftx, rightx;
|
||||
fixed_t topy, bottomy;
|
||||
fixed_t topz;
|
||||
fixed_t topz, bottomz;
|
||||
fixed_t widthfactor, heightfactor;
|
||||
fixed_t a, b, c;
|
||||
mobjtype_t type = MT_ROCKCRUMBLE1;
|
||||
fixed_t spacing = (32<<FRACBITS);
|
||||
tic_t lifetime = 3*TICRATE;
|
||||
INT16 flags = 0;
|
||||
|
||||
// If the control sector has a special
|
||||
// of Section3:7-15, use the custom debris.
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, 3) >= 8)
|
||||
type = MT_ROCKCRUMBLE1+(GETSECSPECIAL(rover->master->frontsector->special, 3)-7);
|
||||
#define controlsec rover->master->frontsector
|
||||
|
||||
if (controlsec->tag != 0)
|
||||
{
|
||||
INT32 tagline = P_FindSpecialLineFromTag(14, controlsec->tag, -1);
|
||||
if (tagline != -1)
|
||||
{
|
||||
if (sides[lines[tagline].sidenum[0]].toptexture)
|
||||
type = (mobjtype_t)sides[lines[tagline].sidenum[0]].toptexture; // Set as object type in p_setup.c...
|
||||
if (sides[lines[tagline].sidenum[0]].textureoffset)
|
||||
spacing = sides[lines[tagline].sidenum[0]].textureoffset;
|
||||
if (sides[lines[tagline].sidenum[0]].rowoffset)
|
||||
{
|
||||
if (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS != -1)
|
||||
lifetime = (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS);
|
||||
else
|
||||
lifetime = 0;
|
||||
}
|
||||
flags = lines[tagline].flags;
|
||||
}
|
||||
}
|
||||
|
||||
#undef controlsec
|
||||
|
||||
// soundorg z height never gets set normally, so MEH.
|
||||
sec->soundorg.z = sec->floorheight;
|
||||
S_StartSound(&sec->soundorg, sfx_crumbl);
|
||||
S_StartSound(&sec->soundorg, mobjinfo[type].activesound);
|
||||
|
||||
// Find the outermost vertexes in the subsector
|
||||
for (i = 0; i < sec->linecount; i++)
|
||||
|
@ -2910,23 +2975,46 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
|
|||
bottommostvertex = i;
|
||||
}
|
||||
|
||||
leftx = sec->lines[leftmostvertex]->v1->x+(16<<FRACBITS);
|
||||
leftx = sec->lines[leftmostvertex]->v1->x+(spacing>>1);
|
||||
rightx = sec->lines[rightmostvertex]->v1->x;
|
||||
topy = sec->lines[topmostvertex]->v1->y-(16<<FRACBITS);
|
||||
topy = sec->lines[topmostvertex]->v1->y-(spacing>>1);
|
||||
bottomy = sec->lines[bottommostvertex]->v1->y;
|
||||
topz = *rover->topheight-(16<<FRACBITS);
|
||||
|
||||
for (a = leftx; a < rightx; a += (32<<FRACBITS))
|
||||
topz = *rover->topheight-(spacing>>1);
|
||||
bottomz = *rover->bottomheight;
|
||||
|
||||
if (flags & ML_EFFECT1)
|
||||
{
|
||||
for (b = topy; b > bottomy; b -= (32<<FRACBITS))
|
||||
widthfactor = (rightx + topy - leftx - bottomy)>>3;
|
||||
heightfactor = (topz - *rover->bottomheight)>>2;
|
||||
}
|
||||
|
||||
for (a = leftx; a < rightx; a += spacing)
|
||||
{
|
||||
for (b = topy; b > bottomy; b -= spacing)
|
||||
{
|
||||
if (R_PointInSubsector(a, b)->sector == sec)
|
||||
{
|
||||
mobj_t *spawned = NULL;
|
||||
for (c = topz; c > *rover->bottomheight; c -= (32<<FRACBITS))
|
||||
#ifdef ESLOPE
|
||||
if (*rover->t_slope)
|
||||
topz = P_GetZAt(*rover->t_slope, a, b) - (spacing>>1);
|
||||
if (*rover->b_slope)
|
||||
bottomz = P_GetZAt(*rover->b_slope, a, b);
|
||||
#endif
|
||||
|
||||
for (c = topz; c > bottomz; c -= spacing)
|
||||
{
|
||||
spawned = P_SpawnMobj(a, b, c, type);
|
||||
spawned->fuse = 3*TICRATE;
|
||||
spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
|
||||
|
||||
if (flags & ML_EFFECT1)
|
||||
{
|
||||
P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor));
|
||||
P_SetObjectMomZ(spawned, FixedDiv((c - bottomz), heightfactor), false);
|
||||
}
|
||||
|
||||
spawned->fuse = lifetime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3086,8 +3174,10 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
|
|||
return 1;
|
||||
}
|
||||
|
||||
INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mobj_t *puncher)
|
||||
INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
|
||||
{
|
||||
sector_t *roversec = rover->master->frontsector;
|
||||
fixed_t topheight = *rover->topheight;
|
||||
levelspecthink_t *block;
|
||||
mobj_t *thing;
|
||||
fixed_t oldx = 0, oldy = 0, oldz = 0;
|
||||
|
@ -3095,11 +3185,14 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
|||
I_Assert(puncher != NULL);
|
||||
I_Assert(puncher->player != NULL);
|
||||
|
||||
if (sec->floordata || sec->ceilingdata)
|
||||
if (roversec->floordata || roversec->ceilingdata)
|
||||
return 0;
|
||||
|
||||
if (!(rover->flags & FF_SOLID))
|
||||
rover->flags |= (FF_SOLID|FF_RENDERALL|FF_CUTLEVEL);
|
||||
|
||||
// Find an item to pop out!
|
||||
thing = SearchMarioNode(sec->touching_thinglist);
|
||||
thing = SearchMarioNode(roversec->touching_thinglist);
|
||||
|
||||
// Found something!
|
||||
if (thing)
|
||||
|
@ -3109,13 +3202,13 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
|||
|
||||
block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL);
|
||||
P_AddThinker(&block->thinker);
|
||||
sec->floordata = block;
|
||||
sec->ceilingdata = block;
|
||||
roversec->floordata = block;
|
||||
roversec->ceilingdata = block;
|
||||
block->thinker.function.acp1 = (actionf_p1)T_MarioBlock;
|
||||
|
||||
// Set up the fields
|
||||
block->sector = sec;
|
||||
block->vars[0] = roversector->tag; // actionsector
|
||||
block->sector = roversec;
|
||||
block->vars[0] = sector->tag; // actionsector
|
||||
block->vars[1] = 4*FRACUNIT; // speed
|
||||
block->vars[2] = 1; // Up // direction
|
||||
block->vars[3] = block->sector->floorheight; // floorwasheight
|
||||
|
@ -3131,8 +3224,8 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
|||
}
|
||||
|
||||
P_UnsetThingPosition(thing);
|
||||
thing->x = roversector->soundorg.x;
|
||||
thing->y = roversector->soundorg.y;
|
||||
thing->x = sector->soundorg.x;
|
||||
thing->y = sector->soundorg.y;
|
||||
thing->z = topheight;
|
||||
thing->momz = FixedMul(6*FRACUNIT, thing->scale);
|
||||
P_SetThingPosition(thing);
|
||||
|
@ -3149,7 +3242,7 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
|||
{
|
||||
if (thing->type == MT_EMMY && thing->spawnpoint && (thing->spawnpoint->options & MTF_OBJECTSPECIAL))
|
||||
{
|
||||
mobj_t *tokenobj = P_SpawnMobj(roversector->soundorg.x, roversector->soundorg.y, topheight, MT_TOKEN);
|
||||
mobj_t *tokenobj = P_SpawnMobj(sector->soundorg.x, sector->soundorg.y, topheight, MT_TOKEN);
|
||||
P_SetTarget(&thing->tracer, tokenobj);
|
||||
P_SetTarget(&tokenobj->target, thing);
|
||||
P_SetMobjState(tokenobj, mobjinfo[MT_TOKEN].seestate);
|
||||
|
|
119
src/p_mobj.c
119
src/p_mobj.c
|
@ -564,7 +564,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
// Adjust the player's animation speed to match their velocity.
|
||||
if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
|
||||
{
|
||||
fixed_t speed;// = FixedDiv(player->speed, mobj->scale);
|
||||
fixed_t speed;// = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor));
|
||||
if (player->panim == PA_FALL)
|
||||
{
|
||||
speed = FixedDiv(abs(mobj->momz), mobj->scale);
|
||||
|
@ -590,7 +590,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
}
|
||||
else
|
||||
{
|
||||
speed = FixedDiv(player->speed, mobj->scale);
|
||||
speed = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor));
|
||||
if (player->panim == PA_ROLL || player->panim == PA_JUMP)
|
||||
{
|
||||
if (speed > 16<<FRACBITS)
|
||||
|
@ -1842,7 +1842,6 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
|
|||
}
|
||||
|
||||
#define STOPSPEED (FRACUNIT)
|
||||
#define FRICTION (ORIG_FRICTION) // 0.90625
|
||||
|
||||
//
|
||||
// P_SceneryXYFriction
|
||||
|
@ -1875,7 +1874,6 @@ static void P_SceneryXYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
|
|||
{
|
||||
// Stolen from P_SpawnFriction
|
||||
mo->friction = FRACUNIT - 0x100;
|
||||
mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158;
|
||||
}
|
||||
else
|
||||
mo->friction = ORIG_FRICTION;
|
||||
|
@ -1900,7 +1898,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
|
|||
// spinning friction
|
||||
if (player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH))
|
||||
{
|
||||
const fixed_t ns = FixedDiv(549*FRICTION,500*FRACUNIT);
|
||||
const fixed_t ns = FixedDiv(549*ORIG_FRICTION,500*FRACUNIT);
|
||||
mo->momx = FixedMul(mo->momx, ns);
|
||||
mo->momy = FixedMul(mo->momy, ns);
|
||||
}
|
||||
|
@ -2409,14 +2407,16 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
|
|||
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||
|
||||
if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected
|
||||
if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should stand on lava or run on water
|
||||
;
|
||||
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
|
||||
continue;
|
||||
else if (rover->flags & FF_QUICKSAND) // quicksand
|
||||
;
|
||||
else if (!((rover->flags & FF_BLOCKPLAYER && mo->player) // solid to players?
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !mo->player))) // solid to others?
|
||||
else if (!( // if it's not either of the following...
|
||||
(rover->flags & (FF_BLOCKPLAYER|FF_MARIO) && mo->player) // ...solid to players? (mario blocks are always solid from beneath to players)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !mo->player) // ...solid to others?
|
||||
)) // ...don't take it into account.
|
||||
continue;
|
||||
if (rover->flags & FF_QUICKSAND)
|
||||
{
|
||||
|
@ -2441,7 +2441,9 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
|
|||
|
||||
delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2));
|
||||
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
|
||||
|
||||
if (topheight > mo->floorz && abs(delta1) < abs(delta2)
|
||||
&& (rover->flags & FF_SOLID) // Non-FF_SOLID Mario blocks are only solid from bottom
|
||||
&& !(rover->flags & FF_REVERSEPLATFORM)
|
||||
&& ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference)
|
||||
{
|
||||
|
@ -2449,7 +2451,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
|
|||
}
|
||||
if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2)
|
||||
&& !(rover->flags & FF_PLATFORM)
|
||||
&& ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below
|
||||
&& ((P_MobjFlip(mo)*mo->momz >= 0) || ((rover->flags & FF_SOLID) && !(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below
|
||||
{
|
||||
mo->ceilingz = bottomheight;
|
||||
}
|
||||
|
@ -2934,7 +2936,6 @@ static boolean P_ZMovement(mobj_t *mo)
|
|||
|
||||
// Stolen from P_SpawnFriction
|
||||
mo->friction = FRACUNIT - 0x100;
|
||||
mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158;
|
||||
}
|
||||
else if (mo->type == MT_FALLINGROCK)
|
||||
{
|
||||
|
@ -3389,8 +3390,13 @@ nightsdone:
|
|||
if (rover->flags & FF_MARIO
|
||||
&& !(mo->eflags & MFE_VERTICALFLIP) // if you were flipped, your head isn't actually hitting your ceilingz is it?
|
||||
&& *rover->bottomheight == mo->ceilingz) // The player's head hit the bottom!
|
||||
{
|
||||
// DO THE MARIO!
|
||||
EV_MarioBlock(rover->master->frontsector, node->m_sector, *rover->topheight, mo);
|
||||
if (rover->flags & FF_SHATTERBOTTOM) // Brick block!
|
||||
EV_CrumbleChain(node->m_sector, rover);
|
||||
else // Question block!
|
||||
EV_MarioBlock(rover, node->m_sector, mo);
|
||||
}
|
||||
}
|
||||
} // Ugly ugly billions of braces! Argh!
|
||||
}
|
||||
|
@ -4551,7 +4557,15 @@ static void P_Boss1Thinker(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
|
||||
if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 && mobj->flags & MF_FLOAT && !(mobj->flags2 & MF2_SKULLFLY))
|
||||
if (mobj->flags2 & MF2_SKULLFLY)
|
||||
{
|
||||
fixed_t dist = (mobj->eflags & MFE_VERTICALFLIP)
|
||||
? ((mobj->ceilingz-(2*mobj->height)) - (mobj->z+mobj->height))
|
||||
: (mobj->z - (mobj->floorz+(2*mobj->height)));
|
||||
if (dist > 0 && P_MobjFlip(mobj)*mobj->momz > 0)
|
||||
mobj->momz = FixedMul(mobj->momz, FRACUNIT - (dist>>12));
|
||||
}
|
||||
else if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 && mobj->flags & MF_FLOAT)
|
||||
mobj->momz = FixedMul(mobj->momz,7*FRACUNIT/8);
|
||||
|
||||
if (mobj->state == &states[mobj->info->meleestate]
|
||||
|
@ -8255,7 +8269,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
|
||||
mobj->friction = ORIG_FRICTION;
|
||||
|
||||
mobj->movefactor = ORIG_FRICTION_FACTOR;
|
||||
mobj->movefactor = FRACUNIT;
|
||||
|
||||
// All mobjs are created at 100% scale.
|
||||
mobj->scale = FRACUNIT;
|
||||
|
@ -9766,6 +9780,85 @@ ML_NOCLIMB : Direction not controllable
|
|||
}
|
||||
break;
|
||||
}
|
||||
case MT_PARTICLEGEN:
|
||||
{
|
||||
fixed_t radius, speed, bottomheight, topheight;
|
||||
INT32 type, numdivisions, time, anglespeed;
|
||||
angle_t angledivision;
|
||||
size_t line;
|
||||
const size_t mthingi = (size_t)(mthing - mapthings);
|
||||
|
||||
for (line = 0; line < numlines; line++)
|
||||
{
|
||||
if (lines[line].special == 15 && lines[line].tag == mthing->angle)
|
||||
break;
|
||||
}
|
||||
|
||||
if (line == numlines)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sides[lines[line].sidenum[0]].toptexture)
|
||||
type = sides[lines[line].sidenum[0]].toptexture; // Set as object type in p_setup.c...
|
||||
else
|
||||
type = (INT32)MT_PARTICLE;
|
||||
|
||||
speed = abs(sides[lines[line].sidenum[0]].textureoffset);
|
||||
bottomheight = lines[line].frontsector->floorheight;
|
||||
topheight = lines[line].frontsector->ceilingheight - mobjinfo[(mobjtype_t)type].height;
|
||||
|
||||
numdivisions = (mthing->options >> ZSHIFT);
|
||||
|
||||
if (numdivisions)
|
||||
{
|
||||
radius = R_PointToDist2(lines[line].v1->x, lines[line].v1->y, lines[line].v2->x, lines[line].v2->y);
|
||||
anglespeed = (sides[lines[line].sidenum[0]].rowoffset >> FRACBITS) % 360;
|
||||
angledivision = 360/numdivisions;
|
||||
}
|
||||
else
|
||||
{
|
||||
numdivisions = 1; // Simple trick to make A_ParticleSpawn simpler.
|
||||
radius = 0;
|
||||
anglespeed = 0;
|
||||
angledivision = 0;
|
||||
}
|
||||
|
||||
if ((speed) && (topheight > bottomheight))
|
||||
time = (INT32)(FixedDiv((topheight - bottomheight), speed) >> FRACBITS);
|
||||
else
|
||||
time = 1; // There's no reasonable way to set it, so just show the object for one tic and move on.
|
||||
|
||||
if (mthing->options & MTF_OBJECTFLIP)
|
||||
{
|
||||
mobj->z = topheight;
|
||||
speed *= -1;
|
||||
}
|
||||
else
|
||||
mobj->z = bottomheight;
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Particle Generator (mapthing #%s):\n"
|
||||
"Radius is %d\n"
|
||||
"Speed is %d\n"
|
||||
"Anglespeed is %d\n"
|
||||
"Numdivisions is %d\n"
|
||||
"Angledivision is %d\n"
|
||||
"Time is %d\n"
|
||||
"Type is %d\n",
|
||||
sizeu1(mthingi), radius, speed, anglespeed, numdivisions, angledivision, time, type);
|
||||
|
||||
mobj->angle = 0;
|
||||
mobj->movefactor = speed;
|
||||
mobj->lastlook = numdivisions;
|
||||
mobj->movedir = angledivision*ANG1;
|
||||
mobj->movecount = anglespeed*ANG1;
|
||||
mobj->health = time;
|
||||
mobj->friction = radius;
|
||||
mobj->threshold = type;
|
||||
|
||||
break;
|
||||
}
|
||||
case MT_ROCKSPAWNER:
|
||||
mobj->threshold = mthing->angle;
|
||||
mobj->movecount = mthing->extrainfo;
|
||||
|
|
|
@ -974,6 +974,7 @@ typedef enum
|
|||
tc_noenemies,
|
||||
tc_eachtime,
|
||||
tc_disappear,
|
||||
tc_planedisplace,
|
||||
#ifdef POLYOBJECTS
|
||||
tc_polyrotate, // haleyjd 03/26/06: polyobjects
|
||||
tc_polymove,
|
||||
|
@ -1097,7 +1098,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
diff |= MD_TRACER;
|
||||
if (mobj->friction != ORIG_FRICTION)
|
||||
diff |= MD_FRICTION;
|
||||
if (mobj->movefactor != ORIG_FRICTION_FACTOR)
|
||||
if (mobj->movefactor != FRACUNIT)
|
||||
diff |= MD_MOVEFACTOR;
|
||||
if (mobj->fuse)
|
||||
diff |= MD_FUSE;
|
||||
|
@ -1537,6 +1538,21 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEINT32(save_p, ht->exists);
|
||||
}
|
||||
|
||||
//
|
||||
// SavePlaneDisplaceThinker
|
||||
//
|
||||
// Saves a planedisplace_t thinker
|
||||
//
|
||||
static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type)
|
||||
{
|
||||
const planedisplace_t *ht = (const void *)th;
|
||||
WRITEUINT8(save_p, type);
|
||||
WRITEINT32(save_p, ht->affectee);
|
||||
WRITEINT32(save_p, ht->control);
|
||||
WRITEFIXED(save_p, ht->last_height);
|
||||
WRITEFIXED(save_p, ht->speed);
|
||||
WRITEUINT8(save_p, ht->type);
|
||||
}
|
||||
#ifdef POLYOBJECTS
|
||||
|
||||
//
|
||||
|
@ -1818,6 +1834,12 @@ static void P_NetArchiveThinkers(void)
|
|||
SaveDisappearThinker(th, tc_disappear);
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace)
|
||||
{
|
||||
SavePlaneDisplaceThinker(th, tc_planedisplace);
|
||||
continue;
|
||||
}
|
||||
#ifdef POLYOBJECTS
|
||||
else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate)
|
||||
{
|
||||
|
@ -2083,7 +2105,7 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
|||
if (diff & MD_MOVEFACTOR)
|
||||
mobj->movefactor = READFIXED(save_p);
|
||||
else
|
||||
mobj->movefactor = ORIG_FRICTION_FACTOR;
|
||||
mobj->movefactor = FRACUNIT;
|
||||
if (diff & MD_FUSE)
|
||||
mobj->fuse = READINT32(save_p);
|
||||
if (diff & MD_WATERTOP)
|
||||
|
@ -2486,6 +2508,23 @@ static inline void LoadDisappearThinker(actionf_p1 thinker)
|
|||
P_AddThinker(&ht->thinker);
|
||||
}
|
||||
|
||||
//
|
||||
// LoadPlaneDisplaceThinker
|
||||
//
|
||||
// Loads a planedisplace_t thinker
|
||||
//
|
||||
static inline void LoadPlaneDisplaceThinker(actionf_p1 thinker)
|
||||
{
|
||||
planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
ht->affectee = READINT32(save_p);
|
||||
ht->control = READINT32(save_p);
|
||||
ht->last_height = READFIXED(save_p);
|
||||
ht->speed = READFIXED(save_p);
|
||||
ht->type = READUINT8(save_p);
|
||||
P_AddThinker(&ht->thinker);
|
||||
}
|
||||
|
||||
#ifdef POLYOBJECTS
|
||||
|
||||
//
|
||||
|
@ -2769,6 +2808,10 @@ static void P_NetUnArchiveThinkers(void)
|
|||
case tc_disappear:
|
||||
LoadDisappearThinker((actionf_p1)T_Disappear);
|
||||
break;
|
||||
|
||||
case tc_planedisplace:
|
||||
LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace);
|
||||
break;
|
||||
#ifdef POLYOBJECTS
|
||||
case tc_polyrotate:
|
||||
LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate);
|
||||
|
|
|
@ -1561,6 +1561,8 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
|||
sd->text[6] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: // Speed pad parameters
|
||||
case 414: // Play SFX
|
||||
{
|
||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||
|
@ -1574,6 +1576,8 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
|||
break;
|
||||
}
|
||||
|
||||
case 14: // Bustable block parameters
|
||||
case 15: // Fan particle spawner parameters
|
||||
case 425: // Calls P_SetMobjState on calling mobj
|
||||
case 434: // Custom Power
|
||||
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
|
||||
|
|
340
src/p_spec.c
340
src/p_spec.c
|
@ -51,6 +51,9 @@ mobj_t *skyboxmo[2];
|
|||
// Amount (dx, dy) vector linedef is shifted right to get scroll amount
|
||||
#define SCROLL_SHIFT 5
|
||||
|
||||
// This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize.
|
||||
#define MAXFLATSIZE (2048<<FRACBITS)
|
||||
|
||||
/** Animated texture descriptor
|
||||
* This keeps track of an animated texture or an animated flat.
|
||||
* \sa P_UpdateSpecials, P_InitPicAnims, animdef_t
|
||||
|
@ -108,6 +111,7 @@ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinker
|
|||
static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
|
||||
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
|
||||
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer);
|
||||
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee);
|
||||
|
||||
|
||||
//SoM: 3/7/2000: New sturcture without limits.
|
||||
|
@ -2440,7 +2444,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
{
|
||||
fixed_t sfxnum;
|
||||
|
||||
sfxnum = sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS;
|
||||
sfxnum = sides[line->sidenum[0]].toptexture;
|
||||
|
||||
if (line->tag != 0 && line->flags & ML_EFFECT5)
|
||||
{
|
||||
|
@ -3683,14 +3687,13 @@ DoneSection2:
|
|||
// Process Section 3
|
||||
switch (special)
|
||||
{
|
||||
case 1: // Ice/Sludge
|
||||
case 1: // Unused
|
||||
case 2: // Wind/Current
|
||||
case 3: // Ice/Sludge and Wind/Current
|
||||
case 3: // Unused
|
||||
case 4: // Conveyor Belt
|
||||
break;
|
||||
|
||||
case 5: // Speed pad w/o spin
|
||||
case 6: // Speed pad w/ spin
|
||||
case 5: // Speed pad
|
||||
if (player->powers[pw_flashing] != 0 && player->powers[pw_flashing] < TICRATE/2)
|
||||
break;
|
||||
|
||||
|
@ -3700,9 +3703,16 @@ DoneSection2:
|
|||
{
|
||||
angle_t lineangle;
|
||||
fixed_t linespeed;
|
||||
fixed_t sfxnum;
|
||||
|
||||
lineangle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y);
|
||||
linespeed = P_AproxDistance(lines[i].v2->x-lines[i].v1->x, lines[i].v2->y-lines[i].v1->y);
|
||||
linespeed = sides[lines[i].sidenum[0]].textureoffset;
|
||||
|
||||
if (linespeed == 0)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad (tag %d) at zero speed.\n", sector->tag);
|
||||
break;
|
||||
}
|
||||
|
||||
player->mo->angle = lineangle;
|
||||
|
||||
|
@ -3732,7 +3742,7 @@ DoneSection2:
|
|||
|
||||
P_InstaThrust(player->mo, player->mo->angle, linespeed);
|
||||
|
||||
if (GETSECSPECIAL(sector->special, 3) == 6 && (player->charability2 == CA2_SPINDASH))
|
||||
if ((lines[i].flags & ML_EFFECT5) && (player->charability2 == CA2_SPINDASH)) // Roll!
|
||||
{
|
||||
if (!(player->pflags & PF_SPINNING))
|
||||
player->pflags |= PF_SPINNING;
|
||||
|
@ -3741,19 +3751,26 @@ DoneSection2:
|
|||
}
|
||||
|
||||
player->powers[pw_flashing] = TICRATE/3;
|
||||
S_StartSound(player->mo, sfx_spdpad);
|
||||
|
||||
sfxnum = sides[lines[i].sidenum[0]].toptexture;
|
||||
|
||||
if (!sfxnum)
|
||||
sfxnum = sfx_spdpad;
|
||||
|
||||
S_StartSound(player->mo, sfxnum);
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: // Bustable block sprite parameter
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 6: // Unused
|
||||
case 7: // Unused
|
||||
case 8: // Unused
|
||||
case 9: // Unused
|
||||
case 10: // Unused
|
||||
case 11: // Unused
|
||||
case 12: // Unused
|
||||
case 13: // Unused
|
||||
case 14: // Unused
|
||||
case 15: // Unused
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3923,8 +3940,14 @@ DoneSection2:
|
|||
}
|
||||
|
||||
// Grab speed and sequence values
|
||||
speed = abs(lines[lineindex].dx)/8;
|
||||
sequence = abs(lines[lineindex].dy)>>FRACBITS;
|
||||
speed = abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8;
|
||||
sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS;
|
||||
|
||||
if (speed == 0)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence);
|
||||
break;
|
||||
}
|
||||
|
||||
// scan the thinkers
|
||||
// to find the first waypoint
|
||||
|
@ -3996,8 +4019,14 @@ DoneSection2:
|
|||
}
|
||||
|
||||
// Grab speed and sequence values
|
||||
speed = -(abs(lines[lineindex].dx)/8); // Negative means reverse
|
||||
sequence = abs(lines[lineindex].dy)>>FRACBITS;
|
||||
speed = -abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8; // Negative means reverse
|
||||
sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS;
|
||||
|
||||
if (speed == 0)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence);
|
||||
break;
|
||||
}
|
||||
|
||||
// scan the thinkers
|
||||
// to find the last waypoint
|
||||
|
@ -4037,6 +4066,7 @@ DoneSection2:
|
|||
player->speed = speed;
|
||||
player->pflags |= PF_SPINNING;
|
||||
player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
|
||||
player->climbing = 0;
|
||||
|
||||
if (player->mo->state-states != S_PLAY_SPIN)
|
||||
{
|
||||
|
@ -4135,8 +4165,14 @@ DoneSection2:
|
|||
}
|
||||
|
||||
// Grab speed and sequence values
|
||||
speed = abs(lines[lineindex].dx)/8;
|
||||
sequence = abs(lines[lineindex].dy)>>FRACBITS;
|
||||
speed = abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8;
|
||||
sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS;
|
||||
|
||||
if (speed == 0)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence);
|
||||
break;
|
||||
}
|
||||
|
||||
// Find the closest waypoint
|
||||
// Find the preceding waypoint
|
||||
|
@ -4983,7 +5019,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
|
|||
|
||||
if ((flags & FF_MARIO))
|
||||
{
|
||||
P_AddBlockThinker(sec2, master);
|
||||
if (!(flags & FF_SHATTERBOTTOM)) // Don't change the textures of a brick block, just a question block
|
||||
P_AddBlockThinker(sec2, master);
|
||||
CheckForMarioBlocks = true;
|
||||
}
|
||||
|
||||
|
@ -5083,6 +5120,33 @@ static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec)
|
|||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds a plane displacement thinker.
|
||||
* Whenever the "control" sector moves,
|
||||
* the "affectee" sector's floor or ceiling plane moves too!
|
||||
*
|
||||
* \param speed Rate of movement relative to control sector
|
||||
* \param control Control sector.
|
||||
* \param affectee Target sector.
|
||||
* \sa P_SpawnSpecials, T_PlaneDisplace
|
||||
* \author Monster Iestyn
|
||||
*/
|
||||
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee)
|
||||
{
|
||||
planedisplace_t *displace;
|
||||
|
||||
// create and initialize new displacement thinker
|
||||
displace = Z_Calloc(sizeof (*displace), PU_LEVSPEC, NULL);
|
||||
P_AddThinker(&displace->thinker);
|
||||
|
||||
displace->thinker.function.acp1 = (actionf_p1)T_PlaneDisplace;
|
||||
displace->affectee = affectee;
|
||||
displace->control = control;
|
||||
displace->last_height = sectors[control].floorheight;
|
||||
displace->speed = speed;
|
||||
displace->type = type;
|
||||
}
|
||||
|
||||
/** Adds a Mario block thinker, which changes the block's texture between blank
|
||||
* and ? depending on whether it has contents.
|
||||
* Needed in case objects respawn inside.
|
||||
|
@ -5321,7 +5385,7 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto
|
|||
elevator->distance = FixedInt(AngleFixed(angle));
|
||||
}
|
||||
|
||||
static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA;
|
||||
static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT;
|
||||
|
||||
/** Flashes a laser block.
|
||||
*
|
||||
|
@ -5341,10 +5405,12 @@ void T_LaserFlash(laserthink_t *flash)
|
|||
if (!ffloor || !(ffloor->flags & FF_EXISTS))
|
||||
return;
|
||||
|
||||
if (leveltime & 1)
|
||||
ffloor->flags |= FF_RENDERALL;
|
||||
if (leveltime & 2)
|
||||
//ffloor->flags |= FF_RENDERALL;
|
||||
ffloor->alpha = 0xB0;
|
||||
else
|
||||
ffloor->flags &= ~FF_RENDERALL;
|
||||
//ffloor->flags &= ~FF_RENDERALL;
|
||||
ffloor->alpha = 0x90;
|
||||
|
||||
sourcesec = ffloor->master->frontsector; // Less to type!
|
||||
|
||||
|
@ -5572,32 +5638,27 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
// Init line EFFECTs
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
// set line specials to 0 here too, same reason as above
|
||||
if (netgame || multiplayer)
|
||||
if (lines[i].special != 7) // This is a hack. I can at least hope nobody wants to prevent flat alignment with arbitrary skin setups...
|
||||
{
|
||||
// future: nonet flag?
|
||||
}
|
||||
else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY)
|
||||
{
|
||||
lines[i].special = 0;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
||||
// set line specials to 0 here too, same reason as above
|
||||
if (netgame || multiplayer)
|
||||
{
|
||||
// future: nonet flag?
|
||||
}
|
||||
else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY)
|
||||
{
|
||||
lines[i].special = 0;
|
||||
continue;
|
||||
}
|
||||
if (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
|
||||
else
|
||||
{
|
||||
lines[i].special = 0;
|
||||
continue;
|
||||
}
|
||||
if (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX))
|
||||
{
|
||||
lines[i].special = 0;
|
||||
continue;
|
||||
if ((players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
|
||||
|| (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
|
||||
|| (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX)))
|
||||
{
|
||||
lines[i].special = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5643,47 +5704,53 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
break;
|
||||
#endif
|
||||
|
||||
case 7: // Flat alignment
|
||||
if (lines[i].flags & ML_EFFECT4) // Align angle
|
||||
case 7: // Flat alignment - redone by toast
|
||||
if ((lines[i].flags & (ML_NOSONIC|ML_NOTAILS)) != (ML_NOSONIC|ML_NOTAILS)) // If you can do something...
|
||||
{
|
||||
if (!(lines[i].flags & ML_EFFECT5)) // Align floor unless ALLTRIGGER flag is set
|
||||
angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y));
|
||||
fixed_t xoffs;
|
||||
fixed_t yoffs;
|
||||
|
||||
if (lines[i].flags & ML_NOKNUX) // Set offset through x and y texture offsets if NOKNUX flag is set
|
||||
{
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y);
|
||||
xoffs = sides[lines[i].sidenum[0]].textureoffset;
|
||||
yoffs = sides[lines[i].sidenum[0]].rowoffset;
|
||||
}
|
||||
else // Otherwise, set calculated offsets such that line's v1 is the apparent origin
|
||||
{
|
||||
fixed_t cosinecomponent = FINECOSINE(flatangle>>ANGLETOFINESHIFT);
|
||||
fixed_t sinecomponent = FINESINE(flatangle>>ANGLETOFINESHIFT);
|
||||
xoffs = (-FixedMul(lines[i].v1->x, cosinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, sinecomponent) % MAXFLATSIZE); // No danger of overflow thanks to the strategically placed modulo operations.
|
||||
yoffs = (FixedMul(lines[i].v1->x, sinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, cosinecomponent) % MAXFLATSIZE); // Ditto.
|
||||
}
|
||||
|
||||
if (!(lines[i].flags & ML_BOUNCY)) // Align ceiling unless BOUNCY flag is set
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
{
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y);
|
||||
}
|
||||
}
|
||||
else // Do offsets
|
||||
{
|
||||
if (!(lines[i].flags & ML_BLOCKMONSTERS)) // Align floor unless BLOCKMONSTERS flag is set
|
||||
{
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
if (!(lines[i].flags & ML_NOSONIC)) // Modify floor flat alignment unless NOSONIC flag is set
|
||||
{
|
||||
sectors[s].floor_xoffs += lines[i].dx;
|
||||
sectors[s].floor_yoffs += lines[i].dy;
|
||||
sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = flatangle;
|
||||
sectors[s].floor_xoffs += xoffs;
|
||||
sectors[s].floor_yoffs += yoffs;
|
||||
// saved for netgames
|
||||
sectors[s].spawn_flr_xoffs = sectors[s].floor_xoffs;
|
||||
sectors[s].spawn_flr_yoffs = sectors[s].floor_yoffs;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(lines[i].flags & ML_NOCLIMB)) // Align ceiling unless NOCLIMB flag is set
|
||||
{
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
if (!(lines[i].flags & ML_NOTAILS)) // Modify ceiling flat alignment unless NOTAILS flag is set
|
||||
{
|
||||
sectors[s].ceiling_xoffs += lines[i].dx;
|
||||
sectors[s].ceiling_yoffs += lines[i].dy;
|
||||
sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = flatangle;
|
||||
sectors[s].ceiling_xoffs += xoffs;
|
||||
sectors[s].ceiling_yoffs += yoffs;
|
||||
// saved for netgames
|
||||
sectors[s].spawn_ceil_xoffs = sectors[s].ceiling_xoffs;
|
||||
sectors[s].spawn_ceil_yoffs = sectors[s].ceiling_yoffs;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Otherwise, print a helpful warning. Can I do no less?
|
||||
CONS_Alert(CONS_WARNING,
|
||||
M_GetText("Flat alignment linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"),
|
||||
lines[i].tag);
|
||||
break;
|
||||
|
||||
case 8: // Sector Parameters
|
||||
|
@ -5795,6 +5862,19 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
P_AddBridgeThinker(&lines[i], §ors[s]);*/
|
||||
break;
|
||||
|
||||
case 66: // Displace floor by front sector
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
|
||||
break;
|
||||
case 67: // Displace ceiling by front sector
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
|
||||
break;
|
||||
case 68: // Displace both floor AND ceiling by front sector
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
|
||||
break;
|
||||
|
||||
case 100: // FOF (solid, opaque, shadows)
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
|
||||
break;
|
||||
|
@ -5809,11 +5889,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
// Draw the 'insides' of the block too
|
||||
if (lines[i].flags & ML_NOCLIMB)
|
||||
{
|
||||
ffloorflags |= FF_CUTLEVEL;
|
||||
ffloorflags |= FF_BOTHPLANES;
|
||||
ffloorflags |= FF_ALLSIDES;
|
||||
ffloorflags &= ~FF_EXTRA;
|
||||
ffloorflags &= ~FF_CUTEXTRA;
|
||||
ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES;
|
||||
ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA);
|
||||
}
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
|
@ -5920,11 +5997,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
// Draw the 'insides' of the block too
|
||||
if (lines[i].flags & ML_EFFECT2)
|
||||
{
|
||||
ffloorflags |= FF_CUTLEVEL;
|
||||
ffloorflags |= FF_BOTHPLANES;
|
||||
ffloorflags |= FF_ALLSIDES;
|
||||
ffloorflags &= ~FF_EXTRA;
|
||||
ffloorflags &= ~FF_CUTEXTRA;
|
||||
ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES;
|
||||
ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA);
|
||||
}
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
|
@ -5938,11 +6012,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
// Draw the 'insides' of the block too
|
||||
if (lines[i].flags & ML_EFFECT2)
|
||||
{
|
||||
ffloorflags |= FF_CUTLEVEL;
|
||||
ffloorflags |= FF_BOTHPLANES;
|
||||
ffloorflags |= FF_ALLSIDES;
|
||||
ffloorflags &= ~FF_EXTRA;
|
||||
ffloorflags &= ~FF_CUTEXTRA;
|
||||
ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES;
|
||||
ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA);
|
||||
}
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
|
@ -5966,11 +6037,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
// Draw the 'insides' of the block too
|
||||
if (lines[i].flags & ML_EFFECT2)
|
||||
{
|
||||
ffloorflags |= FF_CUTLEVEL;
|
||||
ffloorflags |= FF_BOTHPLANES;
|
||||
ffloorflags |= FF_ALLSIDES;
|
||||
ffloorflags &= ~FF_EXTRA;
|
||||
ffloorflags &= ~FF_CUTEXTRA;
|
||||
ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES;
|
||||
ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA);
|
||||
}
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
|
@ -5984,11 +6052,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
// Draw the 'insides' of the block too
|
||||
if (lines[i].flags & ML_EFFECT2)
|
||||
{
|
||||
ffloorflags |= FF_CUTLEVEL;
|
||||
ffloorflags |= FF_BOTHPLANES;
|
||||
ffloorflags |= FF_ALLSIDES;
|
||||
ffloorflags &= ~FF_EXTRA;
|
||||
ffloorflags &= ~FF_CUTEXTRA;
|
||||
ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES;
|
||||
ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA);
|
||||
}
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
|
@ -6166,7 +6231,13 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
break;
|
||||
|
||||
case 250: // Mario Block
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO, secthinkers);
|
||||
ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO;
|
||||
if (lines[i].flags & ML_NOCLIMB)
|
||||
ffloorflags |= FF_SHATTERBOTTOM;
|
||||
if (lines[i].flags & ML_EFFECT1)
|
||||
ffloorflags &= ~(FF_SOLID|FF_RENDERALL|FF_CUTLEVEL);
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
break;
|
||||
|
||||
case 251: // A THWOMP!
|
||||
|
@ -6180,10 +6251,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
break;
|
||||
|
||||
case 252: // Shatter block (breaks when touched)
|
||||
ffloorflags = FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER;
|
||||
if (lines[i].flags & ML_NOCLIMB)
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP|FF_SHATTER|FF_SHATTERBOTTOM, secthinkers);
|
||||
else
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER, secthinkers);
|
||||
ffloorflags |= FF_SOLID|FF_SHATTERBOTTOM;
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
break;
|
||||
|
||||
case 253: // Translucent shatter block (see 76)
|
||||
|
@ -6191,10 +6263,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
break;
|
||||
|
||||
case 254: // Bustable block
|
||||
ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP;
|
||||
if (lines[i].flags & ML_NOCLIMB)
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP|FF_ONLYKNUX, secthinkers);
|
||||
else
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP, secthinkers);
|
||||
ffloorflags |= FF_ONLYKNUX;
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
break;
|
||||
|
||||
case 255: // Spin bust block (breaks when jumped or spun downwards onto)
|
||||
|
@ -6206,10 +6279,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
break;
|
||||
|
||||
case 257: // Quicksand
|
||||
ffloorflags = FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES;
|
||||
if (lines[i].flags & ML_EFFECT5)
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES|FF_RIPPLE, secthinkers);
|
||||
else
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES, secthinkers);
|
||||
ffloorflags |= FF_RIPPLE;
|
||||
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
break;
|
||||
|
||||
case 258: // Laser block
|
||||
|
@ -6970,7 +7044,6 @@ void T_Disappear(disappear_t *d)
|
|||
/** Adds friction thinker.
|
||||
*
|
||||
* \param friction Friction value, 0xe800 is normal.
|
||||
* \param movefactor Inertia factor.
|
||||
* \param affectee Target sector.
|
||||
* \param roverfriction FOF or not
|
||||
* \sa T_Friction, P_SpawnFriction
|
||||
|
@ -7008,22 +7081,10 @@ void T_Friction(friction_t *f)
|
|||
|
||||
sec = sectors + f->affectee;
|
||||
|
||||
// Make sure the sector type hasn't changed
|
||||
// Get FOF control sector
|
||||
if (f->roverfriction)
|
||||
{
|
||||
referrer = sectors + f->referrer;
|
||||
|
||||
if (!(GETSECSPECIAL(referrer->special, 3) == 1
|
||||
|| GETSECSPECIAL(referrer->special, 3) == 3))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(GETSECSPECIAL(sec->special, 3) == 1
|
||||
|| GETSECSPECIAL(sec->special, 3) == 3))
|
||||
return;
|
||||
}
|
||||
|
||||
// Assign the friction value to players on the floor, non-floating,
|
||||
// and clipped. Normally the object's friction value is kept at
|
||||
// ORIG_FRICTION and this thinker changes it for icy or muddy floors.
|
||||
|
@ -7053,14 +7114,16 @@ void T_Friction(friction_t *f)
|
|||
|| (f->friction < thing->friction))
|
||||
{
|
||||
thing->friction = f->friction;
|
||||
thing->movefactor = f->movefactor;
|
||||
if (thing->player)
|
||||
thing->movefactor = f->movefactor;
|
||||
}
|
||||
}
|
||||
else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction?
|
||||
|| f->friction < thing->friction))
|
||||
{
|
||||
thing->friction = f->friction;
|
||||
thing->movefactor = f->movefactor;
|
||||
if (thing->player)
|
||||
thing->movefactor = f->movefactor;
|
||||
}
|
||||
}
|
||||
node = node->m_thinglist_next;
|
||||
|
@ -7076,33 +7139,32 @@ static void P_SpawnFriction(void)
|
|||
size_t i;
|
||||
line_t *l = lines;
|
||||
register INT32 s;
|
||||
fixed_t length; // line length controls magnitude
|
||||
fixed_t strength; // frontside texture offset controls magnitude
|
||||
fixed_t friction; // friction value to be applied during movement
|
||||
INT32 movefactor; // applied to each player move to simulate inertia
|
||||
|
||||
for (i = 0; i < numlines; i++, l++)
|
||||
if (l->special == 540)
|
||||
{
|
||||
length = P_AproxDistance(l->dx, l->dy)>>FRACBITS;
|
||||
friction = (0x1EB8*length)/0x80 + 0xD000;
|
||||
strength = sides[l->sidenum[0]].textureoffset>>FRACBITS;
|
||||
if (strength > 0) // sludge
|
||||
strength = strength*2; // otherwise, the maximum sludginess value is +967...
|
||||
|
||||
// The following might seem odd. At the time of movement,
|
||||
// the move distance is multiplied by 'friction/0x10000', so a
|
||||
// higher friction value actually means 'less friction'.
|
||||
friction = ORIG_FRICTION - (0x1EB8*strength)/0x80; // ORIG_FRICTION is 0xE800
|
||||
|
||||
if (friction > FRACUNIT)
|
||||
friction = FRACUNIT;
|
||||
if (friction < 0)
|
||||
friction = 0;
|
||||
|
||||
// The following check might seem odd. At the time of movement,
|
||||
// the move distance is multiplied by 'friction/0x10000', so a
|
||||
// higher friction value actually means 'less friction'.
|
||||
|
||||
if (friction > ORIG_FRICTION) // ice
|
||||
movefactor = ((0x10092 - friction)*(0x70))/0x158;
|
||||
movefactor = FixedDiv(ORIG_FRICTION, friction);
|
||||
if (movefactor < FRACUNIT)
|
||||
movefactor = 8*movefactor - 7*FRACUNIT;
|
||||
else
|
||||
movefactor = ((friction - 0xDB34)*(0xA))/0x80;
|
||||
|
||||
// killough 8/28/98: prevent odd situations
|
||||
if (movefactor < 32)
|
||||
movefactor = 32;
|
||||
movefactor = FRACUNIT;
|
||||
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
||||
Add_Friction(friction, movefactor, s, -1);
|
||||
|
@ -7352,12 +7414,10 @@ void T_Pusher(pusher_t *p)
|
|||
{
|
||||
referrer = §ors[p->referrer];
|
||||
|
||||
if (!(GETSECSPECIAL(referrer->special, 3) == 2
|
||||
|| GETSECSPECIAL(referrer->special, 3) == 3))
|
||||
if (GETSECSPECIAL(referrer->special, 3) != 2)
|
||||
return;
|
||||
}
|
||||
else if (!(GETSECSPECIAL(sec->special, 3) == 2
|
||||
|| GETSECSPECIAL(sec->special, 3) == 3))
|
||||
else if (GETSECSPECIAL(sec->special, 3) != 2)
|
||||
return;
|
||||
|
||||
// For constant pushers (wind/current) there are 3 situations:
|
||||
|
|
24
src/p_spec.h
24
src/p_spec.h
|
@ -325,7 +325,7 @@ INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover,
|
|||
|
||||
INT32 EV_DoContinuousFall(sector_t *sec, sector_t *pbacksector, fixed_t spd, boolean backwards);
|
||||
|
||||
INT32 EV_MarioBlock(sector_t *sector, sector_t *roversector, fixed_t topheight, mobj_t *puncher);
|
||||
INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
|
||||
|
||||
void T_MoveFloor(floormove_t *movefloor);
|
||||
|
||||
|
@ -388,7 +388,7 @@ typedef struct
|
|||
{
|
||||
thinker_t thinker; ///< Thinker structure for friction.
|
||||
INT32 friction; ///< Friction value, 0xe800 = normal.
|
||||
INT32 movefactor; ///< Inertia factor when adding to momentum.
|
||||
INT32 movefactor; ///< Inertia factor when adding to momentum, FRACUNIT = normal.
|
||||
INT32 affectee; ///< Number of affected sector.
|
||||
INT32 referrer; ///< If roverfriction == true, then this will contain the sector # of the control sector where the effect was applied.
|
||||
UINT8 roverfriction; ///< flag for whether friction originated from a FOF or not
|
||||
|
@ -450,6 +450,26 @@ void T_Disappear(disappear_t *d);
|
|||
void T_Pusher(pusher_t *p);
|
||||
mobj_t *P_GetPushThing(UINT32 s);
|
||||
|
||||
// Plane displacement
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker; ///< Thinker structure for plane displacement effect.
|
||||
INT32 affectee; ///< Number of affected sector.
|
||||
INT32 control; ///< Control sector used to control plane positions.
|
||||
fixed_t last_height; ///< Last known height of control sector.
|
||||
fixed_t speed; ///< Plane movement speed.
|
||||
/** Types of plane displacement effects.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
pd_floor, ///< Displace floor.
|
||||
pd_ceiling, ///< Displace ceiling.
|
||||
pd_both, ///< Displace both floor AND ceiling.
|
||||
} type;
|
||||
} planedisplace_t;
|
||||
|
||||
void T_PlaneDisplace(planedisplace_t *pd);
|
||||
|
||||
void P_CalcHeight(player_t *player);
|
||||
|
||||
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
|
||||
|
|
|
@ -4797,6 +4797,9 @@ static void P_3dMovement(player_t *player)
|
|||
acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration;
|
||||
}
|
||||
|
||||
if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration...
|
||||
acceleration = FixedMul(acceleration<<FRACBITS, player->mo->movefactor)>>FRACBITS;
|
||||
|
||||
// Forward movement
|
||||
if (player->climbing)
|
||||
{
|
||||
|
@ -6453,7 +6456,7 @@ static void P_SkidStuff(player_t *player)
|
|||
// If your push angle is more than this close to a full 180 degrees, trigger a skid.
|
||||
if (dang > ANGLE_157h)
|
||||
{
|
||||
player->skidtime = TICRATE/2;
|
||||
player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS;
|
||||
S_StartSound(player->mo, sfx_skid);
|
||||
if (player->panim != PA_WALK)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
|
||||
|
@ -6490,6 +6493,9 @@ static void P_MovePlayer(player_t *player)
|
|||
cmd = &player->cmd;
|
||||
runspd = FixedMul(player->runspeed, player->mo->scale);
|
||||
|
||||
// Let's have some movement speed fun on low-friction surfaces, JUST for players... (high friction surfaces shouldn't have any adjustment, since the acceleration in this game is super high and that ends up cheesing high-friction surfaces.)
|
||||
runspd = FixedMul(runspd, player->mo->movefactor);
|
||||
|
||||
// Control relinquishing stuff!
|
||||
if (player->powers[pw_ingoop])
|
||||
player->pflags |= PF_FULLSTASIS;
|
||||
|
@ -6680,6 +6686,7 @@ static void P_MovePlayer(player_t *player)
|
|||
if (!player->mo->momx && !player->mo->momy && !player->mo->momz && player->panim == PA_WALK)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
|
||||
player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame.
|
||||
|
||||
//////////////////
|
||||
//GAMEPLAY STUFF//
|
||||
|
|
Loading…
Reference in a new issue