mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
* Add new damagetype flag (DMG_CANHURTSELF) that allows a player to hurt themselves indirectly.
* Add damagetype to P_RadiusAttack (optinteger in lua, A_Explode var1). * Removed the prevention of MF_BOSS objects from getting P_RadiusAttacked. This was a holdover from DooM (I checked) - a way to prevent the Cyberdemon from gibbing itself when firing point blank into a wall, and also a way to make it and the Spider Mastermind harder. * Enemies are solid to other enemies movement-wise now. * (Fun little aside - if you remove MF_SOLID from a monitor, it now behaves like they did in Sonic Adventure (poppable by colliding with, not just attacking). * Fixed Metal Sonic battle conflict in MF_PAIN/mass not picked up earlier. * Miscellaneous tiny code tweaks.
This commit is contained in:
parent
d0575f7fb0
commit
8a61d87961
8 changed files with 59 additions and 60 deletions
|
@ -7400,6 +7400,7 @@ struct {
|
|||
{"DMG_CRUSHED",DMG_CRUSHED},
|
||||
{"DMG_SPECTATOR",DMG_SPECTATOR},
|
||||
//// Masks
|
||||
{"DMG_CANHURTSELF",DMG_CANHURTSELF},
|
||||
{"DMG_DEATHMASK",DMG_DEATHMASK},
|
||||
|
||||
// Gametypes, for use with global var "gametype"
|
||||
|
|
|
@ -5422,7 +5422,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
16*FRACUNIT, // radius
|
||||
48*FRACUNIT, // height
|
||||
0, // display offset
|
||||
sfx_s3k5a, // mass
|
||||
0, // mass
|
||||
3, // damage
|
||||
sfx_mswarp, // activesound
|
||||
MF_NOGRAVITY|MF_BOSS|MF_SLIDEME, // flags
|
||||
|
|
|
@ -1356,11 +1356,12 @@ static int lib_pRadiusAttack(lua_State *L)
|
|||
mobj_t *spot = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
fixed_t damagedist = luaL_checkfixed(L, 3);
|
||||
UINT8 damagetype = luaL_optinteger(L, 4, 0);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!spot || !source)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_RadiusAttack(spot, source, damagedist);
|
||||
P_RadiusAttack(spot, source, damagedist, damagetype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2824,16 +2824,17 @@ void A_GoldMonitorSparkle(mobj_t *actor)
|
|||
//
|
||||
// Description: Explodes an object, doing damage to any objects nearby. The target is used as the cause of the explosion. Damage value is used as explosion range.
|
||||
//
|
||||
// var1 = unused
|
||||
// var1 = damagetype
|
||||
// var2 = unused
|
||||
//
|
||||
void A_Explode(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_Explode", actor))
|
||||
return;
|
||||
#endif
|
||||
P_RadiusAttack(actor, actor->target, actor->info->damage);
|
||||
P_RadiusAttack(actor, actor->target, actor->info->damage, locvar1);
|
||||
}
|
||||
|
||||
// Function: A_BossDeath
|
||||
|
@ -9580,7 +9581,7 @@ void A_VileAttack(mobj_t *actor)
|
|||
actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
fire->z);
|
||||
P_RadiusAttack(fire, actor, 70*FRACUNIT);
|
||||
P_RadiusAttack(fire, actor, 70*FRACUNIT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -9625,7 +9626,7 @@ void A_VileAttack(mobj_t *actor)
|
|||
actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
fire->z);
|
||||
P_RadiusAttack(fire, actor, 70*FRACUNIT);
|
||||
P_RadiusAttack(fire, actor, 70*FRACUNIT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10709,7 +10710,7 @@ void A_MineExplode(mobj_t *actor)
|
|||
quake.intensity = 8*FRACUNIT;
|
||||
quake.time = TICRATE/3;
|
||||
|
||||
P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT);
|
||||
P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, DMG_CANHURTSELF);
|
||||
P_MobjCheckWater(actor);
|
||||
|
||||
{
|
||||
|
|
|
@ -2670,7 +2670,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
|
|||
}
|
||||
}
|
||||
|
||||
static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
||||
{
|
||||
player_t *player = target->player;
|
||||
(void)damage; //unused parm
|
||||
|
@ -2680,7 +2680,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
return false;
|
||||
|
||||
// Ignore IT players shooting each other, unless friendlyfire is on.
|
||||
if ((player->pflags & PF_TAGIT && !(cv_friendlyfire.value &&
|
||||
if ((player->pflags & PF_TAGIT && !((cv_friendlyfire.value || (damagetype & DMG_CANHURTSELF)) &&
|
||||
source && source->player && source->player->pflags & PF_TAGIT)))
|
||||
return false;
|
||||
|
||||
|
@ -2690,7 +2690,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
|
||||
// Don't allow players on the same team to hurt one another,
|
||||
// unless cv_friendlyfire is on.
|
||||
if (!cv_friendlyfire.value && (player->pflags & PF_TAGIT) == (source->player->pflags & PF_TAGIT))
|
||||
if (!(cv_friendlyfire.value || (damagetype & DMG_CANHURTSELF)) && (player->pflags & PF_TAGIT) == (source->player->pflags & PF_TAGIT))
|
||||
{
|
||||
if (!(inflictor->flags & MF_FIRE))
|
||||
P_GivePlayerRings(player, 1);
|
||||
|
@ -2745,21 +2745,26 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
||||
{
|
||||
player_t *player = target->player;
|
||||
|
||||
// You can't kill yourself, idiot...
|
||||
if (source == target)
|
||||
return false;
|
||||
if (!(damagetype & DMG_CANHURTSELF))
|
||||
{
|
||||
// You can't kill yourself, idiot...
|
||||
if (source == target)
|
||||
return false;
|
||||
|
||||
// In COOP/RACE/CHAOS, you can't hurt other players unless cv_friendlyfire is on
|
||||
if (!cv_friendlyfire.value && (G_PlatformGametype()))
|
||||
return false;
|
||||
// In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on
|
||||
if (!cv_friendlyfire.value && (G_PlatformGametype()))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Tag handling
|
||||
if (G_TagGametype())
|
||||
return P_TagDamage(target, inflictor, source, damage);
|
||||
return P_TagDamage(target, inflictor, source, damage, damagetype);
|
||||
else if (damagetype & DMG_CANHURTSELF)
|
||||
return true;
|
||||
else if (G_GametypeHasTeams()) // CTF + Team Match
|
||||
{
|
||||
// Don't allow players on the same team to hurt one another,
|
||||
|
@ -3177,7 +3182,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
// Player hits another player
|
||||
if (!force && source && source->player)
|
||||
{
|
||||
if (!P_PlayerHitsPlayer(target, inflictor, source, damage))
|
||||
if (!P_PlayerHitsPlayer(target, inflictor, source, damage, damagetype))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -363,7 +363,7 @@ void P_DelPrecipSeclist(mprecipsecnode_t *node);
|
|||
void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y);
|
||||
void P_Initsecnode(void);
|
||||
|
||||
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist);
|
||||
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype);
|
||||
|
||||
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height);
|
||||
boolean PIT_PushableMoved(mobj_t *thing);
|
||||
|
@ -413,6 +413,8 @@ typedef struct BasicFF_s
|
|||
#define DMG_DEATHPIT 0x80+3
|
||||
#define DMG_CRUSHED 0x80+4
|
||||
#define DMG_SPECTATOR 0x80+5
|
||||
// Masks
|
||||
#define DMG_CANHURTSELF 0x40 // Flag - can hurt self/team indirectly, such as through mines
|
||||
#define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type
|
||||
|
||||
void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period);
|
||||
|
|
67
src/p_map.c
67
src/p_map.c
|
@ -674,14 +674,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (thing->flags & MF_PAIN)
|
||||
if (thing->flags & MF_PAIN && tmthing->player)
|
||||
{ // Player touches painful thing sitting on the floor
|
||||
// see if it went over / under
|
||||
if (thing->z > tmthing->z + tmthing->height)
|
||||
return true; // overhead
|
||||
if (thing->z + thing->height < tmthing->z)
|
||||
return true; // underneath
|
||||
if (tmthing->player && tmthing->flags & MF_SHOOTABLE && thing->health > 0)
|
||||
if (tmthing->flags & MF_SHOOTABLE && thing->health > 0)
|
||||
{
|
||||
UINT8 damagetype = thing->info->mass;
|
||||
if (!damagetype && thing->flags & MF_FIRE) // BURN!
|
||||
|
@ -691,14 +691,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
else if (tmthing->flags & MF_PAIN)
|
||||
else if (tmthing->flags & MF_PAIN && thing->player)
|
||||
{ // Painful thing splats player in the face
|
||||
// see if it went over / under
|
||||
if (tmthing->z > thing->z + thing->height)
|
||||
return true; // overhead
|
||||
if (tmthing->z + tmthing->height < thing->z)
|
||||
return true; // underneath
|
||||
if (thing->player && thing->flags & MF_SHOOTABLE && tmthing->health > 0)
|
||||
if (thing->flags & MF_SHOOTABLE && tmthing->health > 0)
|
||||
{
|
||||
UINT8 damagetype = tmthing->info->mass;
|
||||
if (!damagetype && tmthing->flags & MF_FIRE) // BURN!
|
||||
|
@ -751,6 +751,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
else if (tmz > thzh - sprarea && tmz < thzh) // Don't damage people springing up / down
|
||||
return true;
|
||||
}
|
||||
|
||||
// missiles can hit other things
|
||||
if (tmthing->flags & MF_MISSILE || tmthing->type == MT_SHELL)
|
||||
{
|
||||
|
@ -805,30 +806,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
|
||||
if (thing->type == MT_EGGSHIELD)
|
||||
{
|
||||
fixed_t touchx, touchy;
|
||||
angle_t angle;
|
||||
angle_t angle = (R_PointToAngle2(thing->x, thing->y, tmthing->x - tmthing->momx, tmthing->y - tmthing->momy) - thing->angle) - ANGLE_90;
|
||||
|
||||
if (P_AproxDistance(tmthing->x-thing->x, tmthing->y-thing->y) >
|
||||
P_AproxDistance((tmthing->x-tmthing->momx)-thing->x, (tmthing->y-tmthing->momy)-thing->y))
|
||||
{
|
||||
touchx = tmthing->x + tmthing->momx;
|
||||
touchy = tmthing->y + tmthing->momy;
|
||||
}
|
||||
else
|
||||
{
|
||||
touchx = tmthing->x;
|
||||
touchy = tmthing->y;
|
||||
}
|
||||
|
||||
angle = R_PointToAngle2(thing->x, thing->y, touchx, touchy) - thing->angle;
|
||||
|
||||
if (!(angle > ANGLE_90 && angle < ANGLE_270)) // hit front of shield, didn't destroy it
|
||||
return false;
|
||||
else // hit shield from behind, shield is destroyed!
|
||||
{
|
||||
if (angle < ANGLE_180) // hit shield from behind, shield is destroyed!
|
||||
P_KillMobj(thing, tmthing, tmthing, 0);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// damage / explode
|
||||
|
@ -1086,6 +1068,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
}
|
||||
}
|
||||
|
||||
// thanks to sal for solidenemies dot lua
|
||||
if (thing->flags & (MF_ENEMY|MF_BOSS) && tmthing->flags & (MF_ENEMY|MF_BOSS))
|
||||
{
|
||||
if ((thing->z + thing->height >= tmthing->z)
|
||||
&& (tmthing->z + tmthing->height >= thing->z))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Damage other players when invincible
|
||||
if (tmthing->player && thing->player
|
||||
// Make sure they aren't able to damage you ANYWHERE along the Z axis, you have to be TOUCHING the person.
|
||||
|
@ -1150,7 +1140,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
{
|
||||
// Objects kill you if it falls from above.
|
||||
if (thing != tmthing->target)
|
||||
P_DamageMobj(thing, tmthing, tmthing->target, 1, DMG_INSTAKILL);
|
||||
P_DamageMobj(thing, tmthing, tmthing->target, 1, DMG_CRUSHED);
|
||||
|
||||
tmthing->momz = -tmthing->momz/2; // Bounce, just for fun!
|
||||
// The tmthing->target allows the pusher of the object
|
||||
|
@ -1185,7 +1175,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
UINT8 elementalpierce = (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (tmthing->player->pflags & PF_SHIELDABILITY)
|
||||
? (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) ? 1 : 2)
|
||||
: 0);
|
||||
if (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|
||||
if (!(thing->flags & MF_SOLID)
|
||||
|| tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|
||||
|| ((tmthing->player->pflags & PF_JUMPED)
|
||||
&& (!(tmthing->player->pflags & PF_NOJUMPDAMAGE)
|
||||
|| (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|
||||
|
@ -1194,8 +1185,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))
|
||||
|| elementalpierce)
|
||||
{
|
||||
if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
|
||||
&& thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z)
|
||||
if (thing->z - thing->scale <= tmthing->z + tmthing->height
|
||||
&& thing->z + thing->height + thing->scale >= tmthing->z)
|
||||
{
|
||||
player_t *player = tmthing->player;
|
||||
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed.
|
||||
|
@ -3527,6 +3518,7 @@ bounceback:
|
|||
static fixed_t bombdamage;
|
||||
static mobj_t *bombsource;
|
||||
static mobj_t *bombspot;
|
||||
static UINT8 bombdamagetype;
|
||||
|
||||
//
|
||||
// PIT_RadiusAttack
|
||||
|
@ -3537,17 +3529,13 @@ static boolean PIT_RadiusAttack(mobj_t *thing)
|
|||
{
|
||||
fixed_t dx, dy, dz, dist;
|
||||
|
||||
if (thing == bombspot // ignore the bomb itself (Deton fix)
|
||||
|| (bombsource && thing->type == bombsource->type)) // ignore the type of guys who dropped the bomb (Jetty-Syn Bomber or Skim can bomb eachother, but not themselves.)
|
||||
if (thing == bombspot) // ignore the bomb itself (Deton fix)
|
||||
return true;
|
||||
|
||||
if (!(thing->flags & MF_SHOOTABLE))
|
||||
if ((thing->flags & (MF_MONITOR|MF_SHOOTABLE)) != MF_SHOOTABLE)
|
||||
return true;
|
||||
|
||||
if (thing->flags & MF_BOSS)
|
||||
return true;
|
||||
|
||||
if (thing->flags & MF_MONITOR)
|
||||
if (bombsource && thing->type == bombsource->type && !(bombdamagetype & DMG_CANHURTSELF)) // ignore the type of guys who dropped the bomb (Jetty-Syn Bomber or Skim can bomb eachother, but not themselves.)
|
||||
return true;
|
||||
|
||||
dx = abs(thing->x - bombspot->x);
|
||||
|
@ -3571,7 +3559,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing)
|
|||
|
||||
if (P_CheckSight(thing, bombspot))
|
||||
{ // must be in direct path
|
||||
P_DamageMobj(thing, bombspot, bombsource, 1, 0); // Tails 01-11-2001
|
||||
P_DamageMobj(thing, bombspot, bombsource, 1, bombdamagetype); // Tails 01-11-2001
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3581,7 +3569,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing)
|
|||
// P_RadiusAttack
|
||||
// Source is the creature that caused the explosion at spot.
|
||||
//
|
||||
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist)
|
||||
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype)
|
||||
{
|
||||
INT32 x, y;
|
||||
INT32 xl, xh, yl, yh;
|
||||
|
@ -3598,6 +3586,7 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist)
|
|||
bombspot = spot;
|
||||
bombsource = source;
|
||||
bombdamage = FixedMul(damagedist, spot->scale);
|
||||
bombdamagetype = damagetype;
|
||||
|
||||
for (y = yl; y <= yh; y++)
|
||||
for (x = xl; x <= xh; x++)
|
||||
|
|
|
@ -877,7 +877,7 @@ void P_ExplodeMissile(mobj_t *mo)
|
|||
|
||||
if (mo->type == MT_DETON)
|
||||
{
|
||||
P_RadiusAttack(mo, mo, 96*FRACUNIT);
|
||||
P_RadiusAttack(mo, mo, 96*FRACUNIT, 0);
|
||||
|
||||
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
|
||||
P_SetScale(explodemo, mo->scale);
|
||||
|
|
Loading…
Reference in a new issue