|
@ -20,13 +20,12 @@ namespace GWConquest |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private enum UnitActionType { |
|
|
private enum UnitActionType { |
|
|
Combat, Shelling |
|
|
|
|
|
|
|
|
Combat, Shelling, Reveal, RevealSelf |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
[System.Serializable] |
|
|
[System.Serializable] |
|
|
private class UnitAction { |
|
|
private class UnitAction { |
|
|
public Unit Unit; |
|
|
public Unit Unit; |
|
|
public BattleFlank BattleFlank; |
|
|
|
|
|
public int WeaponIndex; |
|
|
public int WeaponIndex; |
|
|
public float ActionTime; |
|
|
public float ActionTime; |
|
|
public UnitActionType ActionType = UnitActionType.Combat; |
|
|
public UnitActionType ActionType = UnitActionType.Combat; |
|
@ -34,6 +33,36 @@ namespace GWConquest |
|
|
public WeaponStats Weapon { |
|
|
public WeaponStats Weapon { |
|
|
get => Unit.Class.WeaponStatsArray[WeaponIndex]; |
|
|
get => Unit.Class.WeaponStatsArray[WeaponIndex]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void RenewAction() |
|
|
|
|
|
{ |
|
|
|
|
|
GameManager gm = GameManager.Instance; |
|
|
|
|
|
float attackDelay; |
|
|
|
|
|
if(ActionType == UnitActionType.Reveal || ActionType == UnitActionType.RevealSelf) |
|
|
|
|
|
{ |
|
|
|
|
|
attackDelay = Random.Range(gm.RevealTurnLength - gm.RevealTurnDeviation, gm.RevealTurnLength + gm.RevealTurnDeviation); |
|
|
|
|
|
//attackDelay /= Weapon.AttackCount;
|
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
attackDelay = Random.Range(gm.BattleTurnLength - gm.BattleTurnDeviation, gm.BattleTurnLength + gm.BattleTurnDeviation); |
|
|
|
|
|
attackDelay /= Weapon.AttackCount; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ActionTime = Time.fixedTime + attackDelay; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public bool IsValid() |
|
|
|
|
|
{ |
|
|
|
|
|
if(ActionType == UnitActionType.RevealSelf) |
|
|
|
|
|
{ |
|
|
|
|
|
return Unit.RevealState != RevealState.Visible; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public int FlankCount { |
|
|
public int FlankCount { |
|
@ -249,7 +278,13 @@ namespace GWConquest |
|
|
{ |
|
|
{ |
|
|
SimulateUnitAction(action); |
|
|
SimulateUnitAction(action); |
|
|
|
|
|
|
|
|
RenewUnitAction(action); |
|
|
|
|
|
|
|
|
if(action.IsValid()) |
|
|
|
|
|
{ |
|
|
|
|
|
action.RenewAction(); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
UnitActions.Remove(action); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
hasChanges = true; |
|
|
hasChanges = true; |
|
|
} |
|
|
} |
|
@ -278,7 +313,6 @@ namespace GWConquest |
|
|
|
|
|
|
|
|
private void AddCombatActions(Unit unit) |
|
|
private void AddCombatActions(Unit unit) |
|
|
{ |
|
|
{ |
|
|
float time = Time.fixedTime; |
|
|
|
|
|
if(unit.CurrentFlank != null && !unit.IsDead) |
|
|
if(unit.CurrentFlank != null && !unit.IsDead) |
|
|
{ |
|
|
{ |
|
|
var weapons = unit.Class.WeaponStatsArray; |
|
|
var weapons = unit.Class.WeaponStatsArray; |
|
@ -286,10 +320,9 @@ namespace GWConquest |
|
|
{ |
|
|
{ |
|
|
var action = new UnitAction() { |
|
|
var action = new UnitAction() { |
|
|
Unit = unit, |
|
|
Unit = unit, |
|
|
BattleFlank = unit.CurrentFlank, |
|
|
|
|
|
WeaponIndex = i |
|
|
WeaponIndex = i |
|
|
}; |
|
|
}; |
|
|
RenewUnitAction(action); |
|
|
|
|
|
|
|
|
action.RenewAction(); |
|
|
UnitActions.Add(action); |
|
|
UnitActions.Add(action); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -297,7 +330,6 @@ namespace GWConquest |
|
|
|
|
|
|
|
|
private void AddShellingActions(Unit unit) |
|
|
private void AddShellingActions(Unit unit) |
|
|
{ |
|
|
{ |
|
|
float time = Time.fixedTime; |
|
|
|
|
|
if(!unit.IsDead) |
|
|
if(!unit.IsDead) |
|
|
{ |
|
|
{ |
|
|
var weapons = unit.Class.WeaponStatsArray; |
|
|
var weapons = unit.Class.WeaponStatsArray; |
|
@ -305,25 +337,26 @@ namespace GWConquest |
|
|
{ |
|
|
{ |
|
|
var action = new UnitAction() { |
|
|
var action = new UnitAction() { |
|
|
Unit = unit, |
|
|
Unit = unit, |
|
|
BattleFlank = null, |
|
|
|
|
|
WeaponIndex = i, |
|
|
WeaponIndex = i, |
|
|
ActionType = UnitActionType.Shelling |
|
|
ActionType = UnitActionType.Shelling |
|
|
}; |
|
|
}; |
|
|
RenewUnitAction(action); |
|
|
|
|
|
|
|
|
action.RenewAction(); |
|
|
UnitActions.Add(action); |
|
|
UnitActions.Add(action); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private void RenewUnitAction(UnitAction action) |
|
|
|
|
|
|
|
|
private void AddGenericAction(Unit unit, UnitActionType actionType) |
|
|
{ |
|
|
{ |
|
|
var attackCount = action.Weapon.AttackCount; |
|
|
|
|
|
var gm = GameManager.Instance; |
|
|
|
|
|
|
|
|
|
|
|
float attackDelay = Random.Range(gm.BattleTurnLength - gm.BattleTurnDeviation, gm.BattleTurnLength + gm.BattleTurnDeviation); |
|
|
|
|
|
attackDelay /= attackCount; |
|
|
|
|
|
|
|
|
|
|
|
action.ActionTime = Time.fixedTime + attackDelay; |
|
|
|
|
|
|
|
|
if(!unit.IsDead) |
|
|
|
|
|
{ |
|
|
|
|
|
var action = new UnitAction() { |
|
|
|
|
|
Unit = unit, |
|
|
|
|
|
ActionType = actionType |
|
|
|
|
|
}; |
|
|
|
|
|
action.RenewAction(); |
|
|
|
|
|
UnitActions.Add(action); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private void RemoveUnitActions(Unit unit) |
|
|
private void RemoveUnitActions(Unit unit) |
|
@ -333,11 +366,14 @@ namespace GWConquest |
|
|
|
|
|
|
|
|
private void SimulateUnitAction(UnitAction action) |
|
|
private void SimulateUnitAction(UnitAction action) |
|
|
{ |
|
|
{ |
|
|
var unit = action.Unit; |
|
|
|
|
|
var flank = action.BattleFlank; |
|
|
|
|
|
BoltLog.Info("Simulating action for unit {0} on flank {1}", unit, flank); |
|
|
|
|
|
|
|
|
BoltLog.Info("Simulating action {0} for unit {1} on flank {2}", action.ActionType, action.Unit, action.Unit.CurrentFlank); |
|
|
|
|
|
|
|
|
|
|
|
if(action.ActionType == UnitActionType.RevealSelf) |
|
|
|
|
|
{ |
|
|
|
|
|
PerformRevealSelf(action); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
var weapon = action.Weapon; |
|
|
|
|
|
|
|
|
|
|
|
var target = FindTargetForCombat(action); |
|
|
var target = FindTargetForCombat(action); |
|
|
|
|
|
|
|
@ -346,6 +382,44 @@ namespace GWConquest |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(action.ActionType == UnitActionType.Reveal) |
|
|
|
|
|
{ |
|
|
|
|
|
PerformReveal(action, target); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
PerformAttack(action, target); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void PerformReveal(UnitAction action, Unit target) |
|
|
|
|
|
{ |
|
|
|
|
|
var flank = action.Unit.CurrentFlank; |
|
|
|
|
|
bool areOnOpposingFlanks = flank != null && flank.OpposingFlank == target.CurrentFlank; |
|
|
|
|
|
float chance = areOnOpposingFlanks ? GameManager.Instance.RevealChanceFlank : GameManager.Instance.RevealChanceOther; |
|
|
|
|
|
if(!Check(chance)) |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
BoltLog.Info("Revealing unit {0} from unit {1}", target, action.Unit); |
|
|
|
|
|
|
|
|
|
|
|
target.IncreaseRevealLevel(); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void PerformRevealSelf(UnitAction action) |
|
|
|
|
|
{ |
|
|
|
|
|
if(!Check(GameManager.Instance.RevealChanceSelf)) |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
BoltLog.Info("Revealing unit {0} by itself", action.Unit); |
|
|
|
|
|
|
|
|
|
|
|
action.Unit.IncreaseRevealLevel(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void PerformAttack(UnitAction action, Unit target) |
|
|
|
|
|
{ |
|
|
|
|
|
var weapon = action.Weapon; |
|
|
|
|
|
|
|
|
if(!Check(weapon.Accuracy)) |
|
|
if(!Check(weapon.Accuracy)) |
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
@ -360,12 +434,12 @@ namespace GWConquest |
|
|
if(damage < 0) |
|
|
if(damage < 0) |
|
|
damage = 0; |
|
|
damage = 0; |
|
|
|
|
|
|
|
|
BoltLog.Info("Dealing {0} HP damage (armour modifier: {1}) to unit {2} from unit {3}", damage, modifier, target, unit); |
|
|
|
|
|
|
|
|
BoltLog.Info("Dealing {0} HP damage (armour modifier: {1}) to unit {2} from unit {3}", damage, modifier, target, action.Unit); |
|
|
|
|
|
|
|
|
bool isGlancingHit = damage == 0 || modifier < 1f; |
|
|
bool isGlancingHit = damage == 0 || modifier < 1f; |
|
|
|
|
|
|
|
|
WeaponType weaponType; |
|
|
WeaponType weaponType; |
|
|
if(unit.Class.UnitType == UnitType.Infantry) |
|
|
|
|
|
|
|
|
if(action.Unit.Class.UnitType == UnitType.Infantry) |
|
|
{ |
|
|
{ |
|
|
weaponType = WeaponType.Light; |
|
|
weaponType = WeaponType.Light; |
|
|
} |
|
|
} |
|
@ -373,33 +447,47 @@ namespace GWConquest |
|
|
weaponType = weapon.Penetration > 1f ? WeaponType.Heavy : WeaponType.MG; |
|
|
weaponType = weapon.Penetration > 1f ? WeaponType.Heavy : WeaponType.MG; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
target.TakeDamage(damage, unit, isGlancingHit, weaponType); |
|
|
|
|
|
|
|
|
target.TakeDamage(damage, action.Unit, isGlancingHit, weaponType); |
|
|
|
|
|
|
|
|
|
|
|
if(target.RevealState != RevealState.Visible) |
|
|
|
|
|
{ |
|
|
|
|
|
target.RevealState = RevealState.Visible; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(action.Unit.RevealState != RevealState.Visible) |
|
|
|
|
|
{ |
|
|
|
|
|
if(Check(GameManager.Instance.RevealChanceAttack)) |
|
|
|
|
|
{ |
|
|
|
|
|
BoltLog.Info("Revealing unit {0} as it attacked unit {1}", action.Unit, target); |
|
|
|
|
|
action.Unit.IncreaseRevealLevel(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private Unit FindTargetForCombat(UnitAction action) |
|
|
private Unit FindTargetForCombat(UnitAction action) |
|
|
{ |
|
|
{ |
|
|
|
|
|
var flank = action.Unit.CurrentFlank; |
|
|
IEnumerable<Unit> targets; |
|
|
IEnumerable<Unit> targets; |
|
|
|
|
|
|
|
|
if(action.ActionType == UnitActionType.Combat && action.BattleFlank != null) |
|
|
|
|
|
|
|
|
if(action.ActionType == UnitActionType.Combat && flank != null) |
|
|
{ |
|
|
{ |
|
|
targets = action.BattleFlank.OpposingFlank.Units; |
|
|
|
|
|
|
|
|
targets = flank.OpposingFlank.Units; |
|
|
|
|
|
|
|
|
if(IsSpaceBattle) |
|
|
if(IsSpaceBattle) |
|
|
{ |
|
|
{ |
|
|
var attackRange = action.Unit.Class.AttackRange; |
|
|
var attackRange = action.Unit.Class.AttackRange; |
|
|
var ownRow = action.BattleFlank.GetRowForUnit(action.Unit); |
|
|
|
|
|
|
|
|
var ownRow = flank.GetRowForUnit(action.Unit); |
|
|
targets = targets.Where(u => { |
|
|
targets = targets.Where(u => { |
|
|
var enemyRow = u.CurrentFlank.GetRowForUnit(u); |
|
|
var enemyRow = u.CurrentFlank.GetRowForUnit(u); |
|
|
return Mathf.Abs(enemyRow-ownRow) <= attackRange; |
|
|
return Mathf.Abs(enemyRow-ownRow) <= attackRange; |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
targets = targets.Where(u => !u.Class.IsHero && !u.IsDead); |
|
|
|
|
|
|
|
|
targets = targets.Where(u => !u.Class.IsHero && !u.IsDead && u.RevealState != RevealState.FullHidden); |
|
|
|
|
|
|
|
|
if(targets.FirstOrDefault() == null) |
|
|
if(targets.FirstOrDefault() == null) |
|
|
{ |
|
|
{ |
|
|
targets = AllUnits.Where(u => !u.Class.IsHero && !u.IsDead && u.Player != action.Unit.Player && u.IsInReserve); |
|
|
|
|
|
|
|
|
targets = AllUnits.Where(u => !u.Class.IsHero && !u.IsDead && u.Player != action.Unit.Player && u.IsInReserve && u.RevealState != RevealState.FullHidden); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else if(action.ActionType == UnitActionType.Shelling) { |
|
|
else if(action.ActionType == UnitActionType.Shelling) { |
|
@ -414,6 +502,16 @@ namespace GWConquest |
|
|
|
|
|
|
|
|
targets = targets.Where(u => !u.Class.IsHero && !u.IsDead); |
|
|
targets = targets.Where(u => !u.Class.IsHero && !u.IsDead); |
|
|
} |
|
|
} |
|
|
|
|
|
else if(action.ActionType == UnitActionType.Reveal) { |
|
|
|
|
|
targets = flank.OpposingFlank.Units; |
|
|
|
|
|
|
|
|
|
|
|
targets = targets.Where(u => !u.Class.IsHero && !u.IsDead && u.RevealState != RevealState.Visible); |
|
|
|
|
|
|
|
|
|
|
|
if(targets.FirstOrDefault() == null) |
|
|
|
|
|
{ |
|
|
|
|
|
targets = AllUnits.Where(u => !u.Class.IsHero && !u.IsDead && u.Player != action.Unit.Player && u.RevealState != RevealState.Visible); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
else { |
|
|
else { |
|
|
throw new System.NotImplementedException(); |
|
|
throw new System.NotImplementedException(); |
|
|
} |
|
|
} |
|
@ -423,24 +521,34 @@ namespace GWConquest |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
float penetration = action.Unit.Class.WeaponStatsArray[action.WeaponIndex].Penetration; |
|
|
|
|
|
|
|
|
List<Unit> tList; |
|
|
|
|
|
|
|
|
IEnumerable<Unit> penTargets = null;; |
|
|
|
|
|
for(float p = penetration; p >= 0; p--) |
|
|
|
|
|
|
|
|
if(action.ActionType == UnitActionType.Combat) |
|
|
{ |
|
|
{ |
|
|
penTargets = targets.Where(u => u.Armour <= p && u.Armour > p - 1); |
|
|
|
|
|
if(penTargets.FirstOrDefault() != null) |
|
|
|
|
|
|
|
|
float penetration = action.Unit.Class.WeaponStatsArray[action.WeaponIndex].Penetration; |
|
|
|
|
|
|
|
|
|
|
|
IEnumerable<Unit> penTargets = null;; |
|
|
|
|
|
for(float p = penetration; p >= 0; p--) |
|
|
{ |
|
|
{ |
|
|
break; |
|
|
|
|
|
|
|
|
penTargets = targets.Where(u => u.Armour <= p && u.Armour > p - 1); |
|
|
|
|
|
if(penTargets.FirstOrDefault() != null) |
|
|
|
|
|
{ |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(penTargets == null || penTargets.FirstOrDefault() == null) |
|
|
|
|
|
{ |
|
|
|
|
|
penTargets = targets; |
|
|
|
|
|
|
|
|
if(penTargets == null || penTargets.FirstOrDefault() == null) |
|
|
|
|
|
{ |
|
|
|
|
|
penTargets = targets; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
tList = penTargets.ToList(); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
tList = targets.ToList(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var tList = penTargets.ToList(); |
|
|
|
|
|
|
|
|
|
|
|
int randomInd = Random.Range(0, tList.Count); |
|
|
int randomInd = Random.Range(0, tList.Count); |
|
|
|
|
|
|
|
|
return tList[randomInd]; |
|
|
return tList[randomInd]; |
|
@ -450,9 +558,18 @@ namespace GWConquest |
|
|
{ |
|
|
{ |
|
|
RemoveUnitActions(unit); |
|
|
RemoveUnitActions(unit); |
|
|
|
|
|
|
|
|
|
|
|
if(!IsSpaceBattle && unit.RevealState != RevealState.Visible) |
|
|
|
|
|
{ |
|
|
|
|
|
AddGenericAction(unit, UnitActionType.RevealSelf); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if(unit.BattleState == BattleUnitState.OnFlank) |
|
|
if(unit.BattleState == BattleUnitState.OnFlank) |
|
|
{ |
|
|
{ |
|
|
AddCombatActions(unit); |
|
|
AddCombatActions(unit); |
|
|
|
|
|
if(!IsSpaceBattle) |
|
|
|
|
|
{ |
|
|
|
|
|
AddGenericAction(unit, UnitActionType.Reveal); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
else if(unit.BattleState == BattleUnitState.Shelling) |
|
|
else if(unit.BattleState == BattleUnitState.Shelling) |
|
|
{ |
|
|
{ |
|
@ -507,7 +624,7 @@ namespace GWConquest |
|
|
unit.SetActionCooldown(GameManager.Instance.MoveToReserveCooldown / movement); |
|
|
unit.SetActionCooldown(GameManager.Instance.MoveToReserveCooldown / movement); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private static bool Check(float chance) { |
|
|
|
|
|
|
|
|
public static bool Check(float chance) { |
|
|
return Random.Range(0f, 1f) <= chance; |
|
|
return Random.Range(0f, 1f) <= chance; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|