P_PlayerCanDamage(player_t*, mobj_t*), ported from the abandoned project_birthday because GOD the code looks awful with those huge monolith conditions in it. Available to Lua.

(Also, minor fixes to lib_pSpawnLockOn, and removing the SH_OP fuckery.)
This commit is contained in:
toaster 2019-06-19 12:09:02 +01:00
parent b0326b6dec
commit ef6e00e8a2
6 changed files with 95 additions and 57 deletions

View File

@ -540,6 +540,7 @@ static int lib_pSpawnLockOn(lua_State *L)
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
visual->target = lockon;
visual->flags2 |= MF2_DONTDRAW;
P_SetMobjStateNF(visual, state);
}
return 0;
@ -951,6 +952,21 @@ static int lib_pResetPlayer(lua_State *L)
return 0;
}
static int lib_pPlayerCanDamage(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
//HUDSAFE
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (!thing)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_PlayerCanDamage(player, thing));
return 1;
}
static int lib_pIsObjectInGoop(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -2774,6 +2790,7 @@ static luaL_Reg lib[] = {
{"P_PlayerInPain",lib_pPlayerInPain},
{"P_DoPlayerPain",lib_pDoPlayerPain},
{"P_ResetPlayer",lib_pResetPlayer},
{"P_PlayerCanDamage",lib_pPlayerCanDamage},
{"P_IsObjectInGoop",lib_pIsObjectInGoop},
{"P_IsObjectOnGround",lib_pIsObjectOnGround},
{"P_InSpaceSector",lib_pInSpaceSector},

View File

@ -453,13 +453,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
break;
}
if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|| (player->pflags & (PF_SPINNING|PF_GLIDING))
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
|| ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|| player->powers[pw_invulnerability] || player->powers[pw_super]
|| elementalpierce) // Do you possess the ability to subdue the object?
if (player->powers[pw_invulnerability] || player->powers[pw_super]
|| P_PlayerCanDamage(player, special)) // Do you possess the ability to subdue the object?
{
if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1))
{
@ -1750,6 +1745,10 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
deadtarget = (player->mo->health <= 0);
// Don't log every hazard hit if they don't want us to.
if (!deadtarget && !cv_hazardlog.value)
return;
// Target's name
snprintf(targetname, sizeof(targetname), "%s%s%s",
CTFTEAMCODE(player),
@ -1853,7 +1852,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
switch (damagetype)
{
case DMG_WATER:
str = M_GetText("%s was %s by chemical water.\n");
str = M_GetText("%s was %s by dangerous water.\n");
break;
case DMG_FIRE:
str = M_GetText("%s was %s by molten lava.\n");
@ -1901,10 +1900,6 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
if (!str) // Should not happen! Unless we missed catching something above.
return;
// Don't log every hazard hit if they don't want us to.
if (!deadtarget && !cv_hazardlog.value)
return;
if (deathonly)
{
if (!deadtarget)

View File

@ -128,6 +128,7 @@ pflags_t P_GetJumpFlags(player_t *player);
boolean P_PlayerInPain(player_t *player);
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
void P_ResetPlayer(player_t *player);
boolean P_PlayerCanDamage(player_t *player, mobj_t *thing);
boolean P_IsLocalPlayer(player_t *player);
boolean P_IsObjectInGoop(mobj_t *mo);

View File

@ -1405,51 +1405,41 @@ static boolean PIT_CheckThing(mobj_t *thing)
}
// Monitor?
else if (thing->flags & MF_MONITOR
&& !((thing->type == MT_RING_REDBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_RING_BLUEBOX && tmthing->player->ctfteam != 2)))
&& !((thing->type == MT_RING_REDBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_RING_BLUEBOX && tmthing->player->ctfteam != 2))
&& (!(thing->flags & MF_SOLID) || P_PlayerCanDamage(tmthing->player, thing)))
{
// 0 = none, 1 = elemental pierce, 2 = bubble bounce
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 (!(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)))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|| ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING)
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))
|| elementalpierce)
if (thing->z - thing->scale <= tmthing->z + tmthing->height
&& thing->z + thing->height + 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;
// 0 = none, 1 = elemental pierce, 2 = bubble bounce
UINT8 elementalpierce = (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY)
? (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) ? 1 : 2)
: 0);
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed.
fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;;
fixed_t *z = &tmthing->z; // aau.
// Going down? Then bounce back up.
if (P_DamageMobj(thing, tmthing, tmthing, 1, 0) // break the monitor
&& (flipval*(*momz) < 0) // monitor is on the floor and you're going down, or on the ceiling and you're going up
&& (elementalpierce != 1)) // you're not piercing through the monitor...
{
player_t *player = tmthing->player;
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed.
fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;;
fixed_t *z = &tmthing->z; // aau.
// Going down? Then bounce back up.
if (P_DamageMobj(thing, tmthing, tmthing, 1, 0) // break the monitor
&& (flipval*(*momz) < 0) // monitor is on the floor and you're going down, or on the ceiling and you're going up
&& (elementalpierce != 1)) // you're not piercing through the monitor...
{
if (elementalpierce == 2)
P_DoBubbleBounce(player);
else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
*momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically.
}
if (!(elementalpierce == 1 && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough.
{
if (player->pflags & PF_BOUNCING)
P_DoAbilityBounce(player, false);
return false;
}
else
*z -= *momz; // to ensure proper collision.
if (elementalpierce == 2)
P_DoBubbleBounce(player);
else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
*momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically.
}
return true;
if (!(elementalpierce == 1 && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough.
{
if (player->pflags & PF_BOUNCING)
P_DoAbilityBounce(player, false);
return false;
}
else
*z -= *momz; // to ensure proper collision.
}
return true;
}
}

View File

@ -3396,11 +3396,7 @@ void P_MobjCheckWater(mobj_t *mobj)
if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability])))
{
boolean electric = !!(p->powers[pw_shield] & SH_PROTECTELECTRIC);
#define SH_OP (SH_PROTECTFIRE|SH_PROTECTWATER|SH_PROTECTELECTRIC)
if ((p->powers[pw_shield] & SH_OP) == SH_OP) // No.
P_KillMobj(mobj, NULL, NULL, DMG_INSTAKILL);
#undef SH_OP
else if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER)))
if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER)))
{ // Water removes electric and non-water fire shields...
P_FlashPal(p,
electric
@ -7109,6 +7105,9 @@ void P_MobjThinker(mobj_t *mobj)
P_RemoveMobj(mobj);
return;
}
mobj->flags2 &= ~MF2_DONTDRAW;
mobj->x = mobj->target->x;
mobj->y = mobj->target->y;

View File

@ -977,6 +977,42 @@ void P_ResetPlayer(player_t *player)
CV_SetValue(&cv_analog2, true);
}
// P_PlayerCanDamage
//
// Can player do damage?
// Doesn't count invincibility or super, for the sake of monitors.
//
boolean P_PlayerCanDamage(player_t *player, mobj_t *thing)
{
if (!player->mo || player->spectator || !thing || P_MobjWasRemoved(thing))
return false;
if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
return true;
if ((player->pflags & PF_JUMPED)
&& (!(player->pflags & PF_NOJUMPDAMAGE)
|| (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
return true;
if (player->pflags & (PF_SPINNING|PF_GLIDING))
return true;
if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
return true;
if ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING)
&& (P_MobjFlip(player->mo)*(player->mo->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(player->mo)*player->mo->momz < 0))
return true;
if (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY))
return true;
return false;
}
//
// P_GivePlayerRings
//