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

📄 p_map.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 5 页
字号:
                topslope = slope;        }        if (topslope <= bottomslope)            return false;               // stop        if(li->frontsector->ffloors || li->backsector->ffloors)        {          int  frontflag;          dir = aimslope > 0 ? 1 : aimslope < 0 ? -1 : 0;          frontflag = P_PointOnLineSide(shootthing->x, shootthing->y, li);          //SoM: Check 3D FLOORS!          if(li->frontsector->ffloors)          {            ffloor_t*  rover = li->frontsector->ffloors;            fixed_t    highslope, lowslope;            for(; rover; rover = rover->next)            {              if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;              highslope = FixedDiv (*rover->topheight - shootz, dist);              lowslope = FixedDiv (*rover->bottomheight - shootz, dist);              if((aimslope >= lowslope && aimslope <= highslope))                return false;              if(lastz > *rover->topheight && dir == -1 && aimslope < highslope)                frontflag |= 0x2;              if(lastz < *rover->bottomheight && dir == 1 && aimslope > lowslope)                frontflag |= 0x2;            }          }          if(li->backsector->ffloors)          {            ffloor_t*  rover = li->backsector->ffloors;            fixed_t    highslope, lowslope;            for(; rover; rover = rover->next)            {              if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;              highslope = FixedDiv (*rover->topheight - shootz, dist);              lowslope = FixedDiv (*rover->bottomheight - shootz, dist);              if((aimslope >= lowslope && aimslope <= highslope))                return false;              if(lastz > *rover->topheight && dir == -1 && aimslope < highslope)                frontflag |= 0x4;              if(lastz < *rover->bottomheight && dir == 1 && aimslope > lowslope)                frontflag |= 0x4;            }          }          if((!(frontflag & 0x1) && frontflag & 0x2) || (frontflag & 0x1 && frontflag & 0x4))            return false;        }        lastz = FixedMul (aimslope, dist) + shootz;        return true;                    // shot continues    }    // shoot a thing    th = in->d.thing;    if (th == shootthing)        return true;                    // can't shoot self    if ( (!(th->flags&MF_SHOOTABLE)) || (th->flags&MF_CORPSE) || (th->type == MT_POD))        return true;                    // corpse or something    // check angles to see if the thing can be aimed at    dist = FixedMul (attackrange, in->frac);    thingtopslope = FixedDiv (th->z+th->height - shootz , dist);    //added:15-02-98: bottomslope is negative!    if (thingtopslope < bottomslope)        return true;                    // shot over the thing    thingbottomslope = FixedDiv (th->z - shootz, dist);    if (thingbottomslope > topslope)        return true;                    // shot under the thing    // this thing can be hit!    if (thingtopslope > topslope)        thingtopslope = topslope;    if (thingbottomslope < bottomslope)        thingbottomslope = bottomslope;    //added:15-02-98: find the slope just in the middle(y) of the thing!    aimslope = (thingtopslope+thingbottomslope)/2;    linetarget = th;    return false;                       // don't go any farther}//// PTR_ShootTraverse////added:18-02-98: added clipping the shots on the floor and ceiling.//boolean PTR_ShootTraverse (intercept_t* in){    fixed_t             x;    fixed_t             y;    fixed_t             z;    fixed_t             frac;    line_t*             li;    sector_t*           sector=NULL;    mobj_t*             th;    fixed_t             slope;    fixed_t             dist;    fixed_t             thingtopslope;    fixed_t             thingbottomslope;    fixed_t             floorz;  //SoM: Bullets should hit fake floors!    fixed_t             ceilingz;    //added:18-02-98:    fixed_t        distz;    //dist between hit z on wall       and gun z    fixed_t        clipz;    //dist between hit z on floor/ceil and gun z    boolean        hitplane;    //true if we clipped z on floor/ceil plane    boolean        diffheights; //check for sky hacks with different ceil heights    int            sectorside;    int            dir;    if(aimslope > 0)      dir = 1;    else if(aimslope < 0)      dir = -1;    else      dir = 0;    if (in->isaline)    {        //shut up compiler, otherwise it's only used when TWOSIDED        diffheights = false;        li = in->d.line;        if (li->special)            P_ShootSpecialLine (shootthing, li);        if ( !(li->flags & ML_TWOSIDED) )            goto hitline;        // crosses a two sided line        //added:16-02-98: Fab comments : sets opentop, openbottom, openrange        //                lowfloor is the height of the lowest floor        //                         (be it front or back)        tmthing = NULL;        P_LineOpening (li);        dist = FixedMul (attackrange, in->frac);        // hit lower texture ?        if (li->frontsector->floorheight != li->backsector->floorheight)        {            //added:18-02-98: comments :            // find the slope aiming on the border between the two floors            slope = FixedDiv (openbottom - shootz , dist);            if (slope > aimslope)                goto hitline;        }        // hit upper texture ?        if (li->frontsector->ceilingheight != li->backsector->ceilingheight)        {            //added:18-02-98: remember : diff ceil heights            diffheights = true;            slope = FixedDiv (opentop - shootz , dist);            if (slope < aimslope)                goto hitline;        }        if(li->frontsector->ffloors || li->backsector->ffloors)        {          int  frontflag;          frontflag = P_PointOnLineSide(shootthing->x, shootthing->y, li);          //SoM: Check 3D FLOORS!          if(li->frontsector->ffloors)          {            ffloor_t*  rover = li->frontsector->ffloors;            fixed_t    highslope, lowslope;            for(; rover; rover = rover->next)            {              if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;              highslope = FixedDiv (*rover->topheight - shootz, dist);              lowslope = FixedDiv (*rover->bottomheight - shootz, dist);              if((aimslope >= lowslope && aimslope <= highslope))                goto hitline;              if(lastz > *rover->topheight && dir == -1 && aimslope < highslope)                frontflag |= 0x2;              if(lastz < *rover->bottomheight && dir == 1 && aimslope > lowslope)                frontflag |= 0x2;            }          }          if(li->backsector->ffloors)          {            ffloor_t*  rover = li->backsector->ffloors;            fixed_t    highslope, lowslope;            for(; rover; rover = rover->next)            {              if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;              highslope = FixedDiv (*rover->topheight - shootz, dist);              lowslope = FixedDiv (*rover->bottomheight - shootz, dist);              if((aimslope >= lowslope && aimslope <= highslope))                goto hitline;              if(lastz > *rover->topheight && dir == -1 && aimslope < highslope)                frontflag |= 0x4;              if(lastz < *rover->bottomheight && dir == 1 && aimslope > lowslope)                frontflag |= 0x4;            }          }          if((!(frontflag & 0x1) && frontflag & 0x2) || (frontflag & 0x1 && frontflag & 0x4))            goto hitline;        }        lastz = FixedMul (aimslope, dist) + shootz;        // shot continues        return true;        // hit line      hitline:        // position a bit closer        frac = in->frac - FixedDiv (4*FRACUNIT,attackrange);        dist = FixedMul (frac, attackrange);    //dist to hit on line        distz = FixedMul (aimslope, dist);      //z add between gun z and hit z        z = shootz + distz;                     // hit z on wall        //added:17-02-98: clip shots on floor and ceiling        //                use a simple triangle stuff a/b = c/d ...        // BP:13-3-99: fix the side usage        hitplane = false;        sectorside=P_PointOnLineSide(shootthing->x,shootthing->y,li);        if( li->sidenum[sectorside] != -1 ) // can happen in nocliping mode        {            sector = sides[li->sidenum[sectorside]].sector;            floorz = sector->floorheight;            ceilingz = sector->ceilingheight;            if(sector->ffloors)            {              ffloor_t* rover;              for(rover = sector->ffloors; rover; rover = rover->next)              {                if(!(rover->flags & FF_SOLID)) continue;                if(dir == 1 && *rover->bottomheight < ceilingz && *rover->bottomheight > lastz)                  ceilingz = *rover->bottomheight;                if(dir == -1 && *rover->topheight > floorz && *rover->topheight < lastz)                  floorz = *rover->topheight;              }            }            if ((z > ceilingz) && distz)            {                clipz = ceilingz - shootz;                frac = FixedDiv( FixedMul(frac,clipz), distz );                hitplane = true;            }            else                if ((z < floorz) && distz)                {                    clipz = shootz - floorz;                    frac = -FixedDiv( FixedMul(frac,clipz), distz );                    hitplane = true;                }            if(sector->ffloors)            {                if(dir == 1 && z > ceilingz)                    z = ceilingz;                if(dir == -1 && z < floorz)                    z = floorz;            }        }        //SPLAT TEST ----------------------------------------------------------        #ifdef WALLSPLATS        if (!hitplane && demoversion>=129)        {            divline_t   divl;            fixed_t     frac;            P_MakeDivline (li, &divl);            frac = P_InterceptVector (&divl, &trace);            R_AddWallSplat (li, sectorside, "A_DMG1", z, frac, SPLATDRAWMODE_SHADE);        }        #endif        // --------------------------------------------------------- SPLAT TEST        x = trace.x + FixedMul (trace.dx, frac);        y = trace.y + FixedMul (trace.dy, frac);        if (li->frontsector->ceilingpic == skyflatnum)        {            // don't shoot the sky!            if (z > li->frontsector->ceilingheight)                return false;            //added:24-02-98: compatibility with older demos            if (demoversion<112)            {                diffheights = true;                hitplane = false;            }            // it's a sky hack wall            if  ((!hitplane &&      //added:18-02-98:not for shots on planes                 li->backsector &&                 diffheights &&    //added:18-02-98:skip only REAL sky hacks                                   //   eg: they use different ceil heights.                 li->backsector->ceilingpic == skyflatnum))              return false;        }        if(sector && sector->ffloors)        {          if(dir == 1 && z + (16 << FRACBITS) > ceilingz)            z = ceilingz - (16 << FRACBITS);          if(dir == -1 && z < floorz)            z = floorz;        }        // Spawn bullet puffs.        P_SpawnPuff (x,y,z);        // don't go any farther        return false;    }    // shoot a thing    th = in->d.thing;    if (th == shootthing)        return true;            // can't shoot self    if (!(th->flags&MF_SHOOTABLE))        return true;            // corpse or something// check for physical attacks on a ghost    if (gamemode == heretic && (th->flags & MF_SHADOW) && shootthing->player->readyweapon == wp_staff)        return true;    // check angles to see if the thing can be aimed at    dist = FixedMul (attackrange, in->frac);    thingtopslope = FixedDiv (th->z+th->height - shootz , dist);    if (thingtopslope < aimslope)        return true;            // shot over the thing    thingbottomslope = FixedDiv (th->z - shootz, dist);    if (thingbottomslope > aimslope)        return true;            // shot under the thing    // SoM: SO THIS IS THE PROBLEM!!!    // heh.    // A bullet would travel through a 3D floor until it hit a LINEDEF! Thus    // it appears that the bullet hits the 3D floor but it actually just hits    // the line behind it. Thus allowing a bullet to hit things under a 3D    // floor and still be clipped a 3D floor.    if(th->subsector->sector->ffloors)    {      sector_t* sector = th->subsector->sector;      ffloor_t* rover;      for(rover = sector->ffloors; rover; rover = rover->next)      {        if(!(rover->flags & FF_SOLID))          continue;        if(dir == -1 && *rover->topheight < lastz && *rover->topheight > th->z + th->height)          return true;        if(dir == 1 && *rover->bottomheight > lastz && *rover->bottomheight < th->z)          return true;      }    }    // hit thing    // position a bit closer    frac = in->frac - FixedDiv (10*FRACUNIT,attackrange);    x = trace.x + FixedMul (trace.dx, frac);    y = trace.y + FixedMul (trace.dy, frac);    z = shootz + FixedMul (aimslope, FixedMul(frac, attackrange));    if (demoversion<125)    {        // Spawn bullet puffs or blood spots,        // depending on target type.        if (in->d.thing->flags & MF_NOBLOOD)            P_SpawnPuff (x,y,z);        else            P_SpawnBlood (x,y,z, la_damage);    }    if (la_damage)        hitplane = P_DamageMobj (th, shootthing, shootthing, la_damage);    else        hitplane = false;    if (demoversion>=125)    {        // Spawn bullet puffs or blood spots,        // depending on target type.        if (in->d.thing->flags & MF_NOBLOOD && gamemode != heretic )            P_SpawnPuff (x,y,z);        else        {            if( gamemode == heretic )            {                if(PuffType == MT_BLASTERPUFF1)                  // Make blaster big puff                    S_StartSound(P_SpawnMobj(x, y, z, MT_BLASTERPUFF2), sfx_blshit);                else                    P_SpawnPuff(x, y, z);            }                if (hitplane) {                P_SpawnBloodSplats (x,y,z, la_damage, trace.dx, trace.dy);                return false;            }        }    }    // don't go any farther    return false;}//// P_AimLineAttack//fixed_t P_AimLineAttack ( mobj_t*       t1,                          angle_t       angle,                          fixed_t       distance ){    fixed_t     x2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -