public double GetDamage(Unit target, bool attacking) { double hardness = target.Type.Hardness.Value; double softness = 1 - hardness; if (attacking) { return(Stats.SoftAttack.Value * softness + Stats.HardAttack.Value * hardness); } else { int bonus = 0; int hexOffsetIndex = Map.GetHexOffsetIndex(target.Hex, Hex); RiverEdge riverEdge = Hex.RiverEdges[hexOffsetIndex]; if (riverEdge != null) { // Ground attacks across rivers cause defenders to receive a bonus bonus = 1; } return((Stats.SoftDefence.Value + bonus) * softness + (Stats.HardDefence.Value + bonus) * hardness); } }
void SetHexRiverData(Hex target, Hex neighbour, RiverEdge edge) { int index = GetHexOffsetIndex(target, neighbour); target.RiverEdges[index] = edge; }
void CreateMovementMap(Unit unit, Hex currentHex, Path currentPath, PlayerIdentifier owner, Dictionary <Position, Path> map) { for (int i = 0; i < HexOffsets.Length; i++) { RiverEdge riverEdge = currentHex.RiverEdges[i]; Position offset = HexOffsets[i]; Position neighbourPosition = currentHex.Position + offset; Hex neighbourHex = GetHex(neighbourPosition); if (neighbourHex == null) { // This hex is not part of the map, skip it continue; } if (neighbourHex.Unit != null && neighbourHex.Unit.Owner.Identifier != owner) { // This hex is already occupied by an enemy unit, skip it continue; } int terrainMovementPoints = neighbourHex.GetTerrainMovementPoints(); int movementPointsLost; if (riverEdge != null && !riverEdge.IsBridge) { // It's a move across a river without a bridge // This is only possible under special circumstances // The unit must have its full movement points and it will lose all of them after the crossing int maximumMovementPoints = unit.Stats.Movement.Value; if (currentPath.MovementPointsLeft < maximumMovementPoints) { // The unit had already moved so it can't cross the river continue; } if (currentPath.MovementPointsLeft < terrainMovementPoints) { // This is an extraordinarily rare case but it means that the unit can't cross the river because it couldn't enter the target terrain type, even if the river wasn't there continue; } movementPointsLost = maximumMovementPoints; } else { // It's either a regular move without a river or a move across a bridge movementPointsLost = terrainMovementPoints; } int newMovementPoints = currentPath.MovementPointsLeft - movementPointsLost; if (newMovementPoints < 0) { // The unit doesn't have enough movement points left to enter this hex continue; } Path previousPath; if (map.TryGetValue(neighbourPosition, out previousPath)) { // This neighbouring hex was already analysed by a previous recursive call to this function, check if we can even improve on what it calculated if (previousPath.MovementPointsLeft <= newMovementPoints) { // The solution is inferior or just as good, skip it continue; } } // Create or update the entry in the movement map Path newPath = new Path(currentPath, neighbourHex, newMovementPoints); map[neighbourPosition] = newPath; CreateMovementMap(unit, neighbourHex, newPath, owner, map); } }