// // P_FakeZMovement // void P_FakeZMovement (mobj_t *mo) { // adjust height mo->z += mo->momz; if ((mo->flags & MF_FLOAT) && mo->target) { // float down towards target if too close if (!(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT)) { fixed_t delta = (mo->target->z + (mo->height >> 1) - mo->z) * 3; if (P_ApproxDistance(mo->x - mo->target->x, mo->y - mo->target->y) < ABS(delta)) mo->z += (delta < 0 ? -FLOATSPEED : FLOATSPEED); } }
// // P_WallMomSlide // Adjusts the xmove / ymove // so that the next move will slide along the wall. // static void P_WallMomSlide(line_t *ld) { int side; angle_t lineangle; angle_t moveangle; angle_t deltaangle; fixed_t movelen; fixed_t newlen; // First check the simple cases. 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; lineangle >>= ANGLETOFINESHIFT; deltaangle >>= ANGLETOFINESHIFT; movelen = P_ApproxDistance(tmxmove, tmymove); newlen = FixedMul(movelen, finecosine[deltaangle]); tmxmove = FixedMul(newlen, finecosine[lineangle]); tmymove = FixedMul(newlen, finesine[lineangle]); }
// // PIT_CheckThing // boolean PIT_CheckThing (mobj_t* thing) { fixed_t newdist; fixed_t olddist; fixed_t blockdist; int flags; int damage; int tradius; flags = thing->flags; if (!(flags & (MF_SOLID|MF_SPECIAL|MF_MISSILE|MF_SHOOTABLE) )) return true; /* We've changed all of the MF_SPECIAL stuff to their */ /* actual radius rather than all being 20*FRACUNIT but */ /* we want the original size back again when picking up. */ // if (flags & MF_SPECIAL) tradius = thing->info->pickupradius; // else // tradius = thing->radius; blockdist = tradius + tmthing->radius; if ( abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist ) { // didn't hit it return true; } // don't clip against self if (thing == tmthing) return true; if (flags & MF_MISSILE) { if (!tmthing->player) P_ExplodeMissile (thing); if (!(flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE) )) return (true); } // check if a mobj passed over/under another object if (tmthing->flags2 & MF2_PASSMOBJ) { if (tmthing->z >= thing->z + thing->height) return true; // over thing else if (tmthing->z + tmthing->height <= thing->z) return true; // under thing } // check for skulls slamming into things if (tmthing->flags & MF_SKULLFLY) { damage = ((P_Random()%8)+1)*tmthing->info->damage; P_DamageMobj (thing, tmthing, tmthing, damage); tmthing->flags &= ~MF_SKULLFLY; tmthing->momx = tmthing->momy = tmthing->momz = 0; P_SetMobjState (tmthing, (statenum_t) tmthing->info->spawnstate); return false; // stop moving } // missiles can hit other things if (tmthing->flags & MF_MISSILE) { // see if it went over / under if (tmthing->z > thing->z + thing->height) return true; // overhead if (tmthing->z+tmthing->height < thing->z) return true; // underneath if (tmthing->target && ( tmthing->target->type == thing->type || (tmthing->target->type == MT_KNIGHT && thing->type == MT_BRUISER)|| (tmthing->target->type == MT_BRUISER && thing->type == MT_KNIGHT) ) ) { // Don't hit same species as originator. if (thing == tmthing->target) return true; if ((thing->type != MT_PLAYER) && (Monsters_Infight1 == false) && (Monsters_Infight2 == false)) { // Explode, but do no damage. // Let players missile other players. return false; } } if (! (flags & MF_SHOOTABLE) ) { // didn't do any damage return (boolean)!(flags & MF_SOLID); } // damage / explode damage = ((P_Random()%8)+1)*tmthing->info->damage; P_DamageMobj (thing, tmthing, tmthing->target, damage); // don't traverse any more return false; } // check for special pickup if (flags & MF_SPECIAL) { if (tmflags & MF_PICKUP) { // can remove thing P_TouchSpecialThing (thing, tmthing); } return (boolean)!(flags & MF_SOLID); } // [BH] don't hit if either thing is a corpse, which may still be solid if // they are still going through their death sequence. if ((flags & MF_CORPSE) || (tmthing->flags & MF_CORPSE)) return true; // check if things are stuck and allow move if it makes them further apart if ((tmx == tmthing->x) && (tmy == tmthing->y)) return true; newdist = P_ApproxDistance(thing->x - tmx, thing->y - tmy); olddist = P_ApproxDistance(thing->x - tmthing->x, thing->y - tmthing->y); if ((newdist > olddist) && (!((tmthing->z >= thing->z + thing->height) || (tmthing->z + tmthing->height <= thing->z)))) return true; // killough 3/16/98: Allow non-solid moving objects to move through solid // ones, by allowing the moving thing (tmthing) to move if it's non-solid, // despite another solid thing being in the way. // killough 4/11/98: Treat no-clipping things as not blocking return (boolean)!((flags & MF_SOLID) && !(flags & MF_NOCLIP) && (tmthing->flags & MF_SOLID)); }
//=========================================================================== // PIT_CheckThing //=========================================================================== static boolean PIT_CheckThing(mobj_t *thing, void *parm) { checkpos_data_t *tm = parm; fixed_t blockdist; boolean overlap = false; // don't clip against self if(thing == tm->thing) return true; if(!(thing->ddflags & DDMF_SOLID)) return true; blockdist = thing->radius + tm->thing->radius; // Only players can move under or over other things. if(tm->z != DDMAXINT && (tm->thing->dplayer /* || thing->dplayer */ || thing->ddflags & DDMF_NOGRAVITY)) { if(thing->z > tm->z + tm->height) { // We're under it. return true; } else if(thing->z + thing->height < tm->z) { // We're over it. return true; } overlap = true; } if(abs(thing->x - tm->x) >= blockdist || abs(thing->y - tm->y) >= blockdist) { // Didn't hit it. return true; } if(overlap) { // How are we positioned? if(tm->z >= thing->z + thing->height - 24 * FRACUNIT) { // Above, allowing stepup. tm->thing->onmobj = thing; tm->floorz = thing->z + thing->height; return true; } // To prevent getting stuck, don't block if moving away from // the object. if(tm->thing->dplayer && P_ApproxDistance(tm->thing->x - thing->x, tm->thing->y - thing->y) < P_ApproxDistance(tm->x - thing->x, tm->y - thing->y) && tm->thing->momz > -12 * FRACUNIT) { // The current distance is smaller than the new one would be. // No blocking needs to occur. // The Z movement test is done to prevent a 'falling through' // case when a thing is moving at a high speed. return true; } // We're hitting this mobj. blockingMobj = thing; } return false; }