10 HIMEM: 35070:ADRS = 35070: CALL ADRS: POKE 2072,213: POKE 2073,170: DEF FN DG(H) = (H / 360 - INT (H / 360)) * 360: DEF FN D(H) = FN DG( FN DG(H + 360)): DEF FN RD(X) = INT (X * 1000) / 1000: DEF FN O(X) = INT (X / 45 + .5): DEF FN RN(X) = INT ( RND (1) * X + 1)
15 FOR X = 1 TO 7:CX(X) = 0: NEXT X
150 DEF FN RF(X) = ((3700 - X) / 3700) ^ .286: DEF FN CE(X) = PEEK (X) - 100
# increment turn number
:DA = DA + 1
# increment torpedo time-in-tube; free tubes when torps expire
: FOR Z = 1 TO 6: IF LP(Z) > 0 THEN LP(Z) = LP(Z) + 1: IF LP(Z) > 4 THEN LP(Z) = 0
# zero torpedo spreads
310 SP(Z) = 0: NEXT Z
# clear firing orders, recalculate LP (number of loaded tubes), and "crunch" tube status down
:LP = 0:FH = 0:Z(6) = 0: FOR Z = 1 TO 6:Z(Z) = 0: IF LP(Z) > 0 THEN LP = LP + 1:Z(LP) = LP(Z)
325 NEXT Z: FOR Z = 1 TO 6:LP(Z) = Z(Z): NEXT Z
# update bluff result CB
# if CB is 6, it remains 6
# if CB is not 6, and B = 0 (bug: B is always 0), then CB is random failure, unless total energy < 4500 AND 40% chance
# (note EN is not set until "GOSUB 16000" below, though it may be set by the ENG station)
: IF CB < > 6 AND B = 0 THEN CB = FN RN(5): IF EN < 4500 AND RND (1) < .4 THEN CB = 6
# clear target lock and weapon fire target
350 FOR Z = 0 TO 9:LW(Z) = 0:F(Z) = 0: NEXT Z
# compute absolute max speed in LS (uses stale FE())
: GOSUB 30500
:ZE = EV
# update efficiency in E()
: GOSUB 30000
# update EN() to match AL(), rate-limited
: GOSUB 19000:X3 = 0: GOSUB 25000
# update current position (EX/EY), speed (EW), and heading (EH)
:EX = E3:EY = E4:EW = E1:EH = E2
# update DK(), MH(), PW(), XS(), YA(); uses stale FE()
: GOSUB 32000
# set P to engine power, SP to current speed, and ZE to evasive; used for 17700
:SP = EW:P = EN(11):ZE = EV
370 XS = EW:XC = EH: GOSUB 25000
# set AE/AB
: GOSUB 17000: GOSUB 25000
# compute MS/MN
: GOSUB 17700
# compute predicted position into AX()/AY()
: FOR SH = 1 TO 3: GOSUB 25000: IF K(SH) = 1 THEN GOSUB 15200:AX(SH) = NX:AY(SH) = NY
950 NEXT SH
# compute Ranger's predicted position (used by enemy movement in INFO1)
:X = EX:Y = EY:XH = EH: GOSUB 15000:AX(0) = X:AY(0) = Y: GOSUB 25000
# compute auto-shield assignments, and FE() (which is efficiency E() ^ 1/4; 0.1->0.56, 0.9->0.97)
: GOSUB 21000: GOSUB 25000
# add a small bit of power to battery; computes EN (uses updated FE())
: GOSUB 16000: GOSUB 25000
# update bluff/surrender
: GOSUB 14000
# update efficiency of individual crew members (peek 7728)
: GOSUB 23200: REM
# update crew efficiency CE()
1010 GOSUB 23000: REM
## compute chance of Vegan surrender
# Z1 is number of ships that are alive, Z2 is highest-numbered live enemy
1012 F9 = 1:Z1 = 0:Z2 = 0: FOR Z = 1 TO 3: IF K(Z) THEN Z1 = Z1 + 1:Z2 = Z
1014 NEXT Z
# if Ranger facing shield has 150+ energy, and only one enemy is alive, and enemy total power < Ranger total power,
# and 60% chance, and enemy total power < 2800, then Vegans will surrender
: IF EN(XS(Z2)) > 150 AND Z1 = 1 AND KP(Z2,0) < EN / 1.6 AND RND (1) < .6 AND KP(Z2,0) < 2800 THEN F9 = 2
1020 GOSUB 57000
# set angle begin/end for nav, current heading; set future heading = current, future speed = current
:AE = FN D(AE):AB = FN D(AB):EH = FN D(EH):FA = EH:FS = EW
# go to main menu
: GOTO 61000
### update (maybe) chance to bluff and chance of accepting Ranger's surrender
# this tests C1, which is only used as a temporary variable in "ENG"
# if it happens to be >= 0, which it generally will be if you've been through ENG, we set CB (bluff chance) totally randomly
# set chance of surrender acceptance "not accepted" unless Ranger has more than 3000 energy, and only one Vegan ship is alive
# (otherwise they want to destroy us)
14000 IF C1 > = 0 THEN CB = FN RN(6)
14010 FF = 1
14020 IF EN > 3000 AND K(1) + K(2) + K(3) < 2 THEN FF = 2
14090 RETURN
### update X,Y from angle XH and speed S
15000 REM
15010 XH = XH * .0174533:X = COS (XH) * S ^ 3 + X:Y = SIN (XH) * S ^ 3 + Y: RETURN
### compute angle and distance for shield facing calculation
# pass in XE,YE and XK,YK
# returns ES
# returns EE (180 degrees off ES)
# returns SD (distance between the two points)
# returns SW (ignored)
15100 REM
# if XE,YE=(0,0), and XK,YK=(10,1), this yields XA=84.29, XI=5.71
15110 D1 = XE - XK:D2 = YE - YK:XA = ATN (D1 / (D2 + 1E - 29)) * 57.29578:XI = ATN (D2 / (D1 + 1E - 29)) * 57.29578: IF XE < = XK AND YE = > YK THEN ES = 360 + XI
15160 IF XE < = XK AND YE < = YK THEN ES = 90 - XA
15170 IF XE = > XK AND YE < = YK THEN ES = 180 + XI
15180 IF XE = > XK AND YE = > YK THEN ES = 270 - XA
15185 EE = ES - 180:SD = SQR ((XE - XK) ^ 2 + (YE - YK) ^ 2):SW = SD ^ (1 / 3):EE = FN D(EE):ES = FN D(ES): RETURN
### compute projected position of ship SH, based on current position KX()/KY()
# bug: this should set S to KW(SH); as it is we're getting whatever happens to be in S
15200 REM
15210 X = KX(SH):Y = KY(SH):XH = KH(SH): GOSUB 15000:NX = X:NY = Y: RETURN
### calculate which shield is associated with a given angle
# pass in target angle in X
# returns shield number in SL
15500 REM
15510 X = FN D(X): IF X > = 315 OR X < 45 THEN SL = 1
15530 IF X > = 45 AND X < 135 THEN SL = 2
15540 IF X > = 135 AND X < 225 THEN SL = 4
15550 IF X > = 225 AND X < 315 THEN SL = 3
15590 RETURN
### add a tiny bit of power, based on current battery and total energy levels
16000 REM
# set EN to sum of power in Ranger
16010 EN = 0: FOR I = 1 TO 15:EN = EN + AL(I): NEXT I
# X is battery power ratio, multiplied by Eng crew efficiency and battery system's ^1/4 efficiency
:X = EN(15) / MP(15) * CE(2,DT(2)) * FE(15)
# if we have much power (unlikely) or X went negative, X = 0
: IF EN > 9000 OR X < 0 THEN X = 0
# for low power, set X to 0.34
16015 IF EN < 1000 THEN X = .34
# if we're in reverse or moving moderately fast, X = 0
16020 IF EW < 0 OR EW > 6 THEN X = 0
# add some power back to the battery
# (MP(15) is 9999, so at EN=2000 X is 0.2, and we'll get a whopping 12 energy back assuming perfect efficiency)
16025 Z5 = X * 60:AL(15) = AL(15) + Z5:EN(15) = EN(15) + Z5
# bracket battery at [0,max]
16040 IF AL(15) < 0 THEN AL(15) = 0
16050 IF EN(15) < 0 THEN EN(15) = 0
16055 IF AL(15) > MP(15) THEN AL(15) = MP(15)
16057 IF EN(15) > MP(15) THEN EN(15) = MP(15)
16060 RETURN
### compute max course change, based on current speed in XS
# result in AE/AB
17000 REM
17020 XA = (1729 / ( ABS (XS) ^ 3 + 1)) ^ .26 * 22 * CE(3,DT(3)) ^ .5: IF XA > 100 + CE(3,DT(3)) * 50 THEN XA = CE(3,DT(3)) * 50 + 100
# factor in ion engine power and efficiency
17040 XA = XA + EN(10) / 4 * E(10)
# if not crawling, modify XA computation by light engine efficiency
: IF ABS (XS) > .75 THEN XA = ((FE(11) + FE(12)) / 2) * XA / 2 + XA / 2
17050 IF (E(10) = 0 OR AL(10) = 0) AND (E(11) = 0 OR AL(11) = 0) THEN XA = 1
17080 XE = XC + XA:XB = XC - XA:XE = FN D(XE):XB = FN D(XB):XE = FN D( FN RD(XE)):XB = FN D( FN RD(XB)):AE = XE:AB = XB: RETURN
### compute MS and MN from current speed (SP) and engine efficiency
# MA is max adjustment, based on efficiency of engines and Eng crew
17180 REM
17320 MA = 6 * ((FE(11) + FE(12)) / 2) ^ .34 * CE(2,DT(2)):MS = SP + MA:MN = SP - MA: IF MA = 0 THEN MS = SP / 2:MN = SP / 2
# cap to absolute maximum for ship
17360 IF MS > LS THEN MS = LS
17380 IF MN < - LS / 2 THEN MN = - LS / 2
17400 RETURN
### compute power consumption value P based on speed SP and evasive ZE (same as in INFO1)
17420 P = ( ABS (SP ^ 3) / 100 + 1) ^ (2.5 - SGN (SP) * .4)
17460 IF ZE > 0 THEN P = P * ZE + P
17490 RETURN
### compute min/max speed values based on engine power in P and evasive in ZE
# also updates IP if evasive is set (not used here)
17520 REM
17560 IF ZE THEN P = P - ZE * P / 100:IP = IP - ZE * IP / 100
17580 IF P < = 0 THEN WX = 0:WN = 0: GOTO 17690
17600 WX = (P ^ (1 / 2.1) - 1) * 100:WX = ABS (WX) ^ (1 / 3) * SGN (WX):WN = - (P ^ (1 / 2.9) - 1) * 100:WN = ABS (WN) ^ (1 / 3) * SGN (WN)
17690 RETURN
### update MS/MN based on power level
# P and ZE must be set before calling here
# current SP will be used if power is zero?
17700 REM
# compute MS and MN based on current speed and engine efficiency
17740 GOSUB 17180
# compute min/max speed (WN/WX) based on power level
: GOSUB 17520
# don't drop min below MN
17745 IF WN < MN THEN WN = MN
# don't push max above MS
17750 IF WX > MS THEN WX = MS
17800 IF WN = 0 AND WX = 0 THEN MS = SP:MN = SP
17820 MS = WX:MN = WN
# if max < min, swap min and max
17940 IF MS < MN THEN TE = MS:MS = MN:MN = TE
17960 RETURN
### adjust EN() levels to match AL(), limited by max rate of change
# if any allocations exceed max, reduce and return power to battery
19000 REM
19005 FOR Z = 1 TO 14: IF AL(Z) > MP(Z) THEN AL(15) = AL(15) + AL(Z) - MP(Z):AL(Z) = MP(Z)
19010 IF EN(Z) = AL(Z) THEN 19100
# reductions happen immediately
19020 IF AL(Z) < EN(Z) THEN EN(Z) = AL(Z): GOTO 19100
# T is amount of increase; increases of 50 pts or less happen immediately
19030 T = AL(Z) - EN(Z): IF T < 50 THEN EN(Z) = AL(Z): GOTO 19100
# limit increase based on efficiency of system and efficiency of crew
19040 EN(Z) = EN(Z) + 50 + E(Z) * T * CE(2,DT(2)): IF EN(Z) > AL(Z) THEN EN(Z) = AL(Z)
19100 NEXT Z
# set battery EN to AL (which it should always be)
:EN(15) = AL(15): RETURN
### update auto-shield assignments; also compute FE()
21000 REM
# E1 is sum of energy allocated to shields
21010 E1 = AL(1) + AL(2) + AL(3) + AL(4)
# zero out auto-shield assignment and energy allocation for dead shields
: FOR Z = 1 TO 4: IF D(Z) THEN AS(Z) = 0:AL(Z) = 0
# BS is shield control, 0=manual, 1=semi, 2=auto
21030 NEXT Z: IF BS < > 0 THEN 21110
21040 IF E1 = 0 THEN 21290
# set auto-shield values for manual -- maybe as defaults in case we switch?
21050 FOR Z = 1 TO 4:AS(Z) = AL(Z) / E1 * 100: NEXT Z: GOTO 21290
# configure shield amounts based on enemy facings; this computation is ignored for semi-auto
21110 FOR Z = 1 TO 4:Z(Z) = 0: NEXT Z:Z1 = 0: FOR Z = 1 TO 3: IF D(XS(Z)) = 0 AND K(Z) THEN Z(XS(Z)) = Z(XS(Z)) + 1:Z1 = Z1 + 1
21140 NEXT Z: IF BS < > 2 THEN 21200
# full auto
21160 Z3 = 0: FOR Z = 1 TO 4: IF D(Z) = 0 THEN Z3 = Z3 + 1
21165 NEXT Z: FOR Z = 1 TO 4: IF D(Z) THEN 21190
21180 AS(Z) = 18 * Z(Z) + (100 - (18 * Z1)) / Z3
21190 NEXT Z
# semi-auto assignments: percentages of total energy in system; return any excess caused by per-shield system max to battery
21200 FOR Z = 1 TO 4:AL(Z) = AS(Z) / 100 * E1: IF AL(Z) > MP(Z) THEN EN(15) = EN(15) + AL(Z) - MP(Z):AL(Z) = MP(Z)
21240 NEXT Z
# compute FE()
21290 REM
22020 FOR Z = 1 TO 14:FE(Z) = E(Z) ^ (1 / 4): NEXT Z: RETURN
### update crew efficiency CE()
23000 REM
# for each station...
23005 FOR W2 = 1 TO 4
# compute life support energy for each station in PC()
: GOSUB 23100
# for 1-6 members, Z is N/6; for 7-8 members, Z is 1
: FOR W3 = 1 TO 3:Z = 1: IF CM(W2,W3) < 6 THEN Z = CM(W2,W3) / 6
23010 GOSUB 25000
# if 9-10 members, Z drops slightly below 1
23020 IF CM(W2,W3) > 8 THEN Z = 1 - (CM(W2,W3) - 8) / 25
# Z1 reduces if insufficient officers (or crew) present
23030 Z1 = CO(W2,W3) / 27: IF Z1 > 1 THEN Z1 = 1
# sum up life support costs in Z2
23040 Z2 = 0:Z5 = 0: FOR Z3 = 1 TO 3:Z2 = Z2 + PC(W2,Z3): NEXT Z3
# set Z4 to (life sup energy) * (amount allocated to this station)
:Z4 = 0: IF Z2 > 0 THEN Z4 = EN(12) * LS(W2) / Z2
23050 IF Z4 > 1 THEN Z4 = 1
# sum up crew efficiency in Z2
23060 Z2 = 0: FOR Z3 = 1 TO 10:Y = FN CE(7728 + W2 * 60 + Z3 * 2 + (W3 - 1) * 20): IF Y > 0 THEN Z2 = Z2 + Y / 100
# Z5 gets average efficiency
23070 NEXT Z3: IF CM(W2,W3) > 0 THEN Z5 = Z2 / CM(W2,W3)
23080 IF Z5 > 1 THEN Z5 = 1
# crew efficiency for station / team is weighted average of
# member count, officer adjustment, crew efficiency, and required-vs-provided energy allocation
23090 CE(W2,W3) = (Z + Z1 + Z5 * 4 + Z4) / 7: NEXT W3: NEXT W2: RETURN
### set life support energy required per station / team
23100 REM
23110 FOR W3 = 1 TO 3:PC(W2,W3) = CM(W2,W3) * (1 + (2 - CT(W2,W3)) * .5): IF PC(W2,W3) > 0 THEN PC(W2,W3) = PC(W2,W3) + 2
23120 NEXT W3: RETURN
### update efficiency of individual crew members
23200 REM
# loop over every station and team
23205 FOR Z = 1 TO 4: FOR Z1 = 1 TO 3
# X is -6 for duty, 0 for standby, +6 for sleep
:X = (CT(Z,Z1) - 2) * 6
# X5 is adjustment based on power required / available (full crew is near 2, low power less, low crew more)
:X5 = (PC(Z,1) + PC(Z,2) + PC(Z,3)) / (EN(12) * LS(Z) + .1) * 2: IF X5 > 25 THEN X5 = 25
# increase X5 for duty team, reduce for sleep team
23210 X5 = X5 - X
# for each crewmember on team
23240 FOR Z2 = 1 TO 10
# get efficiency in Z4
:Z3 = 7708 + Z2 * 2 + Z1 * 20 + Z * 60:Z4 = FN CE(Z3): IF Z4 < = 0 THEN Z4 = - 1: GOTO 23290
# if on duty, reduce efficiency by (2-10 + X5)
23242 IF X = - 6 THEN Z4 = Z4 - FN RN(9) + 1 - X5
# if on standby, reduce efficiency by X5
23245 IF X = 0 THEN Z4 = Z4 - X5
# if sleeping, increase efficiency by X - X5 (note X is already factored into X5)
23280 IF X = 6 THEN Z4 = Z4 + X - X5
# cap efficiency
23285 IF Z4 < = 1 THEN Z4 = 1 + FN RN(5)
23287 IF Z4 > 100 THEN Z4 = 100
23290 POKE Z3,Z4 + 100: NEXT Z2
# outer loops
: NEXT Z1: NEXT Z: RETURN
### random chirp
25000 REM
25040 POKE 2048,255 - FN RN(250): POKE 2049,20: CALL 2050: RETURN
### update system efficiency
30000 REM
30005 GOSUB 25000
# shield efficiency -- reduced by high power level, and slight random reduction. Increased by repair droids.
30010 FOR Z = 1 TO 4: IF D(Z) THEN 30050
30015 X = - EN(Z) / MP(Z) * .06 - RND (1) / 40 + RT(Z) / 100:E(Z) = E(Z) + X: IF E(Z) < .1 THEN E(Z) = .1
30030 IF E(Z) > 1 THEN E(Z) = 1
30050 NEXT Z
# positron and ion engine efficiency -- slight random reduction, boost from repair droids
: FOR Z = 6 TO 10: IF D(Z) THEN 30100
30070 X = RT(Z) / 80 - ( FN RN(4) - 1) / 100:E(Z) = E(Z) + X: IF E(Z) < .1 THEN E(Z) = .1
30095 IF E(Z) > 1 THEN E(Z) = 1
30100 NEXT Z
: FOR Z = 11 TO 12: IF D(Z) THEN 30190
# reduce efficiency based on how close to max warp we are
30115 IF EW > LS / 2 THEN X = - .02
30120 IF EW > LS * .75 THEN X = - .04
30125 IF EW > LS * .9 THEN X = - .13
30130 IF EW > LS * .95 THEN X = - .18
30135 IF EW < 0 THEN X = - EW / 40
# reduce efficiency for specific engine for maximum turns
30140 IF EH = AB AND Z = 12 THEN X = X - .015
30145 IF EH = AE AND Z = 11 THEN X = X - .015
# repair droids boost efficiency
30150 X = X + RT(Z) / 65:E(Z) = E(Z) + X: IF E(Z) < .1 THEN E(Z) = .1
30180 IF E(Z) > 1 THEN E(Z) = 1
30190 NEXT Z: RETURN
### calculate absolute max speed (LS)
30500 GOSUB 25000
30510 LS = 0: IF D(11) = 0 THEN LS = 12 * FE(11) * FE(12) * (1 - EV): GOTO 30590
30520 IF D(11) = 1 THEN LS = 6 * FE(12) * (1 - EV): GOTO 30590
30530 IF D(11) = 2 THEN LS = 6 * FE(11) * (1 - EV): GOTO 30590
30540 IF D(10) = 0 THEN LS = .75 * FE(10) * (1 - EV)
30550 IF D(11) = 3 AND D(10) = 1 THEN LS = 0
30590 RETURN
### update DK(), MH(), PW(), XS(), YA()
32000 REM
32008 X = EX:Y = EY:S = EW: GOSUB 15000:BX = X - EX:BY = Y - EY
# CR=300 and EC=492 in DIM; they don't appear to be modified
:CE = EN(12) * .02 + (CR / EC) ^ .22:CE = CE / 2:CF = CE ^ .3
# for each enemy ship...
: FOR Z = 1 TO 3: GOSUB 25000:XE = EX:YE = EY: IF K(Z) = 0 THEN 32100
# compute angle (YA) and distance (DK) to enemy
32040 XK = KX(Z):YK = KY(Z): GOSUB 15100:XX = ES - EH:YA(Z) = FN D(XX)
# compute XS(), which indicates which of our shields faces this enemy
:X = YA(Z): GOSUB 15500:XS(Z) = SL:DK(Z) = SD
# XA(Z) is enemy ship's heading; use that to compute enemy shield facing YS(Z)
:XA(Z) = EE - KH(Z):X = XA(Z): GOSUB 15500:YS(Z) = SL
# compute RS() from enemy position and speed -- distance to projected location?
:X = KX(Z):Y = KY(Z):S = KW(Z): GOSUB 15000:RX = X - KX(Z):RY = Y - KY(Z):RS(Z) = SQR ((BX - RX) ^ 2 + (BY - RY) ^ 2): GOSUB 25000
# update MH() and PW() for positrons
: GOSUB 34000
# update MH() and PW() for torps
: GOSUB 35000
32100 NEXT Z: RETURN
### update MH() (max torp hit / max positron damage) and PW() (chance of hit)
# X1 for PW
# X2 for MH
# (var(n,0-3) are positrons, var(n,4-9) are torps)
34000 REM
# reset all MH/PW
34020 FOR Z1 = 0 TO 9:MH(Z,Z1) = 0:PW(Z,Z1) = 0: NEXT Z1
# calculate X1=hit chance, X2=damage
:X = XS(Z): GOSUB 34500
:PW(Z,XS(Z) - 1) = X1:MH(Z,XS(Z) - 1) = X2
# for shield 1, positrons 2 and 3 have same hit chance but 50% damage
: IF X = 1 THEN PW(Z,1) = X1:PW(Z,2) = X1:MH(Z,2) = X2 / 2:MH(Z,1) = X2 / 2
# positron 4 hits with half power
34060 IF X = 4 THEN MH(Z,3) = X2 / 2
34095 RETURN
### calculate positron damage and hit chance
# pass in X = shield facing toward enemy
# returns X1 = chance (0-1), X2 = damage
34500 REM
# if positron destroyed, leave at zero
34505 X2 = 0:X1 = 0: IF D(X + 5) THEN 34590
# if out of positron range, leave at zero
34515 IF DK(Z) > 1500 THEN 34590
# X2 is damage, based on positron efficency and shield strength
34520 X2 = 200 * FE(X + 5) - EN(X) / 10:X1 = SQR ((1700 - DK(Z)) * .001) * FN RF(RS(Z)) * CE(1,DT(1)) ^ (1 / 3) * (1 - EV(Z)): IF X1 > 1 THEN X1 = 1
34590 RETURN
### compute torp hit probability and spread max
35000 REM
35005 IF DK(Z) > 5000 THEN 35090
35010 FOR X = 6 TO 1 STEP - 1: IF 7 - X > 6 - D(5) OR LP < 7 - X THEN BP = 7 - X: GOTO 35090
# torp hit for given spread is based on distance, Wep team efficiency, enemy evasion, and spread multiplier
35020 PW(Z,10 - X) = SQR ((5400 - DK(Z)) / 5000) * FN RF(RS(Z)) * CE(1,DT(1)) ^ (1 / 3) * (1 - EV(K)) * OF(X): IF PW(Z,10 - X) < = 0 THEN PW(Z,10 - X) = 0
35027 IF PW(Z,10 - X) > 1 THEN PW(Z,10 - X) = 1
# max torps that can hit is based purely on distance
35030 MH(Z,10 - X) = INT (6 / (7 - X) + 1 / DK(Z) * 250): IF MH(Z,10 - X) > 6 THEN MH(Z,10 - X) = 6
35045 IF MH(Z,10 - X) < 1 THEN MH(Z,10 - X) = 1
35050 NEXT X
# if no chance of hit, zero out MH()
: FOR X = 4 TO 9: IF PW(Z,X) < = 0 THEN PW(Z,X) = 0:MH(Z,X) = 0
35054 NEXT X:BP = 6
35090 RETURN
### compute HW based on absolute value of minimum speed
# computes HW, which gets subtracted here, but added back into engine power by "MAIN MENU"
# the optimal speed is the one for which the minimum speed is zero
57000 GOSUB 25000
# ZE is normally evasive, e.g. 0.15 would be evasive of 15; here it's effectively 1500
57010 HW = 0:ZE = 15:SP = MS
# if both light engines are damaged, or no energy in light engines, skip
57200 IF D(11) = 3 OR EN(11) = 0 THEN 57400
# compute power P based on max speed (SP/MS)
57210 SP = MS: GOSUB 17420
# re-compute power P, but based on min speed (SP/MN)
:HW = P:SP = MN: GOSUB 17420
# ...do it again?
:HW = P:SP = MN: GOSUB 17420
# compare P to HW; since we computed it twice, they will always be the same
: IF P > HW THEN HW = P
# deduct power from engines; (see also "INFO1" line 56160)
57400 IF HW > EN(11) THEN HW = EN(11)
57410 EN(11) = EN(11) - HW:AL(11) = AL(11) - HW: RETURN
### continue on to main menu
61000 REM
61003 PRINT CHR$ (4);"BLOAD CHAIN,A520": CALL 520"MAIN MENU"