mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-21 03:11:03 +00:00
Merge branch 'master' of http://git.magicalgirl.moe/STJr/SRB2Internal.git into new_coop
This commit is contained in:
commit
e2a9d47ef6
12 changed files with 450 additions and 204 deletions
|
@ -4681,6 +4681,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_WALLSPIKE5",
|
||||
"S_WALLSPIKE6",
|
||||
"S_WALLSPIKEBASE",
|
||||
"S_WALLSPIKED1",
|
||||
"S_WALLSPIKED2",
|
||||
|
||||
// Starpost
|
||||
"S_STARPOST_IDLE",
|
||||
|
|
26
src/info.c
26
src/info.c
|
@ -1563,13 +1563,13 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// Floor Spike
|
||||
{SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended
|
||||
{SPR_USPK, 5, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2
|
||||
{SPR_USPK, 4, 2, {NULL}, 0, 0, S_SPIKE4}, // S_SPIKE3
|
||||
{SPR_USPK, 1, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2
|
||||
{SPR_USPK, 2, 2, {NULL}, 0, 0, S_SPIKE4}, // S_SPIKE3
|
||||
{SPR_USPK, 3,-1, {A_SpikeRetract}, 0, 0, S_SPIKE5}, // S_SPIKE4 -- Fully retracted
|
||||
{SPR_USPK, 4, 2, {A_Pain}, 0, 0, S_SPIKE6}, // S_SPIKE5
|
||||
{SPR_USPK, 5, 2, {NULL}, 0, 0, S_SPIKE1}, // S_SPIKE6
|
||||
{SPR_USPK, 1,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED1 -- Busted spike particles
|
||||
{SPR_USPK, 2,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2
|
||||
{SPR_USPK, 2, 2, {A_Pain}, 0, 0, S_SPIKE6}, // S_SPIKE5
|
||||
{SPR_USPK, 1, 2, {NULL}, 0, 0, S_SPIKE1}, // S_SPIKE6
|
||||
{SPR_USPK, 4,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED1 -- Busted spike particles
|
||||
{SPR_USPK, 5,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2
|
||||
|
||||
// Wall Spike
|
||||
{SPR_WSPK, 0|FF_PAPERSPRITE,-1, {A_SpikeRetract}, 1, 0, S_WALLSPIKE2}, // S_WALLSPIKE1 -- Fully extended
|
||||
|
@ -1579,6 +1579,8 @@ state_t states[NUMSTATES] =
|
|||
{SPR_WSPK, 2|FF_PAPERSPRITE, 2, {A_Pain}, 0, 0, S_WALLSPIKE6}, // S_WALLSPIKE5
|
||||
{SPR_WSPK, 1|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_WALLSPIKE1}, // S_WALLSPIKE6
|
||||
{SPR_WSPB, 0|FF_PAPERSPRITE,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKEBASE -- Base
|
||||
{SPR_WSPK, 4,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKED1 -- Busted spike particles
|
||||
{SPR_WSPK, 5,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKED2
|
||||
|
||||
// Starpost
|
||||
{SPR_STPT, 0 , -1, {NULL}, 0, 0, S_NULL}, // S_STARPOST_IDLE
|
||||
|
@ -5992,7 +5994,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
|
||||
{ // MT_WALLSPIKE
|
||||
522, // doomednum
|
||||
S_WALLSPIKE1, // spawnstate
|
||||
S_WALLSPIKE1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
@ -6003,11 +6005,11 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_s3k64, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
S_WALLSPIKED1, // deathstate
|
||||
S_WALLSPIKED2, // xdeathstate
|
||||
sfx_mspogo, // deathsound
|
||||
2*TICRATE, // speed
|
||||
32*FRACUNIT, // radius
|
||||
16*FRACUNIT, // radius
|
||||
14*FRACUNIT, // height
|
||||
0, // display offset
|
||||
4, // mass
|
||||
|
@ -6019,7 +6021,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
|
||||
{ // MT_WALLSPIKEBASE
|
||||
-1, // doomednum
|
||||
S_WALLSPIKEBASE, // spawnstate
|
||||
S_WALLSPIKEBASE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
|
|
|
@ -1784,6 +1784,8 @@ typedef enum state
|
|||
S_WALLSPIKE5,
|
||||
S_WALLSPIKE6,
|
||||
S_WALLSPIKEBASE,
|
||||
S_WALLSPIKED1,
|
||||
S_WALLSPIKED2,
|
||||
|
||||
// Starpost
|
||||
S_STARPOST_IDLE,
|
||||
|
|
|
@ -4140,15 +4140,18 @@ void A_SetSolidSteam(mobj_t *actor)
|
|||
#endif
|
||||
actor->flags &= ~MF_NOCLIP;
|
||||
actor->flags |= MF_SOLID;
|
||||
if (P_RandomChance(FRACUNIT/8))
|
||||
if (!(actor->flags2 & MF2_AMBUSH))
|
||||
{
|
||||
if (actor->info->deathsound)
|
||||
S_StartSound(actor, actor->info->deathsound); // Hiss!
|
||||
}
|
||||
else
|
||||
{
|
||||
if (actor->info->painsound)
|
||||
S_StartSound(actor, actor->info->painsound);
|
||||
if (P_RandomChance(FRACUNIT/8))
|
||||
{
|
||||
if (actor->info->deathsound)
|
||||
S_StartSound(actor, actor->info->deathsound); // Hiss!
|
||||
}
|
||||
else
|
||||
{
|
||||
if (actor->info->painsound)
|
||||
S_StartSound(actor, actor->info->painsound);
|
||||
}
|
||||
}
|
||||
|
||||
P_SetObjectMomZ (actor, 1, true);
|
||||
|
|
230
src/p_inter.c
230
src/p_inter.c
|
@ -1692,7 +1692,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
|
|||
if (damagetype == DMG_NUKE) // SH_ARMAGEDDON, armageddon shield
|
||||
str = M_GetText("%s%s's armageddon blast %s %s.\n");
|
||||
else if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && (inflictor->player->pflags & PF_SHIELDABILITY))
|
||||
str = M_GetText("%s%s's flame stomp %s %s.\n");
|
||||
str = M_GetText("%s%s's elemental stomp %s %s.\n");
|
||||
else if (inflictor->player->powers[pw_invulnerability])
|
||||
str = M_GetText("%s%s's invincibility aura %s %s.\n");
|
||||
else if (inflictor->player->powers[pw_super])
|
||||
|
@ -1746,6 +1746,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
|
|||
str = M_GetText("%s was %s by Eggman's nefarious TV magic.\n");
|
||||
break;
|
||||
case MT_SPIKE:
|
||||
case MT_WALLSPIKE:
|
||||
str = M_GetText("%s was %s by spikes.\n");
|
||||
break;
|
||||
default:
|
||||
|
@ -2442,7 +2443,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
else
|
||||
{
|
||||
P_SetObjectMomZ(target, 14*FRACUNIT, false);
|
||||
if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // Spikes
|
||||
if (damagetype == DMG_SPIKE) // Spikes
|
||||
S_StartSound(target, sfx_spkdth);
|
||||
else
|
||||
P_PlayDeathSound(target);
|
||||
|
@ -2504,90 +2505,159 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
}
|
||||
}
|
||||
|
||||
if (target->type == MT_SPIKE && inflictor && target->info->deathstate != S_NULL)
|
||||
if (target->type == MT_SPIKE && target->info->deathstate != S_NULL)
|
||||
{
|
||||
const fixed_t x=target->x,y=target->y,z=target->z;
|
||||
const fixed_t scale=target->scale;
|
||||
const boolean flip=(target->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP;
|
||||
S_StartSound(target,target->info->deathsound);
|
||||
const angle_t ang = ((inflictor) ? inflictor->angle : 0) + ANGLE_90;
|
||||
const fixed_t scale = target->scale;
|
||||
const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale);
|
||||
const UINT16 flip = (target->eflags & MFE_VERTICALFLIP);
|
||||
mobj_t *chunk;
|
||||
fixed_t momz;
|
||||
|
||||
P_SetMobjState(target, target->info->deathstate);
|
||||
target->health = 0;
|
||||
target->angle = inflictor->angle + ANGLE_90;
|
||||
P_UnsetThingPosition(target);
|
||||
target->flags = MF_NOCLIP;
|
||||
target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
||||
target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
||||
if (flip)
|
||||
target->z -= FixedMul(12*FRACUNIT, target->scale);
|
||||
else
|
||||
target->z += FixedMul(12*FRACUNIT, target->scale);
|
||||
P_SetThingPosition(target);
|
||||
P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale));
|
||||
target->momz = FixedMul(7*FRACUNIT, target->scale);
|
||||
if (flip)
|
||||
target->momz = -target->momz;
|
||||
|
||||
if (flip)
|
||||
{
|
||||
target = P_SpawnMobj(x,y,z-FixedMul(12*FRACUNIT, target->scale),MT_SPIKE);
|
||||
target->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
else
|
||||
target = P_SpawnMobj(x,y,z+FixedMul(12*FRACUNIT, target->scale),MT_SPIKE);
|
||||
P_SetMobjState(target, target->info->deathstate);
|
||||
target->health = 0;
|
||||
target->angle = inflictor->angle - ANGLE_90;
|
||||
target->destscale = scale;
|
||||
P_SetScale(target, scale);
|
||||
P_UnsetThingPosition(target);
|
||||
target->flags = MF_NOCLIP;
|
||||
target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
||||
target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
||||
P_SetThingPosition(target);
|
||||
P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale));
|
||||
target->momz = FixedMul(7*FRACUNIT, target->scale);
|
||||
if (flip)
|
||||
target->momz = -target->momz;
|
||||
S_StartSound(target, target->info->deathsound);
|
||||
|
||||
if (target->info->xdeathstate != S_NULL)
|
||||
{
|
||||
target = P_SpawnMobj(x,y,z,MT_SPIKE);
|
||||
momz = 6*scale;
|
||||
if (flip)
|
||||
target->eflags |= MFE_VERTICALFLIP;
|
||||
P_SetMobjState(target, target->info->xdeathstate);
|
||||
target->health = 0;
|
||||
target->angle = inflictor->angle + ANGLE_90;
|
||||
target->destscale = scale;
|
||||
P_SetScale(target, scale);
|
||||
P_UnsetThingPosition(target);
|
||||
target->flags = MF_NOCLIP;
|
||||
target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
||||
target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
||||
P_SetThingPosition(target);
|
||||
P_InstaThrust(target,target->angle,FixedMul(4*FRACUNIT, target->scale));
|
||||
target->momz = FixedMul(6*FRACUNIT, target->scale);
|
||||
if (flip)
|
||||
target->momz = -target->momz;
|
||||
momz *= -1;
|
||||
#define makechunk(angtweak, xmov, ymov) \
|
||||
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE);\
|
||||
chunk->eflags |= flip;\
|
||||
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||
chunk->health = 0;\
|
||||
chunk->angle = angtweak;\
|
||||
chunk->destscale = scale;\
|
||||
P_SetScale(chunk, scale);\
|
||||
P_UnsetThingPosition(chunk);\
|
||||
chunk->flags = MF_NOCLIP;\
|
||||
chunk->x += xmov;\
|
||||
chunk->y += ymov;\
|
||||
P_SetThingPosition(chunk);\
|
||||
P_InstaThrust(chunk,chunk->angle, 4*scale);\
|
||||
chunk->momz = momz
|
||||
|
||||
target = P_SpawnMobj(x,y,z,MT_SPIKE);
|
||||
if (flip)
|
||||
target->eflags |= MFE_VERTICALFLIP;
|
||||
P_SetMobjState(target, target->info->xdeathstate);
|
||||
target->health = 0;
|
||||
target->angle = inflictor->angle - ANGLE_90;
|
||||
target->destscale = scale;
|
||||
P_SetScale(target, scale);
|
||||
P_UnsetThingPosition(target);
|
||||
target->flags = MF_NOCLIP;
|
||||
target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
||||
target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
||||
P_SetThingPosition(target);
|
||||
P_InstaThrust(target,target->angle,FixedMul(4*FRACUNIT, target->scale));
|
||||
target->momz = FixedMul(6*FRACUNIT, target->scale);
|
||||
if (flip)
|
||||
target->momz = -target->momz;
|
||||
makechunk(ang + ANGLE_180, -xoffs, -yoffs);
|
||||
makechunk(ang, xoffs, yoffs);
|
||||
|
||||
#undef makechunk
|
||||
}
|
||||
|
||||
momz = 7*scale;
|
||||
if (flip)
|
||||
momz *= -1;
|
||||
|
||||
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE);
|
||||
chunk->eflags |= flip;
|
||||
|
||||
P_SetMobjState(chunk, target->info->deathstate);
|
||||
chunk->health = 0;
|
||||
chunk->angle = ang + ANGLE_180;
|
||||
chunk->destscale = scale;
|
||||
P_SetScale(chunk, scale);
|
||||
P_UnsetThingPosition(chunk);
|
||||
chunk->flags = MF_NOCLIP;
|
||||
chunk->x -= xoffs;
|
||||
chunk->y -= yoffs;
|
||||
if (flip)
|
||||
chunk->z -= 12*scale;
|
||||
else
|
||||
chunk->z += 12*scale;
|
||||
P_SetThingPosition(chunk);
|
||||
P_InstaThrust(chunk, chunk->angle, 2*scale);
|
||||
chunk->momz = momz;
|
||||
|
||||
P_SetMobjState(target, target->info->deathstate);
|
||||
target->health = 0;
|
||||
target->angle = ang;
|
||||
P_UnsetThingPosition(target);
|
||||
target->flags = MF_NOCLIP;
|
||||
target->x += xoffs;
|
||||
target->y += yoffs;
|
||||
target->z = chunk->z;
|
||||
P_SetThingPosition(target);
|
||||
P_InstaThrust(target, target->angle, 2*scale);
|
||||
target->momz = momz;
|
||||
}
|
||||
else if (target->type == MT_WALLSPIKE && target->info->deathstate != S_NULL)
|
||||
{
|
||||
const angle_t ang = (/*(inflictor) ? inflictor->angle : */target->angle) + ANGLE_90;
|
||||
const fixed_t scale = target->scale;
|
||||
const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale), forwardxoffs = P_ReturnThrustX(target, target->angle, 7*scale), forwardyoffs = P_ReturnThrustY(target, target->angle, 7*scale);
|
||||
const UINT16 flip = (target->eflags & MFE_VERTICALFLIP);
|
||||
mobj_t *chunk;
|
||||
boolean sprflip;
|
||||
|
||||
S_StartSound(target, target->info->deathsound);
|
||||
if (!P_MobjWasRemoved(target->tracer))
|
||||
P_RemoveMobj(target->tracer);
|
||||
|
||||
if (target->info->xdeathstate != S_NULL)
|
||||
{
|
||||
sprflip = P_RandomChance(FRACUNIT/2);
|
||||
|
||||
#define makechunk(angtweak, xmov, ymov) \
|
||||
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE);\
|
||||
chunk->eflags |= flip;\
|
||||
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||
chunk->health = 0;\
|
||||
chunk->angle = target->angle;\
|
||||
chunk->destscale = scale;\
|
||||
P_SetScale(chunk, scale);\
|
||||
P_UnsetThingPosition(chunk);\
|
||||
chunk->flags = MF_NOCLIP;\
|
||||
chunk->x += xmov - forwardxoffs;\
|
||||
chunk->y += ymov - forwardyoffs;\
|
||||
P_SetThingPosition(chunk);\
|
||||
P_InstaThrust(chunk, angtweak, 4*scale);\
|
||||
chunk->momz = P_RandomRange(5, 7)*scale;\
|
||||
if (flip)\
|
||||
chunk->momz *= -1;\
|
||||
if (sprflip)\
|
||||
chunk->frame |= FF_VERTICALFLIP
|
||||
|
||||
makechunk(ang + ANGLE_180, -xoffs, -yoffs);
|
||||
sprflip = !sprflip;
|
||||
makechunk(ang, xoffs, yoffs);
|
||||
|
||||
#undef makechunk
|
||||
}
|
||||
|
||||
sprflip = P_RandomChance(FRACUNIT/2);
|
||||
|
||||
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE);
|
||||
chunk->eflags |= flip;
|
||||
|
||||
P_SetMobjState(chunk, target->info->deathstate);
|
||||
chunk->health = 0;
|
||||
chunk->angle = target->angle;
|
||||
chunk->destscale = scale;
|
||||
P_SetScale(chunk, scale);
|
||||
P_UnsetThingPosition(chunk);
|
||||
chunk->flags = MF_NOCLIP;
|
||||
chunk->x += forwardxoffs - xoffs;
|
||||
chunk->y += forwardyoffs - yoffs;
|
||||
P_SetThingPosition(chunk);
|
||||
P_InstaThrust(chunk, ang + ANGLE_180, 2*scale);
|
||||
chunk->momz = P_RandomRange(5, 7)*scale;
|
||||
if (flip)
|
||||
chunk->momz *= -1;
|
||||
if (sprflip)
|
||||
chunk->frame |= FF_VERTICALFLIP;
|
||||
|
||||
P_SetMobjState(target, target->info->deathstate);
|
||||
target->health = 0;
|
||||
P_UnsetThingPosition(target);
|
||||
target->flags = MF_NOCLIP;
|
||||
target->x += forwardxoffs + xoffs;
|
||||
target->y += forwardyoffs + yoffs;
|
||||
P_SetThingPosition(target);
|
||||
P_InstaThrust(target, ang, 2*scale);
|
||||
target->momz = P_RandomRange(5, 7)*scale;
|
||||
if (flip)
|
||||
target->momz *= -1;
|
||||
if (!sprflip)
|
||||
target->frame |= FF_VERTICALFLIP;
|
||||
}
|
||||
else if (target->player)
|
||||
{
|
||||
|
@ -2923,7 +2993,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes
|
||||
if (damagetype == DMG_SPIKE) // spikes
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
else
|
||||
S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss.
|
||||
|
@ -2952,7 +3022,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
|
|||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes
|
||||
if (damagetype == DMG_SPIKE) // spikes
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
|
||||
if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||
|
|
138
src/p_map.c
138
src/p_map.c
|
@ -439,7 +439,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
// Metal Sonic destroys tiny baby objects.
|
||||
if (tmthing->type == MT_METALSONIC_RACE
|
||||
&& (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) || thing->type == MT_SPIKE))
|
||||
&& (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS)
|
||||
|| (thing->type == MT_SPIKE
|
||||
|| thing->type == MT_WALLSPIKE)))
|
||||
{
|
||||
if ((thing->flags & (MF_ENEMY|MF_BOSS)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE)))
|
||||
return true;
|
||||
|
@ -451,12 +453,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true; // overhead
|
||||
if (tmthing->z + tmthing->height < thing->z)
|
||||
return true; // underneath
|
||||
if (thing->type == MT_SPIKE)
|
||||
if (thing->type == MT_SPIKE
|
||||
|| thing->type == MT_WALLSPIKE)
|
||||
{
|
||||
mobjtype_t type = thing->type;
|
||||
if (thing->flags & MF_SOLID)
|
||||
S_StartSound(tmthing, thing->info->deathsound);
|
||||
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
|
||||
if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale))
|
||||
if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale))
|
||||
P_KillMobj(thing, tmthing, tmthing, 0);
|
||||
}
|
||||
else
|
||||
|
@ -470,10 +474,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
// SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes.
|
||||
if ((tmthing->player)
|
||||
&& (((tmthing->player->charflags & SF_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE)
|
||||
&& (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE))
|
||||
&& (thing->flags & (MF_MONITOR)
|
||||
|| (thing->type == MT_SPIKE
|
||||
|| thing->type == MT_WALLSPIKE)))
|
||||
|| ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY))
|
||||
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2))
|
||||
&& (thing->type == MT_SPIKE))))
|
||||
&& (thing->type == MT_SPIKE
|
||||
|| thing->type == MT_WALLSPIKE))))
|
||||
{
|
||||
if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE)))
|
||||
return true;
|
||||
|
@ -485,12 +492,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true; // overhead
|
||||
if (tmthing->z + tmthing->height < thing->z)
|
||||
return true; // underneath
|
||||
if (thing->type == MT_SPIKE)
|
||||
if (thing->type == MT_SPIKE
|
||||
|| thing->type == MT_WALLSPIKE)
|
||||
{
|
||||
mobjtype_t type = thing->type;
|
||||
if (thing->flags & MF_SOLID)
|
||||
S_StartSound(tmthing, thing->info->deathsound);
|
||||
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
|
||||
if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale))
|
||||
if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale))
|
||||
P_KillMobj(thing, tmthing, tmthing, 0);
|
||||
}
|
||||
else
|
||||
|
@ -937,12 +946,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale)
|
||||
&& thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
|
||||
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && thing->eflags & MFE_VERTICALFLIP))
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
|
||||
}
|
||||
else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale)
|
||||
&& thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
|
||||
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && !(thing->eflags & MFE_VERTICALFLIP)))
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
|
||||
}
|
||||
else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?!
|
||||
{
|
||||
|
@ -951,12 +960,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale)
|
||||
&& tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale)
|
||||
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP))
|
||||
P_DamageMobj(tmthing, thing, thing, 1, 0);
|
||||
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
|
||||
}
|
||||
else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
|
||||
&& tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
|
||||
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP)))
|
||||
P_DamageMobj(tmthing, thing, thing, 1, 0);
|
||||
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
|
||||
}
|
||||
|
||||
if (tmthing->type == MT_WALLSPIKE && tmthing->flags & MF_SOLID && thing->player) // wall spike impales player
|
||||
|
@ -971,15 +980,26 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
if (thing->z + thing->height > bottomz // above bottom
|
||||
&& thing->z < topz) // below top
|
||||
{ // don't check angle, the player was clearly in the way in this case
|
||||
// don't check angle, the player was clearly in the way in this case
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
|
||||
}
|
||||
}
|
||||
else if (thing->type == MT_WALLSPIKE && thing->flags & MF_SOLID && tmthing->player)
|
||||
{
|
||||
fixed_t bottomz, topz;
|
||||
angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y);
|
||||
|
||||
if (P_PlayerInPain(tmthing->player) && (tmthing->momx || tmthing->momy))
|
||||
{
|
||||
angle_t playerangle = R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle;
|
||||
if (playerangle > ANGLE_180)
|
||||
playerangle = InvAngle(playerangle);
|
||||
if (playerangle < ANGLE_90)
|
||||
return true; // Yes, this is intentionally outside the z-height check. No standing on spikes whilst moving away from them.
|
||||
}
|
||||
|
||||
bottomz = thing->z;
|
||||
topz = thing->z + thing->height;
|
||||
|
||||
if (thing->eflags & MFE_VERTICALFLIP)
|
||||
bottomz -= FixedMul(FRACUNIT, thing->scale);
|
||||
else
|
||||
|
@ -989,11 +1009,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
&& tmthing->z < topz // below top
|
||||
&& !P_MobjWasRemoved(thing->tracer)) // this probably wouldn't work if we didn't have a tracer
|
||||
{ // use base as a reference point to determine what angle you touched the spike at
|
||||
angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y);
|
||||
angle_t diffangle = thing->angle - touchangle;
|
||||
if (diffangle > ANGLE_180)
|
||||
diffangle = InvAngle(diffangle);
|
||||
if (diffangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked!
|
||||
touchangle = thing->angle - touchangle;
|
||||
if (touchangle > ANGLE_180)
|
||||
touchangle = InvAngle(touchangle);
|
||||
if (touchangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked!
|
||||
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
|
||||
}
|
||||
}
|
||||
|
@ -1151,12 +1170,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
}
|
||||
}
|
||||
|
||||
if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE))
|
||||
if (!(tmthing->player) && (thing->player))
|
||||
; // no solid thing should ever be able to step up onto a player
|
||||
else if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE))
|
||||
{
|
||||
if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now...
|
||||
return false; // "cancel" P_TryMove via blocking so you keep your current position
|
||||
}
|
||||
else if (tmthing->flags & MF_SPRING && (thing->player || thing->flags & MF_PUSHABLE))
|
||||
else if (tmthing->flags & MF_SPRING && (thing->flags & MF_PUSHABLE))
|
||||
; // Fix a few nasty spring-jumping bugs that happen sometimes.
|
||||
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
|
||||
// unless it's a CTF team monitor and you're on the wrong team
|
||||
|
@ -3093,12 +3114,86 @@ void P_SlideMove(mobj_t *mo)
|
|||
INT16 hitcount = 0;
|
||||
boolean success = false;
|
||||
|
||||
boolean papercol = false;
|
||||
vertex_t v1, v2; // fake vertexes
|
||||
line_t junk; // fake linedef
|
||||
|
||||
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
|
||||
{
|
||||
// Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already.
|
||||
if (tmhitthing->flags & MF_PUSHABLE)
|
||||
return;
|
||||
|
||||
if (tmhitthing->flags & MF_PAPERCOLLISION)
|
||||
{
|
||||
fixed_t cosradius, sinradius, num, den;
|
||||
|
||||
// trace along the three leading corners
|
||||
if (mo->momx > 0)
|
||||
{
|
||||
leadx = mo->x + mo->radius;
|
||||
trailx = mo->x - mo->radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
leadx = mo->x - mo->radius;
|
||||
trailx = mo->x + mo->radius;
|
||||
}
|
||||
|
||||
if (mo->momy > 0)
|
||||
{
|
||||
leady = mo->y + mo->radius;
|
||||
traily = mo->y - mo->radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
leady = mo->y - mo->radius;
|
||||
traily = mo->y + mo->radius;
|
||||
}
|
||||
|
||||
papercol = true;
|
||||
slidemo = mo;
|
||||
bestslideline = &junk;
|
||||
|
||||
cosradius = FixedMul(tmhitthing->radius, FINECOSINE(tmhitthing->angle>>ANGLETOFINESHIFT));
|
||||
sinradius = FixedMul(tmhitthing->radius, FINESINE(tmhitthing->angle>>ANGLETOFINESHIFT));
|
||||
|
||||
v1.x = tmhitthing->x - cosradius;
|
||||
v1.y = tmhitthing->y - sinradius;
|
||||
v2.x = tmhitthing->x + cosradius;
|
||||
v2.y = tmhitthing->y + sinradius;
|
||||
|
||||
junk.v1 = &v1;
|
||||
junk.v2 = &v2;
|
||||
junk.dx = 2*cosradius; // v2.x - v1.x;
|
||||
junk.dy = 2*sinradius; // v2.y - v1.y;
|
||||
|
||||
junk.slopetype = !cosradius ? ST_VERTICAL : !sinradius ? ST_HORIZONTAL :
|
||||
((sinradius > 0) == (cosradius > 0)) ? ST_POSITIVE : ST_NEGATIVE;
|
||||
|
||||
bestslidefrac = FRACUNIT+1;
|
||||
|
||||
den = FixedMul(junk.dy>>8, mo->momx) - FixedMul(junk.dx>>8, mo->momy);
|
||||
|
||||
if (!den)
|
||||
bestslidefrac = 0;
|
||||
else
|
||||
{
|
||||
fixed_t frac;
|
||||
#define P_PaperTraverse(startx, starty) \
|
||||
num = FixedMul((v1.x - leadx)>>8, junk.dy) + FixedMul((leady - v1.y)>>8, junk.dx); \
|
||||
frac = FixedDiv(num, den); \
|
||||
if (frac < bestslidefrac) \
|
||||
bestslidefrac = frac
|
||||
P_PaperTraverse(leadx, leady);
|
||||
P_PaperTraverse(trailx, leady);
|
||||
P_PaperTraverse(leadx, traily);
|
||||
#undef dowork
|
||||
}
|
||||
|
||||
goto papercollision;
|
||||
}
|
||||
|
||||
// Thankfully box collisions are a lot simpler than arbitrary lines. There's only four possible cases.
|
||||
if (mo->y + mo->radius <= tmhitthing->y - tmhitthing->radius)
|
||||
{
|
||||
|
@ -3129,7 +3224,7 @@ void P_SlideMove(mobj_t *mo)
|
|||
bestslideline = NULL;
|
||||
|
||||
retry:
|
||||
if (++hitcount == 3)
|
||||
if ((++hitcount == 3) || papercol)
|
||||
goto stairstep; // don't loop forever
|
||||
|
||||
// trace along the three leading corners
|
||||
|
@ -3171,6 +3266,7 @@ retry:
|
|||
return;
|
||||
}
|
||||
|
||||
papercollision:
|
||||
// move up to the wall
|
||||
if (bestslidefrac == FRACUNIT+1)
|
||||
{
|
||||
|
|
17
src/p_mobj.c
17
src/p_mobj.c
|
@ -2554,8 +2554,9 @@ static boolean P_ZMovement(mobj_t *mo)
|
|||
return true;
|
||||
break;
|
||||
case MT_SPIKE:
|
||||
case MT_WALLSPIKE:
|
||||
// Dead spike particles disappear upon ground contact
|
||||
if ((mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz) && mo->health <= 0)
|
||||
if (!mo->health && (mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz))
|
||||
{
|
||||
P_RemoveMobj(mo);
|
||||
return false;
|
||||
|
@ -7194,16 +7195,18 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK);
|
||||
#if 0
|
||||
if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle
|
||||
{
|
||||
mobj_t *target = mobj->target; // shortcut
|
||||
const fixed_t baseradius = target->radius/2 - FixedMul(FRACUNIT, target->scale);
|
||||
const fixed_t baseradius = target->radius - (target->scale/2); //FixedMul(FRACUNIT/2, target->scale);
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius);
|
||||
mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius);
|
||||
P_SetThingPosition(mobj);
|
||||
mobj->angle = target->angle + ANGLE_90;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case MT_FALLINGROCK:
|
||||
// Despawn rocks here in case zmovement code can't do so (blame slopes)
|
||||
|
@ -9939,8 +9942,8 @@ ML_NOCLIMB : Direction not controllable
|
|||
mobj->flags &= ~MF_SCENERY;
|
||||
mobj->fuse = mthing->angle + mobj->info->speed;
|
||||
}
|
||||
// Use per-thing collision for spikes if the deaf flag is checked.
|
||||
if (mthing->options & MTF_AMBUSH && !metalrecording)
|
||||
// Use per-thing collision for spikes if the deaf flag isn't checked.
|
||||
if (!(mthing->options & MTF_AMBUSH) && !metalrecording)
|
||||
{
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||
|
@ -9956,8 +9959,8 @@ ML_NOCLIMB : Direction not controllable
|
|||
mobj->flags &= ~MF_SCENERY;
|
||||
mobj->fuse = mobj->info->speed;
|
||||
}
|
||||
// Use per-thing collision for spikes if the deaf flag is checked.
|
||||
if (mthing->options & MTF_AMBUSH && !metalrecording)
|
||||
// Use per-thing collision for spikes if the deaf flag isn't checked.
|
||||
if (!(mthing->options & MTF_AMBUSH) && !metalrecording)
|
||||
{
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOCLIPHEIGHT);
|
||||
|
@ -9968,7 +9971,7 @@ ML_NOCLIMB : Direction not controllable
|
|||
// spawn base
|
||||
{
|
||||
const angle_t mobjangle = FixedAngle(mthing->angle*FRACUNIT); // the mobj's own angle hasn't been set quite yet so...
|
||||
const fixed_t baseradius = mobj->radius/2 - FixedMul(FRACUNIT, mobj->scale);
|
||||
const fixed_t baseradius = mobj->radius - mobj->scale;
|
||||
mobj_t *base = P_SpawnMobj(
|
||||
mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius),
|
||||
mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius),
|
||||
|
|
|
@ -1237,7 +1237,7 @@ static void Polyobj_rotateLine(line_t *ld)
|
|||
|
||||
// determine slopetype
|
||||
ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL :
|
||||
FixedDiv(ld->dy, ld->dx) > 0 ? ST_POSITIVE : ST_NEGATIVE;
|
||||
((ld->dy > 0) == (ld->dx > 0)) ? ST_POSITIVE : ST_NEGATIVE;
|
||||
|
||||
// update bounding box
|
||||
if (v1->x < v2->x)
|
||||
|
|
|
@ -1212,7 +1212,7 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
|||
ld->slopetype = ST_VERTICAL;
|
||||
else if (!ld->dy)
|
||||
ld->slopetype = ST_HORIZONTAL;
|
||||
else if (FixedDiv(ld->dy, ld->dx) > 0)
|
||||
else if ((ld->dy > 0) == (ld->dx > 0))
|
||||
ld->slopetype = ST_POSITIVE;
|
||||
else
|
||||
ld->slopetype = ST_NEGATIVE;
|
||||
|
|
|
@ -821,7 +821,10 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
|
|||
|
||||
if (inflictor)
|
||||
{
|
||||
ang = R_PointToAngle2(inflictor->x-inflictor->momx, inflictor->y - inflictor->momy, player->mo->x - player->mo->momx, player->mo->y - player->mo->momy);
|
||||
if (inflictor->type == MT_WALLSPIKE)
|
||||
ang = inflictor->angle;
|
||||
else
|
||||
ang = R_PointToAngle2(inflictor->x-inflictor->momx, inflictor->y - inflictor->momy, player->mo->x - player->mo->momx, player->mo->y - player->mo->momy);
|
||||
|
||||
// explosion and rail rings send you farther back, making it more difficult
|
||||
// to recover
|
||||
|
|
193
src/r_things.c
193
src/r_things.c
|
@ -817,7 +817,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
|
||||
colfunc = basecolfunc; // hack: this isn't resetting properly somewhere.
|
||||
dc_colormap = vis->colormap;
|
||||
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
||||
if (!(vis->cut & SC_PRECIP) && (vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
||||
{
|
||||
// translate certain pixels to white
|
||||
colfunc = transcolfunc;
|
||||
|
@ -832,7 +832,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
{
|
||||
colfunc = transtransfunc;
|
||||
dc_transmap = vis->transmap;
|
||||
if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_>
|
||||
if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_>
|
||||
{
|
||||
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
|
||||
dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE);
|
||||
|
@ -851,7 +851,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
colfunc = transcolfunc;
|
||||
|
||||
// New colormap stuff for skins Tails 06-07-2002
|
||||
if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
|
||||
if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
|
||||
{
|
||||
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
|
||||
dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE);
|
||||
|
@ -881,18 +881,18 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
frac = vis->startfrac;
|
||||
windowtop = windowbottom = sprbotscreen = INT32_MAX;
|
||||
|
||||
if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES)
|
||||
if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES)
|
||||
this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale);
|
||||
if (this_scale <= 0)
|
||||
this_scale = 1;
|
||||
if (this_scale != FRACUNIT)
|
||||
{
|
||||
if (!vis->isScaled)
|
||||
if (!(vis->cut & SC_ISSCALED))
|
||||
{
|
||||
vis->scale = FixedMul(vis->scale, this_scale);
|
||||
vis->scalestep = FixedMul(vis->scalestep, this_scale);
|
||||
vis->xiscale = FixedDiv(vis->xiscale,this_scale);
|
||||
vis->isScaled = true;
|
||||
vis->cut |= SC_ISSCALED;
|
||||
}
|
||||
dc_texturemid = FixedDiv(dc_texturemid,this_scale);
|
||||
}
|
||||
|
@ -934,7 +934,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||
}
|
||||
if (vis->vflip)
|
||||
if (vis->cut & SC_VFLIP)
|
||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||
else
|
||||
R_DrawMaskedColumn(column);
|
||||
|
@ -1013,7 +1013,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
//
|
||||
// R_SplitSprite
|
||||
// runs through a sector's lightlist and
|
||||
static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
|
||||
static void R_SplitSprite(vissprite_t *sprite)
|
||||
{
|
||||
INT32 i, lightnum, lindex;
|
||||
INT16 cutfrac;
|
||||
|
@ -1049,6 +1049,8 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
|
|||
// adjust the heights.
|
||||
newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t));
|
||||
|
||||
newsprite->cut |= (sprite->cut & SC_FLAGMASK);
|
||||
|
||||
sprite->cut |= SC_BOTTOM;
|
||||
sprite->gz = testheight;
|
||||
|
||||
|
@ -1081,15 +1083,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
|
|||
|
||||
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
|
||||
|
||||
/*
|
||||
if (thing->frame & FF_TRANSMASK)
|
||||
;
|
||||
else if (thing->flags2 & MF2_SHADOW)
|
||||
;
|
||||
else
|
||||
*/
|
||||
if (!((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK) || thing->flags2 & MF2_SHADOW)
|
||||
&& (!newsprite->extra_colormap || !newsprite->extra_colormap->fog)))
|
||||
if (!((newsprite->cut & SC_FULLBRIGHT) && (!newsprite->extra_colormap || !newsprite->extra_colormap->fog)))
|
||||
{
|
||||
lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
|
||||
|
||||
|
@ -1109,6 +1103,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
|
|||
//
|
||||
static void R_ProjectSprite(mobj_t *thing)
|
||||
{
|
||||
mobj_t *oldthing = thing;
|
||||
fixed_t tr_x, tr_y;
|
||||
fixed_t gxt, gyt;
|
||||
fixed_t tx, tz;
|
||||
|
@ -1128,6 +1123,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
vissprite_t *vis;
|
||||
|
||||
spritecut_e cut = SC_NONE;
|
||||
|
||||
angle_t ang = 0; // compiler complaints
|
||||
fixed_t iscale;
|
||||
fixed_t scalestep;
|
||||
|
@ -1326,24 +1323,14 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
||||
{
|
||||
fixed_t linkscale;
|
||||
#if 0 // support for chains of linkdraw - probably not network safe to modify mobjs during rendering
|
||||
mobj_t *link, *link2;
|
||||
|
||||
for (link = thing->tracer; (link->tracer && (link->flags2 & MF2_LINKDRAW)); link = link->tracer)
|
||||
link->flags2 &= ~MF2_LINKDRAW; // to prevent infinite loops, otherwise would just be a ;
|
||||
thing = thing->tracer;
|
||||
|
||||
for (link2 = thing->tracer; (link2->tracer && (link2 != link)); link2 = link2->tracer)
|
||||
link->flags2 |= MF2_LINKDRAW; // only needed for correction of the above
|
||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
||||
return;
|
||||
|
||||
if (link->flags2 & MF2_LINKDRAW)
|
||||
link->flags2 &= ~MF2_LINKDRAW; // let's try and make sure this doesn't happen again...
|
||||
|
||||
tr_x = link->x - viewx;
|
||||
tr_y = link->y - viewy;
|
||||
#else
|
||||
tr_x = thing->tracer->x - viewx;
|
||||
tr_y = thing->tracer->y - viewy;
|
||||
#endif
|
||||
tr_x = thing->x - viewx;
|
||||
tr_y = thing->y - viewy;
|
||||
gxt = FixedMul(tr_x, viewcos);
|
||||
gyt = -FixedMul(tr_y, viewsin);
|
||||
tz = gxt-gyt;
|
||||
|
@ -1356,6 +1343,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0)
|
||||
|
||||
sortscale = linkscale; // now make sure it's linked
|
||||
cut = SC_LINKDRAW;
|
||||
}
|
||||
|
||||
// PORTAL SPRITE CLIPPING
|
||||
|
@ -1374,12 +1362,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
|
||||
// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
|
||||
// remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
|
||||
gz = thing->z + thing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||
gz = oldthing->z + oldthing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||
gzt = gz + FixedMul(spritecachedinfo[lump].height, this_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = thing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||
gzt = oldthing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||
gz = gzt - FixedMul(spritecachedinfo[lump].height, this_scale);
|
||||
}
|
||||
|
||||
|
@ -1469,7 +1457,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->sector = thing->subsector->sector;
|
||||
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS);
|
||||
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS);
|
||||
vis->cut = SC_NONE;
|
||||
vis->cut = cut;
|
||||
if (thing->subsector->sector->numlights)
|
||||
vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap;
|
||||
else
|
||||
|
@ -1506,12 +1494,15 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
// specific translucency
|
||||
if (!cv_translucency.value)
|
||||
; // no translucency
|
||||
else if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility)
|
||||
else if (oldthing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility)
|
||||
vis->transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT); // because now the translucency is set through FF_TRANSMASK
|
||||
else if (thing->frame & FF_TRANSMASK)
|
||||
vis->transmap = transtables + (thing->frame & FF_TRANSMASK) - 0x10000;
|
||||
else if (oldthing->frame & FF_TRANSMASK)
|
||||
vis->transmap = transtables + (oldthing->frame & FF_TRANSMASK) - 0x10000;
|
||||
|
||||
if (((thing->frame & FF_FULLBRIGHT) || (thing->flags2 & MF2_SHADOW))
|
||||
if ((oldthing->frame & FF_FULLBRIGHT) || (oldthing->flags2 & MF2_SHADOW))
|
||||
vis->cut |= SC_FULLBRIGHT;
|
||||
|
||||
if (vis->cut & SC_FULLBRIGHT
|
||||
&& (!vis->extra_colormap || !vis->extra_colormap->fog))
|
||||
{
|
||||
// full bright: goggles
|
||||
|
@ -1528,14 +1519,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->colormap = spritelights[lindex];
|
||||
}
|
||||
|
||||
vis->precip = false;
|
||||
|
||||
vis->vflip = vflip;
|
||||
|
||||
vis->isScaled = false;
|
||||
if (vflip)
|
||||
vis->cut |= SC_VFLIP;
|
||||
|
||||
if (thing->subsector->sector->numlights)
|
||||
R_SplitSprite(vis, thing);
|
||||
R_SplitSprite(vis);
|
||||
|
||||
// Debug
|
||||
++objectsdrawn;
|
||||
|
@ -1559,7 +1547,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
fixed_t iscale;
|
||||
|
||||
//SoM: 3/17/2000
|
||||
fixed_t gz ,gzt;
|
||||
fixed_t gz, gzt;
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thing->x - viewx;
|
||||
|
@ -1695,16 +1683,14 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
else
|
||||
vis->transmap = NULL;
|
||||
|
||||
vis->mobj = (mobj_t *)thing;
|
||||
vis->mobjflags = 0;
|
||||
vis->cut = SC_NONE;
|
||||
vis->cut = SC_PRECIP;
|
||||
vis->extra_colormap = thing->subsector->sector->extra_colormap;
|
||||
vis->heightsec = thing->subsector->sector->heightsec;
|
||||
|
||||
// Fullbright
|
||||
vis->colormap = colormaps;
|
||||
vis->precip = true;
|
||||
vis->vflip = false;
|
||||
vis->isScaled = false;
|
||||
}
|
||||
|
||||
// R_AddSprites
|
||||
|
@ -1797,7 +1783,7 @@ static vissprite_t vsprsortedhead;
|
|||
|
||||
void R_SortVisSprites(void)
|
||||
{
|
||||
UINT32 i;
|
||||
UINT32 i, linkedvissprites = 0;
|
||||
vissprite_t *ds, *dsprev, *dsnext, *dsfirst;
|
||||
vissprite_t *best = NULL;
|
||||
vissprite_t unsorted;
|
||||
|
@ -1821,22 +1807,91 @@ void R_SortVisSprites(void)
|
|||
|
||||
ds->next = dsnext;
|
||||
ds->prev = dsprev;
|
||||
ds->linkdraw = NULL;
|
||||
}
|
||||
|
||||
// Fix first and last. ds still points to the last one after the loop
|
||||
dsfirst->prev = &unsorted;
|
||||
unsorted.next = dsfirst;
|
||||
if (ds)
|
||||
{
|
||||
ds->next = &unsorted;
|
||||
ds->linkdraw = NULL;
|
||||
}
|
||||
unsorted.prev = ds;
|
||||
|
||||
// bundle linkdraw
|
||||
for (ds = unsorted.prev; ds != &unsorted; ds = ds->prev)
|
||||
{
|
||||
if (!(ds->cut & SC_LINKDRAW))
|
||||
continue;
|
||||
|
||||
// reuse dsfirst...
|
||||
for (dsfirst = unsorted.prev; dsfirst != &unsorted; dsfirst = dsfirst->prev)
|
||||
{
|
||||
// don't connect if it's also a link
|
||||
if (dsfirst->cut & SC_LINKDRAW)
|
||||
continue;
|
||||
|
||||
// don't connect if it's not the tracer
|
||||
if (dsfirst->mobj != ds->mobj)
|
||||
continue;
|
||||
|
||||
// don't connect if the tracer's top is cut off, but lower than the link's top
|
||||
if ((dsfirst->cut & SC_TOP)
|
||||
&& dsfirst->szt > ds->szt)
|
||||
continue;
|
||||
|
||||
// don't connect if the tracer's bottom is cut off, but higher than the link's bottom
|
||||
if ((dsfirst->cut & SC_BOTTOM)
|
||||
&& dsfirst->sz < ds->sz)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// remove from chain
|
||||
ds->next->prev = ds->prev;
|
||||
ds->prev->next = ds->next;
|
||||
linkedvissprites++;
|
||||
|
||||
if (dsfirst != &unsorted)
|
||||
{
|
||||
if (!(ds->cut & SC_FULLBRIGHT))
|
||||
ds->colormap = dsfirst->colormap;
|
||||
ds->extra_colormap = dsfirst->extra_colormap;
|
||||
|
||||
// reusing dsnext...
|
||||
dsnext = dsfirst->linkdraw;
|
||||
|
||||
if (!dsnext || ds->dispoffset < dsnext->dispoffset)
|
||||
{
|
||||
ds->next = dsnext;
|
||||
dsfirst->linkdraw = ds;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; dsnext->next != NULL; dsnext = dsnext->next)
|
||||
if (ds->dispoffset < dsnext->next->dispoffset)
|
||||
break;
|
||||
ds->next = dsnext->next;
|
||||
dsnext->next = ds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pull the vissprites out by scale
|
||||
vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
|
||||
for (i = 0; i < visspritecount; i++)
|
||||
for (i = 0; i < visspritecount-linkedvissprites; i++)
|
||||
{
|
||||
bestscale = bestdispoffset = INT32_MAX;
|
||||
for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
if (ds->cut & SC_LINKDRAW)
|
||||
I_Error("R_SortVisSprites: no link or discardal made for linkdraw!");
|
||||
#endif
|
||||
|
||||
if (ds->sortscale < bestscale)
|
||||
{
|
||||
bestscale = ds->sortscale;
|
||||
|
@ -2090,20 +2145,6 @@ static void R_CreateDrawNodes(void)
|
|||
}
|
||||
else if (r2->seg)
|
||||
{
|
||||
#if 0 //#ifdef POLYOBJECTS_PLANES
|
||||
if (r2->seg->curline->polyseg && rover->mobj && P_MobjInsidePolyobj(r2->seg->curline->polyseg, rover->mobj)) {
|
||||
// Determine if we need to sort in front of the polyobj, based on the planes. This fixes the issue where
|
||||
// polyobject planes render above the object standing on them. (A bit hacky... but it works.) -Red
|
||||
mobj_t *mo = rover->mobj;
|
||||
sector_t *po = r2->seg->curline->backsector;
|
||||
|
||||
if (po->ceilingheight < viewz && mo->z+mo->height > po->ceilingheight)
|
||||
continue;
|
||||
|
||||
if (po->floorheight > viewz && mo->z < po->floorheight)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (rover->x1 > r2->seg->x2 || rover->x2 < r2->seg->x1)
|
||||
continue;
|
||||
|
||||
|
@ -2230,7 +2271,7 @@ static void R_DrawPrecipitationSprite(vissprite_t *spr)
|
|||
void R_ClipSprites(void)
|
||||
{
|
||||
vissprite_t *spr;
|
||||
for (;clippedvissprites < visspritecount; clippedvissprites++)
|
||||
for (; clippedvissprites < visspritecount; clippedvissprites++)
|
||||
{
|
||||
drawseg_t *ds;
|
||||
INT32 x;
|
||||
|
@ -2451,10 +2492,24 @@ void R_DrawMasked(void)
|
|||
next = r2->prev;
|
||||
|
||||
// Tails 08-18-2002
|
||||
if (r2->sprite->precip == true)
|
||||
if (r2->sprite->cut & SC_PRECIP)
|
||||
R_DrawPrecipitationSprite(r2->sprite);
|
||||
else
|
||||
else if (!r2->sprite->linkdraw)
|
||||
R_DrawSprite(r2->sprite);
|
||||
else // unbundle linkdraw
|
||||
{
|
||||
vissprite_t *ds = r2->sprite->linkdraw;
|
||||
|
||||
for (;
|
||||
(ds != NULL && r2->sprite->dispoffset > ds->dispoffset);
|
||||
ds = ds->next)
|
||||
R_DrawSprite(ds);
|
||||
|
||||
R_DrawSprite(r2->sprite);
|
||||
|
||||
for (; ds != NULL; ds = ds->next)
|
||||
R_DrawSprite(ds);
|
||||
}
|
||||
|
||||
R_DoneWithNode(r2);
|
||||
r2 = next;
|
||||
|
|
|
@ -127,9 +127,19 @@ typedef struct
|
|||
// -----------
|
||||
typedef enum
|
||||
{
|
||||
// actual cuts
|
||||
SC_NONE = 0,
|
||||
SC_TOP = 1,
|
||||
SC_BOTTOM = 2
|
||||
SC_BOTTOM = 1<<1,
|
||||
// other flags
|
||||
SC_PRECIP = 1<<2,
|
||||
SC_LINKDRAW = 1<<3,
|
||||
SC_FULLBRIGHT = 1<<4,
|
||||
SC_VFLIP = 1<<5,
|
||||
SC_ISSCALED = 1>>6,
|
||||
// masks
|
||||
SC_CUTMASK = SC_TOP|SC_BOTTOM,
|
||||
SC_FLAGMASK = ~SC_CUTMASK
|
||||
} spritecut_e;
|
||||
|
||||
// A vissprite_t is a thing that will be drawn during a refresh,
|
||||
|
@ -140,6 +150,9 @@ typedef struct vissprite_s
|
|||
struct vissprite_s *prev;
|
||||
struct vissprite_s *next;
|
||||
|
||||
// Bonus linkdraw pointer.
|
||||
struct vissprite_s *linkdraw;
|
||||
|
||||
mobj_t *mobj; // for easy access
|
||||
|
||||
INT32 x1, x2;
|
||||
|
@ -178,9 +191,6 @@ typedef struct vissprite_s
|
|||
|
||||
INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH];
|
||||
|
||||
boolean precip;
|
||||
boolean vflip; // Flip vertically
|
||||
boolean isScaled;
|
||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||
} vissprite_t;
|
||||
|
||||
|
|
Loading…
Reference in a new issue