Guard retrieval of player index (.yvel) from APLAYER sprite.

It is unacceptable that yvel is on one hand modifiable without restriction from
scripting, but can be used as an array index without prior bound check in the C
code. Because that member has an overloaded meaning and is also used for
innocuous purposes such as the green color intensity of an SE light, it's
infeasible to restrict access from scripting. Consequently, we must add bound
checks on the C side. This is the first part of the effort to make .yvel safe,
adding two functions P_Get() and P_GetP(). There are a couple of other uses as
some kind of index.

git-svn-id: https://svn.eduke32.com/eduke32@4226 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-12-28 17:04:27 +00:00
parent 8a2d786e23
commit efdd31d5a9
10 changed files with 164 additions and 114 deletions

View file

@ -294,7 +294,7 @@ SKIPWALLCHECK:
{
if (sj->picnum == APLAYER)
{
DukePlayer_t *ps = g_player[sj->yvel].ps;
DukePlayer_t *ps = g_player[P_GetP(sj)].ps;
if (ps->newowner >= 0)
G_ClearCameraView(ps);
@ -1015,25 +1015,27 @@ int32_t A_IncurDamage(int32_t sn)
if (targ->picnum == APLAYER)
{
int32_t p = targ->yvel;
int32_t p = P_GetP(targ);
if (ud.god && dmg->picnum != SHRINKSPARK) return -1;
if (dmg->owner >= 0 && ud.ffire == 0 && sprite[dmg->owner].picnum == APLAYER &&
(GametypeFlags[ud.coop] & GAMETYPE_PLAYERSFRIENDLY ||
(GametypeFlags[ud.coop] & GAMETYPE_TDM && g_player[p].ps->team == g_player[sprite[dmg->owner].yvel].ps->team)))
(GametypeFlags[ud.coop] & GAMETYPE_TDM && g_player[p].ps->team == g_player[P_Get(dmg->owner)].ps->team)))
return -1;
targ->extra -= dmg->extra;
if (dmg->owner >= 0 && targ->extra <= 0 && dmg->picnum != FREEZEBLAST)
{
const int32_t ow = dmg->owner;
targ->extra = 0;
g_player[p].ps->wackedbyactor = dmg->owner;
g_player[p].ps->wackedbyactor = ow;
if (sprite[dmg->owner].picnum == APLAYER && p != sprite[dmg->owner].yvel)
g_player[p].ps->frag_ps = sprite[dmg->owner].yvel;
if (sprite[ow].picnum == APLAYER && p != P_Get(ow))
g_player[p].ps->frag_ps = P_Get(ow);
dmg->owner = g_player[p].ps->i;
}
@ -1120,7 +1122,7 @@ void A_MoveDummyPlayers(void)
while (i >= 0)
{
const int32_t p = sprite[OW].yvel;
const int32_t p = P_Get(OW);
DukePlayer_t *const ps = g_player[p].ps;
const int32_t nexti = nextspritestat[i];
@ -1172,7 +1174,7 @@ ACTOR_STATIC void G_MovePlayers(void)
const int32_t nexti = nextspritestat[i];
spritetype *const s = &sprite[i];
DukePlayer_t *const p = g_player[s->yvel].ps;
DukePlayer_t *const p = g_player[P_GetP(s)].ps;
if (s->owner >= 0)
{
@ -1200,24 +1202,24 @@ ACTOR_STATIC void G_MovePlayers(void)
p->on_warping_sector = 1;
if (slotag==ST_1_ABOVE_WATER)
k = P_Submerge(i, s->yvel, p, psect, othersect);
k = P_Submerge(i, P_GetP(s), p, psect, othersect);
else
k = P_Emerge(i, s->yvel, p, psect, othersect);
k = P_Emerge(i, P_GetP(s), p, psect, othersect);
if (k == 1)
P_FinishWaterChange(i, p, slotag, -1, othersect);
}
#endif
if (g_netServer || ud.multimode > 1)
otherp = P_FindOtherPlayer(s->yvel,&otherx);
otherp = P_FindOtherPlayer(P_GetP(s), &otherx);
else
{
otherp = s->yvel;
otherp = P_GetP(s);
otherx = 0;
}
if (G_HaveActor(sprite[i].picnum))
A_Execute(i,s->yvel,otherx);
A_Execute(i, P_GetP(s), otherx);
if (g_netServer || ud.multimode > 1)
if (sprite[g_player[otherp].ps->i].extra > 0)
@ -2845,7 +2847,7 @@ ACTOR_STATIC void Proj_MoveCustom(int32_t i)
if (sprite[j].picnum == APLAYER)
{
int32_t p = sprite[j].yvel;
int32_t p = P_Get(j);
A_PlaySound(PISTOL_BODYHIT, j);
@ -3117,7 +3119,7 @@ ACTOR_STATIC void G_MoveWeapons(void)
if (sprite[j].picnum == APLAYER)
{
int32_t p = sprite[j].yvel;
int32_t p = P_Get(j);
A_PlaySound(PISTOL_BODYHIT, j);
if (s->picnum == SPIT)
@ -3410,7 +3412,7 @@ ACTOR_STATIC void G_MoveTransports(void)
case STAT_PLAYER:
if (sprite[j].owner != -1)
{
const int32_t p = sprite[j].yvel;
const int32_t p = P_Get(j);
DukePlayer_t *const ps = g_player[p].ps;
ps->on_warping_sector = 1;
@ -4645,7 +4647,7 @@ ACTOR_STATIC void G_MoveActors(void)
}
if (sprite[s->owner].picnum == APLAYER)
l = sprite[s->owner].yvel;
l = P_Get(s->owner);
else l = -1;
if (s->xvel > 0)
@ -5069,9 +5071,9 @@ ACTOR_STATIC void G_MoveMisc(void) // STATNUM 5
else if (t[0] == 16)
{
s->picnum = NUKEBUTTON+2;
g_player[sprite[s->owner].yvel].ps->fist_incs = 1;
g_player[P_Get(s->owner)].ps->fist_incs = 1;
}
if (g_player[sprite[s->owner].yvel].ps->fist_incs == GAMETICSPERSEC)
if (g_player[P_Get(s->owner)].ps->fist_incs == GAMETICSPERSEC)
s->picnum = NUKEBUTTON+3;
}
goto BOLT;
@ -5596,8 +5598,8 @@ static void HandleSE31(int32_t i, int32_t setfloorzp, int32_t zref, int32_t t2va
for (SPRITES_OF_SECT(s->sectnum, j))
{
if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0)
if (g_player[sprite[j].yvel].ps->on_ground == 1)
g_player[sprite[j].yvel].ps->pos.z += l;
if (g_player[P_Get(j)].ps->on_ground == 1)
g_player[P_Get(j)].ps->pos.z += l;
if (sprite[j].zvel == 0 && sprite[j].statnum != STAT_EFFECTOR && sprite[j].statnum != STAT_PROJECTILE)
{
@ -6877,7 +6879,7 @@ ACTOR_STATIC void G_MoveEffectors(void) //STATNUM 3
{
if (sprite[j].statnum == STAT_PLAYER && sprite[j].owner >= 0)
{
const int32_t p = sprite[j].yvel;
const int32_t p = P_Get(j);
DukePlayer_t *const ps = g_player[p].ps;
if (numplayers < 2 && !g_netServer)
@ -6931,7 +6933,7 @@ ACTOR_STATIC void G_MoveEffectors(void) //STATNUM 3
{
if (sprite[k].statnum == STAT_PLAYER && sprite[k].owner >= 0)
{
const int32_t p = sprite[k].yvel;
const int32_t p = P_Get(k);
DukePlayer_t *const ps = g_player[p].ps;
ps->pos.x += sprite[j].x-s->x;
@ -6993,8 +6995,8 @@ ACTOR_STATIC void G_MoveEffectors(void) //STATNUM 3
for (SPRITES_OF_SECT(s->sectnum, j))
{
if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0)
if (g_player[sprite[j].yvel].ps->on_ground == 1)
g_player[sprite[j].yvel].ps->pos.z += sc->extra;
if (g_player[P_Get(j)].ps->on_ground == 1)
g_player[P_Get(j)].ps->pos.z += sc->extra;
if (sprite[j].zvel == 0 && sprite[j].statnum != STAT_EFFECTOR && sprite[j].statnum != STAT_PROJECTILE)
{
@ -7028,8 +7030,8 @@ ACTOR_STATIC void G_MoveEffectors(void) //STATNUM 3
for (SPRITES_OF_SECT(s->sectnum, j))
{
if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0)
if (g_player[sprite[j].yvel].ps->on_ground == 1)
g_player[sprite[j].yvel].ps->pos.z -= sc->extra;
if (g_player[P_Get(j)].ps->on_ground == 1)
g_player[P_Get(j)].ps->pos.z -= sc->extra;
if (sprite[j].zvel == 0 && sprite[j].statnum != STAT_EFFECTOR && sprite[j].statnum != STAT_PROJECTILE)
{

View file

@ -3633,8 +3633,8 @@ void G_DisplayRest(int32_t smoothratio)
}
if (I_EscapeTrigger() && ud.overhead_on == 0
&& ud.show_help == 0
&& g_player[myconnectindex].ps->newowner == -1)
&& ud.show_help == 0
&& g_player[myconnectindex].ps->newowner == -1)
{
if ((g_player[myconnectindex].ps->gm&MODE_MENU) == MODE_MENU && g_currentMenu < 51)
{
@ -3763,7 +3763,7 @@ void G_DisplayRest(int32_t smoothratio)
(myps->player_par/(REALGAMETICSPERSEC*60)),
(myps->player_par/REALGAMETICSPERSEC)%60,
((myps->player_par%REALGAMETICSPERSEC)*33)/10
);
);
G_PrintGameText(8+4+1,STARTALPHANUM, j,scale(200-i,ud.config.ScreenHeight,200)-textsc(21),
tempbuf,0,10,26,0, 0, xdim-1, ydim-1, 65536);
@ -3853,7 +3853,7 @@ static void G_DoThirdPerson(const DukePlayer_t *pp, vec3_t *vect, int16_t *vsect
vec3_t n = { (sintable[(ang+1536)&2047]>>4),
(sintable[(ang+1024)&2047]>>4),
(horiz-100)*128
};
};
sp->cstat &= (int16_t)~0x101;
@ -3941,15 +3941,15 @@ void G_DrawBackground(void)
#if !defined LUNATIC
if (Gv_GetVarByLabel("MENU_TILE", !fstilep, -1, -1))
#else
if (!fstilep)
if (!fstilep)
#endif
{
if ((unsigned)bgtile < MAXTILES)
for (y=y1; y<y2; y+=tilesizy[bgtile])
for (x=0; x<xdim; x+=tilesizx[bgtile])
rotatesprite_fs(x<<16,y<<16,65536L,0,bgtile,16,0,8+16+64);
}
else rotatesprite_fs(320<<15,200<<15,65536L,0,bgtile,16,0,2+8+64+(ud.bgstretch?1024:0));
{
if ((unsigned)bgtile < MAXTILES)
for (y=y1; y<y2; y+=tilesizy[bgtile])
for (x=0; x<xdim; x+=tilesizx[bgtile])
rotatesprite_fs(x<<16,y<<16,65536L,0,bgtile,16,0,8+16+64);
}
else rotatesprite_fs(320<<15,200<<15,65536L,0,bgtile,16,0,2+8+64+(ud.bgstretch?1024:0));
return;
}
@ -5548,7 +5548,7 @@ int32_t A_Spawn(int32_t j, int32_t pn)
break;
}
sp->cstat = 32+((g_player[sprite[j].yvel].ps->footprintcount&1)<<2);
sp->cstat = 32+((g_player[P_Get(j)].ps->footprintcount&1)<<2);
sp->ang = sprite[j].ang;
}
@ -5596,7 +5596,7 @@ int32_t A_Spawn(int32_t j, int32_t pn)
sp->xrepeat = sprite[j].xrepeat;
sp->yrepeat = sprite[j].yrepeat;
sp->shade = sprite[j].shade;
sp->pal = g_player[sprite[j].yvel].ps->palookup;
sp->pal = g_player[P_Get(j)].ps->palookup;
}
case DUKECAR__STATIC:
case HELECOPT__STATIC:
@ -5658,16 +5658,17 @@ int32_t A_Spawn(int32_t j, int32_t pn)
case SHOTGUNSHELL__STATIC:
if (j >= 0)
{
int32_t snum,a;
int32_t a;
if (sprite[j].picnum == APLAYER)
{
snum = sprite[j].yvel;
a = g_player[snum].ps->ang-(krand()&63)+8; //Fine tune
int32_t snum = P_Get(j);
const DukePlayer_t *const ps = g_player[snum].ps;
a = ps->ang-(krand()&63)+8; //Fine tune
T1 = krand()&1;
sp->z = (3<<8)+g_player[snum].ps->pyoff+g_player[snum].ps->pos.z-
((g_player[snum].ps->horizoff+g_player[snum].ps->horiz-100)<<4);
sp->z = (3<<8) + ps->pyoff + ps->pos.z - ((ps->horizoff + ps->horiz-100)<<4);
if (sp->picnum == SHOTGUNSHELL)
sp->z += (3<<8);
sp->zvel = -(krand()&255);
@ -7235,21 +7236,26 @@ void G_DoSpriteAnimations(int32_t ourx, int32_t oury, int32_t oura, int32_t smoo
if (t->statnum == TSPR_TEMP)
continue;
if (s->statnum != STAT_ACTOR && s->picnum == APLAYER && g_player[s->yvel].ps->newowner == -1 && s->owner >= 0)
{
t->x -= mulscale16(65536-smoothratio,g_player[s->yvel].ps->pos.x-g_player[s->yvel].ps->opos.x);
t->y -= mulscale16(65536-smoothratio,g_player[s->yvel].ps->pos.y-g_player[s->yvel].ps->opos.y);
// dirty hack
if (g_player[s->yvel].ps->dead_flag) t->z = g_player[s->yvel].ps->opos.z;
t->z += mulscale16(smoothratio,g_player[s->yvel].ps->pos.z-g_player[s->yvel].ps->opos.z) -
(g_player[s->yvel].ps->dead_flag ? 0 : PHEIGHT) + PHEIGHT;
}
else if ((s->statnum == STAT_DEFAULT && s->picnum != CRANEPOLE) || s->statnum == STAT_PLAYER ||
s->statnum == STAT_STANDABLE || s->statnum == STAT_PROJECTILE || s->statnum == STAT_MISC || s->statnum == STAT_ACTOR)
{
t->x -= mulscale16(65536-smoothratio,s->x-actor[i].bpos.x);
t->y -= mulscale16(65536-smoothratio,s->y-actor[i].bpos.y);
t->z -= mulscale16(65536-smoothratio,s->z-actor[i].bpos.z);
int32_t snum = P_GetP(s);
const DukePlayer_t *const ps = g_player[snum].ps;
if (s->statnum != STAT_ACTOR && s->picnum == APLAYER && ps->newowner == -1 && s->owner >= 0)
{
t->x -= mulscale16(65536-smoothratio,ps->pos.x-ps->opos.x);
t->y -= mulscale16(65536-smoothratio,ps->pos.y-ps->opos.y);
// dirty hack
if (ps->dead_flag) t->z = ps->opos.z;
t->z += mulscale16(smoothratio,ps->pos.z-ps->opos.z) -
(ps->dead_flag ? 0 : PHEIGHT) + PHEIGHT;
}
else if ((s->statnum == STAT_DEFAULT && s->picnum != CRANEPOLE) || s->statnum == STAT_PLAYER ||
s->statnum == STAT_STANDABLE || s->statnum == STAT_PROJECTILE || s->statnum == STAT_MISC || s->statnum == STAT_ACTOR)
{
t->x -= mulscale16(65536-smoothratio,s->x-actor[i].bpos.x);
t->y -= mulscale16(65536-smoothratio,s->y-actor[i].bpos.y);
t->z -= mulscale16(65536-smoothratio,s->z-actor[i].bpos.z);
}
}
sect = s->sectnum;
@ -7320,7 +7326,9 @@ void G_DoSpriteAnimations(int32_t ourx, int32_t oury, int32_t oura, int32_t smoo
case BURNING2__STATIC:
if (sprite[s->owner].statnum == STAT_PLAYER)
{
if (display_mirror == 0 && sprite[s->owner].yvel == screenpeek && g_player[sprite[s->owner].yvel].ps->over_shoulder_on == 0)
const int32_t snum = P_Get(s->owner);
if (display_mirror == 0 && snum == screenpeek && g_player[snum].ps->over_shoulder_on == 0)
t->xrepeat = 0;
else
{
@ -7393,7 +7401,7 @@ void G_DoSpriteAnimations(int32_t ourx, int32_t oury, int32_t oura, int32_t smoo
break;
case APLAYER__STATIC:
p = s->yvel;
p = P_GetP(s);
if (t->pal == 1) t->z -= (18<<8);
@ -7851,7 +7859,7 @@ skip:
{
if (sprite[s->owner].picnum == APLAYER)
if (ud.camerasprite == -1)
if (screenpeek == sprite[s->owner].yvel && display_mirror == 0)
if (screenpeek == P_Get(s->owner) && display_mirror == 0)
{
t->owner = -1;
break;
@ -12009,18 +12017,22 @@ int32_t G_DoMoveThings(void)
sprite[g_player[i].ps->holoduke_on].cstat ^= 256;
if ((hit.sprite >= 0) && !(g_player[myconnectindex].ps->gm & MODE_MENU) &&
sprite[hit.sprite].picnum == APLAYER && sprite[hit.sprite].yvel != screenpeek &&
g_player[sprite[hit.sprite].yvel].ps->dead_flag == 0)
sprite[hit.sprite].picnum == APLAYER)
{
if (p->fta == 0 || p->ftq == QUOTE_RESERVED3)
const int32_t snum = P_Get(hit.sprite);
if (snum != screenpeek && g_player[snum].ps->dead_flag == 0)
{
if (ldist(&sprite[p->i],&sprite[hit.sprite]) < 9216)
if (p->fta == 0 || p->ftq == QUOTE_RESERVED3)
{
Bsprintf(ScriptQuotes[QUOTE_RESERVED3],"%s",&g_player[sprite[hit.sprite].yvel].user_name[0]);
p->fta = 12, p->ftq = QUOTE_RESERVED3;
if (ldist(&sprite[p->i], &sprite[hit.sprite]) < 9216)
{
Bsprintf(ScriptQuotes[QUOTE_RESERVED3], "%s", &g_player[snum].user_name[0]);
p->fta = 12, p->ftq = QUOTE_RESERVED3;
}
}
else if (p->fta > 2) p->fta -= 3;
}
else if (p->fta > 2) p->fta -= 3;
}
}

View file

@ -804,7 +804,7 @@ static void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap)
{
if ((ps->weaponswitch & 1) && (ps->weaponswitch & 4))
{
int32_t snum = sprite[ps->i].yvel;
const int32_t snum = P_Get(ps->i);
int32_t i, new_wchoice = -1, curr_wchoice = -1;
for (i=0; i<=FREEZE_WEAPON && (new_wchoice < 0 || curr_wchoice < 0); i++)
@ -1428,7 +1428,7 @@ skip_check:
case CON_GETLASTPAL:
insptr++;
if (vm.g_sp->picnum == APLAYER)
vm.g_sp->pal = g_player[vm.g_sp->yvel].ps->palookup;
vm.g_sp->pal = g_player[P_GetP(vm.g_sp)].ps->palookup;
else
{
if (vm.g_sp->pal == 1 && vm.g_sp->extra == 0) // hack for frozen
@ -1440,7 +1440,7 @@ skip_check:
case CON_TOSSWEAPON:
insptr++;
P_DropWeapon(g_player[vm.g_sp->yvel].ps);
P_DropWeapon(g_player[P_GetP(vm.g_sp)].ps);
continue;
case CON_NULLOP:
@ -5318,7 +5318,7 @@ void A_LoadActor(int32_t iActor)
#endif
// NORECURSE
void A_Execute(int32_t iActor,int32_t iPlayer,int32_t lDist)
void A_Execute(int32_t iActor, int32_t iPlayer, int32_t lDist)
{
#ifdef LUNATIC
int32_t killit=0;
@ -5697,7 +5697,7 @@ void G_RestoreMapState(void)
// - walk backward to the door leading to Shadowpine Forest --> crash.
for (SPRITES_OF(STAT_PLAYER, i))
{
int32_t snum = sprite[i].yvel;
int32_t snum = P_Get(i);
Bassert((unsigned)snum < MAXPLAYERS);
g_player[snum].ps->i = i;
}

View file

@ -143,7 +143,7 @@ extern int32_t g_currentEventExec;
void A_LoadActor(int32_t iActor);
#endif
void A_Execute(int32_t iActor,int32_t iPlayer,int32_t lDist);
void A_Execute(int32_t iActor, int32_t iPlayer, int32_t lDist);
void A_Fall(int32_t iActor);
int32_t A_FurthestVisiblePoint(int32_t iActor,spritetype *ts,int32_t *dax,int32_t *day);
int32_t A_GetFurthestAngle(int32_t iActor,int32_t angs);

View file

@ -1573,7 +1573,9 @@ end
function _getlastpal(spritenum)
local spr = sprite[spritenum]
if (ispic(spr.picnum, "APLAYER")) then
spr.pal = player[spr.yvel].palookup
local pidx = spr.yvel
check_player_idx(pidx)
spr.pal = player[pidx].palookup
else
if (spr.pal == 1 and spr.extra == 0) then -- hack for frozen
spr.extra = spr.extra+1

View file

@ -63,7 +63,7 @@ static void P_IncurDamage(DukePlayer_t *p)
{
int32_t damage;
if (VM_OnEvent(EVENT_INCURDAMAGE, p->i, sprite[p->i].yvel, -1, 0) != 0)
if (VM_OnEvent(EVENT_INCURDAMAGE, p->i, P_Get(p->i), -1, 0) != 0)
return;
sprite[p->i].extra -= p->extra_extra8>>8;
@ -199,12 +199,14 @@ static int32_t A_FindTargetSprite(const spritetype *s, int32_t aang, int32_t atw
int32_t dx1, dy1, dx2, dy2, dx3, dy3, smax, sdist;
int32_t xv, yv;
const int32_t snum = s->picnum == APLAYER ? P_GetP(s) : -1;
if (s->picnum == APLAYER)
{
if (!g_player[s->yvel].ps->auto_aim)
if (!g_player[snum].ps->auto_aim)
return -1;
if (g_player[s->yvel].ps->auto_aim == 2)
if (g_player[snum].ps->auto_aim == 2)
{
if (A_CheckSpriteTileFlags(atwith,SPRITE_PROJECTILE) && (ProjectileData[atwith].workslike & PROJECTILE_RPG))
return -1;
@ -230,8 +232,8 @@ static int32_t A_FindTargetSprite(const spritetype *s, int32_t aang, int32_t atw
j = -1;
gotshrinker = (s->picnum == APLAYER && PWEAPON(0, g_player[s->yvel].ps->curr_weapon, WorksLike) == SHRINKER_WEAPON);
gotfreezer = (s->picnum == APLAYER && PWEAPON(0, g_player[s->yvel].ps->curr_weapon, WorksLike) == FREEZE_WEAPON);
gotshrinker = (s->picnum == APLAYER && PWEAPON(0, g_player[snum].ps->curr_weapon, WorksLike) == SHRINKER_WEAPON);
gotfreezer = (s->picnum == APLAYER && PWEAPON(0, g_player[snum].ps->curr_weapon, WorksLike) == FREEZE_WEAPON);
smax = INT32_MAX;
@ -253,12 +255,10 @@ static int32_t A_FindTargetSprite(const spritetype *s, int32_t aang, int32_t atw
{
if (A_CheckEnemySprite(&sprite[i]) || PN == APLAYER || PN == SHARK)
{
if (PN == APLAYER &&
if (PN == APLAYER && s->picnum == APLAYER && s != &sprite[i] &&
// ud.ffire == 0 &&
(GTFLAGS(GAMETYPE_PLAYERSFRIENDLY) || (GTFLAGS(GAMETYPE_TDM) &&
g_player[sprite[i].yvel].ps->team == g_player[s->yvel].ps->team)) &&
s->picnum == APLAYER &&
s != &sprite[i])
g_player[P_Get(i)].ps->team == g_player[snum].ps->team)))
continue;
if (gotshrinker && sprite[i].xrepeat < 30)
@ -284,7 +284,10 @@ static int32_t A_FindTargetSprite(const spritetype *s, int32_t aang, int32_t atw
if (sdist > 512 && sdist < smax)
{
if (s->picnum == APLAYER)
a = (klabs(scale(SZ-s->z,10,sdist)-(g_player[s->yvel].ps->horiz+g_player[s->yvel].ps->horizoff-100)) < 100);
{
const DukePlayer_t *const ps = g_player[P_GetP(s)].ps;
a = (klabs(scale(SZ-s->z,10,sdist)-(ps->horiz+ps->horizoff-100)) < 100);
}
else a = 1;
if (PN == ORGANTIC || PN == ROTATEGUN)
@ -660,7 +663,7 @@ static int32_t P_PostFireHitscan(int32_t p, int32_t k, hitdata_t *hit, int32_t i
if (sprite[hit->sprite].picnum == APLAYER &&
(ud.ffire == 1 || (!GTFLAGS(GAMETYPE_PLAYERSFRIENDLY) && GTFLAGS(GAMETYPE_TDM) &&
g_player[sprite[hit->sprite].yvel].ps->team != g_player[sprite[i].yvel].ps->team)))
g_player[P_Get(hit->sprite)].ps->team != g_player[P_Get(i)].ps->team)))
{
int32_t l = A_Spawn(k, JIBS6);
sprite[k].xrepeat = sprite[k].yrepeat = 0;
@ -857,7 +860,7 @@ static int32_t A_ShootCustom(const int32_t i, const int32_t atwith, int16_t sa,
hitdata_t hit;
spritetype *const s = &sprite[i];
const int16_t sect = s->sectnum;
const int32_t p = (s->picnum == APLAYER) ? s->yvel : -1;
const int32_t p = (s->picnum == APLAYER) ? P_GetP(s) : -1;
DukePlayer_t *const ps = p >= 0 ? g_player[p].ps : NULL;
#ifdef POLYMER
@ -1103,7 +1106,7 @@ int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel)
int16_t sa;
vec3_t srcvect;
spritetype *const s = &sprite[i];
const int32_t p = (s->picnum == APLAYER) ? s->yvel : -1;
const int32_t p = (s->picnum == APLAYER) ? P_GetP(s) : -1;
DukePlayer_t *const ps = p >= 0 ? g_player[p].ps : NULL;
Bassert(atwith >= 0);
@ -1901,7 +1904,7 @@ void P_SetWeaponGamevars(int32_t snum, const DukePlayer_t *p)
static void P_FireWeapon(DukePlayer_t *p)
{
int32_t i, snum = sprite[p->i].yvel;
int32_t i, snum = P_Get(p->i); // TODO: PASS_SNUM?
if (VM_OnEvent(EVENT_DOFIRE, p->i, snum, -1, 0) == 0)
{
@ -1958,7 +1961,7 @@ static void P_FireWeapon(DukePlayer_t *p)
static void P_DoWeaponSpawn(const DukePlayer_t *p)
{
int32_t j, snum = sprite[p->i].yvel;
int32_t j, snum = P_Get(p->i); // TODO: PASS_SNUM?
// NOTE: For the 'Spawn' member, 0 means 'none', too (originally so,
// i.e. legacy). The check for <0 was added to the check because mod
@ -2952,7 +2955,7 @@ void P_GetInput(int32_t snum)
static int32_t P_DoCounters(DukePlayer_t *p)
{
int32_t snum = sprite[p->i].yvel;
int32_t snum = P_Get(p->i);
// j = g_player[snum].sync->avel;
// p->weapon_ang = -(j/5);
@ -3159,10 +3162,11 @@ int16_t WeaponPickupSprites[MAX_WEAPONS] = { KNEE__STATIC, FIRSTGUNSPRITE__STATI
// this is used for player deaths
void P_DropWeapon(DukePlayer_t *p)
{
int32_t snum = sprite[p->i].yvel,
cw = PWEAPON(snum, p->curr_weapon, WorksLike);
int32_t snum = P_Get(p->i); // TODO: PASS_SNUM?
int32_t cw = PWEAPON(snum, p->curr_weapon, WorksLike);
if ((unsigned)cw >= MAX_WEAPONS) return;
if ((unsigned)cw >= MAX_WEAPONS)
return;
if (krand()&1)
A_Spawn(p->i, WeaponPickupSprites[cw]);
@ -3185,7 +3189,7 @@ void P_AddAmmo(int32_t weapon,DukePlayer_t *p,int32_t amount)
static void P_AddWeaponNoSwitch(DukePlayer_t *p, int32_t weapon)
{
int32_t snum = sprite[p->i].yvel;
int32_t snum = P_Get(p->i); // PASS_SNUM?
if ((p->gotweapon & (1<<weapon)) == 0)
{
@ -3204,10 +3208,11 @@ static void P_AddWeaponNoSwitch(DukePlayer_t *p, int32_t weapon)
void P_ChangeWeapon(DukePlayer_t *p, int32_t weapon)
{
int32_t i = 0, snum = sprite[p->i].yvel;
int32_t i = 0, snum = P_Get(p->i); // PASS_SNUM?
const int8_t curr_weapon = p->curr_weapon;
if (p->reloading) return;
if (p->reloading)
return;
if (p->curr_weapon != weapon && G_HaveEvent(EVENT_CHANGEWEAPON))
i = VM_OnEvent(EVENT_CHANGEWEAPON,p->i, snum, -1, weapon);
@ -3291,7 +3296,7 @@ void P_CheckWeapon(DukePlayer_t *p)
if ((p->gotweapon & (1<<weapon)) && (p->ammo_amount[weapon] > 0 || !(p->weaponswitch & 2)))
return;
snum = sprite[p->i].yvel;
snum = P_Get(p->i);
for (i=0; i<=FREEZE_WEAPON; i++)
{
@ -3335,7 +3340,7 @@ static void DoWallTouchDamage(const DukePlayer_t *p, int32_t obj)
static void P_CheckTouchDamage(DukePlayer_t *p, int32_t obj)
{
if ((obj = VM_OnEvent(EVENT_CHECKTOUCHDAMAGE, p->i, sprite[p->i].yvel, -1, obj)) == -1)
if ((obj = VM_OnEvent(EVENT_CHECKTOUCHDAMAGE, p->i, P_Get(p->i), -1, obj)) == -1)
return;
if ((obj&49152) == 49152)
@ -3396,7 +3401,7 @@ static int32_t P_CheckFloorDamage(DukePlayer_t *p, int32_t tex)
{
spritetype *s = &sprite[p->i];
if ((unsigned)(tex = VM_OnEvent(EVENT_CHECKFLOORDAMAGE, p->i, sprite[p->i].yvel, -1, tex)) >= MAXTILES)
if ((unsigned)(tex = VM_OnEvent(EVENT_CHECKFLOORDAMAGE, p->i, P_Get(p->i), -1, tex)) >= MAXTILES)
return 0;
switch (DYNAMICTILEMAP(tex))
@ -3461,7 +3466,7 @@ static int32_t P_CheckFloorDamage(DukePlayer_t *p, int32_t tex)
}
int32_t P_FindOtherPlayer(int32_t p,int32_t *d)
int32_t P_FindOtherPlayer(int32_t p, int32_t *d)
{
int32_t j, closest_player = p;
int32_t x, closest = INT32_MAX;
@ -5292,9 +5297,12 @@ HORIZONLY:
A_DeleteSprite(p->actorsqu);
break;
case APLAYER__STATIC:
P_QuickKill(g_player[sprite[p->actorsqu].yvel].ps);
g_player[sprite[p->actorsqu].yvel].ps->frag_ps = snum;
{
int32_t snum = P_Get(p->actorsqu);
P_QuickKill(g_player[snum].ps);
g_player[snum].ps->frag_ps = snum;
break;
}
default:
if (A_CheckEnemySprite(&sprite[p->actorsqu]))
p->actors_killed++;

View file

@ -23,6 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __player_h__
#define __player_h__
extern int32_t playerswhenstarted;
#define MOVEFIFOSIZ 2
#define NAM_GRENADE_LIFETIME 120
@ -368,7 +370,7 @@ void P_CheckWeapon(DukePlayer_t *p);
void P_DisplayScuba(int32_t snum);
void P_DisplayWeapon(int32_t snum);
void P_DropWeapon(DukePlayer_t *p);
int32_t P_FindOtherPlayer(int32_t p,int32_t *d);
int32_t P_FindOtherPlayer(int32_t p, int32_t *d);
void P_FragPlayer(int32_t snum);
void P_UpdatePosWhenViewingCam(DukePlayer_t *p);
void P_ProcessInput(int32_t snum);
@ -386,4 +388,30 @@ static inline void P_SetWeaponGamevars(int32_t snum, const DukePlayer_t *p)
}
#endif
// Get the player index given an APLAYER sprite pointer.
static inline int32_t P_GetP(const spritetype *spr)
{
#if 0 // unprotected player index retrieval
return spr->yvel;
#elif defined NETCODE_DISABLE
UNREFERENCED_PARAMETER(spr); // for NDEBUG build
// NOTE: In the no-netcode build, there's no point to pass player indices
// at all since there is ever only one player. However, merely returning 0
// would mean making this build less strict than the normal one.
Bassert(spr->yvel == 0);
return 0;
#else
int32_t pidx = spr->yvel;
if ((unsigned)pidx >= (unsigned)playerswhenstarted)
pidx = 0;
return pidx;
#endif
}
// Get the player index given an APLAYER sprite index.
static inline int32_t P_Get(int32_t spritenum)
{
return P_GetP(&sprite[spritenum]);
}
#endif

View file

@ -503,7 +503,7 @@ void G_CacheMapData(void)
k = 0;
for (k=0; k<MAXPALOOKUPS-RESERVEDPALS && !KB_KeyPressed(sc_Space); k++)
{
// this is the CROSSHAIR_COLOR, see comment in game.c
// this is the CROSSHAIR_PAL, see comment in game.c
if (k == MAXPALOOKUPS-RESERVEDPALS-1)
break;
#ifdef POLYMER
@ -772,7 +772,6 @@ void P_ResetStatus(int32_t snum)
p->loogcnt = 0;
p->angvel = 0;
p->weapon_sway = 0;
// p->select_dir = 0;
p->extra_extra8 = 0;
p->show_empty_weapon= 0;
p->dummyplayersprite=-1;

View file

@ -631,7 +631,6 @@ void G_OperateSectors(int32_t sn, int32_t ii)
case ST_15_WARP_ELEVATOR://Warping elevators
if (sprite[ii].picnum != APLAYER) return;
// if(ps[sprite[ii].yvel].select_dir == 1) return;
i = headspritesect[sn];
while (i >= 0)
@ -2371,7 +2370,7 @@ void A_DamageObject(int32_t i,int32_t sn)
j = sprite[sn].owner;
if (j >= 0 && sprite[j].picnum == APLAYER && PN != ROTATEGUN && PN != DRONE)
if (g_player[sprite[j].yvel].ps->curr_weapon == SHOTGUN_WEAPON)
if (g_player[P_Get(j)].ps->curr_weapon == SHOTGUN_WEAPON)
{
A_Shoot(i,BLOODSPLAT3);
A_Shoot(i,BLOODSPLAT1);
@ -2415,7 +2414,7 @@ void A_DamageObject(int32_t i,int32_t sn)
if (sprite[i].statnum == STAT_PLAYER)
{
DukePlayer_t *ps = g_player[sprite[i].yvel].ps;
DukePlayer_t *ps = g_player[P_Get(i)].ps;
if (ps->newowner >= 0)
G_ClearCameraView(ps);

View file

@ -474,7 +474,7 @@ static int32_t S_CalcDistAndAng(int32_t i, int32_t num, int32_t camsect, int32_t
int32_t sndang, sndist;
int32_t explosion = 0;
if (PN == APLAYER && sprite[i].yvel == screenpeek)
if (PN == APLAYER && P_Get(i) == screenpeek)
{
sndang = sndist = 0;
goto sound_further_processing;
@ -489,7 +489,7 @@ static int32_t S_CalcDistAndAng(int32_t i, int32_t num, int32_t camsect, int32_t
// HACK for splitscreen mod: take the min of sound distances
// to 1st and 2nd player.
if (PN == APLAYER && sprite[i].yvel==1)
if (PN == APLAYER && P_Get(i) == 1)
{
sndist = sndang = 0;
goto sound_further_processing;
@ -588,7 +588,7 @@ int32_t S_PlaySound3D(int32_t num, int32_t i, const vec3_t *pos)
// Duke talk
if (g_sounds[num].m & SF_TALK)
{
if ((g_netServer || ud.multimode > 1) && PN == APLAYER && sprite[i].yvel != screenpeek) // other player sound
if ((g_netServer || ud.multimode > 1) && PN == APLAYER && P_Get(i) != screenpeek) // other player sound
{
if (!(ud.config.VoiceToggle&4))
return -1;