⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 player.c

📁 game duke3d source
💻 C
📖 第 1 页 / 共 5 页
字号:
//-------------------------------------------------------------------------
/*
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,&sect);
          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,&sect,&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,&sect,&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,&sect,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,&sect,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 + -