public virtual void ExecutePhase(VesselPhase vp) { switch (vp.phaseType) { case EPhaseType.MOVE: //Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + " moved to new location."); nextMovePhaseTime += movePhasePeriod; break; case EPhaseType.ACTION: List <Vessel> targets = this.GetTargets(VesselActions.ETargetType.SURF | VesselActions.ETargetType.SUB, true); if (targets.Count > 0 && UnityEngine.Random.Range(0, this.maxHp * 0.6f) <= this.hp) { bool hasLaunchedAircraft = false; int maxAircraftLaunched = this.GetMaxAircraftLaunched(); if (targets.Any((Vessel v) => v.vesselType == EVesselType.CV || v.vesselType == EVesselType.CVL) == false) { // There's no CV/CVL and we don't need to worry about air-strikes. Vessel target = targets[UnityEngine.Random.Range(0, targets.Count)]; if (target.vesselType == EVesselType.SS) { for (int i = 0; i < aircraftSlots.Length; ++i) { if (aircrafts[i].aircraftType == EAircraftType.ASW_BOMBER) { Aircraft aircraft = this.LaunchAircraft(i); if (aircraft != null) { Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + " launched " + aircrafts[i].gameObject.name + "x" + aircraft.hp.ToString() ); hasLaunchedAircraft = true; break; } } } } if (hasLaunchedAircraft == false) { if (this.GetTargets(VesselActions.ETargetType.SURF, true).Count > 0) { for (int i = 0; i < aircraftSlots.Length; ++i) { if (aircrafts[i].aircraftType == EAircraftType.BOMBER || aircrafts[i].aircraftType == EAircraftType.TORPEDO_BOMBER) { Aircraft aircraft = this.LaunchAircraft(i); if (aircraft != null) { Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + " launched " + aircrafts[i].gameObject.name + "x" + aircraft.hp.ToString() ); hasLaunchedAircraft = true; break; } } } } } } if (hasLaunchedAircraft == false) { bool aircraftAvailable = this.CheckAircraftAvailable(); if (aircraftAvailable && maxAircraftLaunched > 0) { // The vessel can launch aircrafts. for (int i = 0; i < aircraftSlots.Length; ++i) { // Kamikaze aircrafts are only launched when there are existing targets. if (aircrafts[i].kamikaze) { bool canEngageAir = aircrafts[i].antiAir > 0; bool canEngageSurf = aircrafts[i].gunPower > 0 || aircrafts[i].torpedoPower > 0; bool canEngageSub = aircrafts[i].aswPower > 0; bool needsToLaunch = false; if (canEngageAir && this.GetTargets(VesselActions.ETargetType.AIR, true).Count > 0) { needsToLaunch |= true; } if (canEngageSurf && this.GetTargets(VesselActions.ETargetType.SURF, true).Count > 0) { needsToLaunch |= true; } if (canEngageSub && this.GetTargets(VesselActions.ETargetType.SUB, true).Count > 0) { needsToLaunch |= true; } if (needsToLaunch == false) { continue; } } Aircraft aircraft = this.LaunchAircraft(i); if (aircraft != null) { Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + " launched " + aircrafts[i].gameObject.name + "x" + aircraft.hp.ToString() ); hasLaunchedAircraft = true; break; } } } } if (hasLaunchedAircraft == true) { nextActionPhaseTime += actionPhasePeriod; } else { Vessel target = targets[UnityEngine.Random.Range(0, targets.Count)]; bool isCritical; bool canUseGun = this.CheckRange(target, VesselActions.EWeaponType.GUN); bool canUseTorpedo = this.CheckRange(target, VesselActions.EWeaponType.TORPEDO); bool canUseASW = this.CheckRange(target, VesselActions.EWeaponType.ASW); if (canUseASW && target.vesselType == EVesselType.SS) { int origHp = hp; int damage = CombatEvaluator.DamageByASW(this, target, out isCritical); Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + " attacked " + target.gameObject.name + " with depth-charges: " + damage.ToString() + (isCritical ? " Critical!" : "")); this.OnDamaged(0); target.OnDamaged(Mathf.Max(0, damage)); nextActionPhaseTime += actionPhasePeriod; } else if (UnityEngine.Random.Range(0, gunPower + torpedoPower) < gunPower) { int damage = CombatEvaluator.DamageByGun(this, target, out isCritical); Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + " attacked " + target.gameObject.name + " with guns: " + damage.ToString() + (isCritical ? " Critical!" : "")); target.OnDamaged(Mathf.Max(0, damage)); nextActionPhaseTime += actionPhasePeriod; } else { int damage = CombatEvaluator.DamageByTorpedo(this, target, out isCritical); Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + " attacked " + target.gameObject.name + " with torpedos: " + damage.ToString() + (isCritical ? " Critical!" : "")); target.OnDamaged(Mathf.Max(0, damage)); nextActionPhaseTime += actionPhasePeriod; } } } else { // Damage control. Recover some hp this round. int hpRepaired = hp; hp = Mathf.Max(hp, Mathf.FloorToInt(Mathf.Lerp(hp, maxHp * 0.75f, 0.15f))); hpRepaired = hp - hpRepaired; if (hpRepaired > 0) { Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + " repaired: +" + hpRepaired.ToString()); nextActionPhaseTime += actionPhasePeriod; } else { nextActionPhaseTime += actionPhasePeriod; } } break; } ownPhases.Remove(vp); CheckPhase(); BattleManager.instance.Invoke("ExecuteNextPhase", 0.25f); }
public override void ExecutePhase(VesselPhase vp) { fuel--; switch (vp.phaseType) { case EPhaseType.MOVE: //Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + " moved to new location."); nextMovePhaseTime += movePhasePeriod; if (aircraftType == EAircraftType.SURVEILLANCE) { if (fuel > 0) { CreatePhase(EPhaseType.MOVE, nextMovePhaseTime); } else { SetupRTBPhase(); } } else { CreatePhase(EPhaseType.ACTION, nextMovePhaseTime); } break; case EPhaseType.ACTION: List <Vessel> targets = this.GetTargets(VesselActions.ETargetType.AIR, false); if (this.aircraftType == EAircraftType.FIGHTER && targets.Count > 0) { Aircraft target = targets[UnityEngine.Random.Range(0, targets.Count)] as Aircraft; int attackerHp = this.hp; if (target == null) { Debug.LogError(targets.Count.ToString()); } int defenderHp = target.hp; CombatEvaluator.AirCombat(this, target); if (kamikaze) { hp = 0; } Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + "(" + attackerHp.ToString() + "->" + this.hp.ToString() + ") engaged with " + target.gameObject.name + "(" + defenderHp.ToString() + "->" + target.hp.ToString() + ")" ); // Notify the attacker/defender that their Hp might have changed. this.OnDamaged(0); target.OnDamaged(0); nextMovePhaseTime += actionPhasePeriod; } else { targets = this.GetTargets(VesselActions.ETargetType.SURF | VesselActions.ETargetType.SUB, false); if (targets.Count > 0) { Vessel target = targets[UnityEngine.Random.Range(0, targets.Count)]; bool isCritical; bool canUseGun = this.CheckRange(target, VesselActions.EWeaponType.BOMB); bool canUseTorpedo = this.CheckRange(target, VesselActions.EWeaponType.AERIAL_TORPEDO); bool canUseASW = this.CheckRange(target, VesselActions.EWeaponType.AERIAL_ASW); if (canUseASW && target.vesselType == EVesselType.SS) { int origHp = hp; int damage = CombatEvaluator.DamageByAerialASW(this, target, out isCritical); if (kamikaze) { hp = 0; } Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + "(" + origHp.ToString() + "->" + hp.ToString() + ") attacked " + target.gameObject.name + (kamikaze ? ": " : " with depth-charges: ") + damage.ToString() + (isCritical ? " Critical!" : "")); this.OnDamaged(0); target.OnDamaged(Mathf.Max(0, damage)); nextMovePhaseTime += actionPhasePeriod; } else if (UnityEngine.Random.Range(0, (canUseGun ? gunPower : 0) + (canUseTorpedo ? torpedoPower : 0)) < (canUseGun ? gunPower : 0)) { int origHp = hp; int damage = CombatEvaluator.DamageByBomb(this, target, out isCritical); if (kamikaze) { hp = 0; } Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + "(" + origHp.ToString() + "->" + hp.ToString() + ") attacked " + target.gameObject.name + (kamikaze ? ": " : " with bombs: ") + damage.ToString() + (isCritical ? " Critical!" : "")); this.OnDamaged(0); target.OnDamaged(Mathf.Max(0, damage)); nextMovePhaseTime += actionPhasePeriod; } else { int origHp = hp; int damage = CombatEvaluator.DamageByAerialTorpedo(this, target, out isCritical); if (kamikaze) { hp = 0; } Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + "(" + origHp.ToString() + "->" + hp.ToString() + ") attacked " + target.gameObject.name + (kamikaze ? ": " : " with torpedos: ") + damage.ToString() + (isCritical ? " Critical!" : "")); this.OnDamaged(0); target.OnDamaged(Mathf.Max(0, damage)); nextMovePhaseTime += actionPhasePeriod; } } else { nextMovePhaseTime += actionPhasePeriod; } } SetupRTBPhase(); break; case EPhaseType.RTB: if (carrier != null && carrier.isAlive) { carrier.aircraftSlots[carrierSlot] += hp; Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + "x" + hp.ToString() + " RTB."); OnDamaged(int.MaxValue); } else { Debug.Log("@" + vp.battleTime.ToString("F1") + ": " + this.gameObject.name + "x" + hp.ToString() + " run out of fuel and crashed."); OnDamaged(int.MaxValue); } break; } ownPhases.Remove(vp); CheckPhase(); BattleManager.instance.Invoke("ExecuteNextPhase", 1f); }