public Dictionary <Position, List <List <Position> > > GetShotOptions(Position Shooter) { Unit unit = GetUnitAtPos(Shooter); Dictionary <Position, List <List <Position> > > ShotOptions = new Dictionary <Position, List <List <Position> > >(); RangedWeapon rangedWeapon = unit.GetRangedWeapon(); if (rangedWeapon != null) //should always be true. because game should only forward requests of units with a ranged weapon { for (int i = 0; i < Rows; i++) { for (int j = 0; j < Columns; j++) { Square square = board[i][j]; if (square.Unit != Config.NullUnit && square.Unit.Player != unit.Player) { Position pos = new Position(i, j); List <List <Position> > ShotDetails = GetShotPathDetails(Shooter, pos); if (ShotDetails[2].Count == 0 && rangedWeapon.Range >= Shooter.Distance(pos) - Utils.epsilon) { ShotOptions[pos] = ShotDetails; } } } } return(ShotOptions); } throw new ArgumentException(); }
} //when you select a unit in the shoot phase. get all shoot options. then store them in a dict. //public void Shoot(Position Shooter,Position Target) { // List<List<Position>> ShotDetails = ShotOptions[Target]; // List<Position> PosPreventingShot = ShotDetails[2]; // Unit ShootingUnit = BoardManager.GetUnitAtPos(Shooter); // RangedWeapon rangedItem = ShootingUnit.GetRangedWeapon(); // if (PosPreventingShot.Count == 0 && !ShootingUnit.HasShot && rangedItem!=null) {//ranged item should never be null // int roll = Utils.RollD6(1)[0]; // ShootingUnit.HasShot = true; // if (roll >= ShootingUnit.ShootingSkill) {//shooter hit target // List<Position> ObstructionPos = ShotDetails[1]; // for (int i = 0; i < ObstructionPos.Count; i++) {//TODO determine if you pass obsticule based upon shootingskill? // //roll to see if you pass each object // roll = Utils.RollD6(1)[0]; // if (roll <= 3) {//didn't pass obj // Unit unit = BoardManager.GetUnitAtPos(Shooter); // Trace.WriteLine(unit.Player.Name + "'s " + unit.Name + " missed his target, (but might still hit someone else acidentally)"); // Square square = BoardManager.GetSquareAtPos(ObstructionPos[i]); // if (!square.Terrain.IsStandable) { // return; // }else if (square.Unit != Config.NullUnit && !square.Unit.InConflict) { // Target = ObstructionPos[i]; // break; // }else if (square.Unit.InConflict) { // List<Unit> unitsInConflict = conflictManager.GetUnitsInTempConflict(BoardManager.GetUnitAtPos(Target)); // int targetIndex = Utils.GenerateRandomInt(unitsInConflict.Count); // Target = unitsInConflict[targetIndex].Position; // break; // } // } // } // Unit struckUnit = BoardManager.GetUnitAtPos(Target); // if (Utils.ResolveStrike(rangedItem.Strength, struckUnit.GetDefense())) { // struckUnit.Wounds -= 1; // Unit unit = BoardManager.GetUnitAtPos(Shooter); // Trace.WriteLine(unit.Player.Name + "'s " + unit.Name + " hit and wounded a unit (probably his target)"); // if (struckUnit.Wounds < 1) { // KillUnit(struckUnit); // if(struckUnit.InConflict) { // conflictManager.ResolvePrematureDeath(struckUnit); // } // } // }else { // Unit unit = BoardManager.GetUnitAtPos(Shooter); // Trace.WriteLine(unit.Player.Name + "'s " + unit.Name + " hit a unit (probably his target) but didn't wound him"); // } // } else { // Unit unit = BoardManager.GetUnitAtPos(Shooter); // Trace.WriteLine(unit.Player.Name + "'s " + unit.Name + " missed his target"); // } // } //} public void Shoot(Position Shooter, Position Target) { //throw new NotImplementedException(); List <List <Position> > ShotDetails = ShotOptions[Target]; List <Position> PosPreventingShot = ShotDetails[2]; Unit ShootingUnit = BoardManager.GetUnitAtPos(Shooter); RangedWeapon rangedItem = ShootingUnit.GetRangedWeapon(); if (PosPreventingShot.Count == 0 && !ShootingUnit.HasShot && rangedItem != null) //ranged item should never be null { int roll = Utils.RollD6(1)[0]; ShootingUnit.HasShot = true; if (roll >= ShootingUnit.ShootingSkill) //shooter hit target { List <Position> ObstructionPos = ShotDetails[1]; for (int i = 0; i < ObstructionPos.Count; i++) //TODO determine if you pass obsticule based upon shootingskill? //roll to see if you pass each object { roll = Utils.RollD6(1)[0]; if (roll <= 3) //didn't pass obj { Unit unit = BoardManager.GetUnitAtPos(Shooter); Trace.WriteLine(unit.Player.Name + "'s " + unit.Name + " missed his target, (but might still hit someone else acidentally)"); Square square = BoardManager.GetSquareAtPos(ObstructionPos[i]); if (!square.Terrain.IsStandable) { return; } else if (square.Unit != Config.NullUnit && !square.Unit.InConflict) { Target = ObstructionPos[i]; break; } else if (square.Unit.InConflict) { List <Unit> unitsInConflict = conflictManager.GetUnitsInTempConflict(BoardManager.GetUnitAtPos(Target)); int targetIndex = Utils.GenerateRandomInt(unitsInConflict.Count); Target = unitsInConflict[targetIndex].Position; break; } } } Unit struckUnit = BoardManager.GetUnitAtPos(Target); if (Utils.ResolveStrike(struckUnit, rangedItem.Strength, rangedItem.Strength)) { KillUnit(struckUnit); if (struckUnit.InConflict) { conflictManager.ResolvePrematureDeath(struckUnit); } } } else { Unit unit = BoardManager.GetUnitAtPos(Shooter); Trace.WriteLine(unit.Player.Name + "'s " + unit.Name + " missed his target"); } } }
} //whenever gui wants to update shot details just send them the dict values public List <Position> GetShotOptions(Position Shooter) { Unit unit = BoardManager.GetUnitAtPos(Shooter); if (!unit.InConflict && !unit.HasShot) { bool canShoot = false; RangedWeapon rangedItem = unit.GetRangedWeapon(); if (rangedItem != null) { if ((double)unit.MovementLeft / unit.MaxMoveDist >= rangedItem.MovementCost - Utils.epsilon) { canShoot = true; } } if (canShoot) // check to make sure unit has an item to shoot with. check to make sure unit has enough movement left and hasn't already shot. { ShotOptions = BoardManager.GetShotOptions(Shooter); return(ShotOptions.Keys.ToList()); //to display shoot buttons } } ShotOptions = new Dictionary <Position, List <List <Position> > >(); return(ShotOptions.Keys.ToList()); } //when you select a unit in the shoot phase. get all shoot options. then store them in a dict.