int GetInRange(Entity *self) { if((self == NULL)||(self->target == NULL))return -1; if(RelativeSize(self->p.x - self->target->p.x, self->p.y - self->target->p.y) < ((self->attackrange + self->target->radius) * (self->attackrange + self->target->radius))) { self->mv.x = self->mv.y = 0; self->v.x = self->v.y = 0; return 1;/*in range!*/ } if(!CanWalkTo(self->p, self->target->p,self->radius,self)) { MonsterPath(self, self->target); } else { VectorToTarget(self,&self->mv); } return 0; }
void AutoNavigator::operate() { GameHandle targetHandle = *mTargets.begin(); // Check if target still exists if (! environment()->exists(targetHandle)) { mTargets.erase(mTargets.begin()); return; } const Location& own = getGoValue<Location>(ID::PV_Location, pluginId()); Location target = environment()->getGoValue<Location>(targetHandle, ID::PV_Location, pluginId()); if (nearEnough(own.position, target.position, mRadius.value())) { mTargets.erase(mTargets.begin()); return; } const v3& targetVelocity = environment()->getGoValue<v3>(targetHandle, ID::PV_Velocity, pluginId()); const v3& ownVelocity = getGoValue<v3>(ID::PV_Velocity, pluginId()); // use two further frame positions because it takes 2 frames for the value to reach the physics v3 targetPositionEx(target.position + targetVelocity * 2.0f * mTime.value()); v3 ownPositionEx(own.position + ownVelocity * 2.0f * mTime.value()); // \todo use rotation velocity to approximate the orientation in the next frame v3 VectorToTarget(unitInverse(own.orientation) * (targetPositionEx - ownPositionEx)); rotate( rotationTo(v3::UNIT_Z, VectorToTarget) ); norm(VectorToTarget); // if the target lies behind the object, than z of VectorToTarget is negative // and the object slows down. accelerate((f32)VectorToTarget.z * mMaxSpeed); }