//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {License Information: Creative Commons}
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace DarkWynter.Engine.GameObjects
{
#region Using Statements
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using System.Xml;
using System.Diagnostics;
using DarkWynter.Engine;
using DarkWynter.Engine.Globals;
using DarkWynter.Engine.ObjectLib;
using DarkWynter.Engine.GameObjects;
using DarkWynter.Stream;
using DarkWynter.Engine.Init;
using Xclna.Xna.Animation;
#endregion
///
/// Bots
///
public class AI : Player
{
private Enums_Engine.TurnDirection turnDirection = Enums_Engine.TurnDirection.NOT_SET;
private Vector3 Destination = new Vector3(0, 0, 0);
private enum State
{
Goto,
Stop,
Exit
}
private State aiState = State.Goto;
///
/// Constructor
///
public AI(Load gameObjectLoader)
: base(gameObjectLoader)
{
mass.objectType = Enums_Engine.ObjectType.PLAYER;
mass.gameObjectPointer = this;
}
///
/// Load stuff from XML
///
/// The Bot node
/// ObjectLibrary
/// True if load was successful
public override bool Load(ObjectLibrary objectLibrary)
{
if (!base.Load(objectLibrary))
{
return false;
}
health = Statics_Engine.AISettings.AI_MAX_HEALTH;
manna = 100;
aiState = State.Goto;
return true;
}
///
/// General update function
///
/// ObjectLibrary
public override void Update(ref ObjectLibrary objectLibrary)
{
// UpdatePercepts(objectLibrary);
if ((aiState == State.Goto) || (Destination != Vector3.Zero))
{
//gotoLogic();
}
base.Update(ref objectLibrary);
}
public void SpawnPlayer(ObjectLibrary objectLibrary)
{
_spawnPosition.Y = objectLibrary.terrain.GetTerrainHeight(
spawnPosition.X / Statics_Engine.TerrainSettings.terrainScaleFactor,
spawnPosition.Z / Statics_Engine.TerrainSettings.terrainScaleFactor);
base.SpawnPlayer();
health = Statics_Engine.AISettings.AI_MAX_HEALTH;
}
public void gotoLogic()
{
goToDestination(Destination);
if (FuzzyDestination(mass.currentPosition, Destination))
{
mass.currentPosition = Destination;
Destination = Vector3.Zero;
aiState = State.Stop;
}
}
public Vector3 goToDestination(Vector3 destination)
{
Vector3 Orientation = destination - mass.currentPosition;
Orientation.Normalize();
MoveTowardDirection(Orientation);
if (DirectionToAngle(Orientation) < Math.PI / 12.0)
{
// Pass in X + Z as the force to apply in the normal's direction
mass.MoveObject((float)Math.Abs(Orientation.X + Orientation.Z), 0.0f);
}
return destination - this.mass.currentPosition;
}
private bool FuzzyDestination(Vector3 Position, Vector3 TargetPosition)
{
if ((Position.X - TargetPosition.X < 20 || TargetPosition.X - Position.X < 20) &&
(Position.Z - TargetPosition.Z < 20 || TargetPosition.Z - Position.Z < 20))
return true;
else return false;
}
public virtual void MoveTowardDirection(Vector3 direction)
{
float angle = DirectionToAngle(direction);
if (float.IsNaN(angle) || angle < 0.1)
{
//If the angle is this small or not a number the idea would be NOT to rotate and just to move.
}
else
{
// Determine which direction to turn
Vector3 toDirection = new Vector3(direction.X, 0, direction.Z);
toDirection.Normalize();
Vector3 lookAt = new Vector3(mass.normalVector.X, 0, mass.normalVector.Z);
lookAt.Normalize();
Vector3 cross = Vector3.Cross(toDirection, lookAt);
if (cross.Y < 0.01)
{
// Turn Left
Rotate(new Vector2(-0.05f, 0.0f));
mass.totalForce = Vector3.Zero;
}
else
{
// Turn Right
Rotate(new Vector2(0.05f, 0.0f));
mass.totalForce = Vector3.Zero;
}
}
}
private float DirectionToAngle(Vector3 direction)
{
Vector2 diff2 = new Vector2(direction.X, direction.Z);
diff2.Normalize();
Vector2 N = new Vector2(mass.normalVector.X, mass.normalVector.Z);
N.Normalize();
return (float)Math.Acos((double)(Vector2.Dot(diff2, N)));
}
//private Enums_Engine.TurnDirection DirectionToOrientation(Vector3 direction)
//{
// // Determine which direction to turn
// Vector3 toDirection = new Vector3(direction.X, 0, direction.Z);
// toDirection.Normalize();
// Vector3 lookAt = new Vector3(mass.normalVector.X, 0, mass.normalVector.Z);
// lookAt.Normalize();
// Vector3 cross = Vector3.Cross(toDirection, lookAt);
// if (cross.Y < 0.01)
// {
// return Enums_Engine.TurnDirection.LEFT;
// }
// else
// {
// return Enums_Engine.TurnDirection.RIGHT;
// }
//}
}
}