Esempio n. 1
0
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);
}