void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist) { float deltax,deltay; float d[3]; float tdir, olddir, turnaround; olddir = anglemod( (int)(actor->v.ideal_yaw/45)*45 ); turnaround = anglemod(olddir - 180); deltax = enemy->v.origin[0] - actor->v.origin[0]; deltay = enemy->v.origin[1] - actor->v.origin[1]; if (deltax>10) d[1]= 0; else if (deltax<-10) d[1]= 180; else d[1]= DI_NODIR; if (deltay<-10) d[2]= 270; else if (deltay>10) d[2]= 90; else d[2]= DI_NODIR; // try direct route if (d[1] != DI_NODIR && d[2] != DI_NODIR) { if (d[1] == 0) tdir = d[2] == 90 ? 45 : 315; else tdir = d[2] == 90 ? 135 : 215; if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) return; } // try other directions if ( ((rand()&3) & 1) || abs(deltay)>abs(deltax)) { tdir=d[1]; d[1]=d[2]; d[2]=tdir; } if (d[1]!=DI_NODIR && d[1]!=turnaround && SV_StepDirection(actor, d[1], dist)) return; if (d[2]!=DI_NODIR && d[2]!=turnaround && SV_StepDirection(actor, d[2], dist)) return; /* there is no direct path to the player, so pick another direction */ if (olddir!=DI_NODIR && SV_StepDirection(actor, olddir, dist)) return; if (rand()&1) /*randomly determine direction of search*/ { for (tdir=0 ; tdir<=315 ; tdir += 45) if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) return; } else { for (tdir=315 ; tdir >=0 ; tdir -= 45) if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) return; } if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) ) return; actor->v.ideal_yaw = olddir; // can't move // if a bridge was pulled out from underneath a monster, it may not have // a valid standing position at all if (!SV_CheckBottom (actor)) SV_FixCheckBottom (actor); }
void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist) { float deltax,deltay; float d[3]; float tdir, olddir, turnaround; //FIXME: how did we get here with no enemy if (!enemy) return; if(actor->flags & FL_ROBOT) olddir = anglemod( (int)(actor->ideal_yaw+0.5) ); else olddir = anglemod( (int)(actor->ideal_yaw/45)*45 ); turnaround = anglemod(olddir - 180); deltax = enemy->s.origin[0] - actor->s.origin[0]; deltay = enemy->s.origin[1] - actor->s.origin[1]; if(actor->flags & FL_ROBOT) { d[1] = d[2] = olddir; } else { if (deltax>10) d[1]= 0; else if (deltax<-10) d[1]= 180; else d[1]= DI_NODIR; if (deltay<-10) d[2]= 270; else if (deltay>10) d[2]= 90; else d[2]= DI_NODIR; } // try direct route if (d[1] != DI_NODIR && d[2] != DI_NODIR) { if(actor->flags & FL_ROBOT) tdir = d[1]; else { if (d[1] == 0) tdir = d[2] == 90 ? 45 : 315; else tdir = d[2] == 90 ? 135 : 215; } if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) return; } // Robots give up if direct path doesn't work if(actor->flags & FL_ROBOT) { actor->ideal_yaw = olddir; // can't move if (!M_CheckBottom (actor)) SV_FixCheckBottom (actor); } // try other directions if ( ((rand()&3) & 1) || abs(deltay)>abs(deltax)) { tdir=d[1]; d[1]=d[2]; d[2]=tdir; } if (d[1]!=DI_NODIR && d[1]!=turnaround && SV_StepDirection(actor, d[1], dist)) return; if (d[2]!=DI_NODIR && d[2]!=turnaround && SV_StepDirection(actor, d[2], dist)) return; if (actor->inuse && (actor->health > 0) && actor->monsterinfo.blocked) { if (actor->monsterinfo.blocked(actor, dist)) return; } /* there is no direct path to the player, so pick another direction */ if (olddir!=DI_NODIR && SV_StepDirection(actor, olddir, dist)) return; if (rand()&1) /*randomly determine direction of search*/ { for (tdir=0 ; tdir<=315 ; tdir += 45) if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) return; } else { for (tdir=315 ; tdir >=0 ; tdir -= 45) if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) return; } if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) ) return; actor->ideal_yaw = olddir; // can't move // if a bridge was pulled out from underneath a monster, it may not have // a valid standing position at all if (!M_CheckBottom (actor)) SV_FixCheckBottom (actor); }
void SV_NewChaseDir2(edict_t *actor, vec3_t destination, float dist) { float deltax, deltay; float tempdir, olddir, turnaround; vec3_t d; olddir = anglemod(((int)(actor->v.ideal_yaw / 45.0)) * 45.0); //So, we're shaving down some of the precision. Ohkay. turnaround = anglemod(olddir - 180); deltax = destination[0] - actor->v.origin[0]; deltay = destination[1] - actor->v.origin[1]; if(deltax > 10) { d[1]= 0; } else if(deltax < -10) { d[1]= 180; } else { d[1] = -1; } //DI_NODIR, so in this function, -1 is a reserved 'null' like value. if(deltay < -10) { d[2] = 270; } else if(deltay > 10) { d[2] = 90; } else { d[2] = -1; } // try direct route if(d[1] != -1 && d[2] != -1) { if(d[1] == 0) { if(d[2] == 90) { tempdir = 45; } else { tempdir = 315; } } else { if(d[2] == 90) { tempdir = 135; } else { tempdir = 215; } } if(tempdir != turnaround && SV_StepDirection(actor, tempdir, dist) != 0) { return; } } // try other directions if(RandomLong(0, 1) != 0 || fabs(deltay) > fabs(deltax)) { //These were originally cast as int before compared. I cannot think of any compelling reason to do so. tempdir = d[1]; d[1] = d[2]; d[2] = tempdir; } if(d[1] != -1 && d[1] != turnaround && SV_StepDirection(actor, d[1], dist) != 0) { return; } if(d[2] != -1 && d[2] != turnaround && SV_StepDirection(actor, d[2], dist) != 0) { return; } /* there is no direct path to the player, so pick another direction */ if(olddir != -1 && SV_StepDirection(actor, olddir, dist) != 0) { return; } //Fine, just run somewhere. if(RandomLong(0, 1) != 0) { for(tempdir = 0; tempdir <= 315; tempdir += 45) { if(tempdir != turnaround && SV_StepDirection(actor, tempdir, dist) != 0) { return; } } } else { for(tempdir = 315; tempdir >= 0; tempdir -= 45) { if(tempdir != turnaround && SV_StepDirection(actor, tempdir, dist) != 0) { return; } } } //We tried. Run backwards. THAT ought to work... if(turnaround != -1 && SV_StepDirection(actor, turnaround, dist) != 0) { return; } //Well, we're stuck somehow. actor->v.ideal_yaw = olddir; // if a bridge was pulled out from underneath a monster, it may not have // a valid standing position at all. if(SV_CheckBottom(actor) == 0) { SV_FixCheckBottom(actor); } }
/* ================== SV_CalculateNewChaseDirection ================== */ static void SV_CalculateNewChaseDirection (edict_t *actor, edict_t *enemy, float dist){ float deltaX, deltaY; float dir[3]; float targetDir, oldTargetDir, turnAround; // FIXME: How did we get here with no enemy if (!enemy) return; oldTargetDir = anglemod((int)(actor->idealYaw / 45.0f) * 45.0f); turnAround = anglemod(oldTargetDir - 180.0f); deltaX = enemy->s.origin[0] - actor->s.origin[0]; deltaY = enemy->s.origin[1] - actor->s.origin[1]; if (deltaX > 10.0f) dir[1]= 0.0f; else if (deltaX < -10.0f) dir[1]= 180.0f; else dir[1]= NO_DIRECTION; if (deltaY < -10.0f) dir[2]= 270.0f; else if (deltaY > 10.0f) dir[2]= 90.0f; else dir[2]= NO_DIRECTION; // Try direct route if (dir[1] != NO_DIRECTION && dir[2] != NO_DIRECTION){ if (dir[1] == 0) targetDir = dir[2] == 90.0f ? 45.0f : 315.0f; else targetDir = dir[2] == 90.0f ? 135.0f : 215.0f; if (targetDir != turnAround && SV_IsStepDirectionValid(actor, targetDir, dist)) return; } // Try other directions if (((rand() & 3) & 1) || abs(deltaY) > abs(deltaX)){ targetDir = dir[1]; dir[1] = dir[2]; dir[2] = targetDir; } if (dir[1] != NO_DIRECTION && dir[1] != turnAround && SV_IsStepDirectionValid(actor, dir[1], dist)) return; if (dir[2] != NO_DIRECTION && dir[2] != turnAround && SV_IsStepDirectionValid(actor, dir[2], dist)) return; // There is no direct path to the player, so pick another direction if (oldTargetDir != NO_DIRECTION && SV_IsStepDirectionValid(actor, oldTargetDir, dist)) return; // Randomly determine direction of search if (rand() & 1){ for (targetDir = 0.0f; targetDir <= 315.0f; targetDir += 45.0f){ if (targetDir != turnAround && SV_IsStepDirectionValid(actor, targetDir, dist)) return; } } else { for (targetDir = 315.0f; targetDir >= 0.0f; targetDir -= 45.0f){ if (targetDir != turnAround && SV_IsStepDirectionValid(actor, targetDir, dist)) return; } } if (turnAround != NO_DIRECTION && SV_IsStepDirectionValid(actor, turnAround, dist)) return; // Can't move actor->idealYaw = oldTargetDir; // If a bridge was pulled out from underneath a monster, it may not have // a valid standing position at all if (!SG_MonsterCheckBottom(actor)) SV_FixCheckBottom(actor); }