public void testGiveCommand() { Scenario scenario = new Scenario(20, 20); Controller controller = new Controller(scenario); Unit unit = new Unit(scenario.getPlayer(), 200); controller.addUnit(unit, 10f, 10f); // Create a MoveAction MoveAction action = new MoveAction(8f, 8f, scenario.getGameWorld(), unit); // Test if the ActionController returns true when it gives the command. Assert.IsTrue(controller.giveActionCommand(unit, action)); // Test if the MoveAction is actually on the unit's action queue. Assert.IsTrue(unit.getActionQueue()[0] == action); // Create a second MoveAction MoveAction action2 = new MoveAction(7f, 7f, scenario.getGameWorld(), unit); // Test if the ActionController interrupts the current MoveAction and replaces it with the new one. Assert.IsTrue(controller.giveActionCommand(unit, action2)); Assert.IsTrue(unit.getActionQueue()[0] == action2); Assert.IsFalse(unit.getActionQueue().Contains(action)); }
byte WAIT_TICKS = 30; // How many ticks to wait for another unit to move. #endregion Fields #region Constructors /// <summary> /// This constructor will create a MoveAction to the given targetX, and targetY. /// </summary> /// <param name="targetX">X coordinate destination of the move action in game space.</param> /// <param name="targetY">Y coordinate destination of the move action in game space.</param> /// <param name="gw">The GameWorld that the move action is occurring in.</param> /// <param name="entity">The Entity being given the MoveAction. (Should only be given to Units)</param> public MoveAction(float targetX, float targetY, GameWorld gw, Entity entity) { this.actionType = ActionType.Move; this.targetY = targetY; this.targetX = targetX; this.entity = entity; this.gw = gw; unit = (Unit)entity; float startX = unit.x; float startY = unit.y; if ((int)targetX >= gw.map.width || (int)targetX < 0 || (int)targetY >= gw.map.height || (int)targetY < 0) { // Invalid target position. path = new List<Cell>(); } else { path = findPath.between(gw.map, gw.map.getCell((int)startX, (int)startY), gw.map.getCell((int)targetX, (int)targetY)); // Don't bother with path if it is just to same cell. if (path.Count > 1) { targetCell = path[1]; cellIndex = 1; } else { path = new List<Cell>(); } } }
public void testInsertCommand() { Scenario scenario = new Scenario(20, 20); Controller controller = new Controller(scenario); Unit unit = new Unit(scenario.getPlayer(), 200); controller.addUnit(unit, 10f, 10f); // Create a MoveAction MoveAction action = new MoveAction(8f, 8f, scenario.getGameWorld(), unit); // Test if the ActionController returns true when it gives the command. Assert.IsTrue(controller.giveActionCommand(unit, action)); // Test if the MoveAction is actually on the unit's action queue. Assert.IsTrue(unit.getActionQueue()[0] == action); // Create a second MoveAction MoveAction action2 = new MoveAction(7f, 7f, scenario.getGameWorld(), unit); // Insert the second MoveAction to the beginning of the units action queue. ActionController.insertIntoActionQueue(unit, action2); Assert.IsTrue(unit.getActionQueue()[0] == action2); Assert.IsTrue(unit.getActionQueue()[1] == action); }
Unit unit; // Unit performing the AttackAction #endregion Fields #region Constructors /// <summary> /// Given a Unit, an Entity and a GameWorld, this constructor will create a GuardAttack object where the Unit is /// attacking the Entity in the GameWorld. /// </summary> /// <param name="unit">The Unit being given the GuardAttack command.</param> /// <param name="target">The Entity being targeted by the command.</param> /// <param name="gw">The GameWorld this is occurring in.</param> public GuardAttack(Unit unit, Entity target, GameWorld gw) { this.unit = unit; this.target = target; this.gw = gw; this.actionType = ActionType.GuardAttack; }
public void testMapWithUnitMove() { Scenario scenario = new Scenario(20, 20); Controller controller = new Controller(scenario); Unit unit = new Unit(scenario.getPlayer(), new UnitStats()); controller.addUnit(unit, 6, 6); MoveAction move = new MoveAction(10, 10, scenario.getGameWorld(), unit); controller.giveActionCommand(unit, move); // Update the world so that the unit moves. for (int i = 0; i < 1000; i++) { controller.updateWorld(); } // Test that all of the cells within the units visibility range have been explored. for (int i = (int)unit.x - (int)unit.stats.visibilityRange; i < (int)unit.x + (int)unit.stats.visibilityRange; i++) { for (int j = (int)unit.y - (int)unit.stats.visibilityRange; j < (int)unit.y + (int)unit.stats.visibilityRange; j++) { Assert.IsTrue(scenario.getGameWorld().map.getCell(i, j).explored); } } }
/// <summary> /// </summary> /// <param name="building"></param> /// <param name="unit"></param> public BuildAction(Building building, Unit unit, GameWorld gw) { this.building = building; this.unit = unit; this.actionType = ActionType.BuildBuilding; this.gw = gw; }
public void testUpdateUnit() { // Create a unit with 50% health unit = new Unit(new Player(0), new UnitStats()); unit.health = 100; unit.stats.maxHealth = 200; UnitStatsLogic.updateUnit(unit, 0); // Check if unit's buffs are set to 75% Assert.IsTrue(unit.attackBuff == 0.75); Assert.AreEqual(0.75, unit.speedBuff); }
public void testDeadUnit() { // Create a dead unit. unit = new Unit(new Player(0), new UnitStats()); unit.health = 0; unit.stats.maxHealth = 200; UnitStatsLogic.updateUnit(unit, 0); // Check if unit's buffs are set to 50% and that the unit's primary state is set to DEAD. Assert.IsTrue(unit.attackBuff == 0.50); Assert.AreEqual(0.50, unit.speedBuff); Assert.AreEqual(State.PrimaryState.Dead, unit.getState().getPrimaryState()); }
/**** FUNCTIONS FOR HANDLING EVENTS WHEN OBSERVER IS A UNIT ******/ /// <summary> /// Given a Unit and a GameWorld, this function will have the Unit "react" to all GameEvents in it's eventList. /// </summary> /// <param name="unit">The Unit reacting to it's events.</param> /// <param name="gw">The GameWorld the Unit is in.</param> private static void handleEventsForUnit(Unit unit, GameWorld gw) { foreach (GameEvent gameEvent in unit.getEventList()) { // Handle MoveEvent if (gameEvent.type == GameEvent.EventType.MoveEvent) { handleMoveEventUnit(unit, gameEvent, gw); } // Handle AttackEvent else if (gameEvent.type == GameEvent.EventType.AttackEvent) { handleAttackEventUnit(unit, gameEvent, gw); } } }
public void testMapWithUnit() { Scenario scenario = new Scenario(20, 20); Controller controller = new Controller(scenario); Unit unit = new Unit(scenario.getPlayer(), new UnitStats()); controller.addUnit(unit, 0, 0); // Test that all of the cells within the units visibility range have been explored. for (int i = 0; i < unit.stats.visibilityRange; i++) { for (int j = 0; j < unit.stats.visibilityRange; j++) { Assert.IsTrue(scenario.getGameWorld().map.getCell(i, j).explored); } } }
/// <summary> /// This method will update the visibility map to show that all Cells in a Units visibilityRange have been explored. /// </summary> /// <param name="unit"></param> public void updateVisMap(Unit unit) { // Only update the map if the unit belongs to the Human player. if (unit.getOwner() != humanPlayer) { return; } byte offset = (byte)unit.stats.visibilityRange; int xStart = (short)unit.x - offset; int xEnd = (short)unit.x + offset; int yStart = (short)unit.y - offset; int yEnd = (short)unit.y + offset; exploreMap(xStart, xEnd, yStart, yEnd); }
/// <summary> /// This method will process an AttackEvent that the unit observed and will determine how the unit should "react" to it. /// </summary> /// <param name="unit"></param> /// <param name="gameEvent"></param> /// <param name="gw"></param> private static void handleAttackEventUnit(Unit unit, GameEvent gameEvent, GameWorld gw) { // Check if unit is in the Passive AttackStance. if (unit.getAttackStance() == Unit.AttackStance.Passive) { // Ignore the AttackEvent. return; } // If an ally Entity is being attacked. if (gameEvent.targetEntity.getOwner() == unit.getOwner() && unit.getOwner().isEnemy(gameEvent.sourceEntity.getOwner())) { // If the unit is not performing any action. if (unit.getActionQueue().Count == 0) { // Attack the sourceEnemy } } }
public void testMove() { Scenario scenario = new Scenario(20, 20); Controller controller = new Controller(scenario); Unit unit = new Unit(scenario.getPlayer(), 200); controller.addUnit(unit, 10f, 10f); // Create a MoveAction MoveAction action = new MoveAction(8f, 8f, scenario.getGameWorld(), unit); controller.giveActionCommand(unit, action); Assert.AreEqual(scenario.getGameWorld().map.getCell(10, 10), unit.getCell()); // Run 1000 cycles of the game for (int i = 0; i < 1000; i++) { controller.updateWorld(); } // Test if the unit has ended up in the target cell. Assert.AreEqual(scenario.getGameWorld().map.getCell(8, 8), unit.getCell()); }
/// <summary> /// This method will find the cell closest to 'unit' that 'entity' is currently occupying. /// </summary> /// <param name="unit"></param> /// <param name="entity"></param> /// <returns></returns> public static Cell findClosestCell(Unit unit, StaticEntity se, GameWorld gw) { Cell cell = null; float dis = 10000; short xC = se.orginCell.Xcoord; short yC = se.orginCell.Ycoord; short width = se.width; short height = se.height; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (EntityLocController.findDistance(unit.x, unit.y, xC + i, yC + j) <= dis) { cell = gw.map.getCell(xC + i, xC + j); dis = EntityLocController.findDistance(unit.x, unit.y, xC + i, yC + j); } } } return cell; }
public bool setUnit(Unit unit) { if (this.isValid && this.unit == null) { this.unit = unit; this.isValid = false; return true; } return false; }
private void updateCellsUnitIsObserving(Unit unit) { // Have unit stop observing all the cells it is currently observing. unit.unregisterAll(); byte offset = (byte)unit.stats.visibilityRange; int xStart = (short)unit.x - offset; int xEnd = (short)unit.x + offset; int yStart = (short)unit.y - offset; int yEnd = (short)unit.y + offset; // Make sure that our bounds are valid. (Assumes that no Unit has a visibility range longer than the map.) if (xStart < 0) { xStart = 0; } else if (xEnd >= gw.map.width) { xEnd = gw.map.width; } if (yStart < 0) { yStart = 0; } else if (yEnd >= gw.map.height) { yEnd = gw.map.height; } // Set all cell explored flags to true. for (int i = xStart; i < xEnd; i++) { for (int j = yStart; j < yEnd; j++) { unit.register(gw.map.getCell(i, j)); } } }
/// <summary> /// This method will update the pointers to the Cell in the GameWorld that is occuppied by the Unit. /// </summary> /// <param name="unit">The unit who's location is being updated.</param> public void updateUnitLocation(Unit unit) { if (!unit.getCell().contains(unit.x, unit.y)) { Cell newCell = gw.map.getCell((int)Math.Floor(unit.x), (int)Math.Floor(unit.y)); Cell oldCell = unit.getCell(); oldCell.removeUnit(); // NOTE: doesn't check if newCell is already occupied. unit.setCell(newCell); newCell.setUnit(unit); } }
private static void updateAttackBuff(Unit unit) { /* The attackBuff is affected by a unit's health. The attack buff may be reduced to 50% if the unit loses all of it's health. */ double baseAttack = 0.5 + 0.5 * unit.health / unit.stats.maxHealth; unit.attackBuff = baseAttack; }
private static void updateSpeedBuff(Unit unit) { double baseSpeed = 0.5 + 0.5 * unit.health / unit.stats.maxHealth; unit.speedBuff = baseSpeed; }
/*** HELPER FUNCTIONS ****/ /// <summary> /// This function will search the cells that the unit can see for the closest enemy Unit. /// </summary> /// <param name="unit">The unit doing the searching</param> /// <param name="gw">The GameWorld to search</param> /// <returns>The closest enemy Unit or null if none exists</returns> private static Unit searchCellsForEnemy(Unit unit, GameWorld gw) { byte offset = (byte)unit.stats.visibilityRange; int xStart = (short)unit.x - offset; int xEnd = (short)unit.x + offset; int yStart = (short)unit.y - offset; int yEnd = (short)unit.y + offset; // Make sure that our bounds are valid. (Assumes that no Unit has a visibility range longer than the map.) if (xStart < 0) { xStart = 0; } else if (xEnd >= gw.map.width) { xEnd = gw.map.width; } if (yStart < 0) { yStart = 0; } else if (yEnd >= gw.map.height) { yEnd = gw.map.height; } Unit target = null; float distance = 10000f; // Set all cell explored flags to true. for (int i = xStart; i < xEnd; i++) { for (int j = yStart; j < yEnd; j++) { Unit temp = gw.map.getCell(i,j).getUnit(); if (temp != null && unit.getOwner().isEnemy(temp.getOwner())) { float tDis = EntityLocController.findDistance(unit.x, unit.y, temp.x, temp.y); if (tDis < distance) { target = temp; distance = tDis; } } } } return target; }
/// <summary> /// This method will update the pointers to the Cell in the GameWorld that is occuppied by the Unit. /// </summary> /// <param name="unit">The unit who's location is being updated.</param> public void updateUnitLocation(Unit unit) { if (!unit.getCell().contains(unit.x, unit.y)) { Cell newCell = gw.map.getCell((int)Math.Floor(unit.x), (int)Math.Floor(unit.y)); Cell oldCell = unit.getCell(); oldCell.removeUnit(); // NOTE: doesn't check if newCell is already occupied. unit.setCell(newCell); newCell.setUnit(unit); // Update the visibility map. this.visMapLogic.updateVisMap(unit); // Update the Cells that the unit is observing. updateCellsUnitIsObserving(unit); // Notify all observers of the cell that a unit has moved onto the cell. newCell.notify(new ZRTSModel.GameEvent.GameEvent(newCell, unit, unit, ZRTSModel.GameEvent.GameEvent.EventType.MoveEvent)); } }
/// <summary> /// This function will create a new Unit that belongs to 'owner' and has the UnitStats belonging to 'type' /// </summary> /// <param name="owner"></param> /// <param name="type"></param> /// <returns>A new Unit.</returns> public Unit createUnit(Player.Player owner, string type) { Unit u = new Unit(owner, stats[type]); u.health = u.stats.maxHealth; return u; }
public SimpleAttackAction(Unit unit, Entity target) { this.unit = unit; this.target = target; this.actionType = ActionType.SimpleAttack; }
public void removeUnit() { this.isValid = true; this.unit = null; }
/// <summary> /// Checking if unit is being selected /// </summary> /// <param name="u">Unit object</param> /// <returns>True if it is being selected</returns> private bool isUnitBeingSelected(ZRTSModel.Entities.Unit u) { return(this.scenario.getPlayer().SelectedEntities.Count > 0 && this.scenario.getPlayer().SelectedEntities.Contains(u)); }
/// <summary> /// This function will process a MoveEvent and will make the unit "react" to that move event. /// </summary> /// <param name="unit">The Unit that observed the event.</param> /// <param name="gameEvent">The MoveEvent</param> /// <param name="gw">The GameWorld this is occurring in.</param> private static void handleMoveEventUnit(Unit unit, GameEvent gameEvent, GameWorld gw) { Console.Write("Unit at (" + unit.x + ", " + unit.y + "): "); // Check if unit caused this MoveEvent if (gameEvent.sourceEntity == (Entity)unit) { Unit target = searchCellsForEnemy(unit, gw); if (target != null) { Console.WriteLine("See Enemy at " + target.getCell().Xcoord + ", ("+ target.getCell().Ycoord + ")"); } } // unit did not cause move event else { // Check if sourceEntity is an enemy if (unit.getOwner().isEnemy(gameEvent.sourceEntity.getOwner())) { // Check if unit is in the Aggressive AttackStance if (unit.getAttackStance() == Unit.AttackStance.Agressive) { if(isInterruptable(unit)) { AttackAction attackAction = new AttackAction(unit, gameEvent.sourceEntity, gw); ActionController.Instance.giveCommand(unit, attackAction); Console.WriteLine("Aggressive attack the entity in cell: " + gameEvent.orginCell.Xcoord + ", " + gameEvent.orginCell.Ycoord + ")"); } } // Check if unit is in the Guard AttackStance else if (unit.getAttackStance() == Unit.AttackStance.Guard) { GuardAttack guardAttack = new GuardAttack(unit, gameEvent.sourceEntity, gw); ActionController.Instance.giveCommand(unit, guardAttack); Console.WriteLine("Guard attack the entity in cell: " + gameEvent.orginCell.Xcoord + ", " + gameEvent.orginCell.Ycoord + ")"); } } } }
public Unit createUnit(Unit unit, string type) { return unit; }
/// <summary> /// Given a Unit an a string type, this function will give the unit the UnitStats of that type of Unit. /// </summary> /// <param name="unit">The Unit being given the UnitStats</param> /// <param name="type">denotes what type of UnitStats to use.</param> /// <returns></returns> public Unit createUnit(Unit unit, string type) { unit.stats = stats[type]; unit.health = unit.stats.maxHealth; return unit; }
Unit unit; // Unit performing the AttackAction #endregion Fields #region Constructors public AttackAction(Unit unit, Entity target, GameWorld gw) { this.unit = unit; this.target = target; this.gw = gw; }
/// <summary> /// Adds a Unit to the game. /// </summary> /// <param name="unit">The unit being added.</param> /// <param name="x">Desired X-coord of the Unit.</param> /// <param name="y">Desired Y-coord of the Unit.</param> /// <returns>true if the unit is added successfully, false otherwise.</returns> public bool addUnit(Unit unit, float x, float y) { return locController.addEntity(unit, x, y); }
public Unit createUnit(ZRTSModel.Player.Player owner, string unitType) { Unit unit = new Unit(owner, uFact.getStats(unitType)); return unit; }