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

📄 p_map.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 5 页
字号:
    fixed_t     y2;#ifdef PARANOIA    if(!t1)       I_Error("P_aimlineattack: mobj == NULL !!!");#endif    angle >>= ANGLETOFINESHIFT;    shootthing = t1;    if(t1->player && demoversion>=128)    {        fixed_t cosineaiming=finecosine[t1->player->aiming>>ANGLETOFINESHIFT];        int aiming=((int)t1->player->aiming)>>ANGLETOFINESHIFT;        x2 = t1->x + FixedMul(FixedMul(distance,finecosine[angle]),cosineaiming);        y2 = t1->y + FixedMul(FixedMul(distance,finesine[angle]),cosineaiming);         topslope    =  100*FRACUNIT/160+finetangent[(2048+aiming) & FINEMASK];        bottomslope = -100*FRACUNIT/160+finetangent[(2048+aiming) & FINEMASK];    }    else    {        x2 = t1->x + (distance>>FRACBITS)*finecosine[angle];        y2 = t1->y + (distance>>FRACBITS)*finesine[angle];        //added:15-02-98: Fab comments...        // Doom's base engine says that at a distance of 160,        // the 2d graphics on the plane x,y correspond 1/1 with plane units        topslope = 100*FRACUNIT/160;        bottomslope = -100*FRACUNIT/160;    }    shootz = lastz = t1->z + (t1->height>>1) + 8*FRACUNIT;    // can't shoot outside view angles    attackrange = distance;    linetarget = NULL;    //added:15-02-98: comments    // traverse all linedefs and mobjs from the blockmap containing t1,    // to the blockmap containing the dest. point.    // Call the function for each mobj/line on the way,    // starting with the mobj/linedef at the shortest distance...    P_PathTraverse ( t1->x, t1->y,                     x2, y2,                     PT_ADDLINES|PT_ADDTHINGS,                     PTR_AimTraverse );    //added:15-02-98: linetarget is only for mobjs, not for linedefs    if (linetarget)        return aimslope;    return 0;}//// P_LineAttack// If damage == 0, it is just a test trace// that will leave linetarget set.////added:16-02-98: Fab comments...//                t1       est l'attaquant (player ou monstre)//                angle    est l'angle de tir sur le plan x,y (orientation)//                distance est la port閑 maximale de la balle//                slope    est la pente vers la destination (up/down)//                damage   est les degats infliges par la ballevoid P_LineAttack ( mobj_t*       t1,                    angle_t       angle,                    fixed_t       distance,                    fixed_t       slope,                    int           damage ){    fixed_t     x2;    fixed_t     y2;    angle >>= ANGLETOFINESHIFT;    shootthing = t1;    la_damage = damage;    // player autoaimed attack,     if(demoversion<128 || !t1->player)    {           x2 = t1->x + (distance>>FRACBITS)*finecosine[angle];         y2 = t1->y + (distance>>FRACBITS)*finesine[angle];       }    else    {        fixed_t cosangle=finecosine[t1->player->aiming>>ANGLETOFINESHIFT];        x2 = t1->x + FixedMul(FixedMul(distance,finecosine[angle]),cosangle);        y2 = t1->y + FixedMul(FixedMul(distance,finesine[angle]),cosangle);     }    shootz = lastz = t1->z + (t1->height>>1) + 8*FRACUNIT;    if (t1->flags2 & MF2_FEETARECLIPPED)        shootz -= FOOTCLIPSIZE;    attackrange = distance;    aimslope = slope;    tmthing = shootthing;    P_PathTraverse ( t1->x, t1->y,                     x2, y2,                     PT_ADDLINES|PT_ADDTHINGS,                     PTR_ShootTraverse );}//// USE LINES//mobj_t*         usething;boolean PTR_UseTraverse (intercept_t* in){    int         side;    tmthing = NULL;    if (!in->d.line->special)    {        P_LineOpening (in->d.line);        if (openrange <= 0)        {            if( gamemode != heretic )                S_StartSound (usething, sfx_noway);            // can't use through a wall            return false;        }        // not a special line, but keep checking        return true ;    }    side = 0;    if (P_PointOnLineSide (usething->x, usething->y, in->d.line) == 1)        side = 1;    //  return false;           // don't use back side    P_UseSpecialLine (usething, in->d.line, side);    // can't use for than one special line in a row    // SoM: USE MORE THAN ONE!    if(boomsupport && (in->d.line->flags&ML_PASSUSE))      return true;    else      return false;}//// P_UseLines// Looks for special lines in front of the player to activate.//void P_UseLines (player_t*      player){    int         angle;    fixed_t     x1;    fixed_t     y1;    fixed_t     x2;    fixed_t     y2;    usething = player->mo;    angle = player->mo->angle >> ANGLETOFINESHIFT;    x1 = player->mo->x;    y1 = player->mo->y;    x2 = x1 + (USERANGE>>FRACBITS)*finecosine[angle];    y2 = y1 + (USERANGE>>FRACBITS)*finesine[angle];    P_PathTraverse ( x1, y1, x2, y2, PT_ADDLINES, PTR_UseTraverse );}//// RADIUS ATTACK//mobj_t*         bombsource;mobj_t*         bombspot;int             bombdamage;//// PIT_RadiusAttack// "bombsource" is the creature// that caused the explosion at "bombspot".//boolean PIT_RadiusAttack (mobj_t* thing){    fixed_t     dx;    fixed_t     dy;    fixed_t     dz;    fixed_t     dist;    if (!(thing->flags & MF_SHOOTABLE) )        return true;    // Boss spider and cyborg    // take no damage from concussion.    if (thing->type == MT_CYBORG        || thing->type == MT_SPIDER        || thing->type == MT_MINOTAUR         || thing->type == MT_SORCERER1        || thing->type == MT_SORCERER2)        return true;    dx = abs(thing->x - bombspot->x);    dy = abs(thing->y - bombspot->y);    dist = dx>dy ? dx : dy;    dist -= thing->radius;    //added:22-02-98: now checks also z dist for rockets exploding    //                above yer head...    if (demoversion>=112)    {        dz = abs(thing->z+(thing->height>>1) - bombspot->z);        dist = dist > dz ? dist : dz;    }    dist >>= FRACBITS;    if (dist < 0)        dist = 0;    if (dist >= bombdamage)        return true;    // out of range    if (thing->floorz > bombspot->z && bombspot->ceilingz < thing->z)        return true;    if (thing->ceilingz < bombspot->z && bombspot->floorz > thing->z)        return true;    if ( P_CheckSight (thing, bombspot) )    {        int  damage=bombdamage - dist;        int  momx=0,momy=0;        if( dist )        {            momx = (thing->x - bombspot->x)/dist;            momy = (thing->y - bombspot->y)/dist;        }        // must be in direct path        if( P_DamageMobj (thing, bombspot, bombsource, damage) && (thing->flags & MF_NOBLOOD)==0 && demoversion>=129 )            P_SpawnBloodSplats (thing->x,thing->y,thing->z, damage, momx, momy);    }    return true;}//// P_RadiusAttack// Source is the creature that caused the explosion at spot.//void P_RadiusAttack ( mobj_t*       spot,                      mobj_t*       source,                      int           damage ){    int         x;    int         y;    int         xl;    int         xh;    int         yl;    int         yh;    fixed_t     dist;    dist = (damage+MAXRADIUS)<<FRACBITS;    yh = (spot->y + dist - bmaporgy)>>MAPBLOCKSHIFT;    yl = (spot->y - dist - bmaporgy)>>MAPBLOCKSHIFT;    xh = (spot->x + dist - bmaporgx)>>MAPBLOCKSHIFT;    xl = (spot->x - dist - bmaporgx)>>MAPBLOCKSHIFT;    bombspot = spot;    if (spot->type == MT_POD && spot->target)        bombsource = spot->target;    else        bombsource = source;    bombdamage = damage;    for (y=yl ; y<=yh ; y++)        for (x=xl ; x<=xh ; x++)            P_BlockThingsIterator (x, y, PIT_RadiusAttack );}//// SECTOR HEIGHT CHANGING// After modifying a sectors floor or ceiling height,// call this routine to adjust the positions// of all things that touch the sector.//// If anything doesn't fit anymore, true will be returned.// If crunch is true, they will take damage//  as they are being crushed.// If Crunch is false, you should set the sector height back//  the way it was and call P_ChangeSector again//  to undo the changes.//boolean         crushchange;boolean         nofit;sector_t        *sectorchecked;//// PIT_ChangeSector//boolean PIT_ChangeSector (mobj_t*       thing){    mobj_t*     mo;    if (P_ThingHeightClip (thing))    {        // keep checking        return true;    }    // crunch bodies to giblets    if (thing->health <= 0)    {        if( gamemode != heretic )        {            P_SetMobjState (thing, S_GIBS);            thing->flags &= ~MF_SOLID;            //added:22-02-98: lets have a neat 'crunch' sound!            S_StartSound (thing, sfx_slop);            thing->skin = 0;        }        thing->height = 0;        thing->radius = 0;        thing->skin = 0;        //added:22-02-98: lets have a neat 'crunch' sound!        S_StartSound (thing, sfx_slop);        // keep checking        return true;    }    // crunch dropped items    if (thing->flags & MF_DROPPED)    {        P_RemoveMobj (thing);        // keep checking        return true;    }    if (! (thing->flags & MF_SHOOTABLE) )    {        // assume it is bloody gibs or something        return true;    }    nofit = true;    if (crushchange && !(leveltime % (4*NEWTICRATERATIO)) )    {        P_DamageMobj(thing,NULL,NULL,10);        if( demoversion<132 || (!(leveltime % (16*NEWTICRATERATIO)) &&                                 !(thing->flags&MF_NOBLOOD)) )        {            // spray blood in a random direction            mo = P_SpawnMobj (thing->x,                              thing->y,                              thing->z + thing->height/2, MT_BLOOD);                        mo->momx  = P_SignedRandom()<<12;            mo->momy  = P_SignedRandom()<<12;        }    }    // keep checking (crush other things)    return true;}//// P_ChangeSector//boolean P_ChangeSector ( sector_t*     sector,                         boolean       crunch ){    int         x;    int         y;    nofit = false;    crushchange = crunch;    sectorchecked = sector;    // re-check heights for all things near the moving sector    for (x=sector->blockbox[BOXLEFT] ; x<= sector->blockbox[BOXRIGHT] ; x++)        for (y=sector->blockbox[BOXBOTTOM];y<= sector->blockbox[BOXTOP] ; y++)            P_BlockThingsIterator (x, y, PIT_ChangeSector);    return nofit;}//SoM: 3/15/2000: New function. Much faster.boolean P_CheckSector(sector_t* sector, boolean crunch){  msecnode_t      *n;  if (!boomsupport) // use the old routine for old demos though    return P_ChangeSector(sector,crunch);  nofit = false;  crushchange = crunch;  // killough 4/4/98: scan list front-to-back until empty or exhausted,  // restarting from beginning after each thing is processed. Avoids  // crashes, and is sure to examine all things in the sector, and only  // the things which are in the sector, until a steady-state is reached.  // Things can arbitrarily be inserted and removed and it won't mess up.  //  // killough 4/7/98: simplified to avoid using complicated counter  if(sector->numattached)  {    int            i;    sector_t*      sec;    for(i = 0; i < sector->numattached; i ++)    {      sec = &sectors[sector->attached[i]];      for (n=sec->touching_thinglist; n; n=n->m_snext)        n->visited = false;      sec->moved = true;      do {      for (n=sec->touching_thinglist; n; n=n->m_snext)        if (!n->visited)          {          n->visited  = true;          if (!(n->m_thing->flags & MF_NOBLOCKMAP))            PIT_ChangeSector(n->m_thing);          break;          }      } while (n);    }  }  // Mark all things invalid  sector->moved = true;  for (n=sector->touching_thinglist; n; n=n->m_snext)      n->visited = false;    do {      for (n=sector->touchi

⌨️ 快捷键说明

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