Adapt push/pull point to UDMF

This commit is contained in:
MascaraSnake 2021-12-16 07:00:30 +01:00
parent 2a2d70e7cf
commit ebf692f143
9 changed files with 216 additions and 379 deletions

View file

@ -4504,13 +4504,27 @@ udmf
754
{
title = "Push Point";
title = "Push/Pull Point";
sprite = "GWLGA0";
}
755
{
title = "Pull Point";
sprite = "GWLRA0";
arg0
{
title = "Radius";
}
arg1
{
title = "Strength";
}
arg2
{
title = "Flags";
type = 12;
enum
{
1 = "Fade using XY";
2 = "Push using XYZ";
4 = "Non-exclusive";
}
}
}
756
{

View file

@ -20713,34 +20713,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
// for use with wind and current effects
{ // MT_PULL
755, // doomednum
S_INVISIBLE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8, // radius
8, // height
0, // display offset
10, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_GHOST
-1, // doomednum
S_THOK, // spawnstate

View file

@ -5046,7 +5046,6 @@ typedef enum mobj_type
MT_CRUMBLEOBJ, // Sound generator for crumbling platform
MT_TUBEWAYPOINT,
MT_PUSH,
MT_PULL,
MT_GHOST,
MT_OVERLAY,
MT_ANGLEMAN,

View file

@ -9234,6 +9234,118 @@ static void P_DragonbomberThink(mobj_t *mobj)
#undef DRAGONTURNSPEED
}
static mobj_t *pushmobj;
#define PUSH_FACTOR 7
static inline boolean PIT_PushThing(mobj_t *thing)
{
if (thing->eflags & MFE_PUSHED)
return false;
if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
return false;
if (!pushmobj)
return false;
if (!pushmobj->spawnpoint)
return false;
// Allow this to affect pushable objects at some point?
if (thing->player && !(thing->flags & (MF_NOGRAVITY|MF_NOCLIP)))
{
INT32 dist;
INT32 speed;
INT32 sx = pushmobj->x;
INT32 sy = pushmobj->y;
INT32 sz = pushmobj->z;
fixed_t radius = pushmobj->spawnpoint->args[0] << FRACBITS;
if (pushmobj->spawnpoint->args[2] & TMPP_NOZFADE)
dist = P_AproxDistance(thing->x - sx, thing->y - sy);
else
{
// Make sure the Z is in range
if (thing->z < sz - radius || thing->z > sz + radius)
return false;
dist = P_AproxDistance(P_AproxDistance(thing->x - sx, thing->y - sy), thing->z - sz);
}
speed = (abs(pushmobj->spawnpoint->args[1]) - ((dist>>FRACBITS)>>1))<<(FRACBITS - PUSH_FACTOR - 1);
// If speed <= 0, you're outside the effective radius. You also have
// to be able to see the push/pull source point.
// Written with bits and pieces of P_HomingAttack
if ((speed > 0) && (P_CheckSight(thing, pushmobj)))
{
fixed_t tmpmomx, tmpmomy, tmpmomz;
if (pushmobj->spawnpoint->args[2] & TMPP_PUSHZ)
{
tmpmomx = FixedMul(FixedDiv(sx - thing->x, dist), speed);
tmpmomy = FixedMul(FixedDiv(sy - thing->y, dist), speed);
tmpmomz = FixedMul(FixedDiv(sz - thing->z, dist), speed);
}
else
{
angle_t pushangle = R_PointToAngle2(thing->x, thing->y, sx, sy) >> ANGLETOFINESHIFT;
tmpmomx = FixedMul(speed, FINECOSINE(pushangle));
tmpmomy = FixedMul(speed, FINESINE(pushangle));
tmpmomz = 0;
}
if (pushmobj->spawnpoint->args[1] > 0) // away!
{
tmpmomx *= -1;
tmpmomy *= -1;
tmpmomz *= -1;
}
thing->momx += tmpmomx;
thing->momy += tmpmomy;
thing->momz += tmpmomz;
if (thing->player)
{
thing->player->cmomx += tmpmomx;
thing->player->cmomy += tmpmomy;
thing->player->cmomx = FixedMul(thing->player->cmomx, 0xe800);
thing->player->cmomy = FixedMul(thing->player->cmomy, 0xe800);
}
}
}
if (!(pushmobj->spawnpoint->args[2] & TMPP_NONEXCLUSIVE))
thing->eflags |= MFE_PUSHED;
return true;
}
static void P_PointPushThink(mobj_t *mobj)
{
INT32 xl, xh, yl, yh, bx, by;
fixed_t radius;
if (!mobj->spawnpoint)
return;
// Seek out all pushable things within the force radius of this
// point pusher. Crosses sectors, so use blockmap.
radius = mobj->spawnpoint->args[0] << FRACBITS;
pushmobj = mobj;
xl = (unsigned)(mobj->x - radius - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
xh = (unsigned)(mobj->x + radius - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
yl = (unsigned)(mobj->y - radius - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
yh = (unsigned)(mobj->y + radius - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
P_BlockThingsIterator(bx, by, PIT_PushThing);
}
static boolean P_MobjRegularThink(mobj_t *mobj)
{
if ((mobj->flags & MF_ENEMY) && (mobj->state->nextstate == mobj->info->spawnstate && mobj->tics == 1))
@ -9721,6 +9833,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
else
mobj->rollangle = R_PointToAngle2(0, 0, mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1));
break;
case MT_PUSH:
P_PointPushThink(mobj);
break;
case MT_SPINFIRE:
if (mobj->flags & MF_NOGRAVITY)
{
@ -12956,18 +13071,6 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
blueflag = mobj;
bflagpoint = mobj->spawnpoint;
break;
case MT_PUSH:
case MT_PULL:
mobj->health = 0; // Default behaviour: pushing uses XY, fading uses XYZ
if (mthing->options & MTF_AMBUSH)
mobj->health |= 1; // If ambush is set, push using XYZ
if (mthing->options & MTF_OBJECTSPECIAL)
mobj->health |= 2; // If object special is set, fade using XY
if (G_IsSpecialStage(gamemap))
P_SetMobjState(mobj, (mobj->type == MT_PUSH) ? S_GRAVWELLGREEN : S_GRAVWELLRED);
break;
case MT_NIGHTSSTAR:
if (maptol & TOL_XMAS)
P_SetMobjState(mobj, mobj->info->seestate);

View file

@ -1537,7 +1537,6 @@ typedef enum
tc_scroll,
tc_friction,
tc_pusher,
tc_pointpusher,
tc_laserflash,
tc_lightfade,
tc_executor,
@ -2191,19 +2190,6 @@ static inline void SavePusherThinker(const thinker_t *th, const UINT8 type)
WRITEINT32(save_p, ht->slider);
}
static inline void SavePointPusherThinker(const thinker_t* th, const UINT8 type)
{
const pointpusher_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->magnitude);
WRITEINT32(save_p, ht->radius);
WRITEINT32(save_p, ht->x);
WRITEINT32(save_p, ht->y);
WRITEINT32(save_p, ht->z);
WRITEINT32(save_p, ht->affectee);
WRITEINT32(save_p, ht->exclusive);
}
static void SaveLaserThinker(const thinker_t *th, const UINT8 type)
{
const laserthink_t *ht = (const void *)th;
@ -2523,11 +2509,6 @@ static void P_NetArchiveThinkers(void)
SavePusherThinker(th, tc_pusher);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PointPusher)
{
SavePointPusherThinker(th, tc_pointpusher);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_BounceCheese)
{
SaveBounceCheeseThinker(th, tc_bouncecheese);
@ -3344,21 +3325,6 @@ static thinker_t* LoadPusherThinker(actionf_p1 thinker)
return &ht->thinker;
}
static thinker_t* LoadPointPusherThinker(actionf_p1 thinker)
{
pointpusher_t *ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->magnitude = READINT32(save_p);
ht->radius = READINT32(save_p);
ht->x = READINT32(save_p);
ht->y = READINT32(save_p);
ht->z = READINT32(save_p);
ht->affectee = READINT32(save_p);
ht->exclusive = READINT32(save_p);
ht->source = P_GetPushThing(ht->affectee);
return &ht->thinker;
}
static inline thinker_t* LoadLaserThinker(actionf_p1 thinker)
{
laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
@ -3821,10 +3787,6 @@ static void P_NetUnArchiveThinkers(void)
th = LoadPusherThinker((actionf_p1)T_Pusher);
break;
case tc_pointpusher:
th = LoadPointPusherThinker((actionf_p1)T_PointPusher);
break;
default:
I_Error("P_UnarchiveSpecials: Unknown tclass %d in savegame", tclass);
}

View file

@ -3146,6 +3146,28 @@ static void P_WriteConstant(INT32 constant, char **target)
M_Memcpy(*target, buffer, strlen(buffer) + 1);
}
static line_t *P_FindPointPushLine(taglist_t *list)
{
INT32 i, l;
for (i = 0; i < list->count; i++)
{
mtag_t tag = list->tags[i];
TAG_ITER_LINES(tag, l)
{
if (Tag_FGet(&lines[l].tags) != tag)
continue;
if (lines[l].special != 547)
continue;
return &lines[l];
}
}
return NULL;
}
//For maps in binary format, converts setup of specials to UDMF format.
static void P_ConvertBinaryMap(void)
{
@ -4851,6 +4873,41 @@ static void P_ConvertBinaryMap(void)
{
switch (mapthings[i].type)
{
case 754: //Push point
case 755: //Pull point
{
subsector_t *ss = R_PointInSubsector(mapthings[i].x << FRACBITS, mapthings[i].y << FRACBITS);
sector_t *s;
line_t *line;
if (!ss)
{
CONS_Debug(DBG_GAMELOGIC, "Push/pull point: Placed outside of map bounds!\n");
break;
}
s = ss->sector;
line = P_FindPointPushLine(&s->tags);
if (!line)
{
CONS_Debug(DBG_GAMELOGIC, "Push/pull point: Unable to find line of type 547 tagged to sector %s!\n", sizeu1((size_t)(s - sectors)));
break;
}
mapthings[i].args[0] = mapthings[i].angle;
mapthings[i].args[1] = P_AproxDistance(line->dx >> FRACBITS, line->dy >> FRACBITS);
if (mapthings[i].type == 755)
mapthings[i].args[1] *= -1;
if (mapthings[i].options & MTF_OBJECTSPECIAL)
mapthings[i].args[2] |= TMPP_NOZFADE;
if (mapthings[i].options & MTF_AMBUSH)
mapthings[i].args[2] |= TMPP_PUSHZ;
if (!(line->flags & ML_NOCLIMB))
mapthings[i].args[2] |= TMPP_NONEXCLUSIVE;
mapthings[i].type = 754;
break;
}
case 762: //PolyObject spawn point (crush)
{
INT32 check = -1;

View file

@ -98,7 +98,6 @@ typedef struct
static void P_SpawnScrollers(void);
static void P_SpawnFriction(void);
static void P_SpawnPushers(void);
static void Add_PointPusher(INT32 magnitude, mobj_t *source, INT32 affectee, INT32 exclusive);
static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, fixed_t z_mag, INT32 affectee, INT32 referrer, INT32 exclusive, INT32 slider); //SoM: 3/9/2000
static void Add_MasterDisappearer(tic_t appeartime, tic_t disappeartime, tic_t offset, INT32 line, INT32 sourceline);
static void P_ResetFakeFloorFader(ffloor_t *rover, fade_t *data, boolean finalize);
@ -5331,7 +5330,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I
thinker_t *th;
friction_t *f;
pusher_t *p;
pointpusher_t *pp;
size_t sec2num;
size_t i;
@ -5442,13 +5440,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I
if (p->affectee == (INT32)sec2num)
Add_Pusher(p->type, p->x_mag, p->y_mag, p->z_mag, (INT32)(sec-sectors), p->affectee, p->exclusive, p->slider);
}
else if (th->function.acp1 == (actionf_p1)T_PointPusher)
{
pp = (pointpusher_t *)th;
if (pp->affectee == (INT32)sec2num)
Add_PointPusher(pp->magnitude, pp->source, pp->affectee, pp->exclusive);
}
if(secthinkers) i++;
else th = th->next;
@ -6024,8 +6015,6 @@ void P_SpawnSpecials(boolean fromnetsave)
secthinkers[((friction_t *)th)->affectee].count++;
else if (th->function.acp1 == (actionf_p1)T_Pusher)
secthinkers[((pusher_t *)th)->affectee].count++;
else if (th->function.acp1 == (actionf_p1)T_PointPusher)
secthinkers[((pointpusher_t *)th)->affectee].count++;
}
// Allocate each list, and then zero the count so we can use it to track
@ -6046,8 +6035,6 @@ void P_SpawnSpecials(boolean fromnetsave)
secnum = ((friction_t *)th)->affectee;
else if (th->function.acp1 == (actionf_p1)T_Pusher)
secnum = ((pusher_t *)th)->affectee;
else if (th->function.acp1 == (actionf_p1)T_PointPusher)
secnum = ((pointpusher_t *)th)->affectee;
if (secnum != (size_t)-1)
secthinkers[secnum].thinkers[secthinkers[secnum].count++] = th;
@ -8328,26 +8315,6 @@ static void P_SpawnFriction(void)
#define PUSH_FACTOR 7
static void Add_PointPusher(INT32 magnitude, mobj_t *source, INT32 affectee, INT32 exclusive)
{
pointpusher_t *p = Z_Calloc(sizeof * p, PU_LEVSPEC, NULL);
p->thinker.function.acp1 = (actionf_p1)T_PointPusher;
p->source = source;
p->magnitude = magnitude;
p->exclusive = exclusive;
if (source) // point source exist?
{
p->radius = AngleFixed(source->angle);
p->x = p->source->x;
p->y = p->source->y;
p->z = p->source->z;
}
p->affectee = affectee;
P_AddThinker(THINK_MAIN, &p->thinker);
}
/** Adds a pusher.
*
* \param type Type of push/pull effect.
@ -8382,187 +8349,6 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, fixed_t
P_AddThinker(THINK_MAIN, &p->thinker);
}
// PIT_PushThing determines the angle and magnitude of the effect.
// The object's x and y momentum values are changed.
static pointpusher_t *tmpusher; // pointpusher structure for blockmap searches
/** Applies a point pusher/puller to a thing.
*
* \param thing Thing to be pushed.
* \return True if the thing was pushed.
* \todo Make a more robust P_BlockThingsIterator() so the hidden parameter
* ::tmpusher won't need to be used.
* \sa T_Pusher
*/
static inline boolean PIT_PushThing(mobj_t *thing)
{
if (thing->eflags & MFE_PUSHED)
return false;
if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
return false;
if (!tmpusher->source)
return false;
// Allow this to affect pushable objects at some point?
if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || thing->player->powers[pw_carry] == CR_NIGHTSMODE))
{
INT32 dist;
INT32 speed;
INT32 sx, sy, sz;
sx = tmpusher->x;
sy = tmpusher->y;
sz = tmpusher->z;
// don't fade wrt Z if health & 2 (mapthing has multi flag)
if (tmpusher->source->health & 2)
dist = P_AproxDistance(thing->x - sx,thing->y - sy);
else
{
// Make sure the Z is in range
if (thing->z < sz - tmpusher->radius || thing->z > sz + tmpusher->radius)
return false;
dist = P_AproxDistance(P_AproxDistance(thing->x - sx, thing->y - sy),
thing->z - sz);
}
speed = (tmpusher->magnitude - ((dist>>FRACBITS)>>1))<<(FRACBITS - PUSH_FACTOR - 1);
// If speed <= 0, you're outside the effective radius. You also have
// to be able to see the push/pull source point.
// Written with bits and pieces of P_HomingAttack
if ((speed > 0) && (P_CheckSight(thing, tmpusher->source)))
{
if (thing->player->powers[pw_carry] != CR_NIGHTSMODE)
{
// only push wrt Z if health & 1 (mapthing has ambush flag)
if (tmpusher->source->health & 1)
{
fixed_t tmpmomx, tmpmomy, tmpmomz;
tmpmomx = FixedMul(FixedDiv(sx - thing->x, dist), speed);
tmpmomy = FixedMul(FixedDiv(sy - thing->y, dist), speed);
tmpmomz = FixedMul(FixedDiv(sz - thing->z, dist), speed);
if (tmpusher->source->type == MT_PUSH) // away!
{
tmpmomx *= -1;
tmpmomy *= -1;
tmpmomz *= -1;
}
thing->momx += tmpmomx;
thing->momy += tmpmomy;
thing->momz += tmpmomz;
if (thing->player)
{
thing->player->cmomx += tmpmomx;
thing->player->cmomy += tmpmomy;
thing->player->cmomx = FixedMul(thing->player->cmomx, 0xe800);
thing->player->cmomy = FixedMul(thing->player->cmomy, 0xe800);
}
}
else
{
angle_t pushangle;
pushangle = R_PointToAngle2(thing->x, thing->y, sx, sy);
if (tmpusher->source->type == MT_PUSH)
pushangle += ANGLE_180; // away
pushangle >>= ANGLETOFINESHIFT;
thing->momx += FixedMul(speed, FINECOSINE(pushangle));
thing->momy += FixedMul(speed, FINESINE(pushangle));
if (thing->player)
{
thing->player->cmomx += FixedMul(speed, FINECOSINE(pushangle));
thing->player->cmomy += FixedMul(speed, FINESINE(pushangle));
thing->player->cmomx = FixedMul(thing->player->cmomx, 0xe800);
thing->player->cmomy = FixedMul(thing->player->cmomy, 0xe800);
}
}
}
else
{
//NiGHTS-specific handling.
//By default, pushes and pulls only affect the Z-axis.
//By having the ambush flag, it affects the X-axis.
//By having the object special flag, it affects the Y-axis.
fixed_t tmpmomx, tmpmomy, tmpmomz;
if (tmpusher->source->health & 1)
tmpmomx = FixedMul(FixedDiv(sx - thing->x, dist), speed);
else
tmpmomx = 0;
if (tmpusher->source->health & 2)
tmpmomy = FixedMul(FixedDiv(sy - thing->y, dist), speed);
else
tmpmomy = 0;
tmpmomz = FixedMul(FixedDiv(sz - thing->z, dist), speed);
if (tmpusher->source->type == MT_PUSH) // away!
{
tmpmomx *= -1;
tmpmomy *= -1;
tmpmomz *= -1;
}
thing->momx += tmpmomx;
thing->momy += tmpmomy;
thing->momz += tmpmomz;
if (thing->player)
{
thing->player->cmomx += tmpmomx;
thing->player->cmomy += tmpmomy;
thing->player->cmomx = FixedMul(thing->player->cmomx, 0xe800);
thing->player->cmomy = FixedMul(thing->player->cmomy, 0xe800);
}
}
}
}
if (tmpusher->exclusive)
thing->eflags |= MFE_PUSHED;
return true;
}
void T_PointPusher(pointpusher_t *p)
{
INT32 xl, xh, yl, yh, bx, by;
sector_t *sec = sectors + p->affectee;
// Be sure the special sector type is still turned on. If so, proceed.
// Else, bail out; the sector type has been changed on us.
if (GETSECSPECIAL(sec->special, 3) != 2)
return;
// Seek out all pushable things within the force radius of this
// point pusher. Crosses sectors, so use blockmap.
tmpusher = p; // MT_PUSH/MT_PULL point source
tmbbox[BOXTOP] = p->y + p->radius;
tmbbox[BOXBOTTOM] = p->y - p->radius;
tmbbox[BOXRIGHT] = p->x + p->radius;
tmbbox[BOXLEFT] = p->x - p->radius;
xl = (unsigned)(tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
P_BlockThingsIterator(bx, by, PIT_PushThing);
}
/** Applies a pusher to all affected objects.
*
* \param p Thinker for the pusher effect.
@ -8751,78 +8537,33 @@ void T_Pusher(pusher_t *p)
}
}
/** Gets a push/pull object.
*
* \param s Sector number to look in.
* \return Pointer to the first ::MT_PUSH or ::MT_PULL object found in the
* sector.
* \sa P_GetTeleportDestThing, P_GetStarpostThing, P_GetAltViewThing
*/
mobj_t *P_GetPushThing(UINT32 s)
{
mobj_t *thing;
sector_t *sec;
sec = sectors + s;
thing = sec->thinglist;
while (thing)
{
switch (thing->type)
{
case MT_PUSH:
case MT_PULL:
return thing;
default:
break;
}
thing = thing->snext;
}
return NULL;
}
/** Spawns pushers.
*
* \todo Remove magic numbers.
* \sa P_SpawnSpecials, Add_Pusher
*/
static void P_SpawnPushers(void)
{
size_t i;
line_t *l = lines;
mtag_t tag;
register INT32 s;
mobj_t *thing;
fixed_t length, hspeed, dx, dy;
for (i = 0; i < numlines; i++, l++)
{
tag = Tag_FGet(&l->tags);
switch (l->special)
{
case 541: // wind/current
{
fixed_t length = R_PointToDist2(l->v2->x, l->v2->y, l->v1->x, l->v1->y);
fixed_t hspeed = l->args[1] << FRACBITS;
fixed_t dx = FixedMul(FixedDiv(l->dx, length), hspeed);
fixed_t dy = FixedMul(FixedDiv(l->dy, length), hspeed);
if (l->special != 541)
continue;
if (l->args[0] == 0)
Add_Pusher(l->args[3], dx, dy, l->args[2] << FRACBITS, (INT32)(l->frontsector - sectors), -1, !(l->args[4] & TMPF_NONEXCLUSIVE), !!(l->args[4] & TMPF_SLIDE));
else
{
TAG_ITER_SECTORS(l->args[0], s)
Add_Pusher(l->args[3], dx, dy, l->args[2] << FRACBITS, s, -1, !(l->args[4] & TMPF_NONEXCLUSIVE), !!(l->args[4] & TMPF_SLIDE));
}
break;
}
case 547: // push/pull
TAG_ITER_SECTORS(tag, s)
{
thing = P_GetPushThing(s);
if (thing) // No MT_P* means no effect
Add_PointPusher(P_AproxDistance(l->dx >> FRACBITS, l->dy >> FRACBITS), thing, s, l->flags & ML_NOCLIMB);
}
break;
length = R_PointToDist2(l->v2->x, l->v2->y, l->v1->x, l->v1->y);
hspeed = l->args[1] << FRACBITS;
dx = FixedMul(FixedDiv(l->dx, length), hspeed);
dy = FixedMul(FixedDiv(l->dy, length), hspeed);
if (l->args[0] == 0)
Add_Pusher(l->args[3], dx, dy, l->args[2] << FRACBITS, (INT32)(l->frontsector - sectors), -1, !(l->args[4] & TMPF_NONEXCLUSIVE), !!(l->args[4] & TMPF_SLIDE));
else
{
TAG_ITER_SECTORS(l->args[0], s)
Add_Pusher(l->args[3], dx, dy, l->args[2] << FRACBITS, s, -1, !(l->args[4] & TMPF_NONEXCLUSIVE), !!(l->args[4] & TMPF_SLIDE));
}
}
}

View file

@ -343,6 +343,14 @@ typedef enum
TMPF_NONEXCLUSIVE = 1<<1,
} textmappusherflags_t;
typedef enum
{
TMPP_NOZFADE = 1,
TMPP_PUSHZ = 1<<1,
TMPP_NONEXCLUSIVE = 1<<2,
} textmappointpushflags_t;
// GETSECSPECIAL (specialval, section)
//
// Pulls out the special # from a particular section.
@ -874,17 +882,6 @@ typedef struct
INT32 slider; /// < Should the player go into an uncontrollable slide?
} pusher_t;
typedef struct
{
thinker_t thinker; ///< Thinker structure for push/pull effect.
mobj_t *source; ///< Point source.
INT32 magnitude; ///< Vector strength.
INT32 radius; ///< Effective radius.
INT32 x, y, z; ///< Point source.
INT32 affectee; ///< Number of affected sector.
INT32 exclusive; /// < Once this affect has been applied to a mobj, no other pushers may affect it.
} pointpusher_t;
// Model for disappearing/reappearing FOFs
typedef struct
{
@ -941,10 +938,8 @@ typedef struct
void T_FadeColormap(fadecolormap_t *d);
// Prototype functions for pushers
// Prototype function for pushers
void T_Pusher(pusher_t *p);
void T_PointPusher(pointpusher_t *p);
mobj_t *P_GetPushThing(UINT32 s);
// Plane displacement
typedef struct

View file

@ -66,8 +66,7 @@ void Command_Numthinkers_f(void)
"\t2: P_NullPrecipThinker\n"
"\t3: T_Friction\n"
"\t4: T_Pusher\n"
"\t5: T_PointPusher\n"
"\t6: P_RemoveThinkerDelayed\n");
"\t5: P_RemoveThinkerDelayed\n");
return;
}
@ -104,11 +103,6 @@ void Command_Numthinkers_f(void)
CONS_Printf(M_GetText("Number of %s: "), "T_Pusher");
break;
case 5:
start = end = THINK_MAIN;
action = (actionf_p1)T_PointPusher;
CONS_Printf(M_GetText("Number of %s: "), "T_PointPusher");
break;
case 6:
action = (actionf_p1)P_RemoveThinkerDelayed;
CONS_Printf(M_GetText("Number of %s: "), "P_RemoveThinkerDelayed");
break;