Created
July 13, 2014 06:01
-
-
Save stevewoolcock/1ae490569ca5a143060c to your computer and use it in GitHub Desktop.
A simple roguelike turn system, very similar to that of Angband.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A Roguelike turn system | |
// http://blog.deadreckoned.com/post/91616626322/havenguard-turn-system | |
// Requires a fast max-heap Priority Queue (I like this one: http://blog.mischel.com/2007/06/22/priority-queue-in-c/) | |
public class TurnEntity | |
{ | |
/// <summary> | |
/// The delegate to execute when the object's turn is executed. | |
/// </summary> | |
public Action TurnHandler { get; set; } | |
/// <summary> | |
/// The entity's speed rating. | |
/// </summary> | |
public int Speed = 0; | |
/// <summary> | |
/// The entity's current energy rating. | |
/// </summary> | |
public int Energy = 0; | |
public TurnEntity() | |
{ | |
// | |
} | |
public TurnEntity(Action turnHandler) | |
{ | |
this.TurnHandler = turnHandler; | |
} | |
} | |
public class TurnSystem | |
{ | |
/// <summary> | |
/// The base speed unit. | |
/// </summary> | |
private const int baseSpeed = 10; | |
/// <summary> | |
/// The amount of energy required to execute an object's turn. | |
/// </summary> | |
public const int TurnEnergy = 100; | |
private List<TurnEntity> entities = new List<TurnEntity>(); | |
private HashSet<TurnEntity> register = new HashSet<TurnEntity>(); | |
private PriorityQueue<TurnEntity, int> turnQueue = new PriorityQueue<TurnEntity, int>(new IntMaxComparer()); | |
/// <summary> | |
/// Adds an entity to the system. | |
/// </summary> | |
/// <param name="entity">The TurnEntity to add</param> | |
public void Register(TurnEntity entity) | |
{ | |
if (!register.Contains(entity)) | |
{ | |
entities.Add(entity); | |
register.Add(entity); | |
} | |
} | |
/// <summary> | |
/// Removes an entity from the system. | |
/// </summary> | |
/// <param name="entity">The TurnEntity to remove</param> | |
public void Deregister(TurnEntity entity) | |
{ | |
if (register.Remove(entity)) | |
{ | |
entities.Remove(entity); | |
} | |
} | |
/// <summary> | |
/// Applies energy recovery and executes turn handles for entities who's energy has reached the turn energy rating. | |
/// </summary> | |
public void NextTurn() | |
{ | |
if (entities.Count == 0) | |
return; | |
// Reset the turn queue | |
turnQueue.Clear(); | |
// Continually apply energy recovery to all entities in the system, until | |
// the queue has at least one entity to execute | |
while (turnQueue.Count == 0) | |
{ | |
for (int i = 0; i < entities.Count; ++i) | |
{ | |
TurnEntity entity = entities[i]; | |
entity.Energy += CalculateEnergyRecovery(entity.Speed); | |
// Once the entity has enough energy, it can be added to the turn queue | |
// The queue will prioritize entities by their energy ratings, so the entities | |
// with the most amount of energy will execute their turn first | |
if (entity.Energy >= TurnEnergy) | |
{ | |
turnQueue.Enqueue(entity, entity.Energy); | |
} | |
} | |
} | |
// Dequeue and execute the handler for each entities in the turn queue until empty | |
// Note that the handler is only executed if the entity is still registered in the system, since | |
// an object may be deregistered by the time its turn handler is executed | |
while (turnQueue.Count > 0) | |
{ | |
TurnEntity entity = turnQueue.Dequeue().Value; | |
if (entity.TurnHandler != null && register.Contains(entity)) | |
entity.TurnHandler(); | |
} | |
} | |
/// <summary> | |
/// Calculates the energy recovery rate for a given speed. | |
/// </summary> | |
/// <param name="speed">The speed</param> | |
/// <returns>The energy recovery amount for the specified speed.</returns> | |
private int CalculateEnergyRecovery(int speed) | |
{ | |
// TODO: Implement the actual recovry table lookup | |
return baseSpeed + speed; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment