📄 p_maputl.c
字号:
if ( trace.dx > FRACUNIT*16 || trace.dy > FRACUNIT*16 || trace.dx < -FRACUNIT*16 || trace.dy < -FRACUNIT*16) { s1 = P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace); s2 = P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace); } else { s1 = P_PointOnLineSide (trace.x, trace.y, ld); s2 = P_PointOnLineSide (trace.x+trace.dx, trace.y+trace.dy, ld); } if (s1 == s2) return true; // line isn't crossed//// hit the line// P_MakeDivline (ld, &dl); frac = P_InterceptVector (&trace, &dl); if (frac < 0) return true; // behind source// try to early out the check if (earlyout && frac < FRACUNIT && !ld->backsector) return false; // stop checking intercept_p->frac = frac; intercept_p->isaline = true; intercept_p->d.line = ld; intercept_p++; return true; // continue}/*==================== PIT_AddThingIntercepts===================*/boolean PIT_AddThingIntercepts (mobj_t *thing){ fixed_t x1,y1, x2,y2; int s1, s2; boolean tracepositive; divline_t dl; fixed_t frac; tracepositive = (trace.dx ^ trace.dy)>0; // check a corner to corner crossection for hit if (tracepositive) { x1 = thing->x - thing->radius; y1 = thing->y + thing->radius; x2 = thing->x + thing->radius; y2 = thing->y - thing->radius; } else { x1 = thing->x - thing->radius; y1 = thing->y - thing->radius; x2 = thing->x + thing->radius; y2 = thing->y + thing->radius; } s1 = P_PointOnDivlineSide (x1, y1, &trace); s2 = P_PointOnDivlineSide (x2, y2, &trace); if (s1 == s2) return true; // line isn't crossed dl.x = x1; dl.y = y1; dl.dx = x2-x1; dl.dy = y2-y1; frac = P_InterceptVector (&trace, &dl); if (frac < 0) return true; // behind source intercept_p->frac = frac; intercept_p->isaline = false; intercept_p->d.thing = thing; intercept_p++; return true; // keep going}/*====================== P_TraverseIntercepts== Returns true if the traverser function returns true for all lines====================*/boolean P_TraverseIntercepts ( traverser_t func, fixed_t maxfrac ){ int count; fixed_t dist; intercept_t *scan, *in; count = intercept_p - intercepts; in = 0; // shut up compiler warning while (count--) { dist = MAXINT; for (scan = intercepts ; scan<intercept_p ; scan++) if (scan->frac < dist) { dist = scan->frac; in = scan; } if (dist > maxfrac) return true; // checked everything in range#if 0 { // don't check these yet, ther may be others inserted in = scan = intercepts; for ( scan = intercepts ; scan<intercept_p ; scan++) if (scan->frac > maxfrac) *in++ = *scan; intercept_p = in; return false; }#endif if ( !func (in) ) return false; // don't bother going farther in->frac = MAXINT; } return true; // everything was traversed}/*==================== P_PathTraverse== Traces a line from x1,y1 to x2,y2, calling the traverser function for each= Returns true if the traverser function returns true for all lines==================*/boolean P_PathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, boolean (*trav) (intercept_t *)){ fixed_t xt1,yt1,xt2,yt2; fixed_t xstep,ystep; fixed_t partial; fixed_t xintercept, yintercept; int mapx, mapy, mapxstep, mapystep; int count; earlyout = flags & PT_EARLYOUT; validcount++; intercept_p = intercepts; if ( ((x1-bmaporgx)&(MAPBLOCKSIZE-1)) == 0) x1 += FRACUNIT; // don't side exactly on a line if ( ((y1-bmaporgy)&(MAPBLOCKSIZE-1)) == 0) y1 += FRACUNIT; // don't side exactly on a line trace.x = x1; trace.y = y1; trace.dx = x2 - x1; trace.dy = y2 - y1; x1 -= bmaporgx; y1 -= bmaporgy; xt1 = x1>>MAPBLOCKSHIFT; yt1 = y1>>MAPBLOCKSHIFT; x2 -= bmaporgx; y2 -= bmaporgy; xt2 = x2>>MAPBLOCKSHIFT; yt2 = y2>>MAPBLOCKSHIFT; if (xt2 > xt1) { mapxstep = 1; partial = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1)); ystep = FixedDiv (y2-y1,abs(x2-x1)); } else if (xt2 < xt1) { mapxstep = -1; partial = (x1>>MAPBTOFRAC)&(FRACUNIT-1); ystep = FixedDiv (y2-y1,abs(x2-x1)); } else { mapxstep = 0; partial = FRACUNIT; ystep = 256*FRACUNIT; } yintercept = (y1>>MAPBTOFRAC) + FixedMul (partial, ystep); if (yt2 > yt1) { mapystep = 1; partial = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1)); xstep = FixedDiv (x2-x1,abs(y2-y1)); } else if (yt2 < yt1) { mapystep = -1; partial = (y1>>MAPBTOFRAC)&(FRACUNIT-1); xstep = FixedDiv (x2-x1,abs(y2-y1)); } else { mapystep = 0; partial = FRACUNIT; xstep = 256*FRACUNIT; } xintercept = (x1>>MAPBTOFRAC) + FixedMul (partial, xstep); //// step through map blocks// Count is present to prevent a round off error from skipping the break mapx = xt1; mapy = yt1; for (count = 0 ; count < 64 ; count++) { if (flags & PT_ADDLINES) { if (!P_BlockLinesIterator (mapx, mapy,PIT_AddLineIntercepts)) return false; // early out } if (flags & PT_ADDTHINGS) { if (!P_BlockThingsIterator (mapx, mapy,PIT_AddThingIntercepts)) return false; // early out } if (mapx == xt2 && mapy == yt2) break; if ( (yintercept >> FRACBITS) == mapy) { yintercept += ystep; mapx += mapxstep; } else if ( (xintercept >> FRACBITS) == mapx) { xintercept += xstep; mapy += mapystep; } }//// go through the sorted list// return P_TraverseIntercepts ( trav, FRACUNIT );}//===========================================================================//// P_RoughMonsterSearch//// Searches though the surrounding mapblocks for monsters/players// distance is in MAPBLOCKUNITS//===========================================================================mobj_t *P_RoughMonsterSearch(mobj_t *mo, int distance){ int blockX; int blockY; int startX, startY; int blockIndex; int firstStop; int secondStop; int thirdStop; int finalStop; int count; mobj_t *target; startX = (mo->x-bmaporgx)>>MAPBLOCKSHIFT; startY = (mo->y-bmaporgy)>>MAPBLOCKSHIFT; if(startX >= 0 && startX < bmapwidth && startY >= 0 && startY < bmapheight) { if(target = RoughBlockCheck(mo, startY*bmapwidth+startX)) { // found a target right away return target; } } for(count = 1; count <= distance; count++) { blockX = startX-count; blockY = startY-count; if(blockY < 0) { blockY = 0; } else if(blockY >= bmapheight) { blockY = bmapheight-1; } if(blockX < 0) { blockX = 0; } else if(blockX >= bmapwidth) { blockX = bmapwidth-1; } blockIndex = blockY*bmapwidth+blockX; firstStop = startX+count; if(firstStop < 0) { continue; } if(firstStop >= bmapwidth) { firstStop = bmapwidth-1; } secondStop = startY+count; if(secondStop < 0) { continue; } if(secondStop >= bmapheight) { secondStop = bmapheight-1; } thirdStop = secondStop*bmapwidth+blockX; secondStop = secondStop*bmapwidth+firstStop; firstStop += blockY*bmapwidth; finalStop = blockIndex; // Trace the first block section (along the top) for(; blockIndex <= firstStop; blockIndex++) { if(target = RoughBlockCheck(mo, blockIndex)) { return target; } } // Trace the second block section (right edge) for(blockIndex--; blockIndex <= secondStop; blockIndex += bmapwidth) { if(target = RoughBlockCheck(mo, blockIndex)) { return target; } } // Trace the third block section (bottom edge) for(blockIndex -= bmapwidth; blockIndex >= thirdStop; blockIndex--) { if(target = RoughBlockCheck(mo, blockIndex)) { return target; } } // Trace the final block section (left edge) for(blockIndex++; blockIndex > finalStop; blockIndex -= bmapwidth) { if(target = RoughBlockCheck(mo, blockIndex)) { return target; } } } return NULL; }//===========================================================================//// RoughBlockCheck////===========================================================================static mobj_t *RoughBlockCheck(mobj_t *mo, int index){ mobj_t *link; mobj_t *master; angle_t angle; link = blocklinks[index]; while(link) { if (mo->player) // Minotaur looking around player { if ((link->flags&MF_COUNTKILL) || (link->player && (link != mo))) { if (!(link->flags&MF_SHOOTABLE)) { link = link->bnext; continue; } if (link->flags2&MF2_DORMANT) { link = link->bnext; continue; } if ((link->type == MT_MINOTAUR) && (((mobj_t *)link->special1) == mo)) { link = link->bnext; continue; } if(netgame && !deathmatch && link->player) { link = link->bnext; continue; } if(P_CheckSight(mo, link)) { return link; } } link = link->bnext; } else if (mo->type == MT_MINOTAUR) // looking around minotaur { master = (mobj_t *)mo->special1; if ((link->flags&MF_COUNTKILL) || (link->player && (link != master))) { if (!(link->flags&MF_SHOOTABLE)) { link = link->bnext; continue; } if (link->flags2&MF2_DORMANT) { link = link->bnext; continue; } if ((link->type == MT_MINOTAUR) && (link->special1 == mo->special1)) { link = link->bnext; continue; } if(netgame && !deathmatch && link->player) { link = link->bnext; continue; } if(P_CheckSight(mo, link)) { return link; } } link = link->bnext; } else if (mo->type == MT_MSTAFF_FX2) // bloodscourge { if ((link->flags&MF_COUNTKILL || (link->player && link != mo->target)) && !(link->flags2&MF2_DORMANT)) { if (!(link->flags&MF_SHOOTABLE)) { link = link->bnext; continue; } if(netgame && !deathmatch && link->player) { link = link->bnext; continue; } else if(P_CheckSight(mo, link)) { master = mo->target; angle = R_PointToAngle2(master->x, master->y, link->x, link->y) - master->angle; angle >>= 24; if (angle>226 || angle<30) { return link; } } } link = link->bnext; } else // spirits { if ((link->flags&MF_COUNTKILL || (link->player && link != mo->target)) && !(link->flags2&MF2_DORMANT)) { if (!(link->flags&MF_SHOOTABLE)) { link = link->bnext; continue; } if(netgame && !deathmatch && link->player) { link = link->bnext; continue; } if (link == mo->target) { link = link->bnext; continue; } else if(P_CheckSight(mo, link)) { return link; } } link = link->bnext; } } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -