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)
# cap future speed to min/max
15 IF FS > MS THEN FS = MS
17 IF FS < MN THEN FS = MN
20 VA$ = CHR$ (129):VN$ = CHR$ (142):VI$ = CHR$ (137):VP$ = CHR$ (144):VY$ = CHR$ (153):VV$ = CHR$ (150):VW$ = CHR$ (151):VK$ = CHR$ (139):VL$ = CHR$ (140)
# clear torp firing status, set time-in-tube to zero
: FOR Z = 1 TO 6: IF F(Z + 3) THEN F(Z + 3) = 0:LP(Z) = 0
25 NEXT Z:K$(1) = "DETAS":K$(2) = "MILAS":K$(3) = "KAMAS"
# if enemy ship is alive and low on power, give them 100 units; this has no
# effect, as it's overwritten by 56300 calling 56200
26 FOR Z = 1 TO F1: IF K(Z) AND KP(Z,0) < 100 THEN KP(Z,0) = 100
# update our evasive
27 NEXT Z: GOSUB 59000
# save current X/Y for Ranger and Vegans in OX(n)/OY(n)
28 OX(0) = EX:OY(0) = EY: FOR Z = 1 TO 3:OX(Z) = KX(Z):OY(Z) = KY(Z): NEXT Z
: DEF FN RF(X) = ((3700 - X) / 3700) ^ .286: DEF FN CE(X) = PEEK (X) - 100: GOSUB 25000
# update DT(), then reallocate power in enemy ships
: GOSUB 56300
# update navigation
: GOSUB 56000
# calculate enemy movement
750 GOSUB 41000: REM
760 GOSUB 25000
# perform repairs
800 GOSUB 16000
# draw motion detector
: GOSUB 20000
810 GOSUB 25000
# detect ships that flew out of range (DK isn't updated until INFO2)
# (bug? we get one turn with ship out of range, and it'll get dropped even if it flies back into range)
10000 Z1 = 0: FOR Z = 1 TO 3: IF DK(Z) > 6500 AND K(Z) = 1 THEN VR(Z) = 1:K(Z) = 0: VTAB (19 + Z1): HTAB (7): PRINT VL$VA$1VN$;"*THE "K$(Z)" IS OUT OF RANGE*": POKE 2048,70: CALL 2050
10020 IF VR(Z) THEN Z1 = Z1 + 1
10030 NEXT Z: IF K(1) OR K(2) OR K(3) THEN 61000
# all ships dead or out of range
10050 PRINT VA$0VK$VN$: PRINT CHR$ (4)"BLOAD CHAIN,A520": CALL 520"BYE"
10060 STOP
### convert angle XH to radians, then update X/Y from angle and speed S
15000 REM
15010 XH = XH * .0174533:X = COS (XH) * S ^ 3 + X:Y = SIN (XH) * S ^ 3 + Y: RETURN
### compute angle required to reach location
# pass in (XE,YE) and (XK,YK)
# returns result angle in ES
# returns EE with opposite course from ES
# returns SD with distance between (XE,YE) and (XK,YK)
# returns SW with cube-root of distance (speed required to travel SD)
15100 REM
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
### perform repairs, pulling energy from General Operations (3pts per repair)
16000 REM
16010 X = EN(13): FOR Z = 1 TO 12
16020 IF RP(Z) > 99 THEN RP(Z) = 99
16025 X1 = RP(Z): IF X1 = 0 THEN 16080
16030 X2 = RT(Z): IF RT(Z) > X1 THEN X2 = X1
# now X2 is the number of repairs we're going to perform on system Z
16040 X3 = INT (X / 3): IF X2 > X3 THEN X2 = X3
# if we can't afford all of it, don't afford any of it
16045 IF X < X2 * 3 THEN 16090
16050 RP(Z) = RP(Z) - X2:X = X - X2 * 3
# if damage is zero, clear damage flag for non-light-engine systems
16080 IF RP(Z) < = 0 AND Z < 11 THEN D(Z) = 0:RP(Z) = 0
16085 NEXT Z
# update engine damage flag
16086 IF RP(11) < = 0 AND RP(12) < = 0 THEN D(11) = 0:RP(11) = 0:RP(12) = 0
16087 IF RP(11) < = 0 AND RP(12) > 0 THEN D(11) = 1:RP(11) = 0
16088 IF RP(11) > 0 AND RP(12) < = 0 THEN D(11) = 2:RP(12) = 0
16090 AL(13) = AL(13) - EN(13) + X:EN(13) = X: RETURN
### compute drain on engine power
# SP is speed
# ZE is evasive action; evasive of 10 drains an extra 10%
# sets P to power drain
17420 P = ( ABS (SP ^ 3) / 100 + 1) ^ (2.5 - SGN (SP) * .4)
17480 IF ZE > 0 THEN P = P * ZE + P
17490 RETURN
### compute some speed values based on engine power in P
# ZE is evasive; IP is updated if ZE is nonzero
# sets WX (max speed), WN (min speed)
# sets XI, NI based on IP (IP doesn't seem to be initialized, and XI/NI aren't used)
17520 REM
17560 IF ZE THEN P = P - ZE * P / 100:IP = IP - ZE / 100 * IP
17580 IF P = 0 THEN WX = 0:WN = 0: GOTO 17640
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) * (WN)
17640 XI = IP / 5:NI = IP / 7: RETURN
### draw animated motion detector
20000 REM
20005 GOSUB 21100
# compute scale based on Ranger warp and most-distant enemy
:SC = ABS (EW ^ 3): FOR Z = 1 TO 3: IF K(Z) AND DK(Z) > SC THEN SC = DK(Z)
20040 NEXT Z: IF SC = 0 THEN SC = 1
20045 SC = SC * 1.1
20050 SC = SC / 10:Z$(1) = "X":Z$(2) = "E":Z$(3) = "T": PRINT CHR$ (143) CHR$ (143);: VTAB (23): HTAB (20): PRINT VA$1VL$VI$; FN RD(SC * 10)" MEGAMETERS";VI$VK$;: PRINT CHR$ (143) CHR$ (144);
# animate ship motion (5 steps)
: FOR Z = 0 TO 10 STEP 2: IF Z > 0 THEN X = (E3 - OX(0)) * (Z - 2) / 10 + OX(0):Y = (E4 - OY(0)) * (Z - 2) / 10 + OY(0):Z$ = " ": GOSUB 21000
20070 X = (E3 - OX(0)) * Z / 10 + OX(0):Y = (E4 - OY(0)) * Z / 10 + OY(0):Z$ = "Z": IF Z2 = 1 THEN Z$ = " "
20080 GOSUB 21000: FOR Z1 = 1 TO 3: IF K(Z1) = 0 THEN 20190
20125 IF Z > 0 THEN X = (KX(Z1) - OX(Z1)) * (Z - 2) / 10 + OX(Z1):Y = (KY(Z1) - OY(Z1)) * (Z - 2) / 10 + OY(Z1):Z$ = " ": GOSUB 21000
20130 X = (KX(Z1) - OX(Z1)) * Z / 10 + OX(Z1):Y = (KY(Z1) - OY(Z1)) * Z / 10 + OY(Z1):Z$ = Z$(Z1): GOSUB 21000
20190 NEXT Z1: POKE 2048,255: POKE 2049,76: CALL 2050
20196 NEXT Z: RETURN
# draw ship
21000 REM
21010 X = FN RD(X - E3) / SC + 20:Y = FN RD(E4 - Y) / SC * .875 + 12: IF X > = 0 AND X < = 40 AND Y > = 2 AND Y < = 22 THEN VTAB (Y): HTAB (X): PRINT Z$;
21090 RETURN
### draw motion detector frame
21100 POKE 2072,127: POKE 2073,127: CALL 2074: HCOLOR= 1: FOR Z = 0 TO 7: HPLOT 0,Z TO 279,Z: NEXT Z: VTAB (1): HTAB (12): PRINT VN$VA$4VK$"MOTION DETECTOR";: VTAB (23): HTAB (1): PRINT VA$1VL$VI$;"SCALE: ": PRINT "KEY: ";VK$"Z"VL$"=RANGER "VK$;: IF K$(1) THEN PRINT "X"VL$"=DETAS ";VK$;
21160 IF K$(2) THEN PRINT "E"VL$"=MILAS ";VK$;
21170 IF K$(3) THEN PRINT "T"VL$"=KAMAS";VK$;
21180 PRINT VK$;: HCOLOR= 2: HPLOT 56,180 TO 126,180: HCOLOR= 1: HPLOT 0,177 TO 279,177: RETURN
### random chirp
25000 REM
25005 Y6 = FN RN(50)
25040 POKE 2048,255 - 5 * Y6: POKE 2049,20: CALL 2050: RETURN
### calculate enemy movement
41000 REM
41010 FOR SH = 1 TO 3: IF K(SH) = 0 THEN 41115
# if crew dead, drop max speed to zero
41011 IF KC(SH) < = 0 THEN MS(SH) = 0: GOTO 41030
# if max speed exceeds max for class, cap it
41012 IF MS(SH) < 14 - KT(SH) THEN 41030
41015 MS(SH) = 14 - KT(SH)
# 14% chance of engine damage for heavy hit; max speed reduced
# (60% chance of it being restored below after movement computed - see line 50020)
41020 IF RND (1) < .14 AND VH(SH) - KP(SH,YS(SH)) > 300 THEN MS(SH) = FN RN(MS(SH) - 1) + RND (1)
# P holds the engine power, and Z3 holds evasive action; Z3 is ignored
# (ZE was set to EV(n) earlier, so we should have the right value anyway)
41030 P = KP(SH,6):Z3 = EV(SH)
# compute WX/WN from P and ZE
: GOSUB 17520
# cap max speed and min speed
: IF WX > KW(SH) + 6 THEN WX = KW(SH) + 6
41060 IF WN < KW(SH) - 6 THEN WN = KW(SH) - 6
41070 IF WX > MS(SH) THEN WX = MS(SH)
41080 IF WN < - MS(SH) / 2 THEN WN = - MS(SH) / 2
# set WH/WL to warp-hi, warp-lo; Y0 set based on ship class
41090 WH(SH) = WX:WL(SH) = WN:Y0 = 100 + (3 - KT(SH)) * 25
# TA(SH) is max turn angle, capped by Y0 (destroyers can turn faster)
41110 TA(SH) = (2198 / ( ABS (KW(SH)) ^ 3 + 1)) ^ .4 * (18 + (3 - KT(SH)) * 3): IF TA(SH) > Y0 THEN TA(SH) = Y0
41115 NEXT SH
#
# for computations below, set:
# Z(n) = angle to target
# X2(n) = speed required to reach target
# Z1(n) = angle to predicted target location
# W(n) = speed required to reach predicted target location
: FOR SH = 1 TO 3: IF K(SH) = 0 THEN 41280
# compute angle to Ranger
41210 XE = EX:YE = EY:XK = KX(SH):YK = KY(SH): GOSUB 15100:Z(SH) = EE:X2(SH) = SW
:XE = AX(0):YE = AY(0): GOSUB 15100:Z1(SH) = EE:W(SH) = SW
41280 NEXT SH
#
: FOR SH = 1 TO 3
# bluff attempted; set B1 to 0-3, Z1 to max speed, Z2 to reverse of current course
# (bug? CB is always nonzero, B1 set by *attempt* not success; should this check CB = 6?)
# 25% of dropping out of bluff each turn
: IF CB AND B1 THEN B1 = FN RN(4) - 1:Z1 = MS(SH):Z2 = FN D(Z1(SH) + 180): GOSUB 49900:KW = T4:KH = T2: GOTO 50000
#
# put number of live Vegan ships in X, and set X2 to F1 (was this attempting to find the first live ship?)
41281 X = 0: FOR Z = 1 TO F1:X = X + K(Z):X2 = Z: NEXT Z
#
# this looks like a test to see if enemy should try to flee
: IF X = 1 AND EN > KP(X2,0) * 2 AND KP(X2,0) < 3000 AND MS(X2) > MS THEN Z1 = MS(X2):Z2 = FN D(Z1(X2) + 180): GOSUB 49900:KW = T4:KH = T2: GOTO 50000
# various maneuverings based on distance and randomness... want speed in Z1, heading in Z2
# T0 matches Ranger warp, unless it's below 6.5, in which case we add a whole bunch
41283 T0 = EW: IF T0 < 6.5 THEN T0 = T0 + 7 + RND (1)
# set W(5) to -1 or 1; doesn't seem to be used anywhere except next line
41285 W(5) = - 1: IF RND (1) < .5 THEN W(5) = 1
# if power in facing shield is low, and we have at least moderate power, and 70% chance, then set speed to slow,
# set heading to somewhere perpendicular to path to target -- present shield 2 or 3
41287 IF KP(SH,YS(SH)) < 200 AND KP(SH,0) > 1500 AND RND (1) < .7 THEN Z1 = RND (1) * 2.5:Z2 = Z1(SH) + W(5) * 90 + FN RN(20) + W(5): GOSUB 49900:KW = T4:KH = T2: GOTO 50000
41290 IF DK(SH) < 1200 THEN 41310
# distance 1200+, Ranger is off our shield 4: drop speed to minimum, turn ship
41291 IF YS(SH) = 4 THEN Z1 = RND (1):Z2 = Z1(SH): GOSUB 49900:KW = T4:KH = T2: GOTO 50000
41293 IF DK(SH) < 2000 THEN 41310
# distance 2000+, Ranger is off our shield 4, same as above
41294 IF YS(SH) = 4 THEN Z1 = RND (1):Z2 = Z1(SH): GOSUB 49900:KW = T4:KH = T2: GOTO 50000
# distance 2000+, Ranger not off shield 4, go to high warp
41295 Z1 = T0 + RND (1) * 2.5:Z2 = Z1(SH): IF Z1 < 7 THEN Z1 = 8 + RND (1) * 3
# ...but not too fast if we're heading toward shield 2 or 3
41298 IF Z1 > 6 AND (YS(SH) = 2 OR YS(SH) = 3) THEN Z1 = Z1 / 2
41305 GOSUB 49900:KW = T4:KH = T2: GOTO 50000
##
41310 IF DK(SH) < 2000 THEN 41360
# distance 2000+ -- this is unreachable -- wouldn't get to 41310 if distance were over 2000
# if he's not behind us, or moving slowly, go to 41340
41315 IF XS(SH) < > 4 OR EW < 6 THEN 41340
# turn to meet, moving proportionally to Ranger
41320 Z1 = T0 + RND (1) * 2.5:Z2 = Z1(SH): GOSUB 49900: IF T1 < 30 THEN KW = T4:KH = T2: GOTO 50000
# move at random speed in the vague general direction
41340 Z1 = FN RN(6) + RND (1) * 3 - .5:Z2 = Z1(SH) + 30 - FN RN(60): GOSUB 49900:KW = T4:KH = T2: GOTO 50000
#
41360 IF DK(SH) < 1500 THEN 41405
# distance 1500-2000
# if 20% chance and my speed < 7 then move quickly in general direction
41400 IF RND (1) < .2 AND KW(SH) < 7 THEN Z1 = FN RN(3) + 6 + RND (1):Z2 = FN D( FN RN(70) + Z1(SH)): GOSUB 49900:KW = T4:KH = T2: GOTO 50000
# if 15% chance and my speed < 7 then move at random speed in a different direction
41403 IF RND (1) < .15 AND KW(SH) < 7 THEN Z1 = FN RN(8) + RND (1):Z2 = FN D( FN RN(185) + Z1(SH)): GOSUB 49900:KW = T4:KH = T2: GOTO 50000
41405 IF DK(SH) < 1200 THEN 41500
# distance 1200-1500
# if he's not behind us, or moving slowly, or 30% chance, goto 41430
41410 IF XS(SH) < > 4 OR EW < 6 OR RND (1) < .3 THEN 41430
# speed proportional to Ranger, headed at it; if course change is minor, go with it
41415 Z1 = T0 + RND (1) + RND (1):Z2 = Z1(SH): GOSUB 49900: IF T1 < 40 THEN KW = T4:KH = T2: GOTO 50000
# speed is random but slow, aiming in general direction of Ranger
41430 Z1 = FN RN(3) + 3 + RND (0) - 1:Z2 = Z1(SH) + 35 - FN RN(70): GOSUB 49900:KW = T4:KH = T2: GOTO 50000
# distance < 1200
# if total power is reasonable goto 41600
41500 IF KP(SH,0) > 1000 THEN 41600
# set KW to distance, because why not; 50% chance of using current or predicted position
41510 KW = W(SH) ^ 3:Z2 = Z1(SH): IF RND (1) < .5 THEN KW = X2(SH) ^ 3:Z2 = Z(SH)
# pick a random target distance from 600-1100 and try to move to that distance
41530 T = 600 + FN RN(500):Z9 = KW - T:Z1 = ABS (Z9) ^ (1 / 3) * SGN (Z9): GOSUB 49900:KW = T4:KH = T2: GOTO 50000
#
# 50% chance of using current or predicted angle (note: using Z1 as temporary)
41600 Z1 = Z1(SH): IF RND (1) < .5 THEN Z1 = Z(SH)
# course is fairly random, as is speed
41610 Z2 = Z1 + 30 - FN RN(60):Z1 = 8 - FN RN(10) + RND (1)
# 25% chance of closing the exact distance
41613 IF RND (1) < .25 THEN Z1 = DK(SH) ^ (1 / 3) - RND (1)
41615 GOSUB 49900
41620 KW = T4:KH = T2: GOTO 50000
### clamp Z1 (speed) and Z2 (heading) to WL()/WH() and TA()
# called from various places below 41000
# T1/T2/T4 get results
49900 GOSUB 25000
49910 X4 = WL(SH):X3 = WH(SH):X2 = KH(SH) - TA(SH):X1 = KH(SH) + TA(SH): GOSUB 55000: RETURN
## (part of FOR loop) update enemy ship position, heading, and speed
# pass speed in KW, heading in KH
#
# update ship position KX(),KY(), and save the speed/heading in KW() and KH()
50000 X = KX(SH):Y = KY(SH):S = KW:XH = KH: GOSUB 15000:KX(SH) = X:KY(SH) = Y:KH(SH) = KH:KW(SH) = KW
# reduce power available to engines based on speed
:X = (( ABS (KW) ^ 3) / 100 + 1) ^ (3 - SGN (KW) * .9):KP(SH,6) = KP(SH,6) - X: IF KP(SH,6) < 0 THEN KP(SH,6) = 0
# 60% chance of engine max speed being restored to max if previously reduced
50020 IF RND (1) > .4 THEN MS(SH) = 14 - KT(SH)
50050 GOSUB 25000: NEXT SH: RETURN
### clamp angle and speed to allowed values
# X1 is max allowed angle (e.g. AE)
# X2 is min allowed angle (e.g. AB)
# X3 is max speed (e.g. MS)
# X4 is min speed (e.g. MN)
# Z1 is desired speed
# Z2 is desired angle
# "returns": T1, T2 (angle), T4
# T1 is difference between desired and actual angle
# T2 is clamped angle
# T4 is clamped speed
55000 REM
55020 T1 = 0:T2 = 0:T3 = 0:T4 = 0:X2 = FN D(X2):X1 = FN D(X1):Z2 = FN D(Z2)
# if turn rate restricted, trivial clamp
: IF ABS (X1 - X2) < = 1 THEN T2 = X1:T1 = ABS (T2 - Z2): GOTO 55150
# if in valid range, pass it through
55025 IF (X1 > = X2 AND Z2 > = X2 AND Z2 < = X1) OR (X1 < = X2 AND (Z2 > = X2 OR Z2 < = X1)) THEN T2 = Z2: GOTO 55150
# clamp angle to X1 or X2
55050 T2 = X2: IF X1 < X2 AND Z2 < X2 THEN Z2 = Z2 + 360
55100 IF X1 < X2 THEN X1 = X1 + 360
55130 IF ABS (X1 - Z2) < ABS (X2 - Z2) THEN T2 = X1
55140 T1 = ABS (T2 - Z2)
# cap actual speed to min/max; T3 is never used
55150 IF Z1 < X4 THEN T4 = X4:T3 = ABS (Z1 - X4): GOTO 55190
55160 IF Z1 > X3 THEN T4 = X3:T3 = ABS (Z1 - X3): GOTO 55190
55170 T4 = Z1
55190 T2 = FN D(T2): RETURN
### handle navigation
# leaves new speed in E1/FS, angle in E2/FA, position in E3/E4 (the latter used by the motion detector)
56000 REM
# if auto-nav toward now-dead ship, switch nav to manual control
56005 IF K(AL) = 0 AND EP > 0 THEN EP = 0
# EP=0 means manual nav
56010 IF EP = 0 THEN X = EX:Y = EY:S = FS:XH = FA
# compute new position, save as E3/E4
: GOSUB 15000:E3 = X:E4 = Y:E1 = FS:E2 = FA: GOTO 56135
#
# AL is auto-nav target, AP is 1 if we want projected rather than current; set XK/YK to target position
56020 XE = EX:YE = EY:XK = KX(AL):YK = KY(AL): IF AP THEN XK = AX(AL):YK = AY(AL)
# compute angle required to get from XE,YE to XK,YK (result in ES), also sets SD to distance to target
56040 GOSUB 15100
# use computed angle and speed from semi-auto; if full-auto, compute speed from SD/ED (ED is auto-nav desired dist)
:E2 = ES:E1 = AS: IF EP = 2 THEN E1 = ABS (SD - ED) ^ (1 / 3) * SGN (SD - ED)
# bracket full-auto-nav speed to [-6,9]
56050 IF E1 > 9 AND EP = 2 THEN E1 = 9
56055 IF E1 < - 6 AND EP = 2 THEN E1 = - 6
# AB/AE are angle begin/end for navigation; MS/MN are speed limits
# E1 is desired speed, E2 is desired angle
56070 X2 = AB:X1 = AE:X3 = MS:X4 = MN:Z1 = E1:Z2 = E2
# clamp angle and speed
: GOSUB 55000
# set E1 and S to clamped speed, E2 and XH to clamped angle
:E1 = T4:E2 = T2:XH = E2:S = E1
# update X/Y from angle XH and speed S
:X = EX:Y = EY: GOSUB 15000
# update future speed (FS), future angle (FA) for nav
:E3 = X:E4 = Y:FS = E1:FA = E2
#
# (common)
56135 SP = E1:ZE = EV
# compute P from SP and ZE, then use it to reduce engine power
# (see also "INFO2" line 57410)
56160 GOSUB 17420:EN(11) = EN(11) - P:AL(11) = AL(11) - P: IF EN(11) < 0 THEN EN(11) = 0
56170 IF AL(11) < 0 THEN AL(11) = 0
56190 RETURN
### compute KP(n,0) for all enemies by summing up power in enemy systems
56200 REM
56210 FOR SH = 1 TO 3: IF K(SH) = 0 THEN 56280
56220 KP(SH,0) = 0: FOR Z = 1 TO 7:KP(SH,0) = KP(SH,0) + KP(SH,Z): NEXT Z
56280 NEXT SH: RETURN
### update DT(), then reallocate power in enemy ships
# set DT(Z) to duty team
56300 REM
56302 FOR Z = 1 TO 4: FOR Z1 = 1 TO 3: IF CT(Z,Z1) = 1 THEN DT(Z) = Z1: GOTO 56304
56303 NEXT Z1
56304 NEXT Z
#
# compute KP(n,0) (total power in enemy ships)
56305 GOSUB 56200
## loop over all enemy ships, including dead ones: reallocate power to shields (1-4), weapons (5), engines(6), battery(7)
: FOR SH = 1 TO 3: IF KP(SH,0) < 5000 THEN 56350
# high power: shields get 15% each, weapons get 5%, engines get 20%
56315 FOR Z = 1 TO 4:Z(Z) = .15 * KP(SH,0): NEXT Z:Z(5) = .05 * KP(SH,0):Z(6) = .20 * KP(SH,0): GOTO 58000
56350 IF KP(SH,0) < 3000 THEN 56400
56360 FOR Z = 1 TO 4:Z(Z) = .15 * KP(SH,0): NEXT Z:Z(YS(SH)) = Z(YS(SH)) + .05 * KP(SH,0):Z(5) = .10 * KP(SH,0):Z(6) = .2 * KP(SH,0): GOTO 58000
56400 IF KP(SH,0) < 2000 THEN 56600
56410 FOR Z = 1 TO 4:Z(Z) = .1 * KP(SH,0):Z1(Z) = Z: NEXT Z:Z1(0) = 3:Z1(5) = 2: IF DK(SH) > MS ^ 3 AND XS(SH) < > 4 THEN X = YS(SH):X1 = .05 * KP(SH,0):Z(Z1(X - 1)) = Z(Z1(X - 1)) + X1:Z(Z1(X + 1)) = Z(Z1(X + 1)) + X1:Z(Z1(X)) = Z(Z1(X)) + X1:FK = - 1: GOTO 56500
56440 IF RND (1) < .6 THEN X = YS(SH):X1 = .08 * KP(SH,0): FOR Z = X - 1 TO X + 1:Z(Z1(Z)) = Z(Z1(Z)) + X1: NEXT Z: GOTO 56500
56450 X2 = .02 + RND (1) / 10:X1 = (.25 - X2) / 3:X2 = (X2 - X1 * 3) * KP(SH,0):X1 = X1 * KP(SH,0): FOR Z = 1 TO 4:Z(Z) = Z(Z) + X1: NEXT Z:Z(YS(SH)) = Z(YS(SH)) + X2
56500 Z(5) = .08 * KP(SH,0):Z(6) = .22 * KP(SH,0): GOTO 58000
# compare KP to 1000, but KP is never initialized -- should be KP(SH,0) (bug)
56600 IF KP < 1000 THEN 56800
# (not reached)
56610 IF RND (1) < .5 THEN 56700
56620 X1 = .15 * KP(SH,0): FOR Z = 1 TO 4:Z(Z) = X1: NEXT Z:Z(YS(SH)) = Z(YS(SH)) + .1 * KP(SH,0):Z( FN RN(4)) = Z( FN RN(4)) + .05 * KP(SH,0):Z(5) = .08 * KP(SH,0):Z(6) = .15 * KP(SH,0): GOTO 58000
56700 X1 = .12 * KP(SH,0): FOR Z = 1 TO 4:Z(Z) = X1: NEXT Z:X1 = .03 * KP(SH,0): FOR Z = 1 TO 4:Z(Z) = X1: NEXT Z: FOR Z = 1 TO 5:X = FN RN(4):Z(X) = Z(X) + X1: NEXT Z:Z(5) = .08 * KP(SH,0):Z(6) = .20 * KP(SH,0): GOTO 58000
56800 X1 = .1 * KP(SH,0): FOR Z = 1 TO 4:Z(Z) = X1: NEXT Z:Z(YS(SH)) = X1 * 3:Z(5) = .1 * KP(SH,0):Z(6) = .2 * KP(SH,0): GOTO 58000
## (common)
# save a copy of current power assigned to shield facing Ranger in Z5 (for later)
58000 Z5 = KP(SH,YS(SH))
# set Z1 to total power
58010 Z1 = KP(SH,0)
# loop over all systems except battery...
: FOR Z = 1 TO 6
# set Z2 to power currently in that system, + 181-230. Cap adjustment to that value. This limits rate of increase.
:Z2 = KP(SH,Z) + 180 + FN RN(50): IF Z(Z) > Z2 THEN Z(Z) = Z2
# cap power to max allowed in that system
58045 IF Z(Z) > MK(SH,Z) THEN Z(Z) = MK(SH,Z)
# update KP for that system, and total power
58050 KP(SH,Z) = Z(Z):Z1 = Z1 - Z(Z): NEXT Z
# store the overage in KP(n,7) (battery)
:KP(SH,7) = Z1
# cap total power to max
: IF MK(SH,0) < KP(SH,0) THEN KP(SH,0) = MK(SH,0)
# subtract damage taken this turn on facing shield
# (I think the idea is to ensure the impact on the shield is reflected in the current power level)
# (...but we already subtracted the damage in TARGET, so this is redundant. But we already
# computed KP(SH,0), so it won't be obvious. Next turn we'll see their energy mysteriously
# drop by the size of this turn's hit.)
58060 KP(SH,YS(SH)) = KP(SH,YS(SH)) - VH(SH): IF KP(SH,YS(SH)) < 0 THEN KP(SH,YS(SH)) = 0
# simulate damage to shield from heavy hit -- 30% chance of damage causing energy to go
# to zero if (damage-inflicted - pre-adjustment-shield) > 300
58070 IF RND (1) < .3 AND VH(SH) - Z5 > 300 THEN KP(SH,YS(SH)) = 0
58095 NEXT SH: RETURN
### update evasive EV, capping at current/allocated energy level
# goes to zero if ion engine damaged
59000 IF EV * 100 > EN(10) THEN EV = EN(10) / 100
59005 IF EV * 100 > AL(10) THEN EV = AL(10) / 100
59010 IF D(10) THEN EV = 0
# cap based on efficiency of ion engine
# CT(3,DT(3)) should always be 1
59015 Z = .15 * E(10) * SQR (CT(3,DT(3))): IF EV > Z THEN EV = Z
59017 EV = INT (EV * 100) / 100
59020 EN(10) = EN(10) - EV * 100:AL(10) = AL(10) - EV * 100
59090 RETURN
### advance to INFO2
61000 REM
61002 VTAB (2): PRINT VN$VA$0VK$: PRINT CHR$ (4);"BLOAD CHAIN,A520": CALL 520"INFO2"