int P_PathXYTraverse(coord_t fromX, coord_t fromY, coord_t toX, coord_t toY, traverser_t callback, void *context) { vec2d_t from = { fromX, fromY }; vec2d_t to = { toX, toY }; return P_PathTraverse(from, to, callback, context); }
static void P_GetChasecamTarget() { int aimfor; subsector_t *ss; int ceilingheight, floorheight; // aimfor is the preferred height of the chasecam above // the player // haleyjd: 1 unit for each degree of pitch works surprisingly well aimfor = players[displayplayer].viewheight + chasecam_height*FRACUNIT + FixedDiv(players[displayplayer].pitch, ANGLE_1); trace.sin = finesine[playerangle>>ANGLETOFINESHIFT]; trace.cos = finecosine[playerangle>>ANGLETOFINESHIFT]; targetx = playermobj->x - chasecam_dist * trace.cos; targety = playermobj->y - chasecam_dist * trace.sin; targetz = playermobj->z + aimfor; #ifdef R_LINKEDPORTALS targetgroupid = playermobj->groupid; #endif // the intersections test mucks up the first time, but // aiming at something seems to cure it // ioanch 20160101: don't let P_AimLineAttack change global trace.attackrange fixed_t oldAttackRange = trace.attackrange; // ioanch 20160225: just change trace.attackrange, don't call P_AimLineAttack trace.attackrange = MELEERANGE; // check for intersections P_PathTraverse(playermobj->x, playermobj->y, targetx, targety, PT_ADDLINES, PTR_chaseTraverse); trace.attackrange = oldAttackRange; ss = R_PointInSubsector(targetx, targety); floorheight = ss->sector->floorheight; ceilingheight = ss->sector->ceilingheight; // don't aim above the ceiling or below the floor if(targetz > ceilingheight - 10*FRACUNIT) targetz = ceilingheight - 10*FRACUNIT; if(targetz < floorheight + 10*FRACUNIT) targetz = floorheight + 10*FRACUNIT; }
//Checks TRUE reachability from //one actor to another. First mobj (actor) is looker. bool DCajunMaster::Reachable (AActor *actor, AActor *target) { if (actor == target) return false; if ((target->Sector->ceilingplane.ZatPoint (target->x, target->y) - target->Sector->floorplane.ZatPoint (target->x, target->y)) < actor->height) //Where target is, looker can't be. return false; looker = actor; rtarget = target; last_s = actor->Sector; last_z = last_s->floorplane.ZatPoint (actor->x, actor->y); reachable = true; estimated_dist = P_AproxDistance (actor->x - target->x, actor->y - target->y); P_PathTraverse (actor->x+actor->momx, actor->y+actor->momy, target->x, target->y, PT_ADDLINES|PT_ADDTHINGS, PTR_Reachable); return reachable; }
void RB_SpawnWallDecal(mobj_t *mobj) { int i; line_t *line; rbDecal_t *decal; rbDecalDef_t *decalDef; float dx, dy; float cx, cy; float fx, fy, fz; float nx, ny; float s, c; float lx1, lx2; float ly1, ly2; float d; float an; float offs; float cHeight = 0; float fHeight = 0; float size; if(!rbDecals) { return; } decalwall = NULL; decal_x = mobj->x; decal_y = mobj->y; decal_z = mobj->z; if(P_PathTraverse(decal_x, decal_y, mobj->x + FixedMul(mobj->momx, 10*FRACUNIT), mobj->y + FixedMul(mobj->momy, 10*FRACUNIT), PT_ADDLINES, PIT_DecalCheckLine)) { return; } line = decalwall; if(!line || !(decalDef = RB_GetDecalDef(mobj->type))) { return; } decal = RB_CreateDecal(decalDef); decal->x = mobj->x; decal->y = mobj->y; decal->z = mobj->z; decal->type = DCT_WALL; // look for a sector to stick to if(line->backsector) { decal->stickSector = line->backsector; if(decal->z > line->backsector->ceilingheight) { decal->type = DCT_UPPERWALL; decal->initialStickZ = line->backsector->ceilingheight; } else if(decal->z < line->backsector->floorheight) { decal->type = DCT_LOWERWALL; decal->initialStickZ = line->backsector->floorheight; } } RB_LinkDecal(decal); dx = line->fdx; dy = line->fdy; lx1 = line->v1->fx; ly1 = line->v1->fy; lx2 = line->v2->fx; ly2 = line->v2->fy; // get line angle (direction) an = atan2f(dx, dy); c = cosf(an); s = sinf(an); // get line distance cx = lx1 - FIXED2FLOAT(decal->x); cy = ly1 - FIXED2FLOAT(decal->y); d = (dx * cy - dy * cx) * InvSqrt(dx * dx + dy * dy); // get nudge direction an -= DEG2RAD(90.0f); offs = (float)decal->offset / 256.0f; nx = (d - 0.8f) * sinf(an); ny = (d - 0.8f) * cosf(an); /* 2 ----------- 3 | | | | | | | | | | 1 ----------- 0 */ decal->numpoints = 4; size = 16 * decal->scale; decal->points[0].x = decal->points[3].x = size * s; decal->points[0].y = decal->points[3].y = size * c; decal->points[1].x = decal->points[2].x = -size * s; decal->points[1].y = decal->points[2].y = -size * c; decal->points[2].z = decal->points[3].z = size; decal->points[0].z = decal->points[1].z = -size; fx = FIXED2FLOAT(decal->x); fy = FIXED2FLOAT(decal->y); fz = FIXED2FLOAT(decal->z); decal->points[0].tu = decal->points[3].tu = 0; decal->points[0].tv = decal->points[1].tv = 0; decal->points[1].tu = decal->points[2].tu = 1; decal->points[3].tv = decal->points[2].tv = 1; if(line->backsector) { cHeight = FIXED2FLOAT(line->backsector->ceilingheight); fHeight = FIXED2FLOAT(line->backsector->floorheight); } for(i = 0; i < decal->numpoints; ++i) { decal->points[i].x += fx; decal->points[i].y += fy; decal->points[i].z += fz; // nudge decal to be closer to the wall decal->points[i].x += nx; decal->points[i].y += ny; RB_ClampWallDecalToLine(&decal->points[i], line->backsector != NULL, cHeight, fHeight, fz, lx1, ly1, lx2, ly2); // jitter offset a bit decal->points[i].x -= (nx * offs); decal->points[i].y -= (ny * offs); } RB_RotateDecalTextureCoords(decal); activedecals++; }
// // 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. (No kidding?) // static void P_ThingSlidingMove(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_TryMoveXYZ(mo, mo->x, mo->y + mo->momy, mo->z)) P_TryMoveXYZ(mo, mo->x + mo->momx, mo->y, mo->z); return; } // 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_TryMoveXYZ(mo, mo->x + newx, mo->y + newy, mo->z)) 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_WallMomSlide(bestslideline); // clip the moves mo->momx = tmxmove; mo->momy = tmymove; if(!P_TryMoveXYZ(mo, mo->x + tmxmove, mo->y + tmymove, mo->z)) { goto retry; } }