//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// 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 Globals;
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;
}
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 Vector3 goToDestination(Vector3 destination)
{
Vector3 Orientation = destination - mass.currentPosition;
Orientation.Normalize();
MoveTowardDirection(Orientation);
mass.MoveObject((float)Math.Abs(Orientation.Z), 0.0f);
return destination - this.mass.currentPosition;
}
///
/// 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)
{
// cap the y at zero so they can't get above the H2O plane
//mass.currentPosition.Y = 0.0f;
// If dead they can't update
if (IsAlive() == false)
{
return;
}
if ((aiState == State.Goto) || (Destination != Vector3.Zero))
{
gotoLogic();
}
else if (aiState == State.Stop)
{
stopLogic();
}
else if (aiState == State.Exit)
{
exitLogic();
}
base.Update(ref objectLibrary);
}
public void SetDestination(Vector3 Location)
{
Destination = Location;
}
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 void gotoLogic()
{
goToDestination(Destination);
if (fuzzyDestination(mass.currentPosition, Destination))
{
mass.currentPosition = Destination;
Destination = Vector3.Zero;
aiState = State.Stop;
}
}
public void stopLogic()
{
}
public void exitLogic()
{
}
public void UpdateState(ObjectLibrary objectLibrary)
{
if (aiState == State.Stop)
{
idleLogic();
}
}
private void idleLogic()
{
}
private float AngleToDirection(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;
}
}
public virtual void MoveTowardDirection(Vector3 direction)
{
float angle = AngleToDirection(direction);
if (float.IsNaN(angle) || angle < 0.1)
{
// this was set to 10.0 f which completely turned the character around in the wrong direction ALWAYS
// we twitched it to something much smaller and the character walks in a straight line
//Rotate(new Vector2(0.0f, 0.0f));
//DarkWynterGame.playerController.gameInput.playerRotation.X = 0.0f;
//DarkWynterGame.playerController.gameInput.playerMotion.Y = 10.0f;
// weird math
//ACTUALLY
//If the angle is this small or not a number the idea would be NOT to rotate and just to move.
}
else
{
if (turnDirection == Enums_Engine.TurnDirection.NOT_SET)
{
// Determine which direction to turn
turnDirection = DirectionToOrientation(direction);
}
if (turnDirection == Enums_Engine.TurnDirection.LEFT)
{
Rotate(new Vector2(0.05f, 0.0f));
//DarkWynterGame.playerController.gameInput.playerRotation.X = 0.05f;
}
else
{
Rotate(new Vector2(-0.05f, 0.0f));
//DarkWynterGame.playerController.gameInput.playerRotation.X = -0.05f;
}
}
}
}
}