📄 player.c
字号:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is NOT part of Duke Nukem 3D version 1.5 - Atomic EditionHowever, it is either an older version of a file that is, or issome test code written during the development of Duke Nukem 3D.This file is provided purely for educational interest.Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
// Savage Baggage Masters
#include "duke3d.h"
int32 turnheldtime; //MED
int32 lastcontroltime; //MED
void setpal(struct player_struct *p)
{
if(p->heat_on) p->palette = slimepal;
else switch(sector[p->cursectnum].ceilingpicnum)
{
case FLOORSLIME:
case FLOORSLIME+1:
case FLOORSLIME+2:
p->palette = slimepal;
break;
default:
if(sector[p->cursectnum].lotag == 2) p->palette = waterpal;
else p->palette = palette;
break;
}
restorepalette = 1;
}
void incur_damage( struct player_struct *p )
{
long damage = 0L, shield_damage = 0L;
short i, damage_source;
sprite[p->i].extra -= p->extra_extra8>>8;
damage = sprite[p->i].extra - p->last_extra;
if ( damage < 0 )
{
p->extra_extra8 = 0;
if ( p->shield_amount > 0 )
{
shield_damage = damage * (20 + (TRAND%30)) / 100;
damage -= shield_damage;
p->shield_amount += shield_damage;
if ( p->shield_amount < 0 )
{
damage += p->shield_amount;
p->shield_amount = 0;
}
}
sprite[p->i].extra = p->last_extra + damage;
}
}
void quickkill(struct player_struct *p)
{
p->pals[0] = 48;
p->pals[1] = 48;
p->pals[2] = 48;
p->pals_time = 48;
sprite[p->i].extra = 0;
sprite[p->i].cstat |= 32768;
if(ud.god == 0) guts(&sprite[p->i],JIBS6,8,myconnectindex);
return;
}
void forceplayerangle(struct player_struct *p)
{
short n;
n = 128-(TRAND&255);
p->horiz += 64;
p->return_to_center = 9;
p->look_ang = n>>1;
p->rotscrnang = n>>1;
}
void tracers(long x1,long y1,long z1,long x2,long y2,long z2,long n)
{
long i, xv, yv, zv;
short sect = -1;
i = n+1;
xv = (x2-x1)/i;
yv = (y2-y1)/i;
zv = (z2-z1)/i;
if( ( klabs(x1-x2)+klabs(y1-y2) ) < 3084 )
return;
for(i=n;i>0;i--)
{
x1 += xv;
y1 += yv;
z1 += zv;
updatesector(x1,y1,§);
if(sect >= 0)
{
if(sector[sect].lotag == 2)
EGS(sect,x1,y1,z1,WATERBUBBLE,-32,4+(TRAND&3),4+(TRAND&3),TRAND&2047,0,0,ps[0].i,5);
else
EGS(sect,x1,y1,z1,SMALLSMOKE,-32,14,14,0,0,0,ps[0].i,5);
}
}
}
long hits(short i)
{
long sx,sy,sz;
short sect,hw,hs;
long zoff;
if(PN == APLAYER) zoff = (40<<8);
else zoff = 0;
hitscan(SX,SY,SZ-zoff,SECT,
sintable[(SA+512)&2047],
sintable[SA&2047],
0,§,&hw,&hs,&sx,&sy,&sz,CLIPMASK1);
return ( FindDistance2D( sx-SX,sy-SY ) );
}
long hitasprite(short i,short *hitsp)
{
long sx,sy,sz,zoff;
short sect,hw;
if(badguy(&sprite[i]) )
zoff = (42<<8);
else if(PN == APLAYER) zoff = (39<<8);
else zoff = 0;
hitscan(SX,SY,SZ-zoff,SECT,
sintable[(SA+512)&2047],
sintable[SA&2047],
0,§,&hw,hitsp,&sx,&sy,&sz,CLIPMASK1);
if(hw >= 0 && (wall[hw].cstat&16) && badguy(&sprite[i]) )
return((1<<30));
return ( FindDistance2D(sx-SX,sy-SY) );
}
/*
long hitaspriteandwall(short i,short *hitsp,short *hitw,short *x, short *y)
{
long sz;
short sect;
hitscan(SX,SY,SZ,SECT,
sintable[(SA+512)&2047],
sintable[SA&2047],
0,§,hitw,hitsp,x,y,&sz,CLIPMASK1);
return ( FindDistance2D(*x-SX,*y-SY) );
}
*/
long hitawall(struct player_struct *p,short *hitw)
{
long sx,sy,sz;
short sect,hs;
hitscan(p->posx,p->posy,p->posz,p->cursectnum,
sintable[(p->ang+512)&2047],
sintable[p->ang&2047],
0,§,hitw,&hs,&sx,&sy,&sz,CLIPMASK0);
return ( FindDistance2D(sx-p->posx,sy-p->posy) );
}
short aim(spritetype *s,short aang)
{
char gotshrinker,gotfreezer;
short i, j, a, k, cans;
short aimstats[] = {10,13,1,2};
long dx1, dy1, dx2, dy2, dx3, dy3, smax, sdist;
long xv, yv;
a = s->ang;
j = -1;
// if(s->picnum == APLAYER && ps[s->yvel].aim_mode) return -1;
gotshrinker = s->picnum == APLAYER && ps[s->yvel].curr_weapon == SHRINKER_WEAPON;
gotfreezer = s->picnum == APLAYER && ps[s->yvel].curr_weapon == FREEZE_WEAPON;
smax = 0x7fffffff;
dx1 = sintable[(a+512-aang)&2047];
dy1 = sintable[(a-aang)&2047];
dx2 = sintable[(a+512+aang)&2047];
dy2 = sintable[(a+aang)&2047];
dx3 = sintable[(a+512)&2047];
dy3 = sintable[a&2047];
for(k=0;k<4;k++)
{
if( j >= 0 )
break;
for(i=headspritestat[aimstats[k]];i >= 0;i=nextspritestat[i])
if( sprite[i].xrepeat > 0 && sprite[i].extra >= 0 && (sprite[i].cstat&(257+32768)) == 257)
if( badguy(&sprite[i]) || k < 2 )
{
if(badguy(&sprite[i]) || PN == APLAYER || PN == SHARK)
{
if( PN == APLAYER &&
// ud.ffire == 0 &&
ud.coop == 1 &&
s->picnum == APLAYER &&
s != &sprite[i])
continue;
if(gotshrinker && sprite[i].xrepeat < 30 )
{
switch(PN)
{
case SHARK:
if(sprite[i].xrepeat < 20) continue;
continue;
case GREENSLIME:
case GREENSLIME+1:
case GREENSLIME+2:
case GREENSLIME+3:
case GREENSLIME+4:
case GREENSLIME+5:
case GREENSLIME+6:
case GREENSLIME+7:
break;
default:
continue;
}
}
if(gotfreezer && sprite[i].pal == 1) continue;
}
xv = (SX-s->x);
yv = (SY-s->y);
if( (dy1*xv) <= (dx1*yv) )
if( ( dy2*xv ) >= (dx2*yv) )
{
sdist = mulscale(dx3,xv,14) + mulscale(dy3,yv,14);
if( sdist > 512 && sdist < smax )
{
if(s->picnum == APLAYER)
a = (klabs(scale(SZ-s->z,10,sdist)-(ps[s->yvel].horiz+ps[s->yvel].horizoff-100)) < 100);
else a = 1;
if(PN == ORGANTIC || PN == ROTATEGUN )
cans = cansee(SX,SY,SZ,SECT,s->x,s->y,s->z-(32<<8),s->sectnum);
else cans = cansee(SX,SY,SZ-(32<<8),SECT,s->x,s->y,s->z-(32<<8),s->sectnum);
if( a && cans )
{
smax = sdist;
j = i;
}
}
}
}
}
return j;
}
void shoot(short i,short atwith)
{
short sect, hitsect, hitspr, hitwall, l, sa, p, j, k, scount;
long sx, sy, sz, vel, zvel, hitx, hity, hitz, x, oldzvel, dal;
unsigned char sizx,sizy;
spritetype *s;
s = &sprite[i];
sect = s->sectnum;
zvel = 0;
if( s->picnum == APLAYER )
{
p = s->yvel;
sx = ps[p].posx;
sy = ps[p].posy;
sz = ps[p].posz+ps[p].pyoff+(4<<8);
sa = ps[p].ang;
ps[p].crack_time = 777;
}
else
{
p = -1;
sa = s->ang;
sx = s->x;
sy = s->y;
sz = s->z-((s->yrepeat*tilesizy[s->picnum])<<1)+(4<<8);
if(s->picnum != ROTATEGUN)
{
sz -= (7<<8);
if(badguy(s) && PN != COMMANDER)
{
sx += (sintable[(sa+1024+96)&2047]>>7);
sy += (sintable[(sa+512+96)&2047]>>7);
}
}
}
switch(atwith)
{
case BLOODSPLAT1:
case BLOODSPLAT2:
case BLOODSPLAT3:
case BLOODSPLAT4:
if(p >= 0)
sa += 64 - (TRAND&127);
else sa += 1024 + 64 - (TRAND&127);
zvel = 1024-(TRAND&2047);
case KNEE:
if(atwith == KNEE )
{
if(p >= 0)
{
zvel = (100-ps[p].horiz-ps[p].horizoff)<<5;
sz += (6<<8);
sa += 15;
}
else
{
j = ps[findplayer(s,&x)].i;
zvel = ( (sprite[j].z-sz)<<8 ) / (x+1);
sa = getangle(sprite[j].x-sx,sprite[j].y-sy);
}
}
// writestring(sx,sy,sz,sect,sintable[(sa+512)&2047],sintable[sa&2047],zvel<<6);
hitscan(sx,sy,sz,sect,
sintable[(sa+512)&2047],
sintable[sa&2047],zvel<<6,
&hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1);
if( atwith == BLOODSPLAT1 ||
atwith == BLOODSPLAT2 ||
atwith == BLOODSPLAT3 ||
atwith == BLOODSPLAT4 )
{
if( FindDistance2D(sx-hitx,sy-hity) < 1024 )
if( hitwall >= 0 && wall[hitwall].overpicnum != BIGFORCE )
if( ( wall[hitwall].nextsector >= 0 && hitsect >= 0 &&
sector[wall[hitwall].nextsector].lotag == 0 &&
sector[hitsect].lotag == 0 &&
sector[wall[hitwall].nextsector].lotag == 0 &&
(sector[hitsect].floorz-sector[wall[hitwall].nextsector].floorz) > (16<<8) ) ||
( wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0 ) )
if( (wall[hitwall].cstat&16) == 0)
{
if(wall[hitwall].nextsector >= 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -