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

📄 p_map.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 5 页
字号:
             && tmceilingz - thing->z < thing->height             && !(thing->flags2&MF2_FLY))        {            CheckMissileImpact(thing);            return false;       // mobj must lower itself to fit        }        if(thing->flags2&MF2_FLY)        {            if(thing->z+thing->height > tmceilingz)            {                thing->momz = -8*FRACUNIT;                return false;            }            else if(thing->z < tmfloorz && tmfloorz-tmdropoffz > 24*FRACUNIT)            {                thing->momz = 8*FRACUNIT;                return false;            }        }        // jump out of water        if((thing->eflags & (MF_UNDERWATER|MF_TOUCHWATER))==(MF_UNDERWATER|MF_TOUCHWATER))            maxstep=37*FRACUNIT;        if ( !(thing->flags & MF_TELEPORT)              // The Minotaur floor fire (MT_MNTRFX2) can step up any amount             && thing->type != MT_MNTRFX2             && (tmfloorz - thing->z > maxstep ) )        {            CheckMissileImpact(thing);            return false;       // too big a step up        }        if((thing->flags&MF_MISSILE) && tmfloorz > thing->z)            CheckMissileImpact(thing);        if ( !boomsupport || !allowdropoff)          if ( !(thing->flags&(MF_DROPOFF|MF_FLOAT))               && !tmfloorthing               && tmfloorz - tmdropoffz > MAXSTEPMOVE )              return false;       // don't stand over a dropoff    }    // the move is ok,    // so link the thing into its new position    P_UnsetThingPosition (thing);    //added:28-02-98: gameplay hack : walk over a small wall while jumping    //                stop jumping it succeeded    // BP: removed in 1.28 because we can move in air now    if ( demoplayback>=112 && demoplayback<128 && thing->player &&         (thing->player->cheats & CF_JUMPOVER) )    {        if (tmfloorz > thing->floorz + MAXSTEPMOVE)            thing->momz >>= 2;    }    oldx = thing->x;    oldy = thing->y;    thing->floorz = tmfloorz;    thing->ceilingz = tmceilingz;    thing->x = x;    thing->y = y;    //added:28-02-98:    if (tmfloorthing)        thing->eflags &= ~MF_ONGROUND;  //not on real floor    else        thing->eflags |= MF_ONGROUND;    P_SetThingPosition (thing);    if (thing->flags2 & MF2_FOOTCLIP        && P_GetThingFloorType (thing) != FLOOR_SOLID && gamemode == heretic )        thing->flags2 |= MF2_FEETARECLIPPED;    else if (thing->flags2 & MF2_FEETARECLIPPED)          thing->flags2 &= ~MF2_FEETARECLIPPED;    // if any special lines were hit, do the effect    if ( !(thing->flags&(MF_TELEPORT|MF_NOCLIP)) &&         (thing->type != MT_CHASECAM) && (thing->type != MT_SPIRIT))    {        while (numspechit--)        {            // see if the line was crossed            ld = lines + spechit[numspechit];            side = P_PointOnLineSide (thing->x, thing->y, ld);            oldside = P_PointOnLineSide (oldx, oldy, ld);            if (side != oldside)            {                if (ld->special)                    P_CrossSpecialLine (ld-lines, oldside, thing);            }        }    }    return true;}//// P_ThingHeightClip// Takes a valid thing and adjusts the thing->floorz,// thing->ceilingz, and possibly thing->z.// This is called for all nearby monsters// whenever a sector changes height.// If the thing doesn't fit,// the z will be set to the lowest value// and false will be returned.//boolean P_ThingHeightClip (mobj_t* thing){    boolean             onfloor;    onfloor = (thing->z <= thing->floorz);    P_CheckPosition (thing, thing->x, thing->y);    // what about stranding a monster partially off an edge?    thing->floorz = tmfloorz;    thing->ceilingz = tmceilingz;    if (!tmfloorthing && onfloor)    {        // walking monsters rise and fall with the floor        thing->z = thing->floorz;    }    else    {        // don't adjust a floating monster unless forced to        //added:18-04-98:test onfloor        if (!onfloor)                    //was tmsectorceilingz            if (thing->z+thing->height > tmceilingz)                thing->z = thing->ceilingz - thing->height;        //thing->eflags &= ~MF_ONGROUND;    }    //debug : be sure it falls to the floor    thing->eflags &= ~MF_ONGROUND;    //added:28-02-98:    // test sector bouding top & bottom, not things    //if (tmsectorceilingz - tmsectorfloorz < thing->height)    //    return false;    if (thing->ceilingz - thing->floorz < thing->height)        return false;    return true;}//// SLIDE MOVE// Allows the player to slide along any angled walls.//fixed_t         bestslidefrac;fixed_t         secondslidefrac;line_t*         bestslideline;line_t*         secondslideline;mobj_t*         slidemo;fixed_t         tmxmove;fixed_t         tmymove;//// P_HitSlideLine// Adjusts the xmove / ymove// so that the next move will slide along the wall.//void P_HitSlideLine (line_t* ld){    int                 side;    angle_t             lineangle;    angle_t             moveangle;    angle_t             deltaangle;    fixed_t             movelen;    fixed_t             newlen;    if (ld->slopetype == ST_HORIZONTAL)    {        tmymove = 0;        return;    }    if (ld->slopetype == ST_VERTICAL)    {        tmxmove = 0;        return;    }    side = P_PointOnLineSide (slidemo->x, slidemo->y, ld);    lineangle = R_PointToAngle2 (0,0, ld->dx, ld->dy);    if (side == 1)        lineangle += ANG180;    moveangle = R_PointToAngle2 (0,0, tmxmove, tmymove);    deltaangle = moveangle-lineangle;    if (deltaangle > ANG180)        deltaangle += ANG180;    //  I_Error ("SlideLine: ang>ANG180");    lineangle >>= ANGLETOFINESHIFT;    deltaangle >>= ANGLETOFINESHIFT;    movelen = P_AproxDistance (tmxmove, tmymove);    newlen = FixedMul (movelen, finecosine[deltaangle]);    tmxmove = FixedMul (newlen, finecosine[lineangle]);    tmymove = FixedMul (newlen, finesine[lineangle]);}//// PTR_SlideTraverse//boolean PTR_SlideTraverse (intercept_t* in){    line_t*     li;#ifdef PARANOIA    if (!in->isaline)        I_Error ("PTR_SlideTraverse: not a line?");#endif    li = in->d.line;    if ( ! (li->flags & ML_TWOSIDED) )    {        if (P_PointOnLineSide (slidemo->x, slidemo->y, li))        {            // don't hit the back side            return true;        }        goto isblocking;    }    // set openrange, opentop, openbottom    P_LineOpening (li);    if (openrange < slidemo->height)        goto isblocking;                // doesn't fit    if (opentop - slidemo->z < slidemo->height)        goto isblocking;                // mobj is too high    if (openbottom - slidemo->z > 24*FRACUNIT )        goto isblocking;                // too big a step up    // this line doesn't block movement    return true;    // the line does block movement,    // see if it is closer than best so far  isblocking:    // SoM: Add code here for checking portals and subsiquent portal lines..    if(li->wallportals)    {      wallportal_t*   wpr;      for(wpr = li->wallportals; wpr; wpr = wpr->next)        if(slidemo->z >= *wpr->bottomheight && slidemo->z + slidemo->height <= *wpr->topheight)          break;      if(wpr)        return true;    }    if (in->frac < bestslidefrac)    {        secondslidefrac = bestslidefrac;        secondslideline = bestslideline;        bestslidefrac = in->frac;        bestslideline = li;    }    return false;       // stop}//// P_SlideMove// The momx / momy move is bad, so try to slide// along a wall.// Find the first line hit, move flush to it,// and slide along it//// This is a kludgy mess.//void P_SlideMove (mobj_t* mo){    fixed_t             leadx;    fixed_t             leady;    fixed_t             trailx;    fixed_t             traily;    fixed_t             newx;    fixed_t             newy;    int                 hitcount;    slidemo = mo;    hitcount = 0;  retry:    if (++hitcount == 3)        goto stairstep;         // don't loop forever    // trace along the three leading corners    if (mo->momx > 0)    {        leadx = mo->x + mo->radius;        trailx = mo->x - mo->radius;    }    else    {        leadx = mo->x - mo->radius;        trailx = mo->x + mo->radius;    }    if (mo->momy > 0)    {        leady = mo->y + mo->radius;        traily = mo->y - mo->radius;    }    else    {        leady = mo->y - mo->radius;        traily = mo->y + mo->radius;    }    bestslidefrac = FRACUNIT+1;    P_PathTraverse ( leadx, leady, leadx+mo->momx, leady+mo->momy,                     PT_ADDLINES, PTR_SlideTraverse );    P_PathTraverse ( trailx, leady, trailx+mo->momx, leady+mo->momy,                     PT_ADDLINES, PTR_SlideTraverse );    P_PathTraverse ( leadx, traily, leadx+mo->momx, traily+mo->momy,                     PT_ADDLINES, PTR_SlideTraverse );    // move up to the wall    if (bestslidefrac == FRACUNIT+1)    {        // the move most have hit the middle, so stairstep      stairstep:        if (!P_TryMove (mo, mo->x, mo->y + mo->momy, true)) //SoM: 4/10/2000            P_TryMove (mo, mo->x + mo->momx, mo->y, true);  //Allow things to        return;                                             //drop off.    }    // fudge a bit to make sure it doesn't hit    bestslidefrac -= 0x800;    if (bestslidefrac > 0)    {        newx = FixedMul (mo->momx, bestslidefrac);        newy = FixedMul (mo->momy, bestslidefrac);        if (!P_TryMove (mo, mo->x+newx, mo->y+newy, true))            goto stairstep;    }    // Now continue along the wall.    // First calculate remainder.    bestslidefrac = FRACUNIT-(bestslidefrac+0x800);    if (bestslidefrac > FRACUNIT)        bestslidefrac = FRACUNIT;    if (bestslidefrac <= 0)        return;    tmxmove = FixedMul (mo->momx, bestslidefrac);    tmymove = FixedMul (mo->momy, bestslidefrac);    P_HitSlideLine (bestslideline);     // clip the moves    mo->momx = tmxmove;    mo->momy = tmymove;    if (!P_TryMove (mo, mo->x+tmxmove, mo->y+tmymove, true))    {        goto retry;    }}//// P_LineAttack//mobj_t*         linetarget;     // who got hit (or NULL)mobj_t*         shootthing;// Height if not aiming up or down// ???: use slope for monsters?fixed_t         shootz;fixed_t         lastz; //SoM: The last z height of the bullet when it crossed a lineint             la_damage;fixed_t         attackrange;fixed_t         aimslope;//// PTR_AimTraverse// Sets linetarget and aimslope when a target is aimed at.////added:15-02-98: comment// Returns true if the thing is not shootable, else continue through..//boolean PTR_AimTraverse (intercept_t* in){    line_t*             li;    mobj_t*             th;    fixed_t             slope;    fixed_t             thingtopslope;    fixed_t             thingbottomslope;    fixed_t             dist;    int                 dir;    if (in->isaline)    {        li = in->d.line;        if ( !(li->flags & ML_TWOSIDED) )            return false;               // stop        // Crosses a two sided line.        // A two sided line will restrict        // the possible target ranges.        tmthing = NULL;        P_LineOpening (li);        if (openbottom >= opentop)            return false;               // stop        dist = FixedMul (attackrange, in->frac);        if (li->frontsector->floorheight != li->backsector->floorheight)        {            slope = FixedDiv (openbottom - shootz , dist);            if (slope > bottomslope)                bottomslope = slope;        }        if (li->frontsector->ceilingheight != li->backsector->ceilingheight)        {            slope = FixedDiv (opentop - shootz , dist);            if (slope < topslope)

⌨️ 快捷键说明

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