diff --git a/airpower/aircraft.py b/airpower/aircraft.py index 8045db5f..6afa9b16 100644 --- a/airpower/aircraft.py +++ b/airpower/aircraft.py @@ -439,13 +439,19 @@ def startmove(self, flighttype, powerap, actions): if flighttype not in ["LV", "SC", "ZC", "VC", "SD", "UD", "VD"]: raise ValueError("invalid flight type %s." % flighttype) - # TODO: IDLE power. - if not isinstance(powerap, (int, float)) or powerap < 0 or powerap % 0.5 != 0: - raise ValueError("invalid power AP %s" % powerap) # TODO: Don't assume CL. powerchart = self._aircrafttype.powerchart("CL") - if powerap == 0: + if powerap == "IDLE": + powersetting = "IDLE" + powerap = 0 + elif powerap == "NOR" or powerap == 0: powersetting = "NOR" + powerap = 0 + elif powerap == "MIL" or (powerap == "AB" and "AB" in powerchart): + powersetting = powerap + powerap = powerchart[powersetting] + elif not isinstance(powerap, (int, float)) or powerap < 0 or powerap % 0.5 != 0: + raise ValueError("invalid power AP %s" % powerap) elif powerap <= powerchart["MIL"]: powersetting = "MIL" elif "AB" in powerchart and powerap <= powerchart["AB"]: @@ -487,6 +493,25 @@ def startmove(self, flighttype, powerap, actions): self._fpcarry, self._apcarry, apaltitude.formataltitudecarry(self._altitudecarry) )) + self._log("min speed is %.1f, cruise speed is %.1f, and max speed is %.1f." % ( + self._aircrafttype.minspeed("CL", self._altitudeband), + self._aircrafttype.cruisespeed(), + self._aircrafttype.maxspeed("CL", self._altitudeband), + )) + self._log("climb speed is %.1f, dive speed is %.1f, and M1 is %.1f." % ( + self._aircrafttype.climbspeed(), + self._aircrafttype.divespeed(self._altitudeband), + self._m1(), + )) + + # See rule 6.1. + if (powersetting == "IDLE" or powersetting == "NOR") and self._speed > self._aircrafttype.cruisespeed(): + self._log("insufficient power above cruise speed.") + self._powerap -= 1.0 + if powersetting == "IDLE" and self._speed > 0.5: + self._log("reducing speed by 0.5 as the power setting is idle.") + self._speed -= 0.5 + m1 = self._m1() if self._speed >= m1: speed = "%.1f (SSS)" % self._speed @@ -560,8 +585,9 @@ def _endmove(self): self._log("total APs = %+.1f with %+.1f carry = %+.1f." % (ap, self._apcarry, ap + self._apcarry)) ap += self._apcarry - initialspeed = self._speed + # See rule 6.2. # TODO: rates for RA aircraft. + initialspeed = self._speed if ap < 0: aprate = -2.0 elif initialspeed >= self._m1(): @@ -573,6 +599,13 @@ def _endmove(self): else: self._speed -= 0.5 * (ap // aprate) self._apcarry = ap % aprate + + # See rule 6.2. + if self._speed <= 0: + self._speed = 0 + if self._apcarry < 0: + self._apcarry = 0 + if self._speed != initialspeed: self._log("speed changed from %.1f to %.1f." % (initialspeed, self._speed)) else: diff --git a/airpower/aircrafttype.py b/airpower/aircrafttype.py index 6be41bac..3f5226b5 100644 --- a/airpower/aircrafttype.py +++ b/airpower/aircrafttype.py @@ -6,15 +6,17 @@ def __init__(self, name): def powerchart(self, configuration): if self._name == "F-80C": return { - "CL" : { "MIL": 1.0, }, - "1/2": { "MIL": 1.0, }, - "DT" : { "MIL": 1.0, }, + "CL" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5, }, + "1/2" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5, }, + "DT" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5, }, + "FUEL": { "IDLE": 0.0, "NOR": 0.5, "MIL": 1.0, } }[configuration] elif self._name == "F-84E": return { - "CL" : { "MIL": 1.0, }, - "1/2": { "MIL": 0.5, }, - "DT" : { "MIL": 0.5, }, + "CL" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5, }, + "1/2" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 0.5, "SPBR": 0.5, }, + "DT" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 0.5, "SPBR": 1.0, }, + "FUEL": { "IDLE": 0.0, "NOR": 0.5, "MIL": 1.0, } }[configuration] def turndragchart(self, configuration): @@ -30,3 +32,61 @@ def turndragchart(self, configuration): "1/2": { "TT": 1.0, "HT": 2.0, "BT": 2.0, }, "DT" : { "TT": 1.0, "HT": 2.0, "BT": 2.0, }, }[configuration] + + def minspeed(self, configuration, altitudeband): + if altitudeband == "UH": + altitudeband = "EH" + if self._name == "F-80C": + return { + "CL" : { "LO": 1.5, "ML": 1.5, "MH": 2.0, "HI": 2.0, "VH": 2.5, "EH": 0.0, }, + "1/2": { "LO": 1.5, "ML": 2.0, "MH": 2.0, "HI": 2.5, "VH": 2.5, "EH": 0.0, }, + "DT" : { "LO": 2.0, "ML": 2.0, "MH": 2.5, "HI": 2.5, "VH": 0.0, "EH": 0.0, }, + }[configuration][altitudeband] + elif self._name == "F-84E": + return { + "CL" : { "LO": 1.5, "ML": 1.5, "MH": 2.0, "HI": 2.5, "VH": 2.5, "EH": 0.0, }, + "1/2": { "LO": 1.5, "ML": 2.0, "MH": 2.0, "HI": 2.5, "VH": 2.5, "EH": 0.0, }, + "DT" : { "LO": 2.0, "ML": 2.0, "MH": 2.5, "HI": 0.0, "VH": 0.0, "EH": 0.0, }, + }[configuration][altitudeband] + + def maxspeed(self, configuration, altitudeband): + if altitudeband == "UH": + altitudeband = "EH" + if self._name == "F-80C": + return { + "CL" : { "LO": 5.5, "ML": 5.5, "MH": 5.0, "HI": 4.5, "VH": 4.0, "EH": 0.0, }, + "1/2": { "LO": 5.5, "ML": 5.0, "MH": 4.5, "HI": 4.5, "VH": 4.0, "EH": 0.0, }, + "DT" : { "LO": 5.0, "ML": 4.5, "MH": 4.5, "HI": 4.0, "VH": 0.0, "EH": 0.0, }, + }[configuration][altitudeband] + elif self._name == "F-84E": + return { + "CL" : { "LO": 6.0, "ML": 6.0, "MH": 5.5, "HI": 5.5, "VH": 5.5, "EH": 0.0, }, + "1/2": { "LO": 5.5, "ML": 5.5, "MH": 5.5, "HI": 5.0, "VH": 5.0, "EH": 0.0, }, + "DT" : { "LO": 5.5, "ML": 5.0, "MH": 5.5, "HI": 0.0, "VH": 0.0, "EH": 0.0, }, + }[configuration][altitudeband] + + def cruisespeed(self): + if self._name == "F-80C": + return 4.0 + elif self._name == "F-84E": + return 4.5 + + def climbspeed(self): + if self._name == "F-80C": + return 3.0 + elif self._name == "F-84E": + return 3.5 + + def divespeed(self, altitudeband): + if altitudeband == "UH": + altitudeband = "EH" + if self._name == "F-80C": + return { "LO": 6.5, "ML": 6.5, "MH": 6.5, "HI": 6.5, "VH": 6.0, "EH": 0.0, }[altitudeband] + elif self._name == "F-84E": + return { "LO": 7.0, "ML": 7.0, "MH": 6.5, "HI": 6.5, "VH": 6.0, "EH": 0.0, }[altitudeband] + + def ceiling(self, configuration): + if self._name == "F-80C": + return { "CL": 45, "1/2": 40, "DT": 35, }[configuration] + elif self._name == "F-84E": + return { "CL": 41, "1/2": 36, "DT": 30, }[configuration]