#region File Description
//-----------------------------------------------------------------------------
// AIContext.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using RobotGameData;
#endregion
namespace RobotGameData.AI
{
///
/// This manages A.I.
/// If an A.I. class is added, it will get updated every time when it gets played.
/// When an A.I. gets played, the A.I.’s former Finish event handler,
/// which has not been replaced yet, will be called.
/// And, then, when the context gets updated, the A.I.’s current
/// Update event handler will be called.
///
public class AIContext : GameNode
{
#region Fields
///
/// If set to false, all of the related functions get turned off.
///
bool activeOn = true;
List aiList = new List();
AIBase activeAI = null;
AIBase nextAI = null;
#endregion
#region Properties
public AIBase ActiveAI
{
get { return activeAI; }
}
public AIBase NextAI
{
get { return nextAI; }
}
#endregion
#region Update
///
/// It will process the A.I. which has been registered to the list.
/// When the current A.I. is updated and then, when ActiveTime,
/// which is specified in the current A.I.,
/// becomes zero, it will be replaced with the next-to-be-executed A.I.
///
protected override void OnUpdate(GameTime gameTime)
{
if ((ActiveAI == null && NextAI == null) || !activeOn) return;
// Change to next AI
if (ActiveAI == null)
{
PlayAI(NextAI, NextAI.ActiveTime);
}
else if (NextAI != null && ActiveAI.ActiveTime == 0.0f)
{
PlayAI(NextAI, NextAI.ActiveTime);
nextAI = null;
}
else
{
// Process to current AI
if (ActiveAI != null)
{
ActiveAI.Update(gameTime);
if (ActiveAI.ActiveTime > 0.0f)
ActiveAI.ActiveTime -=
(float)gameTime.ElapsedGameTime.TotalSeconds;
if( ActiveAI.ActiveTime < 0.0f)
ActiveAI.ActiveTime = 0.0f;
}
}
}
#endregion
#region A.I. Controls
///
/// By using the index, it returns one from the A.I.
/// classes which have been registered to the list.
///
public AIBase FindAI(int index)
{
if (!activeOn) return null;
return aiList[index];
}
///
/// By using the name, it returns one from the A.I.
/// classes which have been registered to the list.
///
public AIBase FindAI(string name)
{
if (!activeOn) return null;
foreach (AIBase aiBase in aiList)
{
if (name == aiBase.Name)
return aiBase;
}
return null;
}
///
/// it adds an A.I. with the specified name to the list.
///
public int AddAI(string name, AIBase aiBase)
{
if (!activeOn) return -1;
aiBase.Name = name;
aiList.Add(aiBase);
return aiList.IndexOf(aiBase);
}
///
/// by using the index of A.I., it removes an A.I. from the registered list.
///
public void RemoveAI(int index)
{
aiList.RemoveAt(index);
}
///
/// it removes every registered A.I.
///
public void RemoveAllAI()
{
aiList.Clear();
}
///
/// by using the index of the registered A.I.,
/// it specifies the next-to-be-executed A.I.
/// The active time of the next-to-be-executed A.I. is specified by activeTime.
///
public void SetNextAI(int index, float activeTime)
{
if (!activeOn) return;
nextAI = FindAI(index);
nextAI.ActiveTime = activeTime;
}
///
/// A new A.I. will be played.
/// The active time of the A.I. is specified by activeTime.
/// The A.I., which has been active so far, will be ignored.
///
public void StartAI(int index, float activeTime)
{
if (!activeOn) return;
activeAI = null;
nextAI = null;
PlayAI(index, activeTime);
}
///
/// The specified A.I. will be played.
/// The active time of the A.I. is specified by activeTime.
/// The A.I., which has been active so far, will call the
/// Finish event handler and will be replaced by the newly specified A.I.
/// When the newly specified A.I. start activating,
/// Start event handler is called.
///
private void PlayAI(int index, float activeTime)
{
if (!activeOn) return;
AIBase aiBase = FindAI(index);
PlayAI(aiBase, activeTime);
}
///
/// The specified A.I. will be played.
/// The active time of the A.I. is specified by activeTime.
/// The A.I., which has been active so far, will call the
/// Finish event handler and will be replaced by the newly specified A.I.
/// When the newly specified A.I. start activating,
/// Start event handler is called.
///
private void PlayAI(AIBase aiBase, float activeTime)
{
if (!activeOn) return;
// Call the finish event of the previous A.I.
if (activeAI != null)
activeAI.AIFinish();
// Set to new active A.I.
activeAI = aiBase;
activeAI.ActiveTime = activeTime;
// Call start event of new A.I.
activeAI.AIStart();
}
#endregion
}
}