mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
Merge branch 'master' of http://git.magicalgirl.moe/STJr/SRB2Internal.git into shield-actions
# Conflicts: # src/p_inter.c # src/p_user.c # src/st_stuff.c
This commit is contained in:
commit
85fb02aaf6
28 changed files with 830 additions and 657 deletions
|
@ -495,7 +495,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]);
|
||||
|
||||
// Score is resynched in the rspfirm resync packet
|
||||
rsp->health = 0; // resynched with mo health
|
||||
rsp->rings = LONG(players[i].rings);
|
||||
rsp->lives = players[i].lives;
|
||||
rsp->continues = players[i].continues;
|
||||
rsp->scoreadd = players[i].scoreadd;
|
||||
|
@ -582,7 +582,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
rsp->hasmo = true;
|
||||
|
||||
rsp->health = LONG(players[i].mo->health);
|
||||
|
||||
rsp->angle = (angle_t)LONG(players[i].mo->angle);
|
||||
rsp->x = LONG(players[i].mo->x);
|
||||
rsp->y = LONG(players[i].mo->y);
|
||||
|
@ -625,7 +624,7 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]);
|
||||
|
||||
// Score is resynched in the rspfirm resync packet
|
||||
players[i].health = rsp->health;
|
||||
players[i].rings = LONG(rsp->rings);
|
||||
players[i].lives = rsp->lives;
|
||||
players[i].continues = rsp->continues;
|
||||
players[i].scoreadd = rsp->scoreadd;
|
||||
|
@ -2254,7 +2253,7 @@ static void CL_RemovePlayer(INT32 playernum)
|
|||
}
|
||||
|
||||
count--;
|
||||
rings = players[playernum].health - 1;
|
||||
rings = players[playernum].rings;
|
||||
increment = rings/count;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
|
@ -155,7 +155,7 @@ typedef struct
|
|||
UINT16 powers[NUMPOWERS];
|
||||
|
||||
// Score is resynched in the confirm resync packet
|
||||
INT32 health;
|
||||
INT32 rings;
|
||||
SINT8 lives;
|
||||
SINT8 continues;
|
||||
UINT8 scoreadd;
|
||||
|
@ -236,6 +236,7 @@ typedef struct
|
|||
//player->mo stuff
|
||||
UINT8 hasmo; //boolean
|
||||
|
||||
INT32 health;
|
||||
angle_t angle;
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
|
|
|
@ -2574,7 +2574,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
if (players[playernum].spectator)
|
||||
{
|
||||
players[playernum].score = 0;
|
||||
players[playernum].health = 1;
|
||||
players[playernum].rings = 0;
|
||||
if (players[playernum].mo)
|
||||
players[playernum].mo->health = 1;
|
||||
}
|
||||
|
|
|
@ -314,10 +314,8 @@ typedef struct player_s
|
|||
// It is updated with cmd->aiming.
|
||||
angle_t aiming;
|
||||
|
||||
// This is only used between levels,
|
||||
// mo->health is used during levels.
|
||||
/// \todo Remove this. We don't need a second health definition for players.
|
||||
INT32 health;
|
||||
// player's ring count
|
||||
INT32 rings;
|
||||
|
||||
SINT8 pity; // i pity the fool.
|
||||
INT32 currentweapon; // current weapon selected.
|
||||
|
|
|
@ -7221,6 +7221,22 @@ struct {
|
|||
{"PAL_MIXUP",PAL_MIXUP},
|
||||
{"PAL_RECYCLE",PAL_RECYCLE},
|
||||
{"PAL_NUKE",PAL_NUKE},
|
||||
// for P_DamageMobj
|
||||
//// Damage types
|
||||
{"DMG_WATER",DMG_WATER},
|
||||
{"DMG_FIRE",DMG_FIRE},
|
||||
{"DMG_ELECTRIC",DMG_ELECTRIC},
|
||||
{"DMG_SPIKE",DMG_SPIKE},
|
||||
{"DMG_NUKE",DMG_NUKE},
|
||||
//// Death types
|
||||
{"DMG_INSTAKILL",DMG_INSTAKILL},
|
||||
{"DMG_DROWNED",DMG_DROWNED},
|
||||
{"DMG_SPACEDROWN",DMG_SPACEDROWN},
|
||||
{"DMG_DEATHPIT",DMG_DEATHPIT},
|
||||
{"DMG_CRUSHED",DMG_CRUSHED},
|
||||
{"DMG_SPECTATOR",DMG_SPECTATOR},
|
||||
//// Masks
|
||||
{"DMG_DEATHMASK",DMG_DEATHMASK},
|
||||
|
||||
// Gametypes, for use with global var "gametype"
|
||||
{"GT_COOP",GT_COOP},
|
||||
|
|
|
@ -88,6 +88,7 @@ UINT8 modeattacking = ATTACKING_NONE;
|
|||
boolean disableSpeedAdjust = false;
|
||||
boolean imcontinuing = false;
|
||||
boolean runemeraldmanager = false;
|
||||
UINT16 emeraldspawndelay = 60*TICRATE;
|
||||
|
||||
// menu demo things
|
||||
UINT8 numDemos = 3;
|
||||
|
@ -2193,7 +2194,7 @@ void G_PlayerReborn(INT32 player)
|
|||
p->pflags |= PF_JUMPDOWN;
|
||||
|
||||
p->playerstate = PST_LIVE;
|
||||
p->health = 1; // 0 rings
|
||||
p->rings = 0; // 0 rings
|
||||
p->panim = PA_IDLE; // standing animation
|
||||
|
||||
if ((netgame || multiplayer) && !p->spectator)
|
||||
|
|
|
@ -656,6 +656,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
|
|||
{
|
||||
FOutVector v[4];
|
||||
FSurfaceInfo Surf;
|
||||
float sdupx, sdupy;
|
||||
|
||||
if (w < 0 || h < 0)
|
||||
return; // consistency w/ software
|
||||
|
@ -664,10 +665,16 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
|
|||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
v[0].x = v[3].x = (x - 160.0f)/160.0f;
|
||||
v[2].x = v[1].x = ((x+w) - 160.0f)/160.0f;
|
||||
v[0].y = v[1].y = -(y - 100.0f)/100.0f;
|
||||
v[2].y = v[3].y = -((y+h) - 100.0f)/100.0f;
|
||||
sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
|
||||
sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
|
||||
|
||||
if (color & V_NOSCALESTART)
|
||||
sdupx = sdupy = 2.0f;
|
||||
|
||||
v[0].x = v[3].x = (x*sdupx)/vid.width - 1;
|
||||
v[2].x = v[1].x = (x*sdupx + w*sdupx)/vid.width - 1;
|
||||
v[0].y = v[1].y = 1-(y*sdupy)/vid.height;
|
||||
v[2].y = v[3].y = 1-(y*sdupy + h*sdupy)/vid.height;
|
||||
|
||||
//Hurdler: do we still use this argb color? if not, we should remove it
|
||||
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;
|
||||
|
|
|
@ -1191,7 +1191,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
|
||||
V_DrawString(x + 20, y,
|
||||
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
|
||||
| ((players[tab[i].num].health > 0) ? 0 : V_60TRANS)
|
||||
| ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS)
|
||||
| V_ALLOWLOWERCASE, tab[i].name);
|
||||
|
||||
// Draw emeralds
|
||||
|
@ -1201,7 +1201,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
HU_DrawEmeralds(x-12,y+2,tab[i].emeralds);
|
||||
}
|
||||
|
||||
if (players[tab[i].num].health <= 0)
|
||||
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
|
||||
V_DrawSmallTranslucentPatch (x, y-4, V_80TRANS, livesback);
|
||||
else
|
||||
V_DrawSmallScaledPatch (x, y-4, 0, livesback);
|
||||
|
@ -1213,7 +1213,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
V_DrawSmallScaledPatch(x, y-4, 0, superprefix[players[tab[i].num].skin]);
|
||||
else
|
||||
{
|
||||
if (players[tab[i].num].health <= 0)
|
||||
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
|
||||
V_DrawSmallTranslucentPatch(x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin]);
|
||||
else
|
||||
V_DrawSmallScaledPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin]);
|
||||
|
@ -1229,7 +1229,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
else
|
||||
{
|
||||
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
|
||||
if (players[tab[i].num].health <= 0)
|
||||
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
|
||||
V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap);
|
||||
else
|
||||
V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap);
|
||||
|
@ -1237,10 +1237,10 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
}
|
||||
|
||||
if (G_GametypeUsesLives()) //show lives
|
||||
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%dx", players[tab[i].num].lives));
|
||||
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%dx", players[tab[i].num].lives));
|
||||
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
||||
{
|
||||
if (players[tab[i].num].health <= 0)
|
||||
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
|
||||
V_DrawSmallTranslucentPatch(x-32, y-4, V_60TRANS, tagico);
|
||||
else
|
||||
V_DrawSmallScaledPatch(x-32, y-4, 0, tagico);
|
||||
|
@ -1253,13 +1253,13 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
if (players[tab[i].num].exiting)
|
||||
V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
|
||||
else
|
||||
V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count));
|
||||
V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count));
|
||||
}
|
||||
else
|
||||
V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
|
||||
V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
|
||||
}
|
||||
else
|
||||
V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count));
|
||||
V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count));
|
||||
|
||||
y += 16;
|
||||
}
|
||||
|
@ -1304,7 +1304,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
strlcpy(name, tab[i].name, 9);
|
||||
V_DrawString(x + 20, y,
|
||||
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
|
||||
| ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT)
|
||||
| ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT)
|
||||
| V_ALLOWLOWERCASE, name);
|
||||
|
||||
if (gametype == GT_CTF)
|
||||
|
@ -1330,12 +1330,12 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
else
|
||||
{
|
||||
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
|
||||
if (players[tab[i].num].health <= 0)
|
||||
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
|
||||
V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap);
|
||||
else
|
||||
V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap);
|
||||
}
|
||||
V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
|
||||
V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1360,7 +1360,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
|||
strlcpy(name, tab[i].name, 9);
|
||||
V_DrawString(x + 20, y,
|
||||
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
|
||||
| ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT)
|
||||
| ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT)
|
||||
| V_ALLOWLOWERCASE, name);
|
||||
|
||||
if (G_GametypeUsesLives()) //show lives
|
||||
|
@ -1383,7 +1383,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
|||
V_DrawSmallScaledPatch (x, y-4, 0, superprefix[players[tab[i].num].skin]);
|
||||
else
|
||||
{
|
||||
if (players[tab[i].num].health <= 0)
|
||||
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
|
||||
V_DrawSmallTranslucentPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]);
|
||||
else
|
||||
V_DrawSmallScaledPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]);
|
||||
|
@ -1399,7 +1399,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
|||
else
|
||||
{
|
||||
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
|
||||
if (players[tab[i].num].health <= 0)
|
||||
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
|
||||
V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap);
|
||||
else
|
||||
V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap);
|
||||
|
@ -1414,13 +1414,13 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
|||
if (players[tab[i].num].exiting)
|
||||
V_DrawRightAlignedThinString(x+156, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
|
||||
else
|
||||
V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
|
||||
V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
|
||||
}
|
||||
else
|
||||
V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
|
||||
V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
|
||||
}
|
||||
else
|
||||
V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
|
||||
V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
|
||||
|
||||
y += 16;
|
||||
if (y > 160)
|
||||
|
|
94
src/info.c
94
src/info.c
|
@ -485,32 +485,32 @@ state_t states[NUMSTATES] =
|
|||
{SPR_THOK, FF_TRANS50, 8, {NULL}, 0, 0, S_NULL}, // S_THOK
|
||||
|
||||
// Player
|
||||
{SPR_PLAY, SPR2_STND, 105, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_STND
|
||||
{SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT
|
||||
{SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK
|
||||
{SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN
|
||||
{SPR_PLAY, SPR2_PEEL, 2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL
|
||||
{SPR_PLAY, SPR2_PAIN, 350, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_PAIN
|
||||
{SPR_PLAY, SPR2_DEAD, 4, {NULL}, 0, 0, S_PLAY_DEAD}, // S_PLAY_DEAD
|
||||
{SPR_PLAY, SPR2_DRWN, 4, {NULL}, 0, 0, S_PLAY_DRWN}, // S_PLAY_DRWN
|
||||
{SPR_PLAY, SPR2_SPIN, 1, {NULL}, 0, 0, S_PLAY_SPIN}, // S_PLAY_SPIN
|
||||
{SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH
|
||||
{SPR_PLAY, SPR2_GASP, 14, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_GASP
|
||||
{SPR_PLAY, SPR2_JUMP, 1, {NULL}, 0, 0, S_PLAY_JUMP}, // S_PLAY_JUMP
|
||||
{SPR_PLAY, SPR2_SPNG, 2, {NULL}, 0, 0, S_PLAY_SPRING}, // S_PLAY_SPRING
|
||||
{SPR_PLAY, SPR2_FALL, 2, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_FALL
|
||||
{SPR_PLAY, SPR2_EDGE, 12, {NULL}, 0, 0, S_PLAY_EDGE}, // S_PLAY_EDGE
|
||||
{SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE
|
||||
{SPR_PLAY, SPR2_STND|FF_ANIMATE, 105, {NULL}, 0, 7, S_PLAY_WAIT}, // S_PLAY_STND
|
||||
{SPR_PLAY, SPR2_WAIT|FF_ANIMATE, -1, {NULL}, 0, 16, S_NULL}, // S_PLAY_WAIT
|
||||
{SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK
|
||||
{SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN
|
||||
{SPR_PLAY, SPR2_PEEL, 2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL
|
||||
{SPR_PLAY, SPR2_PAIN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_FALL}, // S_PLAY_PAIN
|
||||
{SPR_PLAY, SPR2_DEAD|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_DEAD
|
||||
{SPR_PLAY, SPR2_DRWN|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_DRWN
|
||||
{SPR_PLAY, SPR2_SPIN, 1, {NULL}, 0, 0, S_PLAY_SPIN}, // S_PLAY_SPIN
|
||||
{SPR_PLAY, SPR2_DASH, 2, {NULL}, 0, 0, S_PLAY_DASH}, // S_PLAY_DASH
|
||||
{SPR_PLAY, SPR2_GASP|FF_ANIMATE, 14, {NULL}, 0, 4, S_PLAY_WALK}, // S_PLAY_GASP
|
||||
{SPR_PLAY, SPR2_JUMP, 1, {NULL}, 0, 0, S_PLAY_JUMP}, // S_PLAY_JUMP
|
||||
{SPR_PLAY, SPR2_SPNG, 2, {NULL}, 0, 0, S_PLAY_SPRING}, // S_PLAY_SPRING
|
||||
{SPR_PLAY, SPR2_FALL, 2, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_FALL
|
||||
{SPR_PLAY, SPR2_EDGE|FF_ANIMATE, -1, {NULL}, 0, 12, S_NULL}, // S_PLAY_EDGE
|
||||
{SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE
|
||||
|
||||
// CA_FLY/CA_SWIM
|
||||
{SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY
|
||||
{SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM
|
||||
{SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED
|
||||
{SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY
|
||||
{SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM
|
||||
{SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED
|
||||
|
||||
// CA_GLIDEANDCLIMB
|
||||
{SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE
|
||||
{SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING
|
||||
{SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB
|
||||
{SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE
|
||||
{SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_CLING
|
||||
{SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB
|
||||
|
||||
// CA_TWINSPIN
|
||||
{SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN
|
||||
|
@ -520,33 +520,33 @@ state_t states[NUMSTATES] =
|
|||
{SPR_PLAY, SPR2_MLEE, 20, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_MELEE_FINISH
|
||||
|
||||
// SF_SUPERANIMS
|
||||
{SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND
|
||||
{SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK
|
||||
{SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN
|
||||
{SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL
|
||||
{SPR_PLAY, SPR2_SPAN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN
|
||||
{SPR_PLAY, SPR2_SSTN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN
|
||||
{SPR_PLAY, SPR2_SDTH, 4, {NULL}, 0, 0, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD
|
||||
{SPR_PLAY, SPR2_SDRN, 4, {NULL}, 0, 0, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN
|
||||
{SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN
|
||||
{SPR_PLAY, SPR2_SGSP, 14, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_GASP
|
||||
{SPR_PLAY, SPR2_SJMP, 1, {NULL}, 0, 0, S_PLAY_SUPER_JUMP}, // S_PLAY_SUPER_JUMP
|
||||
{SPR_PLAY, SPR2_SSPG, 2, {NULL}, 0, 0, S_PLAY_SUPER_SPRING}, // S_PLAY_SUPER_SPRING
|
||||
{SPR_PLAY, SPR2_SFAL, 2, {NULL}, 0, 0, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_FALL
|
||||
{SPR_PLAY, SPR2_SEDG, 12, {NULL}, 0, 0, S_PLAY_SUPER_EDGE}, // S_PLAY_SUPER_EDGE
|
||||
{SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE
|
||||
{SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT
|
||||
{SPR_PLAY, SPR2_SSTD|FF_ANIMATE, -1, {NULL}, 0, 7, S_NULL}, // S_PLAY_SUPER_STND
|
||||
{SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK
|
||||
{SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN
|
||||
{SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL
|
||||
{SPR_PLAY, SPR2_SPAN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_PAIN
|
||||
{SPR_PLAY, SPR2_SSTN|FF_ANIMATE, 350, {NULL}, 0, 4, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_STUN
|
||||
{SPR_PLAY, SPR2_SDTH|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_SUPER_DEAD
|
||||
{SPR_PLAY, SPR2_SDRN|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_SUPER_DRWN
|
||||
{SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN
|
||||
{SPR_PLAY, SPR2_SGSP|FF_ANIMATE, 14, {NULL}, 0, 4, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_GASP
|
||||
{SPR_PLAY, SPR2_SJMP, 1, {NULL}, 0, 0, S_PLAY_SUPER_JUMP}, // S_PLAY_SUPER_JUMP
|
||||
{SPR_PLAY, SPR2_SSPG, 2, {NULL}, 0, 0, S_PLAY_SUPER_SPRING}, // S_PLAY_SUPER_SPRING
|
||||
{SPR_PLAY, SPR2_SFAL, 2, {NULL}, 0, 0, S_PLAY_SUPER_FALL}, // S_PLAY_SUPER_FALL
|
||||
{SPR_PLAY, SPR2_SEDG|FF_ANIMATE, -1, {NULL}, 0, 12, S_NULL}, // S_PLAY_SUPER_EDGE
|
||||
{SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE
|
||||
{SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT
|
||||
|
||||
// SF_SUPER
|
||||
{SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS
|
||||
{SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9
|
||||
{SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS
|
||||
{SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9
|
||||
|
||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY
|
||||
|
||||
|
|
|
@ -309,6 +309,19 @@ static int lib_pRemoveMobj(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// P_IsValidSprite2 technically doesn't exist, and probably never should... but too much would need to be exposed to allow this to be checked by other methods.
|
||||
|
||||
static int lib_pIsValidSprite2(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
UINT8 spr2 = (UINT8)luaL_checkinteger(L, 2);
|
||||
//HUDSAFE
|
||||
if (!mobj)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
lua_pushboolean(L, (mobj->skin && (((skin_t *)mobj->skin)->sprites[spr2].numframes > 0)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pSpawnMissile(lua_State *L)
|
||||
{
|
||||
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
@ -618,6 +631,17 @@ static int lib_pAddPlayerScore(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pStealPlayerScore(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
UINT32 amount = (UINT32)luaL_checkinteger(L, 2);
|
||||
NOHUD
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_StealPlayerScore(player, amount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pPlayerInPain(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
@ -1144,7 +1168,7 @@ static int lib_pPlayerRingBurst(lua_State *L)
|
|||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
if (num_rings == -1)
|
||||
num_rings = player->health - 1;
|
||||
num_rings = player->rings;
|
||||
P_PlayerRingBurst(player, num_rings);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1169,6 +1193,16 @@ static int lib_pPlayerWeaponAmmoBurst(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pPlayerWeaponPanelOrAmmoBurst(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
NOHUD
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_PlayerWeaponPanelOrAmmoBurst(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pPlayerEmeraldBurst(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
@ -1276,6 +1310,16 @@ static int lib_pDoNightsScore(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pDoMatchSuper(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
NOHUD
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_DoMatchSuper(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// P_SPEC
|
||||
////////////
|
||||
|
||||
|
@ -2017,6 +2061,7 @@ static luaL_Reg lib[] = {
|
|||
// don't add P_SetMobjState or P_SetPlayerMobjState, use "mobj.state = S_NEWSTATE" instead.
|
||||
{"P_SpawnMobj",lib_pSpawnMobj},
|
||||
{"P_RemoveMobj",lib_pRemoveMobj},
|
||||
{"P_IsValidSprite2", lib_pIsValidSprite2},
|
||||
{"P_SpawnMissile",lib_pSpawnMissile},
|
||||
{"P_SpawnXYZMissile",lib_pSpawnXYZMissile},
|
||||
{"P_SpawnPointMissile",lib_pSpawnPointMissile},
|
||||
|
@ -2043,6 +2088,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_GetPlayerSpinHeight",lib_pGetPlayerSpinHeight},
|
||||
{"P_GetPlayerControlDirection",lib_pGetPlayerControlDirection},
|
||||
{"P_AddPlayerScore",lib_pAddPlayerScore},
|
||||
{"P_StealPlayerScore",lib_pStealPlayerScore},
|
||||
{"P_PlayerInPain",lib_pPlayerInPain},
|
||||
{"P_DoPlayerPain",lib_pDoPlayerPain},
|
||||
{"P_ResetPlayer",lib_pResetPlayer},
|
||||
|
@ -2094,6 +2140,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_PlayerRingBurst",lib_pPlayerRingBurst},
|
||||
{"P_PlayerWeaponPanelBurst",lib_pPlayerWeaponPanelBurst},
|
||||
{"P_PlayerWeaponAmmoBurst",lib_pPlayerWeaponAmmoBurst},
|
||||
{"P_PlayerWeaponPanelOrAmmoBurst", lib_pPlayerWeaponPanelOrAmmoBurst},
|
||||
{"P_PlayerEmeraldBurst",lib_pPlayerEmeraldBurst},
|
||||
{"P_PlayerFlagBurst",lib_pPlayerFlagBurst},
|
||||
{"P_PlayRinglossSound",lib_pPlayRinglossSound},
|
||||
|
@ -2102,6 +2149,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_PlayLivesJingle",lib_pPlayLivesJingle},
|
||||
{"P_CanPickupItem",lib_pCanPickupItem},
|
||||
{"P_DoNightsScore",lib_pDoNightsScore},
|
||||
{"P_DoMatchSuper",lib_pDoMatchSuper},
|
||||
|
||||
// p_spec
|
||||
{"P_Thrust",lib_pThrust},
|
||||
|
|
|
@ -64,9 +64,9 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_Touch
|
|||
#define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type
|
||||
#define LUAh_MobjThinker(mo) LUAh_MobjHook(mo, hook_MobjThinker) // Hook for P_MobjThinker or P_SceneryThinker by mobj type
|
||||
#define LUAh_BossThinker(mo) LUAh_MobjHook(mo, hook_BossThinker) // Hook for P_GenericBossThinker by mobj type
|
||||
UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); // Hook for P_DamageMobj by mobj type (Should mobj take damage?)
|
||||
boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!)
|
||||
boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source); // Hook for P_KillMobj by mobj type
|
||||
UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Should mobj take damage?)
|
||||
boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!)
|
||||
boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for P_KillMobj by mobj type
|
||||
#define LUAh_BossDeath(mo) LUAh_MobjHook(mo, hook_BossDeath) // Hook for A_BossDeath by mobj type
|
||||
#define LUAh_MobjRemoved(mo) LUAh_MobjHook(mo, hook_MobjRemoved) // Hook for P_RemoveMobj by mobj type
|
||||
#define LUAh_JumpSpecial(player) LUAh_PlayerHook(player, hook_JumpSpecial) // Hook for P_DoJumpStuff (Any-jumping)
|
||||
|
@ -77,7 +77,7 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd
|
|||
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name
|
||||
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors
|
||||
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages
|
||||
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages
|
||||
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages
|
||||
#define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer
|
||||
#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb
|
||||
#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities
|
||||
|
|
|
@ -414,7 +414,7 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher)
|
|||
}
|
||||
|
||||
// Hook for P_DamageMobj by mobj type (Should mobj take damage?)
|
||||
UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
||||
{
|
||||
hook_p hookp;
|
||||
UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no.
|
||||
|
@ -433,14 +433,16 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32
|
|||
LUA_PushUserdata(gL, inflictor, META_MOBJ);
|
||||
LUA_PushUserdata(gL, source, META_MOBJ);
|
||||
lua_pushinteger(gL, damage);
|
||||
lua_pushinteger(gL, damagetype);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
if (lua_pcall(gL, 4, 1, 0)) {
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
if (lua_pcall(gL, 5, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
|
@ -462,7 +464,7 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32
|
|||
}
|
||||
|
||||
// Hook for P_DamageMobj by mobj type (Mobj actually takes damage!)
|
||||
boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
||||
{
|
||||
hook_p hookp;
|
||||
boolean hooked = false;
|
||||
|
@ -481,14 +483,16 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32
|
|||
LUA_PushUserdata(gL, inflictor, META_MOBJ);
|
||||
LUA_PushUserdata(gL, source, META_MOBJ);
|
||||
lua_pushinteger(gL, damage);
|
||||
lua_pushinteger(gL, damagetype);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
if (lua_pcall(gL, 4, 1, 0)) {
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
lua_pushvalue(gL, -6);
|
||||
if (lua_pcall(gL, 5, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
|
@ -505,7 +509,7 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32
|
|||
}
|
||||
|
||||
// Hook for P_KillMobj by mobj type
|
||||
boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype)
|
||||
{
|
||||
hook_p hookp;
|
||||
boolean hooked = false;
|
||||
|
@ -523,13 +527,15 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
|||
LUA_PushUserdata(gL, target, META_MOBJ);
|
||||
LUA_PushUserdata(gL, inflictor, META_MOBJ);
|
||||
LUA_PushUserdata(gL, source, META_MOBJ);
|
||||
lua_pushinteger(gL, damagetype);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -4);
|
||||
lua_pushvalue(gL, -4);
|
||||
lua_pushvalue(gL, -4);
|
||||
if (lua_pcall(gL, 3, 1, 0)) {
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
if (lua_pcall(gL, 4, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
|
@ -731,7 +737,7 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg)
|
|||
}
|
||||
|
||||
// Hook for hurt messages
|
||||
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype)
|
||||
{
|
||||
hook_p hookp;
|
||||
boolean hooked = false;
|
||||
|
@ -749,13 +755,15 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
|
|||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
LUA_PushUserdata(gL, inflictor, META_MOBJ);
|
||||
LUA_PushUserdata(gL, source, META_MOBJ);
|
||||
lua_pushinteger(gL, damagetype);
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -4);
|
||||
lua_pushvalue(gL, -4);
|
||||
lua_pushvalue(gL, -4);
|
||||
if (lua_pcall(gL, 3, 1, 0)) {
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
lua_pushvalue(gL, -5);
|
||||
if (lua_pcall(gL, 4, 1, 0)) {
|
||||
if (!hookp->error || cv_debug & DBG_LUA)
|
||||
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
|
|
|
@ -34,6 +34,7 @@ enum mobj_e {
|
|||
mobj_angle,
|
||||
mobj_sprite,
|
||||
mobj_frame,
|
||||
mobj_sprite2,
|
||||
mobj_anim_duration,
|
||||
mobj_touching_sectorlist,
|
||||
mobj_subsector,
|
||||
|
@ -93,6 +94,7 @@ static const char *const mobj_opt[] = {
|
|||
"angle",
|
||||
"sprite",
|
||||
"frame",
|
||||
"sprite2",
|
||||
"anim_duration",
|
||||
"touching_sectorlist",
|
||||
"subsector",
|
||||
|
@ -189,6 +191,9 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_frame:
|
||||
lua_pushinteger(L, mo->frame);
|
||||
break;
|
||||
case mobj_sprite2:
|
||||
lua_pushinteger(L, mo->sprite2);
|
||||
break;
|
||||
case mobj_anim_duration:
|
||||
lua_pushinteger(L, mo->anim_duration);
|
||||
break;
|
||||
|
@ -411,6 +416,9 @@ static int mobj_set(lua_State *L)
|
|||
case mobj_frame:
|
||||
mo->frame = (UINT32)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mobj_sprite2:
|
||||
mo->sprite2 = P_GetMobjSprite2(mo, (UINT8)luaL_checkinteger(L, 3));
|
||||
break;
|
||||
case mobj_anim_duration:
|
||||
mo->anim_duration = (UINT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
|
|
|
@ -122,8 +122,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushfixed(L, plr->bob);
|
||||
else if (fastcmp(field,"aiming"))
|
||||
lua_pushangle(L, plr->aiming);
|
||||
else if (fastcmp(field,"health"))
|
||||
lua_pushinteger(L, plr->health);
|
||||
else if (fastcmp(field,"rings"))
|
||||
lua_pushinteger(L, plr->rings);
|
||||
else if (fastcmp(field,"pity"))
|
||||
lua_pushinteger(L, plr->pity);
|
||||
else if (fastcmp(field,"currentweapon"))
|
||||
|
@ -382,8 +382,8 @@ static int player_set(lua_State *L)
|
|||
else if (plr == &players[secondarydisplayplayer])
|
||||
localaiming2 = plr->aiming;
|
||||
}
|
||||
else if (fastcmp(field,"health"))
|
||||
plr->health = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"rings"))
|
||||
plr->rings = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"pity"))
|
||||
plr->pity = (SINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"currentweapon"))
|
||||
|
|
|
@ -606,7 +606,7 @@ void Command_CauseCfail_f(void)
|
|||
players[consoleplayer].mo->y = 123311; //cfail cansuled kthxbye
|
||||
players[consoleplayer].mo->z = 123311;
|
||||
players[consoleplayer].score = 1337;
|
||||
players[consoleplayer].health = 1337;
|
||||
players[consoleplayer].rings = 1337;
|
||||
players[consoleplayer].mo->destscale = 25;
|
||||
P_SetThingPosition(players[consoleplayer].mo);
|
||||
|
||||
|
@ -720,7 +720,7 @@ void Command_Setrings_f(void)
|
|||
if (COM_Argc() > 1)
|
||||
{
|
||||
// P_GivePlayerRings does value clamping
|
||||
players[consoleplayer].health = players[consoleplayer].mo->health = 1;
|
||||
players[consoleplayer].rings = 0;
|
||||
P_GivePlayerRings(&players[consoleplayer], atoi(COM_Argv(1)));
|
||||
if (!G_IsSpecialStage(gamemap) || !useNightsSS)
|
||||
players[consoleplayer].totalring -= atoi(COM_Argv(1)); //undo totalring addition done in P_GivePlayerRings
|
||||
|
@ -1298,7 +1298,7 @@ void Command_ObjectPlace_f(void)
|
|||
// Like the classics, recover from death by entering objectplace
|
||||
if (players[0].mo->health <= 0)
|
||||
{
|
||||
players[0].mo->health = players[0].health = 1;
|
||||
players[0].mo->health = 1;
|
||||
players[0].deadtimer = 0;
|
||||
op_oldflags1 = mobjinfo[MT_PLAYER].flags;
|
||||
++players[0].lives;
|
||||
|
|
|
@ -3819,7 +3819,7 @@ static void M_HandleImageDef(INT32 choice)
|
|||
static void M_PandorasBox(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].health - 1, 0));
|
||||
CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].rings, 0));
|
||||
CV_StealthSetValue(&cv_dummylives, players[consoleplayer].lives);
|
||||
CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues);
|
||||
M_SetupNextMenu(&SR_PandoraDef);
|
||||
|
@ -3827,7 +3827,7 @@ static void M_PandorasBox(INT32 choice)
|
|||
|
||||
static boolean M_ExitPandorasBox(void)
|
||||
{
|
||||
if (cv_dummyrings.value != max(players[consoleplayer].health - 1, 0))
|
||||
if (cv_dummyrings.value != max(players[consoleplayer].rings, 0))
|
||||
COM_ImmedExecute(va("setrings %d", cv_dummyrings.value));
|
||||
if (cv_dummylives.value != players[consoleplayer].lives)
|
||||
COM_ImmedExecute(va("setlives %d", cv_dummylives.value));
|
||||
|
|
|
@ -661,15 +661,15 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
|
|||
if ((netgame || multiplayer) && player->spectator)
|
||||
continue;
|
||||
|
||||
if (player->health <= 0)
|
||||
continue; // dead
|
||||
|
||||
if (player->pflags & PF_INVIS)
|
||||
continue; // ignore notarget
|
||||
|
||||
if (!player->mo || P_MobjWasRemoved(player->mo))
|
||||
continue;
|
||||
|
||||
if (player->mo->health <= 0)
|
||||
continue; // dead
|
||||
|
||||
if (dist > 0
|
||||
&& P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist)
|
||||
continue; // Too far away
|
||||
|
@ -733,7 +733,7 @@ static boolean P_LookForShield(mobj_t *actor)
|
|||
|
||||
player = &players[actor->lastlook];
|
||||
|
||||
if (player->health <= 0 || !player->mo)
|
||||
if (!player->mo || player->mo->health <= 0)
|
||||
continue; // dead
|
||||
|
||||
//When in CTF, don't pull rings that you cannot pick up.
|
||||
|
@ -2556,6 +2556,7 @@ void A_1upThinker(mobj_t *actor)
|
|||
{
|
||||
P_SetTarget(&actor->tracer, P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY));
|
||||
P_SetTarget(&actor->tracer->target, actor);
|
||||
actor->tracer->skin = &skins[players[closestplayer].skin]; // required here to prevent spr2 default showing stand for a single frame
|
||||
P_SetMobjState(actor->tracer, actor->info->seestate);
|
||||
|
||||
// The overlay is going to be one tic early turning off and on
|
||||
|
@ -2816,7 +2817,7 @@ void A_BossDeath(mobj_t *mo)
|
|||
|
||||
// make sure there is a player alive for victory
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && (players[i].health > 0
|
||||
if (playeringame[i] && ((players[i].mo && players[i].mo->health > 0)
|
||||
|| ((netgame || multiplayer) && (players[i].lives > 0 || players[i].continues > 0))))
|
||||
break;
|
||||
|
||||
|
@ -8443,7 +8444,7 @@ void A_RingDrain(mobj_t *actor)
|
|||
}
|
||||
|
||||
player = actor->target->player;
|
||||
P_GivePlayerRings(player, -min(locvar1, player->mo->health-1));
|
||||
P_GivePlayerRings(player, -min(locvar1, player->rings));
|
||||
}
|
||||
|
||||
// Function: A_SplitShot
|
||||
|
@ -8751,7 +8752,7 @@ void A_CheckTargetRings(mobj_t *actor)
|
|||
if (!(actor->target) || !(actor->target->player))
|
||||
return;
|
||||
|
||||
if (actor->target->player->health >= locvar1)
|
||||
if (actor->target->player->rings >= locvar1)
|
||||
P_SetMobjState(actor, locvar2);
|
||||
}
|
||||
|
||||
|
@ -8773,7 +8774,7 @@ void A_CheckRings(mobj_t *actor)
|
|||
#endif
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
cntr += players[i].health-1;
|
||||
cntr += players[i].rings;
|
||||
|
||||
if (cntr >= locvar1)
|
||||
P_SetMobjState(actor, locvar2);
|
||||
|
@ -9345,7 +9346,7 @@ void A_ForceWin(mobj_t *actor)
|
|||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && (players[i].health > 0
|
||||
if (playeringame[i] && ((players[i].mo && players[i].mo->health > 0)
|
||||
|| ((netgame || multiplayer) && (players[i].lives > 0 || players[i].continues > 0))))
|
||||
break;
|
||||
}
|
||||
|
|
341
src/p_inter.c
341
src/p_inter.c
|
@ -224,6 +224,65 @@ void P_DoNightsScore(player_t *player)
|
|||
dummymo->destscale = 2*FRACUNIT;
|
||||
}
|
||||
|
||||
//
|
||||
// P_DoMatchSuper
|
||||
//
|
||||
// Checks if you have all 7 pw_emeralds, then turns you "super". =P
|
||||
//
|
||||
void P_DoMatchSuper(player_t *player)
|
||||
{
|
||||
UINT16 match_emeralds = player->powers[pw_emeralds];
|
||||
boolean doteams = false;
|
||||
int i;
|
||||
|
||||
// If this gametype has teams, check every player on your team for emeralds.
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
doteams = true;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (players[i].ctfteam == player->ctfteam)
|
||||
match_emeralds |= players[i].powers[pw_emeralds];
|
||||
}
|
||||
|
||||
if (!ALL7EMERALDS(match_emeralds))
|
||||
return;
|
||||
|
||||
// Got 'em all? Turn "super"!
|
||||
emeraldspawndelay = invulntics + 1;
|
||||
player->powers[pw_emeralds] = 0;
|
||||
player->powers[pw_invulnerability] = emeraldspawndelay;
|
||||
player->powers[pw_sneakers] = emeraldspawndelay;
|
||||
if (P_IsLocalPlayer(player) && !player->powers[pw_super])
|
||||
{
|
||||
S_StopMusic();
|
||||
if (mariomode)
|
||||
G_GhostAddColor(GHC_INVINCIBLE);
|
||||
S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false);
|
||||
}
|
||||
|
||||
// Also steal 50 points from every enemy, sealing your victory.
|
||||
P_StealPlayerScore(player, 50);
|
||||
|
||||
// In a team game?
|
||||
// Check everyone else on your team for emeralds, and turn those helpful assisting players invincible too.
|
||||
if (doteams)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].ctfteam == player->ctfteam
|
||||
&& players[i].powers[pw_emeralds] != 0)
|
||||
{
|
||||
players[i].powers[pw_emeralds] = 0;
|
||||
player->powers[pw_invulnerability] = invulntics + 1;
|
||||
player->powers[pw_sneakers] = player->powers[pw_invulnerability];
|
||||
if (P_IsLocalPlayer(player) && !player->powers[pw_super])
|
||||
{
|
||||
S_StopMusic();
|
||||
if (mariomode)
|
||||
G_GhostAddColor(GHC_INVINCIBLE);
|
||||
S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Takes action based on a ::MF_SPECIAL thing touched by a player.
|
||||
* Actually, this just checks a few things (heights, toucher->player, no
|
||||
* objectplace, no dead or disappearing things)
|
||||
|
@ -465,7 +524,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
{
|
||||
INT32 pindex = special->info->mass - (INT32)pw_infinityring;
|
||||
|
||||
player->powers[special->info->mass] += (UINT16)special->info->reactiontime;
|
||||
player->powers[special->info->mass] += (UINT16)special->reactiontime;
|
||||
player->ringweapons |= 1 << (pindex-1);
|
||||
|
||||
if (player->powers[special->info->mass] > rw_maximums[pindex])
|
||||
|
@ -552,7 +611,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
|
||||
if (special->threshold)
|
||||
{
|
||||
player->powers[pw_emeralds] |= special->info->speed;
|
||||
P_DoMatchSuper(player);
|
||||
}
|
||||
else
|
||||
emeralds |= special->info->speed;
|
||||
|
||||
|
@ -573,6 +635,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
return;
|
||||
|
||||
player->powers[pw_emeralds] |= special->threshold;
|
||||
P_DoMatchSuper(player);
|
||||
break;
|
||||
|
||||
// Secret emblem thingy
|
||||
|
@ -834,16 +897,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (G_IsSpecialStage(gamemap) && !player->exiting)
|
||||
{ // In special stages, share rings. Everyone gives up theirs to the player who touched the capsule
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && (&players[i] != player) && players[i].mo->health > 1)
|
||||
if (playeringame[i] && (&players[i] != player) && players[i].rings > 0)
|
||||
{
|
||||
toucher->health += players[i].mo->health-1;
|
||||
player->health = toucher->health;
|
||||
players[i].mo->health = 1;
|
||||
players[i].health = players[i].mo->health;
|
||||
player->rings += players[i].rings;
|
||||
players[i].rings = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(player->health > 1) || player->exiting)
|
||||
if (player->rings <= 0 || player->exiting)
|
||||
return;
|
||||
|
||||
// Mark the player as 'pull into the capsule'
|
||||
|
@ -1408,7 +1469,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
|
||||
if (player->powers[pw_invulnerability] || player->powers[pw_flashing]
|
||||
|| (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds]))))
|
||||
|| player->powers[pw_super])
|
||||
return;
|
||||
if (player->powers[pw_shield] || player->bot) //If One-Hit Shield
|
||||
{
|
||||
|
@ -1418,11 +1479,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
else
|
||||
{
|
||||
P_PlayRinglossSound(toucher);
|
||||
if (toucher->health > 10)
|
||||
toucher->health -= 10;
|
||||
if (player->rings >= 10)
|
||||
player->rings -= 10;
|
||||
else
|
||||
toucher->health = 1;
|
||||
player->health = toucher->health;
|
||||
player->rings = 0;
|
||||
}
|
||||
|
||||
P_DoPlayerPain(player, special, NULL);
|
||||
|
@ -1524,6 +1584,9 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
|
|||
if (!player)
|
||||
return; // Impossible!
|
||||
|
||||
if (!player->mo)
|
||||
return; // Also impossible!
|
||||
|
||||
if (player->spectator)
|
||||
return; // No messages for dying (crushed) spectators.
|
||||
|
||||
|
@ -1531,11 +1594,11 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
|
|||
return; // Presumably it's obvious what's happening in splitscreen.
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_HurtMsg(player, inflictor, source))
|
||||
if (LUAh_HurtMsg(player, inflictor, source, damagetype))
|
||||
return;
|
||||
#endif
|
||||
|
||||
deadtarget = (player->health <= 0);
|
||||
deadtarget = (player->mo->health <= 0);
|
||||
|
||||
// Target's name
|
||||
snprintf(targetname, sizeof(targetname), "%s%s%s",
|
||||
|
@ -1569,8 +1632,10 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
|
|||
else switch (inflictor->type)
|
||||
{
|
||||
case MT_PLAYER:
|
||||
if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON)
|
||||
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");
|
||||
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])
|
||||
|
@ -2002,7 +2067,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
target->health = 0; // This makes it easy to check if something's dead elsewhere.
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MobjDeath(target, inflictor, source) || P_MobjWasRemoved(target))
|
||||
if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target))
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
@ -2473,8 +2538,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
|
|||
player_t *player = target->player;
|
||||
tic_t oldnightstime = player->nightstime;
|
||||
|
||||
if (!player->powers[pw_flashing]
|
||||
&& !(player->pflags & PF_GODMODE))
|
||||
if (!player->powers[pw_flashing])
|
||||
{
|
||||
angle_t fa;
|
||||
|
||||
|
@ -2589,27 +2653,18 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
return true;
|
||||
}
|
||||
|
||||
if (target->health <= 1) // Death
|
||||
if (player->rings > 0) // Ring loss
|
||||
{
|
||||
P_PlayRinglossSound(target);
|
||||
P_PlayerRingBurst(player, player->rings);
|
||||
}
|
||||
else // Death
|
||||
{
|
||||
P_PlayDeathSound(target);
|
||||
P_PlayVictorySound(source); // Killer laughs at you! LAUGHS! BWAHAHAHHAHAA!!
|
||||
}
|
||||
else if (target->health > 1) // Ring loss
|
||||
{
|
||||
P_PlayRinglossSound(target);
|
||||
P_PlayerRingBurst(player, player->mo->health - 1);
|
||||
}
|
||||
|
||||
if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))
|
||||
{
|
||||
player->health -= 10;
|
||||
if (player->health < 2)
|
||||
player->health = 2;
|
||||
target->health = player->health;
|
||||
}
|
||||
else
|
||||
player->health = target->health = 1;
|
||||
|
||||
player->rings = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2659,8 +2714,12 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
|||
|
||||
// Burst weapons and emeralds in Match/CTF only
|
||||
if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF))
|
||||
P_PlayerRingBurst(player, player->health - 1);
|
||||
{
|
||||
P_PlayerRingBurst(player, player->rings);
|
||||
P_PlayerEmeraldBurst(player, false);
|
||||
}
|
||||
|
||||
// Get rid of shield
|
||||
player->powers[pw_shield] = SH_NONE;
|
||||
player->mo->color = player->skincolor;
|
||||
|
||||
|
@ -2783,7 +2842,7 @@ void P_RemoveShield(player_t *player)
|
|||
player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK;
|
||||
}
|
||||
|
||||
static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
||||
{
|
||||
// Must do pain first to set flashing -- P_RemoveShield can cause damage
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
|
@ -2792,7 +2851,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 || (source->type == MT_NULL && source->threshold == 43))) // spikes
|
||||
if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
else
|
||||
S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss.
|
||||
|
@ -2817,15 +2876,12 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
|
||||
static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
||||
{
|
||||
if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])))
|
||||
{
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
}
|
||||
if ((source && source->type == MT_SPIKE) || 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
|
||||
{
|
||||
|
@ -2847,6 +2903,10 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
|
|||
|
||||
// Ring loss sound plays despite hitting spikes
|
||||
P_PlayRinglossSound(player->mo); // Ringledingle!
|
||||
P_PlayerRingBurst(player, damage);
|
||||
player->rings -= damage;
|
||||
if (player->rings < 0)
|
||||
player->rings = 0;
|
||||
}
|
||||
|
||||
/** Damages an object, which may or may not be a player.
|
||||
|
@ -2895,7 +2955,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
// Everything above here can't be forced.
|
||||
if (!metalrecording)
|
||||
{
|
||||
UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage);
|
||||
UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage, damagetype);
|
||||
if (P_MobjWasRemoved(target))
|
||||
return (shouldForce == 1); // mobj was removed
|
||||
if (shouldForce == 1)
|
||||
|
@ -2938,7 +2998,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return false;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target))
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
|
@ -2966,7 +3026,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return false;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target))
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
|
@ -2976,7 +3036,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
#ifdef HAVE_BLUA
|
||||
else if (target->flags & MF_ENEMY)
|
||||
{
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage) || P_MobjWasRemoved(target))
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target))
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -2990,6 +3050,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
if (player->exiting)
|
||||
return false;
|
||||
|
||||
if (player->pflags & PF_GODMODE)
|
||||
return false;
|
||||
|
||||
if (!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS))
|
||||
return false;
|
||||
|
||||
|
@ -3020,11 +3083,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return false; // Don't hit yourself with your own paraloop, baka
|
||||
if (source && source->player && !cv_friendlyfire.value
|
||||
&& (gametype == GT_COOP
|
||||
|| (G_GametypeHasTeams() && target->player->ctfteam == source->player->ctfteam)))
|
||||
|| (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam)))
|
||||
return false; // Don't run eachother over in special stages and team games and such
|
||||
}
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage))
|
||||
if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype))
|
||||
return true;
|
||||
#endif
|
||||
P_NiGHTSDamage(target, source); // -5s :(
|
||||
|
@ -3055,12 +3118,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!force && player->pflags & PF_GODMODE)
|
||||
return false;
|
||||
|
||||
// Instant-Death
|
||||
if (damagetype & DMG_DEATHMASK)
|
||||
{
|
||||
P_KillPlayer(player, source, damage);
|
||||
player->rings = 0;
|
||||
}
|
||||
else if (metalrecording)
|
||||
{
|
||||
if (!inflictor)
|
||||
|
@ -3074,19 +3137,19 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return false; // Metal Sonic walk through flame !!
|
||||
else
|
||||
{ // Oh no! Metal Sonic is hit !!
|
||||
P_ShieldDamage(player, inflictor, source, damage);
|
||||
P_ShieldDamage(player, inflictor, source, damage, damagetype);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] // ignore bouncing & such in invulnerability
|
||||
|| (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player))))
|
||||
|| player->powers[pw_super])
|
||||
{
|
||||
if (force || (inflictor && (inflictor->flags & MF_MISSILE)
|
||||
&& (inflictor->flags2 & MF2_SUPERFIRE)
|
||||
&& player->powers[pw_super]))
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
if (!LUAh_MobjDamage(target, inflictor, source, damage))
|
||||
if (!LUAh_MobjDamage(target, inflictor, source, damage, damagetype))
|
||||
#endif
|
||||
P_SuperDamage(player, inflictor, source, damage);
|
||||
return true;
|
||||
|
@ -3095,67 +3158,35 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
return false;
|
||||
}
|
||||
#ifdef HAVE_BLUA
|
||||
else if (LUAh_MobjDamage(target, inflictor, source, damage))
|
||||
else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype))
|
||||
return true;
|
||||
#endif
|
||||
else if (!player->powers[pw_super] && (player->powers[pw_shield] || player->bot)) //If One-Hit Shield
|
||||
else if (player->powers[pw_shield] || player->bot) //If One-Hit Shield
|
||||
{
|
||||
P_ShieldDamage(player, inflictor, source, damage);
|
||||
P_ShieldDamage(player, inflictor, source, damage, damagetype);
|
||||
damage = 0;
|
||||
}
|
||||
else if (player->mo->health > 1) // No shield but have rings.
|
||||
else if (player->rings > 0) // No shield but have rings.
|
||||
{
|
||||
damage = player->mo->health - 1;
|
||||
damage = player->rings;
|
||||
P_RingDamage(player, inflictor, source, damage, damagetype);
|
||||
damage = 0;
|
||||
}
|
||||
// To reduce griefing potential, don't allow players to be killed
|
||||
// by friendly fire. Spilling their rings and other items is enough.
|
||||
else if (!force && G_GametypeHasTeams()
|
||||
&& source && source->player && (source->player->ctfteam == player->ctfteam)
|
||||
&& cv_friendlyfire.value)
|
||||
{
|
||||
damage = 0;
|
||||
P_ShieldDamage(player, inflictor, source, damage, damagetype);
|
||||
}
|
||||
else // No shield, no rings, no invincibility.
|
||||
{
|
||||
// To reduce griefing potential, don't allow players to be killed
|
||||
// by friendly fire. Spilling their rings and other items is enough.
|
||||
if (force || !(G_GametypeHasTeams()
|
||||
&& source && source->player && (source->player->ctfteam == player->ctfteam)
|
||||
&& cv_friendlyfire.value))
|
||||
{
|
||||
damage = 1;
|
||||
P_KillPlayer(player, source, damage);
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = 0;
|
||||
P_ShieldDamage(player, inflictor, source, damage);
|
||||
}
|
||||
damage = 1;
|
||||
P_KillPlayer(player, source, damage);
|
||||
}
|
||||
|
||||
if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))
|
||||
{
|
||||
if (player->powers[pw_shield])
|
||||
{
|
||||
P_RemoveShield(player);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500)));
|
||||
if (player->health < 2)
|
||||
player->health = 2;
|
||||
}
|
||||
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
P_PlayerFlagBurst(player, false);
|
||||
}
|
||||
else if (damagetype & DMG_DEATHMASK)
|
||||
player->health = 0;
|
||||
else
|
||||
{
|
||||
player->health -= damage; // mirror mobj health here
|
||||
|
||||
if (damage > 0) // don't spill emeralds/ammo/panels for shield damage
|
||||
P_PlayerRingBurst(player, damage);
|
||||
}
|
||||
|
||||
if (player->health < 0)
|
||||
player->health = 0;
|
||||
|
||||
P_HitDeathMessages(player, inflictor, source, damagetype);
|
||||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
@ -3167,13 +3198,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
P_DamageMobj(source, target, target, 1, 0);
|
||||
|
||||
// do the damage
|
||||
if (player && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player))
|
||||
{
|
||||
target->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500)));
|
||||
if (target->health < 2)
|
||||
target->health = 2;
|
||||
}
|
||||
else if (damagetype & DMG_DEATHMASK)
|
||||
if (damagetype & DMG_DEATHMASK)
|
||||
target->health = 0;
|
||||
else
|
||||
target->health -= damage;
|
||||
|
@ -3188,10 +3213,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
}
|
||||
|
||||
if (player)
|
||||
{
|
||||
if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])))
|
||||
P_ResetPlayer(target->player);
|
||||
}
|
||||
P_ResetPlayer(target->player);
|
||||
else
|
||||
switch (target->type)
|
||||
{
|
||||
|
@ -3214,16 +3236,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
// if not intent on another player,
|
||||
// chase after this one
|
||||
P_SetTarget(&target->target, source);
|
||||
if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
if (!(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])))
|
||||
P_SetPlayerMobjState(target, target->info->seestate);
|
||||
}
|
||||
else
|
||||
P_SetMobjState(target, target->info->seestate);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3249,7 +3261,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
return;
|
||||
|
||||
// If no health, don't spawn ring!
|
||||
if (player->mo->health <= 1)
|
||||
if (player->rings <= 0)
|
||||
num_rings = 0;
|
||||
|
||||
if (num_rings > 32 && !(player->pflags & PF_NIGHTSFALL))
|
||||
|
@ -3259,11 +3271,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
P_PlayerEmeraldBurst(player, false);
|
||||
|
||||
// Spill weapons first
|
||||
if (player->ringweapons)
|
||||
P_PlayerWeaponPanelBurst(player);
|
||||
|
||||
// Spill the ammo
|
||||
P_PlayerWeaponAmmoBurst(player);
|
||||
P_PlayerWeaponPanelOrAmmoBurst(player);
|
||||
|
||||
for (i = 0; i < num_rings; i++)
|
||||
{
|
||||
|
@ -3520,6 +3528,75 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
void P_PlayerWeaponPanelOrAmmoBurst(player_t *player)
|
||||
{
|
||||
mobj_t *mo;
|
||||
angle_t fa;
|
||||
fixed_t ns;
|
||||
INT32 i = 0;
|
||||
fixed_t z;
|
||||
|
||||
#define SETUP_DROP(thingtype) \
|
||||
z = player->mo->z; \
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP) \
|
||||
z += player->mo->height - mobjinfo[thingtype].height; \
|
||||
fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; \
|
||||
ns = FixedMul(3*FRACUNIT, player->mo->scale); \
|
||||
|
||||
#define DROP_WEAPON(rwflag, pickup, ammo, power) \
|
||||
if (player->ringweapons & rwflag) \
|
||||
{ \
|
||||
player->ringweapons &= ~rwflag; \
|
||||
SETUP_DROP(pickup) \
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, pickup); \
|
||||
mo->reactiontime = 0; \
|
||||
mo->flags2 |= MF2_DONTRESPAWN; \
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \
|
||||
P_SetTarget(&mo->target, player->mo); \
|
||||
mo->fuse = 12*TICRATE; \
|
||||
mo->destscale = player->mo->scale; \
|
||||
P_SetScale(mo, player->mo->scale); \
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns); \
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \
|
||||
mo->momy = FixedMul(FINESINE(fa),ns); \
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, false); \
|
||||
if (i & 1) \
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, true); \
|
||||
++i; \
|
||||
} \
|
||||
else if (player->powers[power] > 0) \
|
||||
{ \
|
||||
SETUP_DROP(ammo) \
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, ammo); \
|
||||
mo->health = player->powers[power]; \
|
||||
mo->flags2 |= MF2_DONTRESPAWN; \
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \
|
||||
P_SetTarget(&mo->target, player->mo); \
|
||||
mo->fuse = 12*TICRATE; \
|
||||
mo->destscale = player->mo->scale; \
|
||||
P_SetScale(mo, player->mo->scale); \
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns); \
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \
|
||||
mo->momy = FixedMul(FINESINE(fa),ns); \
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, false); \
|
||||
if (i & 1) \
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, true); \
|
||||
player->powers[power] = 0; \
|
||||
++i; \
|
||||
}
|
||||
|
||||
DROP_WEAPON(RW_BOUNCE, MT_BOUNCEPICKUP, MT_BOUNCERING, pw_bouncering);
|
||||
DROP_WEAPON(RW_RAIL, MT_RAILPICKUP, MT_RAILRING, pw_railring);
|
||||
DROP_WEAPON(RW_AUTO, MT_AUTOPICKUP, MT_AUTOMATICRING, pw_automaticring);
|
||||
DROP_WEAPON(RW_EXPLODE, MT_EXPLODEPICKUP, MT_EXPLOSIONRING, pw_explosionring);
|
||||
DROP_WEAPON(RW_SCATTER, MT_SCATTERPICKUP, MT_SCATTERRING, pw_scatterring);
|
||||
DROP_WEAPON(RW_GRENADE, MT_GRENADEPICKUP, MT_GRENADERING, pw_grenadering);
|
||||
DROP_WEAPON(0, 0, MT_INFINITYRING, pw_infinityring);
|
||||
|
||||
#undef DROP_WEAPON
|
||||
#undef SETUP_DROP
|
||||
}
|
||||
|
||||
//
|
||||
// P_PlayerEmeraldBurst
|
||||
//
|
||||
|
|
|
@ -125,6 +125,7 @@ extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate;
|
|||
|
||||
INT32 P_GetPlayerControlDirection(player_t *player);
|
||||
void P_AddPlayerScore(player_t *player, UINT32 amount);
|
||||
void P_StealPlayerScore(player_t *player, UINT32 amount);
|
||||
void P_ResetCamera(player_t *player, camera_t *thiscam);
|
||||
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
|
||||
void P_SlideCameraMove(camera_t *thiscam);
|
||||
|
@ -214,6 +215,7 @@ void P_PrecipitationEffects(void);
|
|||
void P_RemoveMobj(mobj_t *th);
|
||||
boolean P_MobjWasRemoved(mobj_t *th);
|
||||
void P_RemoveSavegameMobj(mobj_t *th);
|
||||
UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2);
|
||||
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
|
||||
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
|
||||
void P_RunShields(void);
|
||||
|
@ -383,7 +385,8 @@ typedef struct BasicFF_s
|
|||
#define DMG_FIRE 2
|
||||
#define DMG_ELECTRIC 3
|
||||
#define DMG_SPIKE 4
|
||||
//#define DMG_SPECIALSTAGE 5
|
||||
#define DMG_NUKE 5 // bomb shield
|
||||
//#define DMG_SPECIALSTAGE 6
|
||||
//// Death types - cannot be combined with damage types
|
||||
#define DMG_INSTAKILL 0x80
|
||||
#define DMG_DROWNED 0x80+1
|
||||
|
@ -402,6 +405,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
void P_PlayerRingBurst(player_t *player, INT32 num_rings); /// \todo better fit in p_user.c
|
||||
void P_PlayerWeaponPanelBurst(player_t *player);
|
||||
void P_PlayerWeaponAmmoBurst(player_t *player);
|
||||
void P_PlayerWeaponPanelOrAmmoBurst(player_t *player);
|
||||
void P_PlayerEmeraldBurst(player_t *player, boolean toss);
|
||||
|
||||
void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck);
|
||||
|
@ -416,6 +420,7 @@ void P_ResetStarposts(void);
|
|||
|
||||
boolean P_CanPickupItem(player_t *player, boolean weapon);
|
||||
void P_DoNightsScore(player_t *player);
|
||||
void P_DoMatchSuper(player_t *player);
|
||||
|
||||
//
|
||||
// P_SPEC
|
||||
|
|
520
src/p_mobj.c
520
src/p_mobj.c
|
@ -86,9 +86,14 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum)
|
|||
//
|
||||
FUNCINLINE static ATTRINLINE void P_SetupStateAnimation(mobj_t *mobj, state_t *st)
|
||||
{
|
||||
INT32 animlength = (mobj->skin && mobj->sprite == SPR_PLAY)
|
||||
? (INT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes) - 1
|
||||
: st->var1;
|
||||
|
||||
if (!(st->frame & FF_ANIMATE))
|
||||
return;
|
||||
if (st->var1 == 0 || st->var2 == 0)
|
||||
|
||||
if (animlength <= 0 || st->var2 == 0)
|
||||
{
|
||||
mobj->frame &= ~FF_ANIMATE;
|
||||
return; // Crash/stupidity prevention
|
||||
|
@ -102,11 +107,11 @@ FUNCINLINE static ATTRINLINE void P_SetupStateAnimation(mobj_t *mobj, state_t *s
|
|||
if (!leveltime) return;
|
||||
|
||||
mobj->anim_duration -= (leveltime + 2) % st->var2; // Duration synced to timer
|
||||
mobj->frame += ((leveltime + 2) / st->var2) % (st->var1 + 1); // Frame synced to timer (duration taken into account)
|
||||
mobj->frame += ((leveltime + 2) / st->var2) % (animlength + 1); // Frame synced to timer (duration taken into account)
|
||||
}
|
||||
else if (st->frame & FF_RANDOMANIM)
|
||||
{
|
||||
mobj->frame += P_RandomKey(st->var1 + 1); // Random starting frame
|
||||
mobj->frame += P_RandomKey(animlength + 1); // Random starting frame
|
||||
mobj->anim_duration -= P_RandomKey(st->var2); // Random duration for first frame
|
||||
}
|
||||
}
|
||||
|
@ -119,13 +124,23 @@ FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj)
|
|||
// var2 determines delay between animation frames
|
||||
if (!(mobj->frame & FF_ANIMATE) || --mobj->anim_duration != 0)
|
||||
return;
|
||||
|
||||
mobj->anim_duration = (UINT16)mobj->state->var2;
|
||||
|
||||
// compare the current sprite frame to the one we started from
|
||||
// if more than var1 away from it, swap back to the original
|
||||
// else just advance by one
|
||||
if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > (UINT32)mobj->state->var1)
|
||||
mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK);
|
||||
if (mobj->sprite != SPR_PLAY)
|
||||
{
|
||||
// compare the current sprite frame to the one we started from
|
||||
// if more than var1 away from it, swap back to the original
|
||||
// else just advance by one
|
||||
if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > (UINT32)mobj->state->var1)
|
||||
mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// sprite2 version of above
|
||||
if (mobj->skin && (((++mobj->frame) & FF_FRAMEMASK) >= (UINT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes)))
|
||||
mobj->frame &= ~FF_FRAMEMASK;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -170,6 +185,215 @@ static void P_CyclePlayerMobjState(mobj_t *mobj)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_GetMobjSprite2
|
||||
//
|
||||
|
||||
UINT8 P_GetMobjSprite2(mobj_t *mobj, UINT8 spr2)
|
||||
{
|
||||
player_t *player = mobj->player;
|
||||
skin_t *skin = ((skin_t *)mobj->skin);
|
||||
|
||||
if (!skin)
|
||||
return 0;
|
||||
|
||||
while ((skin->sprites[spr2].numframes <= 0)
|
||||
&& spr2 != SPR2_STND)
|
||||
{
|
||||
switch(spr2)
|
||||
{
|
||||
case SPR2_PEEL:
|
||||
spr2 = SPR2_RUN;
|
||||
break;
|
||||
case SPR2_RUN:
|
||||
spr2 = SPR2_WALK;
|
||||
break;
|
||||
case SPR2_DRWN:
|
||||
spr2 = SPR2_DEAD;
|
||||
break;
|
||||
case SPR2_DASH:
|
||||
spr2 = SPR2_SPIN;
|
||||
break;
|
||||
case SPR2_GASP:
|
||||
spr2 = SPR2_SPNG;
|
||||
break;
|
||||
case SPR2_JUMP:
|
||||
spr2 = ((player
|
||||
? player->charflags
|
||||
: skin->flags)
|
||||
& SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_SPIN;
|
||||
break;
|
||||
case SPR2_SPNG: // spring
|
||||
spr2 = SPR2_FALL;
|
||||
break;
|
||||
case SPR2_FALL:
|
||||
spr2 = SPR2_WALK;
|
||||
break;
|
||||
case SPR2_RIDE:
|
||||
spr2 = SPR2_FALL;
|
||||
break;
|
||||
|
||||
case SPR2_FLY:
|
||||
spr2 = SPR2_SPNG;
|
||||
break;
|
||||
case SPR2_SWIM:
|
||||
spr2 = SPR2_FLY;
|
||||
break;
|
||||
case SPR2_TIRE:
|
||||
spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||
break;
|
||||
|
||||
case SPR2_GLID:
|
||||
spr2 = SPR2_FLY;
|
||||
break;
|
||||
case SPR2_CLMB:
|
||||
spr2 = SPR2_SPIN;
|
||||
break;
|
||||
case SPR2_CLNG:
|
||||
spr2 = SPR2_CLMB;
|
||||
break;
|
||||
|
||||
case SPR2_TWIN:
|
||||
spr2 = SPR2_SPIN;
|
||||
break;
|
||||
|
||||
case SPR2_MLEE:
|
||||
spr2 = SPR2_TWIN;
|
||||
break;
|
||||
|
||||
// Super sprites fallback to regular sprites
|
||||
case SPR2_SWLK:
|
||||
spr2 = SPR2_WALK;
|
||||
break;
|
||||
case SPR2_SRUN:
|
||||
spr2 = SPR2_RUN;
|
||||
break;
|
||||
case SPR2_SPEE:
|
||||
spr2 = SPR2_PEEL;
|
||||
break;
|
||||
case SPR2_SPAN:
|
||||
spr2 = SPR2_PAIN;
|
||||
break;
|
||||
case SPR2_SSTN:
|
||||
spr2 = SPR2_SPAN;
|
||||
break;
|
||||
case SPR2_SDTH:
|
||||
spr2 = SPR2_DEAD;
|
||||
break;
|
||||
case SPR2_SDRN:
|
||||
spr2 = SPR2_DRWN;
|
||||
break;
|
||||
case SPR2_SSPN:
|
||||
spr2 = SPR2_SPIN;
|
||||
break;
|
||||
case SPR2_SGSP:
|
||||
spr2 = SPR2_GASP;
|
||||
break;
|
||||
case SPR2_SJMP:
|
||||
spr2 = ((player
|
||||
? player->charflags
|
||||
: skin->flags)
|
||||
& SF_NOJUMPSPIN) ? SPR2_SSPG : SPR2_SSPN;
|
||||
break;
|
||||
case SPR2_SSPG:
|
||||
spr2 = SPR2_SPNG;
|
||||
break;
|
||||
case SPR2_SFAL:
|
||||
spr2 = SPR2_FALL;
|
||||
break;
|
||||
case SPR2_SEDG:
|
||||
spr2 = SPR2_EDGE;
|
||||
break;
|
||||
case SPR2_SRID:
|
||||
spr2 = SPR2_RIDE;
|
||||
break;
|
||||
case SPR2_SFLT:
|
||||
spr2 = SPR2_SWLK;
|
||||
break;
|
||||
|
||||
// NiGHTS sprites.
|
||||
case SPR2_NTRN:
|
||||
spr2 = SPR2_TRNS;
|
||||
break;
|
||||
case SPR2_NSTD:
|
||||
spr2 = SPR2_SSTD;
|
||||
break;
|
||||
case SPR2_NFLT:
|
||||
spr2 = (skin->flags & SF_SUPERANIMS) ? SPR2_SFLT : SPR2_FALL; // This is skin-exclusive so the default NiGHTS skin changing system plays nice.
|
||||
break;
|
||||
case SPR2_NPUL:
|
||||
spr2 = SPR2_NFLT;
|
||||
break;
|
||||
case SPR2_NPAN:
|
||||
spr2 = SPR2_NPUL;
|
||||
break;
|
||||
case SPR2_NATK:
|
||||
spr2 = SPR2_SSPN;
|
||||
break;
|
||||
/*case SPR2_NGT0:
|
||||
spr2 = SPR2_STND;
|
||||
break;*/
|
||||
case SPR2_NGT1:
|
||||
case SPR2_NGT7:
|
||||
case SPR2_DRL0:
|
||||
spr2 = SPR2_NGT0;
|
||||
break;
|
||||
case SPR2_NGT2:
|
||||
case SPR2_DRL1:
|
||||
spr2 = SPR2_NGT1;
|
||||
break;
|
||||
case SPR2_NGT3:
|
||||
case SPR2_DRL2:
|
||||
spr2 = SPR2_NGT2;
|
||||
break;
|
||||
case SPR2_NGT4:
|
||||
case SPR2_DRL3:
|
||||
spr2 = SPR2_NGT3;
|
||||
break;
|
||||
case SPR2_NGT5:
|
||||
case SPR2_DRL4:
|
||||
spr2 = SPR2_NGT4;
|
||||
break;
|
||||
case SPR2_NGT6:
|
||||
case SPR2_DRL5:
|
||||
spr2 = SPR2_NGT5;
|
||||
break;
|
||||
case SPR2_DRL6:
|
||||
spr2 = SPR2_NGT6;
|
||||
break;
|
||||
case SPR2_NGT8:
|
||||
case SPR2_DRL7:
|
||||
spr2 = SPR2_NGT7;
|
||||
break;
|
||||
case SPR2_NGT9:
|
||||
case SPR2_DRL8:
|
||||
spr2 = SPR2_NGT8;
|
||||
break;
|
||||
case SPR2_NGTA:
|
||||
case SPR2_DRL9:
|
||||
spr2 = SPR2_NGT9;
|
||||
break;
|
||||
case SPR2_NGTB:
|
||||
case SPR2_DRLA:
|
||||
spr2 = SPR2_NGTA;
|
||||
break;
|
||||
case SPR2_NGTC:
|
||||
case SPR2_DRLB:
|
||||
spr2 = SPR2_NGTB;
|
||||
break;
|
||||
case SPR2_DRLC:
|
||||
spr2 = SPR2_NGTC;
|
||||
break;
|
||||
|
||||
// Dunno? Just go to standing then.
|
||||
default:
|
||||
spr2 = SPR2_STND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return spr2;
|
||||
}
|
||||
|
||||
//
|
||||
// P_SetPlayerMobjState
|
||||
// Returns true if the mobj is still present.
|
||||
|
@ -396,216 +620,18 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
}
|
||||
}
|
||||
|
||||
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
|
||||
|
||||
// Player animations
|
||||
if (st->sprite == SPR_PLAY)
|
||||
{
|
||||
skin_t *skin = ((skin_t *)mobj->skin);
|
||||
boolean noalt = false;
|
||||
UINT8 spr2 = st->frame & FF_FRAMEMASK;
|
||||
UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1;
|
||||
UINT8 numframes;
|
||||
|
||||
while (skin && ((numframes = skin->sprites[spr2].numframes) <= 0)
|
||||
&& spr2 != SPR2_STND)
|
||||
{
|
||||
switch(spr2)
|
||||
{
|
||||
case SPR2_PEEL:
|
||||
spr2 = SPR2_RUN;
|
||||
break;
|
||||
case SPR2_RUN:
|
||||
spr2 = SPR2_WALK;
|
||||
break;
|
||||
case SPR2_DRWN:
|
||||
spr2 = SPR2_DEAD;
|
||||
break;
|
||||
case SPR2_DASH:
|
||||
spr2 = SPR2_SPIN;
|
||||
break;
|
||||
case SPR2_GASP:
|
||||
spr2 = SPR2_SPNG;
|
||||
break;
|
||||
case SPR2_JUMP:
|
||||
spr2 = (player->charflags & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_SPIN;
|
||||
break;
|
||||
case SPR2_SPNG: // spring
|
||||
spr2 = SPR2_FALL;
|
||||
break;
|
||||
case SPR2_FALL:
|
||||
spr2 = SPR2_WALK;
|
||||
break;
|
||||
case SPR2_RIDE:
|
||||
spr2 = SPR2_FALL;
|
||||
break;
|
||||
UINT8 spr2 = P_GetMobjSprite2(mobj, st->frame & FF_FRAMEMASK);
|
||||
|
||||
case SPR2_FLY:
|
||||
spr2 = SPR2_SPNG;
|
||||
break;
|
||||
case SPR2_SWIM:
|
||||
spr2 = SPR2_FLY;
|
||||
break;
|
||||
case SPR2_TIRE:
|
||||
spr2 = (player->charability == CA_FLY) ? SPR2_FLY : SPR2_SWIM;
|
||||
break;
|
||||
|
||||
case SPR2_GLID:
|
||||
spr2 = SPR2_FLY;
|
||||
break;
|
||||
case SPR2_CLMB:
|
||||
spr2 = SPR2_SPIN;
|
||||
break;
|
||||
case SPR2_CLNG:
|
||||
spr2 = SPR2_CLMB;
|
||||
break;
|
||||
|
||||
case SPR2_TWIN:
|
||||
spr2 = SPR2_SPIN;
|
||||
break;
|
||||
|
||||
case SPR2_MLEE:
|
||||
spr2 = SPR2_TWIN;
|
||||
break;
|
||||
|
||||
// Super sprites fallback to regular sprites
|
||||
case SPR2_SWLK:
|
||||
spr2 = SPR2_WALK;
|
||||
break;
|
||||
case SPR2_SRUN:
|
||||
spr2 = SPR2_RUN;
|
||||
break;
|
||||
case SPR2_SPEE:
|
||||
spr2 = SPR2_PEEL;
|
||||
break;
|
||||
case SPR2_SPAN:
|
||||
spr2 = SPR2_PAIN;
|
||||
break;
|
||||
case SPR2_SSTN:
|
||||
spr2 = SPR2_SPAN;
|
||||
break;
|
||||
case SPR2_SDTH:
|
||||
spr2 = SPR2_DEAD;
|
||||
break;
|
||||
case SPR2_SDRN:
|
||||
spr2 = SPR2_DRWN;
|
||||
break;
|
||||
case SPR2_SSPN:
|
||||
spr2 = SPR2_SPIN;
|
||||
break;
|
||||
case SPR2_SGSP:
|
||||
spr2 = SPR2_GASP;
|
||||
break;
|
||||
case SPR2_SJMP:
|
||||
spr2 = (player->charflags & SF_NOJUMPSPIN) ? SPR2_SSPG : SPR2_SSPN;
|
||||
break;
|
||||
case SPR2_SSPG:
|
||||
spr2 = SPR2_SPNG;
|
||||
break;
|
||||
case SPR2_SFAL:
|
||||
spr2 = SPR2_FALL;
|
||||
break;
|
||||
case SPR2_SEDG:
|
||||
spr2 = SPR2_EDGE;
|
||||
break;
|
||||
case SPR2_SRID:
|
||||
spr2 = SPR2_RIDE;
|
||||
break;
|
||||
case SPR2_SFLT:
|
||||
spr2 = SPR2_SWLK;
|
||||
break;
|
||||
|
||||
// NiGHTS sprites.
|
||||
case SPR2_NTRN:
|
||||
spr2 = SPR2_TRNS;
|
||||
break;
|
||||
case SPR2_NSTD:
|
||||
spr2 = SPR2_SSTD;
|
||||
break;
|
||||
case SPR2_NFLT:
|
||||
spr2 = (skin->flags & SF_SUPERANIMS) ? SPR2_SFLT : SPR2_FALL; // This is skin-exclusive so the default NiGHTS skin changing system plays nice.
|
||||
break;
|
||||
case SPR2_NPUL:
|
||||
spr2 = SPR2_NFLT;
|
||||
break;
|
||||
case SPR2_NPAN:
|
||||
spr2 = SPR2_NPUL;
|
||||
break;
|
||||
case SPR2_NATK:
|
||||
spr2 = SPR2_SSPN;
|
||||
break;
|
||||
/*case SPR2_NGT0:
|
||||
spr2 = SPR2_STND;
|
||||
break;*/
|
||||
case SPR2_NGT1:
|
||||
case SPR2_NGT7:
|
||||
case SPR2_DRL0:
|
||||
spr2 = SPR2_NGT0;
|
||||
break;
|
||||
case SPR2_NGT2:
|
||||
case SPR2_DRL1:
|
||||
spr2 = SPR2_NGT1;
|
||||
break;
|
||||
case SPR2_NGT3:
|
||||
case SPR2_DRL2:
|
||||
spr2 = SPR2_NGT2;
|
||||
break;
|
||||
case SPR2_NGT4:
|
||||
case SPR2_DRL3:
|
||||
spr2 = SPR2_NGT3;
|
||||
break;
|
||||
case SPR2_NGT5:
|
||||
case SPR2_DRL4:
|
||||
spr2 = SPR2_NGT4;
|
||||
break;
|
||||
case SPR2_NGT6:
|
||||
case SPR2_DRL5:
|
||||
spr2 = SPR2_NGT5;
|
||||
break;
|
||||
case SPR2_DRL6:
|
||||
spr2 = SPR2_NGT6;
|
||||
break;
|
||||
case SPR2_NGT8:
|
||||
case SPR2_DRL7:
|
||||
spr2 = SPR2_NGT7;
|
||||
break;
|
||||
case SPR2_NGT9:
|
||||
case SPR2_DRL8:
|
||||
spr2 = SPR2_NGT8;
|
||||
break;
|
||||
case SPR2_NGTA:
|
||||
case SPR2_DRL9:
|
||||
spr2 = SPR2_NGT9;
|
||||
break;
|
||||
case SPR2_NGTB:
|
||||
case SPR2_DRLA:
|
||||
spr2 = SPR2_NGTA;
|
||||
break;
|
||||
case SPR2_NGTC:
|
||||
case SPR2_DRLB:
|
||||
spr2 = SPR2_NGTB;
|
||||
break;
|
||||
case SPR2_DRLC:
|
||||
spr2 = SPR2_NGTC;
|
||||
break;
|
||||
|
||||
|
||||
// Sprites for non-player objects? There's nothing we can do.
|
||||
case SPR2_SIGN:
|
||||
case SPR2_LIFE:
|
||||
noalt = true;
|
||||
break;
|
||||
|
||||
// Dunno? Just go to standing then.
|
||||
default:
|
||||
spr2 = SPR2_STND;
|
||||
break;
|
||||
}
|
||||
if (noalt)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!skin)
|
||||
if (skin)
|
||||
numframes = skin->sprites[spr2].numframes;
|
||||
else
|
||||
{
|
||||
frame = 0;
|
||||
numframes = 0;
|
||||
|
@ -628,7 +654,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
{
|
||||
if (st->frame & FF_SPR2ENDSTATE) // no frame advancement
|
||||
{
|
||||
if (st->var1 == S_NULL)
|
||||
if (st->var1 == mobj->state-states)
|
||||
frame--;
|
||||
else
|
||||
{
|
||||
|
@ -651,9 +677,10 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
|
|||
{
|
||||
mobj->sprite = st->sprite;
|
||||
mobj->frame = st->frame;
|
||||
P_SetupStateAnimation(mobj, st);
|
||||
}
|
||||
|
||||
P_SetupStateAnimation(mobj, st);
|
||||
|
||||
// Modified handling.
|
||||
// Call action functions when the state is set
|
||||
|
||||
|
@ -723,10 +750,11 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
|
|||
if (st->sprite == SPR_PLAY)
|
||||
{
|
||||
skin_t *skin = ((skin_t *)mobj->skin);
|
||||
UINT8 spr2 = st->frame & FF_FRAMEMASK;
|
||||
UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1;
|
||||
UINT8 numframes;
|
||||
|
||||
UINT8 spr2 = P_GetMobjSprite2(mobj, st->frame & FF_FRAMEMASK);
|
||||
|
||||
if (skin)
|
||||
numframes = skin->sprites[spr2].numframes;
|
||||
else
|
||||
|
@ -750,8 +778,17 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
|
|||
|
||||
if (frame >= numframes)
|
||||
{
|
||||
if (st->frame & FF_SPR2ENDSTATE)
|
||||
return P_SetPlayerMobjState(mobj, st->var1); // Differs from P_SetPlayerMobjState - allows object to be removed via S_NULL
|
||||
if (st->frame & FF_SPR2ENDSTATE) // no frame advancement
|
||||
{
|
||||
if (st->var1 == mobj->state-states)
|
||||
frame--;
|
||||
else
|
||||
{
|
||||
if (mobj->frame & FF_FRAMEMASK)
|
||||
mobj->frame--;
|
||||
return P_SetMobjState(mobj, st->var1);
|
||||
}
|
||||
}
|
||||
else
|
||||
frame = 0;
|
||||
}
|
||||
|
@ -764,9 +801,10 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
|
|||
{
|
||||
mobj->sprite = st->sprite;
|
||||
mobj->frame = st->frame;
|
||||
P_SetupStateAnimation(mobj, st);
|
||||
}
|
||||
|
||||
P_SetupStateAnimation(mobj, st);
|
||||
|
||||
// Modified handling.
|
||||
// Call action functions when the state is set
|
||||
|
||||
|
@ -1046,14 +1084,12 @@ void P_EmeraldManager(void)
|
|||
else
|
||||
break;
|
||||
|
||||
if (leveltime < TICRATE) // Start of map
|
||||
spawnpoints[j]->threshold = 60*TICRATE + P_RandomByte() * (TICRATE/5);
|
||||
else
|
||||
spawnpoints[j]->threshold = P_RandomByte() * (TICRATE/5);
|
||||
|
||||
spawnpoints[j]->threshold = emeraldspawndelay + P_RandomByte() * (TICRATE/5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emeraldspawndelay = 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -4223,17 +4259,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
|||
}
|
||||
|
||||
animonly:
|
||||
// cycle through states,
|
||||
// calling action functions at transitions
|
||||
if (mobj->tics != -1)
|
||||
{
|
||||
mobj->tics--;
|
||||
|
||||
// you can cycle through multiple states in a tic
|
||||
if (!mobj->tics)
|
||||
if (!P_SetPlayerMobjState(mobj, mobj->state->nextstate))
|
||||
return; // freed itself
|
||||
}
|
||||
P_CyclePlayerMobjState(mobj);
|
||||
}
|
||||
|
||||
static void CalculatePrecipFloor(precipmobj_t *mobj)
|
||||
|
@ -4404,15 +4430,15 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest)
|
|||
|
||||
player = &players[actor->lastlook];
|
||||
|
||||
if (player->health <= 0)
|
||||
continue; // dead
|
||||
|
||||
if (player->pflags & PF_INVIS || player->bot || player->spectator)
|
||||
continue; // ignore notarget
|
||||
|
||||
if (!player->mo || P_MobjWasRemoved(player->mo))
|
||||
continue;
|
||||
|
||||
if (player->mo->health <= 0)
|
||||
continue; //dead
|
||||
|
||||
if (!P_CheckSight(actor, player->mo))
|
||||
continue; // out of sight
|
||||
|
||||
|
@ -4442,15 +4468,15 @@ boolean P_SupermanLook4Players(mobj_t *actor)
|
|||
{
|
||||
if (playeringame[c])
|
||||
{
|
||||
if (players[c].health <= 0)
|
||||
continue; // dead
|
||||
|
||||
if (players[c].pflags & PF_INVIS)
|
||||
continue; // ignore notarget
|
||||
|
||||
if (!players[c].mo || players[c].bot)
|
||||
continue;
|
||||
|
||||
if (players[c].mo->health <= 0)
|
||||
continue; // dead
|
||||
|
||||
playersinthegame[stop] = &players[c];
|
||||
stop++;
|
||||
}
|
||||
|
@ -7342,7 +7368,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetTarget(&mobj->target, NULL);
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].mo
|
||||
&& players[i].mare == mobj->threshold && players[i].health > 1)
|
||||
&& players[i].mare == mobj->threshold && players[i].rings > 0)
|
||||
{
|
||||
fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y);
|
||||
if (dist < shortest)
|
||||
|
@ -9009,8 +9035,10 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
// (usefulness: when body mobj is detached from player (who respawns),
|
||||
// the dead body mobj retains the skin through the 'spritedef' override).
|
||||
mobj->skin = &skins[p->skin];
|
||||
P_SetupStateAnimation(mobj, mobj->state);
|
||||
|
||||
mobj->health = p->health;
|
||||
mobj->health = 1;
|
||||
p->rings = 0;
|
||||
p->playerstate = PST_LIVE;
|
||||
|
||||
p->bonustime = false;
|
||||
|
@ -10910,7 +10938,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai
|
|||
{
|
||||
mobj_t *th;
|
||||
angle_t an;
|
||||
fixed_t x, y, z, slope = 0;
|
||||
fixed_t x, y, z, slope = 0, speed;
|
||||
|
||||
// angle at which you fire, is player angle
|
||||
an = angle;
|
||||
|
@ -10942,9 +10970,13 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai
|
|||
|
||||
P_SetTarget(&th->target, source);
|
||||
|
||||
speed = th->info->speed;
|
||||
if (source->player && source->player->charability == CA_FLY)
|
||||
speed = FixedMul(speed, 3*FRACUNIT/2);
|
||||
|
||||
th->angle = an;
|
||||
th->momx = FixedMul(th->info->speed, FINECOSINE(an>>ANGLETOFINESHIFT));
|
||||
th->momy = FixedMul(th->info->speed, FINESINE(an>>ANGLETOFINESHIFT));
|
||||
th->momx = FixedMul(speed, FINECOSINE(an>>ANGLETOFINESHIFT));
|
||||
th->momy = FixedMul(speed, FINESINE(an>>ANGLETOFINESHIFT));
|
||||
|
||||
if (allowaim)
|
||||
{
|
||||
|
@ -10952,7 +10984,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai
|
|||
th->momy = FixedMul(th->momy,FINECOSINE(source->player->aiming>>ANGLETOFINESHIFT));
|
||||
}
|
||||
|
||||
th->momz = FixedMul(th->info->speed, slope);
|
||||
th->momz = FixedMul(speed, slope);
|
||||
|
||||
//scaling done here so it doesn't clutter up the code above
|
||||
th->momx = FixedMul(th->momx, th->scale);
|
||||
|
|
|
@ -454,5 +454,6 @@ void P_EmeraldManager(void);
|
|||
extern mapthing_t *huntemeralds[MAXHUNTEMERALDS];
|
||||
extern INT32 numhuntemeralds;
|
||||
extern boolean runemeraldmanager;
|
||||
extern UINT16 emeraldspawndelay;
|
||||
extern INT32 numstarposts;
|
||||
#endif
|
||||
|
|
|
@ -128,7 +128,7 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEANGLE(save_p, players[i].aiming);
|
||||
WRITEANGLE(save_p, players[i].awayviewaiming);
|
||||
WRITEINT32(save_p, players[i].awayviewtics);
|
||||
WRITEINT32(save_p, players[i].health);
|
||||
WRITEINT32(save_p, players[i].rings);
|
||||
|
||||
WRITESINT8(save_p, players[i].pity);
|
||||
WRITEINT32(save_p, players[i].currentweapon);
|
||||
|
@ -308,7 +308,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].aiming = READANGLE(save_p);
|
||||
players[i].awayviewaiming = READANGLE(save_p);
|
||||
players[i].awayviewtics = READINT32(save_p);
|
||||
players[i].health = READINT32(save_p);
|
||||
players[i].rings = READINT32(save_p);
|
||||
|
||||
players[i].pity = READSINT8(save_p);
|
||||
players[i].currentweapon = READINT32(save_p);
|
||||
|
|
|
@ -2086,6 +2086,7 @@ static void P_LevelInitStuff(void)
|
|||
// special stage tokens, emeralds, and ring total
|
||||
tokenbits = 0;
|
||||
runemeraldmanager = false;
|
||||
emeraldspawndelay = 60*TICRATE;
|
||||
nummaprings = 0;
|
||||
|
||||
// emerald hunt
|
||||
|
@ -2128,7 +2129,7 @@ static void P_LevelInitStuff(void)
|
|||
players[i].gotcontinue = false;
|
||||
|
||||
players[i].xtralife = players[i].deadtimer = players[i].numboxes = players[i].totalring = players[i].laps = 0;
|
||||
players[i].health = 1;
|
||||
players[i].rings = 0;
|
||||
players[i].aiming = 0;
|
||||
players[i].pflags &= ~PF_TIMEOVER;
|
||||
|
||||
|
|
22
src/p_spec.c
22
src/p_spec.c
|
@ -1621,10 +1621,10 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
|||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
if (!players[i].mo || players[i].mo->health < 1)
|
||||
if (!players[i].mo || players[i].rings <= 0)
|
||||
continue;
|
||||
|
||||
rings += players[i].mo->health-1;
|
||||
rings += players[i].rings;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1632,7 +1632,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
|||
if (!(actor && actor->player))
|
||||
return false; // no player to count rings from here, sorry
|
||||
|
||||
rings = actor->health-1;
|
||||
rings = actor->player->rings;
|
||||
}
|
||||
|
||||
if (triggerline->flags & ML_NOCLIMB)
|
||||
|
@ -3548,10 +3548,9 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
break;
|
||||
case 9: // Ring Drainer (Floor Touch)
|
||||
case 10: // Ring Drainer (No Floor Touch)
|
||||
if (leveltime % (TICRATE/2) == 0 && player->mo->health > 1)
|
||||
if (leveltime % (TICRATE/2) == 0 && player->rings > 0)
|
||||
{
|
||||
player->mo->health--;
|
||||
player->health--;
|
||||
player->rings--;
|
||||
S_StartSound(player->mo, sfx_itemup);
|
||||
}
|
||||
break;
|
||||
|
@ -3559,7 +3558,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super] || player->exiting || player->bot)
|
||||
break;
|
||||
|
||||
if (!(player->powers[pw_shield] || player->mo->health > 1)) // Don't do anything if no shield or rings anyway
|
||||
if (!(player->powers[pw_shield] || player->rings > 0)) // Don't do anything if no shield or rings anyway
|
||||
break;
|
||||
|
||||
if (player->powers[pw_shield])
|
||||
|
@ -3567,14 +3566,13 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
P_RemoveShield(player);
|
||||
S_StartSound(player->mo, sfx_shldls); // Ba-Dum! Shield loss.
|
||||
}
|
||||
else if (player->mo->health > 1)
|
||||
else if (player->rings > 0)
|
||||
{
|
||||
P_PlayRinglossSound(player->mo);
|
||||
if (player->mo->health > 10)
|
||||
player->mo->health -= 10;
|
||||
if (player->rings >= 10)
|
||||
player->rings -= 10;
|
||||
else
|
||||
player->mo->health = 1;
|
||||
player->health = player->mo->health;
|
||||
player->rings = 0;
|
||||
}
|
||||
|
||||
P_DoPlayerPain(player, NULL, NULL); // this does basically everything that was here before
|
||||
|
|
|
@ -469,7 +469,7 @@ static inline void P_DoSpecialStageStuff(void)
|
|||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
{
|
||||
ssrings += (players[i].mo->health-1);
|
||||
ssrings += players[i].rings;
|
||||
|
||||
// If in water, deplete timer 6x as fast.
|
||||
if ((players[i].mo->eflags & MFE_TOUCHWATER)
|
||||
|
|
218
src/p_user.c
218
src/p_user.c
|
@ -697,7 +697,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i]/* && players[i].pflags & PF_NIGHTSMODE*/)
|
||||
total_rings += players[i].health-1;
|
||||
total_rings += players[i].rings;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -715,8 +715,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
}
|
||||
else
|
||||
{
|
||||
players[i].finishedrings = (INT16)(players[i].health - 1);
|
||||
P_AddPlayerScore(&players[i], (players[i].health - 1) * 50);
|
||||
players[i].finishedrings = (INT16)(players[i].rings);
|
||||
P_AddPlayerScore(&players[i], (players[i].rings) * 50);
|
||||
}
|
||||
|
||||
// Add score to leaderboards now
|
||||
|
@ -727,7 +727,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
players[i].lastmarescore = players[i].marescore;
|
||||
players[i].marescore = 0;
|
||||
|
||||
players[i].mo->health = players[i].health = 1;
|
||||
players[i].rings = 0;
|
||||
P_DoPlayerExit(&players[i]);
|
||||
}
|
||||
}
|
||||
|
@ -735,12 +735,12 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
{
|
||||
/// \todo Handle multi-mare special stages.
|
||||
// Ring bonus
|
||||
P_AddPlayerScore(player, (player->health - 1) * 50);
|
||||
P_AddPlayerScore(player, (player->rings) * 50);
|
||||
|
||||
player->lastmare = (UINT8)oldmare;
|
||||
player->texttimer = 4*TICRATE;
|
||||
player->textvar = 4; // Score and grades
|
||||
player->finishedrings = (INT16)(player->health - 1);
|
||||
player->finishedrings = (INT16)(player->rings);
|
||||
|
||||
// Add score to temp leaderboards
|
||||
if (!(netgame||multiplayer) && P_IsLocalPlayer(player))
|
||||
|
@ -751,7 +751,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
player->marescore = 0;
|
||||
player->marebegunat = leveltime;
|
||||
|
||||
player->mo->health = player->health = 1;
|
||||
player->rings = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -898,30 +898,23 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings)
|
|||
if (!player->mo)
|
||||
return;
|
||||
|
||||
player->mo->health += num_rings;
|
||||
player->health += num_rings;
|
||||
player->rings += num_rings;
|
||||
|
||||
if (!G_IsSpecialStage(gamemap) || !useNightsSS)
|
||||
player->totalring += num_rings;
|
||||
|
||||
// Can only get up to 9999 rings, sorry!
|
||||
if (player->mo->health > 10000)
|
||||
{
|
||||
player->mo->health = 10000;
|
||||
player->health = 10000;
|
||||
}
|
||||
else if (player->mo->health < 1)
|
||||
{
|
||||
player->mo->health = 1;
|
||||
player->health = 1;
|
||||
}
|
||||
if (player->rings > 9999)
|
||||
player->rings = 9999;
|
||||
else if (player->rings < 0)
|
||||
player->rings = 0;
|
||||
|
||||
// Now extra life bonuses are handled here instead of in P_MovePlayer, since why not?
|
||||
if (!ultimatemode && !modeattacking && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives())
|
||||
{
|
||||
INT32 gainlives = 0;
|
||||
|
||||
while (player->xtralife < maxXtraLife && player->health > 100 * (player->xtralife+1))
|
||||
while (player->xtralife < maxXtraLife && player->rings >= 100 * (player->xtralife+1))
|
||||
{
|
||||
++gainlives;
|
||||
++player->xtralife;
|
||||
|
@ -972,10 +965,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
|
|||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
|
||||
if (giverings)
|
||||
{
|
||||
player->mo->health = 51;
|
||||
player->health = player->mo->health;
|
||||
}
|
||||
player->rings = 50;
|
||||
|
||||
// Just in case.
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC))
|
||||
|
@ -994,6 +984,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
|
|||
|
||||
P_PlayerFlagBurst(player, false);
|
||||
}
|
||||
|
||||
// Adds to the player's score
|
||||
void P_AddPlayerScore(player_t *player, UINT32 amount)
|
||||
{
|
||||
|
@ -1080,6 +1071,42 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
|
|||
}
|
||||
}
|
||||
|
||||
// Steals from every enemy's score.
|
||||
void P_StealPlayerScore(player_t *player, UINT32 amount)
|
||||
{
|
||||
boolean teams = G_GametypeHasTeams();
|
||||
UINT32 stolen = 0;
|
||||
int i;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (&players[i] == player
|
||||
|| (teams && players[i].ctfteam == player->ctfteam))
|
||||
continue;
|
||||
if (players[i].score >= amount)
|
||||
{
|
||||
stolen += amount;
|
||||
players[i].score -= amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
stolen += players[i].score;
|
||||
players[i].score = 0;
|
||||
}
|
||||
}
|
||||
if (stolen > 0)
|
||||
{
|
||||
// In team match, all stolen points are removed from the enemy team's running score.
|
||||
if (gametype == GT_TEAMMATCH)
|
||||
{
|
||||
if (player->ctfteam == 1)
|
||||
bluescore -= amount;
|
||||
else if (player->ctfteam == 2)
|
||||
redscore -= amount;
|
||||
}
|
||||
P_AddPlayerScore(player, stolen);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_PlayLivesJingle
|
||||
//
|
||||
|
@ -3194,72 +3221,61 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
|
|||
mobj_t *mo = NULL;
|
||||
player->pflags |= PF_ATTACKDOWN;
|
||||
|
||||
#define TAKE_AMMO(player, power) \
|
||||
player->powers[power]--; \
|
||||
if (player->rings < 1) \
|
||||
{ \
|
||||
if (player->powers[power] > 0) \
|
||||
player->powers[power]--; \
|
||||
} \
|
||||
else \
|
||||
player->rings--;
|
||||
|
||||
if (cmd->buttons & BT_FIRENORMAL) // No powers, just a regular ring.
|
||||
goto firenormal; //code repetition sucks.
|
||||
// Bounce ring
|
||||
else if (player->currentweapon == WEP_BOUNCE && player->powers[pw_bouncering])
|
||||
{
|
||||
if (player->health <= 1)
|
||||
return;
|
||||
TAKE_AMMO(player, pw_bouncering);
|
||||
P_SetWeaponDelay(player, TICRATE/4);
|
||||
|
||||
mo = P_SpawnPlayerMissile(player->mo, MT_THROWNBOUNCE, MF2_BOUNCERING);
|
||||
|
||||
if (mo)
|
||||
mo->fuse = 3*TICRATE; // Bounce Ring time
|
||||
|
||||
player->powers[pw_bouncering]--;
|
||||
player->mo->health--;
|
||||
player->health--;
|
||||
}
|
||||
// Rail ring
|
||||
else if (player->currentweapon == WEP_RAIL && player->powers[pw_railring])
|
||||
{
|
||||
if (player->health <= 1)
|
||||
return;
|
||||
TAKE_AMMO(player, pw_railring);
|
||||
P_SetWeaponDelay(player, (3*TICRATE)/2);
|
||||
|
||||
mo = P_SpawnPlayerMissile(player->mo, MT_REDRING, MF2_RAILRING|MF2_DONTDRAW);
|
||||
|
||||
// Rail has no unique thrown object, therefore its sound plays here.
|
||||
S_StartSound(player->mo, sfx_rail1);
|
||||
|
||||
player->powers[pw_railring]--;
|
||||
player->mo->health--;
|
||||
player->health--;
|
||||
}
|
||||
// Automatic
|
||||
else if (player->currentweapon == WEP_AUTO && player->powers[pw_automaticring])
|
||||
{
|
||||
if (player->health <= 1)
|
||||
return;
|
||||
TAKE_AMMO(player, pw_automaticring);
|
||||
player->pflags &= ~PF_ATTACKDOWN;
|
||||
P_SetWeaponDelay(player, 2);
|
||||
|
||||
mo = P_SpawnPlayerMissile(player->mo, MT_THROWNAUTOMATIC, MF2_AUTOMATIC);
|
||||
|
||||
player->powers[pw_automaticring]--;
|
||||
player->mo->health--;
|
||||
player->health--;
|
||||
}
|
||||
// Explosion
|
||||
else if (player->currentweapon == WEP_EXPLODE && player->powers[pw_explosionring])
|
||||
{
|
||||
if (player->health <= 1)
|
||||
return;
|
||||
TAKE_AMMO(player, pw_explosionring);
|
||||
P_SetWeaponDelay(player, (3*TICRATE)/2);
|
||||
|
||||
mo = P_SpawnPlayerMissile(player->mo, MT_THROWNEXPLOSION, MF2_EXPLOSION);
|
||||
|
||||
player->powers[pw_explosionring]--;
|
||||
player->mo->health--;
|
||||
player->health--;
|
||||
}
|
||||
// Grenade
|
||||
else if (player->currentweapon == WEP_GRENADE && player->powers[pw_grenadering])
|
||||
{
|
||||
if (player->health <= 1)
|
||||
return;
|
||||
TAKE_AMMO(player, pw_grenadering);
|
||||
P_SetWeaponDelay(player, TICRATE/3);
|
||||
|
||||
mo = P_SpawnPlayerMissile(player->mo, MT_THROWNGRENADE, MF2_EXPLOSION);
|
||||
|
@ -3269,10 +3285,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
|
|||
//P_InstaThrust(mo, player->mo->angle, FixedMul(mo->info->speed, player->mo->scale));
|
||||
mo->fuse = mo->info->mass;
|
||||
}
|
||||
|
||||
player->powers[pw_grenadering]--;
|
||||
player->mo->health--;
|
||||
player->health--;
|
||||
}
|
||||
// Scatter
|
||||
// Note: Ignores MF2_RAILRING
|
||||
|
@ -3282,8 +3294,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
|
|||
angle_t shotangle = player->mo->angle;
|
||||
angle_t oldaiming = player->aiming;
|
||||
|
||||
if (player->health <= 1)
|
||||
return;
|
||||
TAKE_AMMO(player, pw_scatterring);
|
||||
P_SetWeaponDelay(player, (2*TICRATE)/3);
|
||||
|
||||
// Center
|
||||
|
@ -3309,10 +3320,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
player->mo->z = oldz;
|
||||
player->aiming = oldaiming;
|
||||
|
||||
player->powers[pw_scatterring]--;
|
||||
player->mo->health--;
|
||||
player->health--;
|
||||
return;
|
||||
}
|
||||
// No powers, just a regular ring.
|
||||
|
@ -3336,7 +3343,7 @@ firenormal:
|
|||
// Red Ring
|
||||
else
|
||||
{
|
||||
if (player->health <= 1)
|
||||
if (player->rings <= 0)
|
||||
return;
|
||||
P_SetWeaponDelay(player, TICRATE/4);
|
||||
|
||||
|
@ -3345,11 +3352,12 @@ firenormal:
|
|||
if (mo)
|
||||
P_ColorTeamMissile(mo, player);
|
||||
|
||||
player->mo->health--;
|
||||
player->health--;
|
||||
player->rings--;
|
||||
}
|
||||
}
|
||||
|
||||
#undef TAKE_AMMO
|
||||
|
||||
if (mo)
|
||||
{
|
||||
if (mo->flags & MF_MISSILE && mo->flags2 & MF2_RAILRING)
|
||||
|
@ -3400,7 +3408,7 @@ static void P_DoSuperStuff(player_t *player)
|
|||
return; // NiGHTS Super doesn't mix with normal super
|
||||
|
||||
// Does player have all emeralds? If so, flag the "Ready For Super!"
|
||||
if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->health > 50)
|
||||
if (ALL7EMERALDS(emeralds) && player->rings >= 50)
|
||||
player->pflags |= PF_SUPERREADY;
|
||||
else
|
||||
player->pflags &= ~PF_SUPERREADY;
|
||||
|
@ -3408,7 +3416,7 @@ static void P_DoSuperStuff(player_t *player)
|
|||
if (player->powers[pw_super])
|
||||
{
|
||||
// If you're super and not Sonic, de-superize!
|
||||
if (!((ALL7EMERALDS(emeralds)) && (player->charflags & SF_SUPER)) && !(ALL7EMERALDS(player->powers[pw_emeralds])))
|
||||
if (!(ALL7EMERALDS(emeralds) && player->charflags & SF_SUPER))
|
||||
{
|
||||
player->powers[pw_super] = 0;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
|
||||
|
@ -3438,10 +3446,7 @@ static void P_DoSuperStuff(player_t *player)
|
|||
|
||||
// Deplete one ring every second while super
|
||||
if ((leveltime % TICRATE == 0) && !(player->exiting))
|
||||
{
|
||||
player->health--;
|
||||
player->mo->health--;
|
||||
}
|
||||
player->rings--;
|
||||
|
||||
player->mo->color = (player->pflags & PF_GODMODE && cv_debug == 0)
|
||||
? (SKINCOLOR_SUPERSILVER1 + 5*((leveltime >> 1) % 7)) // A wholesome easter egg.
|
||||
|
@ -3458,7 +3463,7 @@ static void P_DoSuperStuff(player_t *player)
|
|||
G_GhostAddColor(GHC_SUPER);
|
||||
|
||||
// Ran out of rings while super!
|
||||
if (player->health <= 1 || player->exiting)
|
||||
if (player->rings <= 0 || player->exiting)
|
||||
{
|
||||
player->powers[pw_emeralds] = 0; // lost the power stones
|
||||
P_SpawnGhostMobj(player->mo);
|
||||
|
@ -3515,12 +3520,6 @@ static void P_DoSuperStuff(player_t *player)
|
|||
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!player->exiting)
|
||||
{
|
||||
player->health = 1;
|
||||
player->mo->health = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Inform the netgame that the champion has fallen in the heat of battle.
|
||||
|
@ -3548,12 +3547,12 @@ static void P_DoSuperStuff(player_t *player)
|
|||
//
|
||||
boolean P_SuperReady(player_t *player)
|
||||
{
|
||||
if ((player->pflags & PF_SUPERREADY) && !player->powers[pw_super] && !player->powers[pw_tailsfly]
|
||||
if (player->pflags & PF_SUPERREADY && !player->powers[pw_super] && !player->powers[pw_tailsfly]
|
||||
&& !(player->powers[pw_shield] & SH_NOSTACK)
|
||||
&& !player->powers[pw_invulnerability]
|
||||
&& !(maptol & TOL_NIGHTS) // don't turn 'regular super' in nights levels
|
||||
&& player->pflags & PF_JUMPED
|
||||
&& ((player->charflags & SF_SUPER) || ALL7EMERALDS(player->powers[pw_emeralds])))
|
||||
&& player->charflags & SF_SUPER)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -4195,13 +4194,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
player->pflags |= PF_GLIDING|PF_THOKKED;
|
||||
player->glidetime = 0;
|
||||
|
||||
if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))
|
||||
{
|
||||
// Glide at double speed while super.
|
||||
glidespeed *= 2;
|
||||
player->pflags &= ~PF_THOKKED;
|
||||
}
|
||||
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
|
||||
P_InstaThrust(player->mo, player->mo->angle, FixedMul(glidespeed, player->mo->scale));
|
||||
player->pflags &= ~(PF_SPINNING|PF_STARTDASH);
|
||||
|
@ -4326,8 +4318,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
player->pflags &= ~PF_JUMPDOWN;
|
||||
|
||||
// Repeat abilities, but not double jump!
|
||||
if ((player->charability2 == CA2_MULTIABILITY && player->charability != CA_DOUBLEJUMP)
|
||||
|| (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])))
|
||||
if (player->charability2 == CA2_MULTIABILITY && player->charability != CA_DOUBLEJUMP)
|
||||
player->secondjump = 0;
|
||||
else if (player->charability == CA_FLOAT && player->secondjump == 1)
|
||||
player->secondjump = 2;
|
||||
|
@ -4571,9 +4562,6 @@ static void P_2dMovement(player_t *player)
|
|||
if (cmd->forwardmove != 0)
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT,10*FRACUNIT), false);
|
||||
|
||||
if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))
|
||||
player->mo->momz *= 2;
|
||||
|
||||
player->mo->momx = 0;
|
||||
}
|
||||
else if (cmd->sidemove != 0 && !(player->pflags & PF_GLIDING || player->exiting
|
||||
|
@ -4771,11 +4759,7 @@ static void P_3dMovement(player_t *player)
|
|||
if (player->climbing)
|
||||
{
|
||||
if (cmd->forwardmove)
|
||||
{
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 10*FRACUNIT), false);
|
||||
if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))
|
||||
player->mo->momz *= 2;
|
||||
}
|
||||
}
|
||||
else if (!analogmove
|
||||
&& cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting
|
||||
|
@ -4809,12 +4793,7 @@ static void P_3dMovement(player_t *player)
|
|||
}
|
||||
// Sideways movement
|
||||
if (player->climbing)
|
||||
{
|
||||
if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))
|
||||
P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 5*FRACUNIT), player->mo->scale));
|
||||
else
|
||||
P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 10*FRACUNIT), player->mo->scale));
|
||||
}
|
||||
P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 10*FRACUNIT), player->mo->scale));
|
||||
// Analog movement control
|
||||
else if (analogmove)
|
||||
{
|
||||
|
@ -5543,12 +5522,10 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
|||
if (G_IsSpecialStage(gamemap))
|
||||
{ // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here!
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && (&players[i] != player) && players[i].mo->health > 1)
|
||||
if (playeringame[i] && (&players[i] != player) && players[i].rings > 0)
|
||||
{
|
||||
player->mo->health += players[i].mo->health-1;
|
||||
player->health = player->mo->health;
|
||||
players[i].mo->health = 1;
|
||||
players[i].health = players[i].mo->health;
|
||||
player->rings += players[i].rings;
|
||||
players[i].rings = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5557,10 +5534,9 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
|||
&& player->mo->y == player->capsule->y
|
||||
&& player->mo->z == player->capsule->z+(player->capsule->height/3))
|
||||
{
|
||||
if (player->mo->health > 1)
|
||||
if (player->rings > 0)
|
||||
{
|
||||
player->mo->health--;
|
||||
player->health--;
|
||||
player->rings--;
|
||||
player->capsule->health--;
|
||||
player->capsule->extravalue1++;
|
||||
|
||||
|
@ -6252,7 +6228,7 @@ static void P_PlayerDropWeapon(player_t *player)
|
|||
|
||||
if (mo)
|
||||
{
|
||||
player->mo->health--;
|
||||
player->rings--;
|
||||
P_InstaThrust(mo, player->mo->angle-ANGLE_180, 8*FRACUNIT);
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, false);
|
||||
mo->flags2 |= MF2_DONTRESPAWN;
|
||||
|
@ -6580,7 +6556,7 @@ static void P_MovePlayer(player_t *player)
|
|||
if (playeringame[i])
|
||||
players[i].exiting = (14*TICRATE)/5 + 1;
|
||||
}
|
||||
else if (player->health > 1)
|
||||
else if (player->rings > 0)
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, 0);
|
||||
player->pflags &= ~PF_NIGHTSFALL;
|
||||
}
|
||||
|
@ -6737,8 +6713,8 @@ static void P_MovePlayer(player_t *player)
|
|||
P_ResetPlayer(player); // down, stop gliding.
|
||||
if (onground)
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
|
||||
else if ((player->charability2 == CA2_MULTIABILITY)
|
||||
|| (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]) && player->charability == CA_GLIDEANDCLIMB))
|
||||
else if (player->charability2 == CA2_MULTIABILITY
|
||||
&& player->charability == CA_GLIDEANDCLIMB)
|
||||
{
|
||||
player->pflags |= PF_JUMPED;
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
|
||||
|
@ -7660,12 +7636,12 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
|
|||
mo->flags |= MF_SPECIAL|MF_SHOOTABLE;
|
||||
|
||||
if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield!
|
||||
P_KillMobj(mo->tracer, inflictor, source, 0);
|
||||
P_KillMobj(mo->tracer, inflictor, source, DMG_NUKE);
|
||||
|
||||
if (mo->flags & MF_BOSS || mo->type == MT_PLAYER) //don't OHKO bosses nor players!
|
||||
P_DamageMobj(mo, inflictor, source, 1, 0);
|
||||
P_DamageMobj(mo, inflictor, source, 1, DMG_NUKE);
|
||||
else
|
||||
P_DamageMobj(mo, inflictor, source, 1000, 0);
|
||||
P_DamageMobj(mo, inflictor, source, 1000, DMG_NUKE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8860,7 +8836,7 @@ void P_PlayerThink(player_t *player)
|
|||
#endif
|
||||
|
||||
// todo: Figure out what is actually causing these problems in the first place...
|
||||
if ((player->health <= 0 || player->mo->health <= 0) && player->playerstate == PST_LIVE) //you should be DEAD!
|
||||
if (player->mo->health <= 0 && player->playerstate == PST_LIVE) //you should be DEAD!
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "P_PlayerThink: Player %s in PST_LIVE with 0 health. (\"Zombie bug\")\n", sizeu1(playeri));
|
||||
player->playerstate = PST_DEAD;
|
||||
|
@ -8965,7 +8941,7 @@ void P_PlayerThink(player_t *player)
|
|||
// it to the exit, you're a goner!
|
||||
else if (countdown == 1 && !player->exiting && player->lives > 0)
|
||||
{
|
||||
if (netgame && player->health > 0)
|
||||
if (netgame && player->mo->health > 0)
|
||||
CONS_Printf(M_GetText("%s ran out of time.\n"), player_names[player-players]);
|
||||
|
||||
player->pflags |= PF_TIMEOVER;
|
||||
|
@ -9054,7 +9030,7 @@ void P_PlayerThink(player_t *player)
|
|||
{
|
||||
player->score = 0;
|
||||
player->mo->health = 1;
|
||||
player->health = 1;
|
||||
player->rings = 0;
|
||||
}
|
||||
|
||||
if ((netgame || multiplayer) && player->lives <= 0)
|
||||
|
@ -9227,7 +9203,7 @@ void P_PlayerThink(player_t *player)
|
|||
if (player->powers[pw_flashing] && player->powers[pw_flashing] < UINT16_MAX && ((player->pflags & PF_NIGHTSMODE) || player->powers[pw_flashing] < flashingtics))
|
||||
player->powers[pw_flashing]--;
|
||||
|
||||
if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM && !(player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) // tails fly counter
|
||||
if (player->powers[pw_tailsfly] && player->powers[pw_tailsfly] < UINT16_MAX && player->charability != CA_SWIM) // tails fly counter
|
||||
player->powers[pw_tailsfly]--;
|
||||
|
||||
if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER)))
|
||||
|
@ -9543,10 +9519,6 @@ void P_PlayerAfterThink(player_t *player)
|
|||
if (player->currentweapon == WEP_RAIL && (!(player->ringweapons & RW_RAIL) || !player->powers[pw_railring]))
|
||||
player->currentweapon = 0;
|
||||
|
||||
// If you're out of rings, but have Infinity Rings left, switch to that.
|
||||
if (player->currentweapon != 0 && player->health <= 1 && player->powers[pw_infinityring])
|
||||
player->currentweapon = 0;
|
||||
|
||||
if (P_IsLocalPlayer(player) && (player->pflags & PF_WPNDOWN) && player->currentweapon != oldweapon)
|
||||
S_StartSound(NULL, sfx_wepchg);
|
||||
|
||||
|
|
|
@ -679,9 +679,9 @@ static void ST_drawTime(void)
|
|||
|
||||
static inline void ST_drawRings(void)
|
||||
{
|
||||
INT32 ringnum = max(stplyr->health-1, 0);
|
||||
INT32 ringnum = max(stplyr->rings, 0);
|
||||
|
||||
ST_DrawPatchFromHudWS(HUD_RINGS, ((stplyr->health <= 1 && leveltime/5 & 1) ? rrings : sborings));
|
||||
ST_DrawPatchFromHudWS(HUD_RINGS, ((stplyr->rings <= 0 && leveltime/5 & 1) ? rrings : sborings));
|
||||
|
||||
if (objectplacing)
|
||||
ringnum = op_currentdoomednum;
|
||||
|
@ -690,8 +690,8 @@ static inline void ST_drawRings(void)
|
|||
INT32 i;
|
||||
ringnum = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].mo && players[i].mo->health > 1)
|
||||
ringnum += players[i].mo->health - 1;
|
||||
if (playeringame[i] && players[i].mo && players[i].rings > 0)
|
||||
ringnum += players[i].rings;
|
||||
}
|
||||
|
||||
ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum);
|
||||
|
@ -1163,11 +1163,11 @@ static void ST_drawNiGHTSHUD(void)
|
|||
INT32 i;
|
||||
total_ringcount = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] /*&& players[i].pflags & PF_NIGHTSMODE*/ && players[i].health)
|
||||
total_ringcount += players[i].health - 1;
|
||||
if (playeringame[i] /*&& players[i].pflags & PF_NIGHTSMODE*/ && players[i].rings)
|
||||
total_ringcount += players[i].rings;
|
||||
}
|
||||
else
|
||||
total_ringcount = stplyr->health-1;
|
||||
total_ringcount = stplyr->rings;
|
||||
|
||||
if (stplyr->capsule)
|
||||
{
|
||||
|
@ -1379,7 +1379,7 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I
|
|||
txtflags |= V_YELLOWMAP;
|
||||
|
||||
if (weapon == pw_infinityring
|
||||
|| (stplyr->ringweapons & rwflag && stplyr->health > 1))
|
||||
|| (stplyr->ringweapons & rwflag))
|
||||
txtflags |= V_20TRANS;
|
||||
else
|
||||
{
|
||||
|
@ -1417,7 +1417,7 @@ static void ST_drawMatchHUD(void)
|
|||
|
||||
if (stplyr->powers[pw_infinityring])
|
||||
ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring);
|
||||
else if (stplyr->health > 1)
|
||||
else if (stplyr->rings > 0)
|
||||
V_DrawScaledPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT, normring);
|
||||
else
|
||||
V_DrawTranslucentPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT|V_80TRANS, normring);
|
||||
|
|
|
@ -839,13 +839,13 @@ static void Y_UpdateRecordReplays(void)
|
|||
if ((mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < mainrecords[gamemap-1]->time))
|
||||
mainrecords[gamemap-1]->time = players[consoleplayer].realtime;
|
||||
|
||||
if ((UINT16)(players[consoleplayer].health - 1) > mainrecords[gamemap-1]->rings)
|
||||
mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].health - 1);
|
||||
if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings)
|
||||
mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings);
|
||||
|
||||
// Save demo!
|
||||
bestdemo[255] = '\0';
|
||||
lastdemo[255] = '\0';
|
||||
G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].health-1));
|
||||
G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].rings));
|
||||
G_CheckDemoStatus();
|
||||
|
||||
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
|
||||
|
@ -1435,7 +1435,7 @@ static void Y_CalculateCompetitionWinners(void)
|
|||
bestat[j] = true;
|
||||
|
||||
times[i] = players[i].realtime;
|
||||
rings[i] = (UINT32)max(players[i].health-1, 0);
|
||||
rings[i] = (UINT32)max(players[i].rings, 0);
|
||||
maxrings[i] = (UINT32)players[i].totalring;
|
||||
monitors[i] = (UINT32)players[i].numboxes;
|
||||
scores[i] = (UINT32)min(players[i].score, 99999990);
|
||||
|
@ -1450,7 +1450,7 @@ static void Y_CalculateCompetitionWinners(void)
|
|||
else
|
||||
bestat[0] = false;
|
||||
|
||||
if (max(players[i].health-1, 0) >= max(players[j].health-1, 0))
|
||||
if (max(players[i].rings, 0) >= max(players[j].rings, 0))
|
||||
points[i]++;
|
||||
else
|
||||
bestat[1] = false;
|
||||
|
@ -1573,7 +1573,7 @@ static void Y_SetRingBonus(player_t *player, y_bonus_t *bstruct)
|
|||
{
|
||||
strncpy(bstruct->patch, "YB_RING", sizeof(bstruct->patch));
|
||||
bstruct->display = true;
|
||||
bstruct->points = max(0, (player->health-1) * 100);
|
||||
bstruct->points = max(0, (player->rings) * 100);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1621,7 +1621,7 @@ static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct)
|
|||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i]) continue;
|
||||
sharedringtotal += players[i].health - 1;
|
||||
sharedringtotal += players[i].rings;
|
||||
}
|
||||
if (!sharedringtotal || sharedringtotal < nummaprings)
|
||||
data.coop.gotperfbonus = 0;
|
||||
|
|
Loading…
Reference in a new issue