mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-31 13:40:45 +00:00
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:
parent
b0326b6dec
commit
ef6e00e8a2
6 changed files with 95 additions and 57 deletions
|
@ -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
|
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
|
||||||
visual->target = lockon;
|
visual->target = lockon;
|
||||||
|
visual->flags2 |= MF2_DONTDRAW;
|
||||||
P_SetMobjStateNF(visual, state);
|
P_SetMobjStateNF(visual, state);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -951,6 +952,21 @@ static int lib_pResetPlayer(lua_State *L)
|
||||||
return 0;
|
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)
|
static int lib_pIsObjectInGoop(lua_State *L)
|
||||||
{
|
{
|
||||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||||
|
@ -2774,6 +2790,7 @@ static luaL_Reg lib[] = {
|
||||||
{"P_PlayerInPain",lib_pPlayerInPain},
|
{"P_PlayerInPain",lib_pPlayerInPain},
|
||||||
{"P_DoPlayerPain",lib_pDoPlayerPain},
|
{"P_DoPlayerPain",lib_pDoPlayerPain},
|
||||||
{"P_ResetPlayer",lib_pResetPlayer},
|
{"P_ResetPlayer",lib_pResetPlayer},
|
||||||
|
{"P_PlayerCanDamage",lib_pPlayerCanDamage},
|
||||||
{"P_IsObjectInGoop",lib_pIsObjectInGoop},
|
{"P_IsObjectInGoop",lib_pIsObjectInGoop},
|
||||||
{"P_IsObjectOnGround",lib_pIsObjectOnGround},
|
{"P_IsObjectOnGround",lib_pIsObjectOnGround},
|
||||||
{"P_InSpaceSector",lib_pInSpaceSector},
|
{"P_InSpaceSector",lib_pInSpaceSector},
|
||||||
|
|
|
@ -453,13 +453,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|
if (player->powers[pw_invulnerability] || player->powers[pw_super]
|
||||||
|| ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|
|| P_PlayerCanDamage(player, special)) // Do you possess the ability to subdue the object?
|
||||||
|| (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 ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1))
|
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);
|
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
|
// Target's name
|
||||||
snprintf(targetname, sizeof(targetname), "%s%s%s",
|
snprintf(targetname, sizeof(targetname), "%s%s%s",
|
||||||
CTFTEAMCODE(player),
|
CTFTEAMCODE(player),
|
||||||
|
@ -1853,7 +1852,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
|
||||||
switch (damagetype)
|
switch (damagetype)
|
||||||
{
|
{
|
||||||
case DMG_WATER:
|
case DMG_WATER:
|
||||||
str = M_GetText("%s was %s by chemical water.\n");
|
str = M_GetText("%s was %s by dangerous water.\n");
|
||||||
break;
|
break;
|
||||||
case DMG_FIRE:
|
case DMG_FIRE:
|
||||||
str = M_GetText("%s was %s by molten lava.\n");
|
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.
|
if (!str) // Should not happen! Unless we missed catching something above.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Don't log every hazard hit if they don't want us to.
|
|
||||||
if (!deadtarget && !cv_hazardlog.value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (deathonly)
|
if (deathonly)
|
||||||
{
|
{
|
||||||
if (!deadtarget)
|
if (!deadtarget)
|
||||||
|
|
|
@ -128,6 +128,7 @@ pflags_t P_GetJumpFlags(player_t *player);
|
||||||
boolean P_PlayerInPain(player_t *player);
|
boolean P_PlayerInPain(player_t *player);
|
||||||
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
|
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
|
||||||
void P_ResetPlayer(player_t *player);
|
void P_ResetPlayer(player_t *player);
|
||||||
|
boolean P_PlayerCanDamage(player_t *player, mobj_t *thing);
|
||||||
boolean P_IsLocalPlayer(player_t *player);
|
boolean P_IsLocalPlayer(player_t *player);
|
||||||
|
|
||||||
boolean P_IsObjectInGoop(mobj_t *mo);
|
boolean P_IsObjectInGoop(mobj_t *mo);
|
||||||
|
|
70
src/p_map.c
70
src/p_map.c
|
@ -1405,51 +1405,41 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
}
|
}
|
||||||
// Monitor?
|
// Monitor?
|
||||||
else if (thing->flags & MF_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
|
if (thing->z - thing->scale <= tmthing->z + tmthing->height
|
||||||
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)
|
&& thing->z + thing->height + thing->scale >= tmthing->z)
|
||||||
? (((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
|
player_t *player = tmthing->player;
|
||||||
&& thing->z + thing->height + thing->scale >= tmthing->z)
|
// 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;
|
if (elementalpierce == 2)
|
||||||
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed.
|
P_DoBubbleBounce(player);
|
||||||
fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;;
|
else if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
|
||||||
fixed_t *z = &tmthing->z; // aau.
|
*momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically.
|
||||||
// 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 == 1 && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough.
|
||||||
return true;
|
{
|
||||||
|
if (player->pflags & PF_BOUNCING)
|
||||||
|
P_DoAbilityBounce(player, false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*z -= *momz; // to ensure proper collision.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3396,11 +3396,7 @@ void P_MobjCheckWater(mobj_t *mobj)
|
||||||
if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability])))
|
if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability])))
|
||||||
{
|
{
|
||||||
boolean electric = !!(p->powers[pw_shield] & SH_PROTECTELECTRIC);
|
boolean electric = !!(p->powers[pw_shield] & SH_PROTECTELECTRIC);
|
||||||
#define SH_OP (SH_PROTECTFIRE|SH_PROTECTWATER|SH_PROTECTELECTRIC)
|
if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER)))
|
||||||
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)))
|
|
||||||
{ // Water removes electric and non-water fire shields...
|
{ // Water removes electric and non-water fire shields...
|
||||||
P_FlashPal(p,
|
P_FlashPal(p,
|
||||||
electric
|
electric
|
||||||
|
@ -7109,6 +7105,9 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
P_RemoveMobj(mobj);
|
P_RemoveMobj(mobj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||||
|
|
||||||
mobj->x = mobj->target->x;
|
mobj->x = mobj->target->x;
|
||||||
mobj->y = mobj->target->y;
|
mobj->y = mobj->target->y;
|
||||||
|
|
||||||
|
|
36
src/p_user.c
36
src/p_user.c
|
@ -977,6 +977,42 @@ void P_ResetPlayer(player_t *player)
|
||||||
CV_SetValue(&cv_analog2, true);
|
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
|
// P_GivePlayerRings
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue