'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' CT-Vector (formerly Star Ruttier)
' 2D6 Sci Fi roleplaying utility
' coding by Richard Wessel
' using QB64 v.1.4
' Made possible with guidance and code contributions by
' Bplus, Petr, SMcNeill, and many others at QB64.org forum. Thank you.
' Thanks to my son Erik for the idea to include an auto counter thrust
' development and beta test version 0.36 uploaded 7-26-2020
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' USER DEFINED VARIABLES
TYPE unitpoint
' relative unit placement pX
AS INTEGER64
' X coordinate / mem 0-7 pY
AS INTEGER64
' Y coordinate / mem 8-15 pZ
AS INTEGER64
' Z coordinate / mem 16-23
TYPE ship
' unit info variable id
AS BYTE
' unit ID / mem 0 Nam
AS STRING * 10 ' unit name / mem 1 - 10 MaxG
AS SINGLE ' Maximum thrust ship can use / mem 11-14 op
AS unitpoint
' previous turn x,y,z position op=old position / mem 15-22,23-30,31-38 OSp
AS SINGLE ' previous turn velocity / mem 39-42 OHd
AS SINGLE ' previous turn heading / mem 43-46 OIn
AS SINGLE ' previous turn inclination / mem 47-50 Ostat
AS BYTE
' previous turn status / mem 51 ap
AS unitpoint
' Absolute x,y,z position ap=absolute position / mem 52-59,60-67,68-75 Sp
AS SINGLE ' coasting velocity / mem 76-79 Hd
AS SINGLE ' coasting heading / mem 80-83 In
AS SINGLE ' coasting inclination / mem 84-87 status
AS BYTE
' 0=destroyed 1=in flight 2=landed 3=disabled / mem 88 bogey
AS BYTE
' target of intercept/evade solution / mem 89 bstat
AS BYTE
' type of solution 0=none 1=evade 2=intercept 3=Planetfall / mem 90 mil
AS BYTE
' military sensors? true/false / mem 91
TYPE Maneuver
' active thrust polar vector Azi
AS SINGLE ' Thrust heading / mem 0-3 Inc
AS SINGLE ' Thrust inclination / mem 4-7 Gs
AS SINGLE ' Thrust acceleration / mem 8-11
TYPE body
' Celestial bodies parnt
AS STRING * 20 ' name of parent body / mem 20-39 radi
AS INTEGER64
' Size (needs INTEGER64 in event of large star) / mem 40-47 orad
AS INTEGER64
' Orbital radius / mem 48-55 oprd
AS SINGLE ' Orbital period (years) / mem 56-59 rota
AS SINGLE ' Rotational period / mem 60-63 dens
AS SINGLE ' Density, basis for grav(Gs) calculation / mem 64-67 rank
AS BYTE
' 1=primary, 2=planet/companion, 3=satelite / mem 68 star
AS BYTE
' -1=star 0=non-stellar body 2=planetoid belt / mem 69 class
AS STRING * 2 ' Two digit code, use for stellar class, GG, etc. / mem 70-71 siz
AS STRING * 3 ' three digit code, use for stellar size, / mem 72-74 ps
AS unitpoint
' coordinate position / mem 75-98
' GLOBAL VARIABLES AND ARRAYS
DIM SHARED clr&
(0 TO 15) ' 32 bit equivalent of SCREEN 0 colors DIM SHARED cmb
(x
) AS ship
' unit info array (Combatants) DIM SHARED rcs
(x
) AS unitpoint
' Relative Coordinate Ship- x,y,z relative to vpoint DIM SHARED rcp
(x
) AS unitpoint
' Relative Coordinate Planet- " " " " " DIM SHARED dcs
(x
) AS unitpoint
' Display Coordinate Ship DIM SHARED dcp
(x
) AS unitpoint
' Display Coordinate Planet DIM SHARED vpoint
AS UNSIGNED BYTE
' active unit pointer DIM SHARED shipoff
AS UNSIGNED BYTE
' display offset for ship data scroll DIM SHARED units
AS UNSIGNED BYTE
' number of combatant units DIM SHARED collision
AS BYTE
' collision check variable DIM SHARED Thrust
(x
) AS Maneuver
' Applied acceleration DIM SHARED Gwat
AS Maneuver
' Acceleration vector of gravitational influences DIM SHARED mouse_left
AS BYTE
' mouse left button pressed DIM SHARED mouse_right
AS BYTE
' mouse right button pressed DIM SHARED AW&
' Azimuth wheel overlay handle DIM SHARED flight&
' Flightplan solution buttons DIM SHARED intercept&
' Intercept solution buttons ' Undo toggle- prevents more than one turn undo togs bit=0
' Z-pan toggle togs bit=1
' Azimuth wheel toggle togs bit=2
' Grid toggle togs bit=3
' Ranging circle toggle togs bit=4
' Inclinometer toggle togs bit=5
' Jump diameter toggle togs bit=6
' Orbit track display toggle togs bit=7
' Gravity zone toggle togs bit=8
' compute jump diameters accounting for density togs bit=9
' Belt/ring display toggle togs bit=10
' bits 11-15 for future expansions
' DEBUGGING VARIABLES (if any present for beta testing)
' INITIAL PARAMETERS
ttl = "CT Vector 0.36"
Px = 0: Py = 0: Pz = 0 ' (x,y,z) position of system primary aka ORIGIN
cmb(0).ap.pX = 0 ' No ships left active unit
cmb(0).ap.pY = 0
cmb(0).ap.pZ = 0
Turncount = 0 ' game turn number- determines elapsed time in scenario
vpoint = 1 ' active unit pointer
ZoomFac = 1 ' Zoom factor
togs = &B0000010110001101 ' set toggle initial state
shipoff = 0 ' ship list scrolling offset value
REDIM SHARED Sensor
(x
, x
) AS BYTE
' Sensor ops- planetary obscuration array, who can see who? ' bit 0 = Sensor occlusion flag
' bit 1 = Target lock flag
' bit 2 = Contact indistinct/Extreme range flag
FOR x
= 0 TO 15 ' iterate colors 0 thru 15 READ r%
' get red component READ g%
' get green component READ b%
' get blue component clr&(x) = RGB32(r%, g%, b%) ' mix color x into array
' IMAGES AND BUTTONS
FOR Ascii
= 0 TO 255 ' PETR'S CHARACTER IMAGE LOADER chr_img(Ascii) = NEWIMAGE(8, 16, 32) ' create image for each ASCII character
DEST chr_img(Ascii) ' set image destination of ASCII character
PRINTMODE KEEPBACKGROUND ' transparency for graphics overlays
PRINTSTRING
(0, 0), CHR$(Ascii
), chr_img
(Ascii
) ' put ASCII character in imageNEXT Ascii
' now any size ASCII character can be printed
A& = NEWIMAGE(1250, 700, 32) ' Main display
SS& = NEWIMAGE(620, 620, 32) ' Sensor screen display
AW& = NEWIMAGE(620, 620, 32) ' Azimuth wheel overlay
ZS& = NEWIMAGE(40, 650, 32) ' Z-pan slider display
ORI& = NEWIMAGE(254, 254, 32) ' Orientation display
flight& = NEWIMAGE(80, 16, 32) ' Flightplan solution button
evade& = NEWIMAGE(40, 16, 32) ' Evade solution button
intercept& = NEWIMAGE(72, 16, 32) ' Intercept solution button
cancel& = NEWIMAGE(48, 16, 32) ' Cancel solution button
XZ& = NEWIMAGE(64, 32, 32) ' Zoom extents button
IZ& = NEWIMAGE(64, 32, 32) ' Zoom In button
OZ& = NEWIMAGE(64, 32, 32) ' Zoom Out button
RG& = NEWIMAGE(56, 32, 32) ' Ranging button
OB& = NEWIMAGE(56, 32, 32) ' Orbit track button
GD& = NEWIMAGE(48, 32, 32) ' Grid button
AZ& = NEWIMAGE(40, 32, 32) ' Azimuth button
IN& = NEWIMAGE(40, 32, 32) ' Inclinometer button
JP& = NEWIMAGE(48, 32, 32) ' Jump envelope button
DI& = NEWIMAGE(48, 32, 32) ' Jump Diameter button
DN& = NEWIMAGE(48, 32, 32) ' Jump Density button
QT& = NEWIMAGE(48, 32, 32) ' Quit button (program end)
strfld = LOADIMAGE("images\starfield.jpg", 32) ' Gatekeeper background image
ShpT = LOADIMAGE("images\suleimant.png", 32) ' ship- thrusting
ShpO = LOADIMAGE("images\suleimano.png", 32) ' ship- no thrust
TLoc = LOADIMAGE("images\tlock.png", 32) ' target lock icon
TLocn = LOADIMAGE("images\tlockn.png", 32) ' target lock n/a
Make_Images ' Create overlays
Make_Buttons ' Create control buttons
SCREEN A&
' Initiate main screen TITLE "CT-vector 0.352 beta testing"
SCREENMOVE 5, 5
GateKeeper
SetUp ' Read/Load ships and planets
t1% = FREETIMER ' Autosave timer
ON TIMER(t1%
, 60) Save_Scenario
0 ' save every minute
MainLoop ' Enter main program loop
Terminus ' do housekeeping and exit
' DATA SECTION
colors:
' colors 0-4
DATA 0,0,0,0,0,168,0,168,0,0,168,168,168,0,0 ' colors 5-9
DATA 168,0,168,168,84,0,168,168,168,84,84,84,84,84,252 ' colors 10-14
DATA 84,252,84,84,252,252,252,84,84,252,84,252,252,252,84 ' color 15
ships: ' Sample ships for demo and debugging
'index, name, MaxG,ap.pX,ap.pY,ap.pZ,Speed,Heading,Inclination,mil
'DATA 7
'DATA 1,"Crotalus",2,-5000000,-5000000,0,0,0,0,0
'DATA 2,"Zho Trader",2,-5500000,-5780000,0,30,90,0,0
'DATA 3,"Tigress",6,-5060000,-5300000,5,10,0,90,-1
'DATA 4,"SDB",6,-5500000,-5400000,0,0,0,0,-1
'DATA 5,"Corsair",2,-5660000,-5200000,0,0,0,0,0
'DATA 6,"Beowulf",1,-5400000,-5000000,0,0,0,0,0
'DATA 7,"Slow Boat",3,-5300000,-5300000,0,0,0,0,0
DATA 1,"PC vessel",2,-500000,-500000,0,0,0,0,0 DATA 2,"bogey 1",2,-650000,-530000,0,0,0,0,0 DATA 3,"bogey 2",2,-700000,230000,0,0,0,0,0
' END DATA SECTION
' END MAIN MODULE
'**********************************************************************************
' BEGIN SUB/FUNCTION SECTION
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
PanelBlank 420, 578, 64, 32, &HFF0F0F0F
Con_Blok 420, 578, 64, 32, "Adding", 0, &H508C5B4C
DISPLAY
DIM ts
(units
, units
) AS BYTE
x = 0 ' save state of Sensor & TLock
x = x + 1
y = 0
y = y + 1
ts(x, y) = Sensor(x, y)
units = units + 1 ' increment ship counter
REDIM Sensor
(units
, units
) x = 0 ' reload Sensor & TLock
x = x + 1
y = 0
y = y + 1
Sensor(x, y) = ts(x, y)
REDIM PRESERVE Thrust
(units
) AS Maneuver
ship_box(units) = NEWIMAGE(290, 96, 32)
cmb(units).id = units
cmb(units).status = 1
cmb(units).ap.pX = cmb(vpoint).ap.pX + 100000 ' start near active unit
cmb(units).ap.pY = cmb(vpoint).ap.pY + 100000 ' edit call can change this
cmb(units).ap.pZ = 0
FOR x
= 1 TO orbs
' check planets for interference IF Pyth
(cmb
(units
).ap
, hvns
(x
).ps
) < hvns
(x
).radi
THEN 'if inside planet cmb(units).ap.pX = cmb(units).ap.pX + 100000 ' move ship until beyond planet radius
LOOP UNTIL Pyth
(cmb
(units
).ap
, hvns
(x
).ps
) > hvns
(x
).radi
vpoint = units
EditShip -1
Refresh
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Returns the azimuth bearing of a relative (x,y) offset
Azimuth!
= 450 - ABS(R2D
(ATAN2
(y
, x
))) Azimuth! = 90 - (R2D(ATAN2(y, x)))
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Draw Azimuth wheel display - controlled by Aztog
PUTIMAGE (-1000, 1000)-(1000, -1000), AW& ' Overlay azimuth scale wheel
'Direction to Primary indicator- draw yellow primary azimuth indicator along azimuth wheel
FCirc
990 * SIN(D2R
(Azimuth!
(Px
- cmb
(vpoint
).ap.pX
, Py
- cmb
(vpoint
).ap.pY
))),_
990 * COS(D2R
(Azimuth!
(Px
- cmb
(vpoint
).ap.pX
, Py
- cmb
(vpoint
).ap.pY
))), 10, clr&
(14)
'Heading indicator
'draw heading arrow
LINE (950 * SIN(D2R
(cmb
(vpoint
).Hd
- 1)), 950 * COS(D2R
(cmb
(vpoint
).Hd
- 1)))-_
(1000 * SIN(D2R
(cmb
(vpoint
).Hd
)), 1000 * COS(D2R
(cmb
(vpoint
).Hd
))), clr&
(10) LINE (1000 * SIN(D2R
(cmb
(vpoint
).Hd
)), 1000 * COS(D2R
(cmb
(vpoint
).Hd
)))-_
(950 * SIN(D2R
(cmb
(vpoint
).Hd
+ 1)), 950 * COS(D2R
(cmb
(vpoint
).Hd
+ 1))), clr&
(10) 'heading leader line
LINE (0, 0)-(1000 * SIN(D2R
(cmb
(vpoint
).Hd
)), 1000 * COS(D2R
(cmb
(vpoint
).Hd
))), RGBA32
(168, 0, 168, 40)
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'determine azimuth bearing on ecliptic plane of 'unit' from viewpoint
'and check for possible collision/docking
IF rcs
(unit
).pX
= 0 AND rcs
(unit
).pY
= 0 AND rcs
(unit
).pZ
= 0 THEN collision = -1
collision = 0
Bearing = Azimuth!(rcs(unit).pX, rcs(unit).pY)
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'MANEUVER AND PROGRAM CONTROLS - temorary images
'Upper corner @ (0,578) just under unit data blocks
'First tier
Con_Blok 0, 578, 64, 32, "Vector", 1, &HFF2C9B2C
Con_Blok 70, 578, 64, 32, "n/a", 0, &HFF2C9B2C 'Con_Blok 70, 578, 64, 32, "Brake", 0, &HFF2C9B2C
Con_Blok 140, 578, 64, 32, "Turn", 1, &HFF2C9B2C
Con_Blok 210, 578, 64, 32, "Undo", 1, &HFF2C9B2C
Con_Blok 280, 578, 64, 32, "Edit", 1, &HFFA6A188 '&HFF8C5B4C
Con_Blok 350, 578, 64, 32, "Delete", 0, &HFFC80000
Con_Blok 420, 578, 64, 32, "LoadAll", 0, &HFF2C9B2C
Con_Blok 490, 578, 64, 32, "SaveAll", 1, &HFF8C5B4C
'Second tier
Con_Blok 0, 614, 64, 32, "Gs= 0", 0, &HFF2C9B2C
Con_Blok 70, 614, 64, 32, "n/a", 0, &HFF2C9B2C
Con_Blok 140, 614, 64, 32, "n/a", 0, &HFF2C9B2C
Con_Blok 210, 614, 64, 32, "n/a", 0, &HFF2C9B2C
Con_Blok 280, 614, 64, 32, "Add", 0, &HFFA6A188 '&HFF8C5B4C
Con_Blok 350, 614, 64, 32, "Purge", 0, &HFFC80000
Con_Blok 420, 614, 64, 32, "LoadSys", 0, &HFF2C9B2C
Con_Blok 490, 614, 64, 32, "SaveSys", 0, &HFF8C5B4C
'Third tier
Con_Blok 0, 650, 64, 32, "Brake", 0, &HFF2C9B2C 'Con_Blok 0, 650, 64, 32, "n/a", 0, &HFF2C9B2C
Con_Blok 70, 650, 64, 32, "n/a", 0, &HFF2C9B2C
Con_Blok 140, 650, 64, 32, "n/a", 0, &HFF2C9B2C
Con_Blok 210, 650, 64, 32, "n/a", 0, &HFF2C9B2C
Con_Blok 280, 650, 64, 32, "Help", 1, &HFF4CCB9C
IF cmb
(vpoint
).status
= 3 THEN Con_Blok 350, 650, 64, 32, "Repair", 0, &HFFC80000
Con_Blok 350, 650, 64, 32, "Adrift", 0, &HFFC80000
Con_Blok 420, 650, 64, 32, "LoadShp", 0, &HFF2C9B2C
Con_Blok 490, 650, 64, 32, "SaveShp", 0, &HFF8C5B4C
'sensor screen put @ 560,18 dimensions 620 x 620
'560,18 - 1180,638
'DISPLAY CONTROL TOGGLES - permanent images
PUTIMAGE (560, 660), XZ&, A& ' Zoom Extents
PUTIMAGE (626, 660), IZ&, A& ' Zoom In
PUTIMAGE (692, 660), OZ&, A& ' Zoom Out
PRINTSTRING
(560, 641), "Zoom Factor: " + STR$(ZoomFac
), A&
PUTIMAGE (762, 660), RG&, A& ' Ranging Band toggle
PUTIMAGE (820, 660), OB&, A& ' Orbit track toggle
PUTIMAGE (878, 660), GD&, A& ' Grid toggle
PUTIMAGE (928, 660), AZ&, A& ' Azimuth Wheel toggle
PUTIMAGE (970, 660), IN&, A& ' Inclinometer toggle
PUTIMAGE (1012, 660), JP&, A& ' Jump Envelope toggle
PUTIMAGE (1062, 660), DI&, A& ' Jump Diameter toggle
PUTIMAGE (1062, 660), DN&, A& ' Jump Density toggle
PUTIMAGE (1132, 660), QT&, A& ' Quit (program) button
Con_Blok 1204, 660, 40, 32, "3D", 0, &HFFB5651D
Con_Blok 1204, 660, 40, 32, "2D", 0, &HFFB5651D
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB Cancel_AI
(var
AS BYTE
)
FOR x
= 1 TO units
' cancel any intercept/evades targeting the wreck IF (cmb
(x
).bstat
= 1 OR cmb
(x
).bstat
= 2) AND cmb
(x
).bogey
= var
THEN cmb(x).bstat = 0: cmb(x).bogey = 0
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'CHECK FOR COLLISION WITH STAR/PLANET
DIM sphr
AS unitpoint
' center point of sphere DIM strt
AS unitpoint
' start point of unit vector DIM nd
AS unitpoint
' end point of unit vector DIM neari
AS unitpoint
' near intersection point on surface of sphere FOR p
= 1 TO orbs
' iterate for each body in system against unit (var) IF Pyth
(cmb
(var
).ap
, hvns
(p
).ps
) < hvns
(p
).radi
THEN cmb(var).status = 0 ' ends turn within sphere- crashed
IF Pyth
(hvns
(p
).ps
, cmb
(var
).op
) - hvns
(p
).radi
< cmb
(var
).Sp
* 1000 THEN 'wait for proximity to calculate sphr = hvns(p).ps
strt = cmb(var).op
nd = cmb(var).ap
'Use FLOAT variables, these numbers are friggin' enormous!
dx## = nd.pX - strt.pX: dy## = nd.pY - strt.pY: dz## = nd.pZ - strt.pZ
A## = (dx## * dx##) + (dy## * dy##) + (dz## * dz##)
B## = 2 * dx## * (strt.pX - sphr.pX) + 2 * dy## * (strt.pY - sphr.pY) + 2 * dz## * (strt.pZ - sphr.pZ)
C## = (sphr.pX * sphr.pX) + (sphr.pY * sphr.pY) + (sphr.pZ * sphr.pZ) + (strt.pX * strt.pX) +_
(strt.pY * strt.pY) + (strt.pZ * strt.pZ) + -2 * (sphr.pX * strt.pX + sphr.pY * strt.pY + sphr.pZ * strt.pZ)_
- (hvns(p).radi * hvns(p).radi)
disabc## = (B## * B##) - 4 * A## * C## ' if disabc <0 then no intersection =0 tangent >0 intersects two points
'No intersection detected, go on checking other bodies.
ELSE ' course intersects body t## = (-B## - ((B## * B##) - 4 * A## * C##) ^ .5) / (2 * A##) 'Near intersect quadratic
neari.pX = strt.pX + t## * dx##: neari.pY = strt.pY + t## * dy##: neari.pZ = strt.pZ + t## * dz##
IF Pyth
(neari
, strt
) <= Pyth
(nd
, strt
) THEN ' impact cmb(var).status = 0
cmb(var).ap = neari
Cancel_AI var
'if neari impact point needed in future upgrades, such as landing options, determine that point here
'landing option would entail a speed vs maximum thrust potential check.
'interestingly a ghost is left on the screen where the ship "died", probably a remnant of vector indicators.
'Purge will remove the ghosts.
END IF ' end: if vector intersects END IF ' end: check for intersection END IF ' end: if close proximity do the check
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
PRINTSTRING (300, 560), "Coming soon...maybe", A&
DISPLAY
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'VERSION COMMENTS
'Basic algorithm for rewrite of STARRUTR.BAS
'starship vector movement handler for Classic Traveller RPG
'
'
'HISTORIC COMMENTS
' STARRUTR.BAS (8.3 short for Star Ruttier)
' The ruttier being an archaic term for the charts and directions
'that a sailing ships pilot would use to navigate, Star Ruttier is
'a QBasic based program for tracking 3 dimensional space craft
'maneuvers in an interplanetary setting.
' Conceived as a ship to ship combat game aid for the Traveller
'Role Playing system, Star Ruttier displays graphic position and numeric
'data for vector maneuvers in a turn based 3D cartesian (X,Y,Z) system.
' On the left each ship unit is displayed with Unit index, Name, Azimuth
'Heading, Inclination, and Speed with one ship highlighted as the active
'unit. All inactive units are additionally displayed with Azimuth Bearing,
'Inclination, and Distance from the active unit. On the right of the screen
'a graphics window is displayed showing the relative positions of each
'indexed unit. The active unit is displayed in the center of the graphics
'window, with the other units positioned relative to the active unit. The
'active unit can be chosen by using the up and down arrows.
' The display is dynamically resized to include all units displayed
'regardless of distance from the active unit. The display is viewed from
'the Galactic zenith with the top edge being Coreward. Other viewpoints
'may be offered in subsequent versions. In this release units above or
'below the active unit are displayed Blue shift and Red shift
'respectively.
' The 'chose' menu in the lower left corner displays the menu options
'which can be accessed by typing the highlighted letter of each choice.
'Type 'V' for vector to input new thrust, Azimuth, and Inclination
'headings for the active unit. If no new values are entered the active
'unit will default to the last entered values. The unit will continue
'to thrust until the power is cut by entering zero values for thrust,
'though the unit will continue to coast at the current vector.
' Type 'T' for turn after all desired vectors have been entered and
'the new vectors will be applied for the current turn. All unit positions
'will be updated and displayed and new vectors can be entered.
' Type 'Q' to quit program
'CT Vector.bas comments
'HOT KEYS accessible in main loop
' "S" Ship display mode (proposed)
' "P" Planet display mode (proposed)
'[up arrow] increments active unit pointer
'[down arrow] decrements active unit pointer
'[Delete] delete the active unit
'[Insert] Add new unit and make active
' "+" zoom in
' "-" zoom out
' "X" zoom extents (default zoom factor 1)
' "A" toggle azimuth wheel....................... [default=on]
' "B" toggle planetoid belt/ring display......... [default=on]
' "G" toggle grid................................ [default=on]
' "I" toggle inclinometer........................ [default=off]
' "R" toggle ranging bands....................... [default=off]
' "J" toggle jump diameters...................... [default=off]
' "D" toggle density based jump diameters........ [default=off]
' "O" toggle orbit tracks........................ [default=on]
' "Z" toggle gravity zones....................... [default=on]
' "3" toggle 3D panning.......................... [default=off]
' "V" enter new vector for active unit. Enter azimuth "c" to counter vector
' "T" apply vectors to game turn
' "U" undo previous turn
' "E" edit active unit data
' "Q" end program
'CT Vector has updated displays to 32 bit images. Mouse support has been added.
'Navigation aids of azimuth wheel, inclinometer, scale grid as well as jump
'diameter and combat range bands have been added. All may be toggled on and off
'as needed. Planetary bodies will now occlude sensors of active ship.
'Right mouse click will reposition active unit, in x,y, to anywhere on the visible
'sensor screen limits. Z-pan slider rotates view 180 deg. around Y axis. Systems,
'ships and scenarios may be saved and recalled.
'The program will zoom out to distances of many parsecs, but has difficulty
'zooming in tightly under several circumstances.
'Tentative ideas for data system...
'File system: [name].tss for star systems, [name].tvg for vessel group
' [scenario].tgn for loading both (game name for saving state for later recall)
'TRAVEL FORMULAE (from Traveller Book)
'Time[s] = 2 * ((Distance[m] / Acceleration[m/s^2])^.5)
'Distance[m] = Acceleration[m/s^2] * Time[s]^2 / 4
'Acceleration[m/s^2] = 4 * Distance[m] / Time[s]^2
'GRAVITY FORMULAE (from Traveller Book)
'Radius[100km] = 8 * Diameter[UPP]
'Mass[earth mass] = K[earth densities] * (diameter[UPP] / 8)^3
'Gs = K[earth densities] * (Diameter[UPP] / 8)
'L = 64 * (Mass / G)^.5
'OTHER USEFUL THINGS
'from http://braeunig.us/space/vectors.htm
'longitude=l=azimuth, latitude=b=inclination, and radial distance, r.
'x = r cos b cos l it must be noted that x & y are transposed with respect to
'y = r cos b sin l this application.
'z = r sin b
'color legend- for clr&(x) assignments
'0=black,1=blue,2=green,3=aqua,4=red,5=purple,6=brown,7=white
'8=gray, +8=bright color, except 14=yellow,
'Mean Density of Earth = 5.514
'LINKS
'http://www.batesville.k12.in.us/Physics/PhyNet/Mechanics/Gravity/lab/excel_orbits.htm
'USEFUL ALGORITHMS that are faster implemented outside of FUNCTION
'find the x coordinate of a magnitude and azimuth: x = magnitude * SIN(_D2R(Azimuth))
'find the y coordinate of a magnitude and azimuth: y = magnitude * COS(_D2R(Azimuth))
'Deceleration = v^2 - u^2 / 2s
'Where,
'v = The Final Velocity
'u = The Initial Velocity
's = Distance
'BUG LIST
'somebody please shoot me...
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Create control block
'upper left corner @ (xpos,ypos), size of (xsiz,ysiz), label, high= highlight character position, col= box color
CN& = NEWIMAGE(xsiz, ysiz, 32)
DEST CN&
LINE (1, 1)-(xsiz
- 2, ysiz
- 2), clr&
(0), B
PRINTMODE KEEPBACKGROUND
sx = xsiz / 2 - x * 4
sy = ysiz / 2 - 8
PRINTSTRING
(sx
+ (p
- 1) * 8, sy
), MID$(label
, p
, 1) PUTIMAGE (xpos, ypos), CN&, A&
FREEIMAGE CN&
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'convert polar data to cartesian and updates coordinates.x
'var1 sends unit index
'var2 sends origin T for turn or I for intercept/evade
ms = MEM(cmb())
mt = MEM(Thrust())
'Determine coasting deltaXYZ
'CoastDeltaZ&& = cmb(var1).Sp * SIN(_D2R(cmb(var1).In))
CoastD.pZ
= MEMGET
(ms
, ms.OFFSET
+ var1
* ms.ELEMENTSIZE
+ 76, SINGLE)_
* SIN(D2R
(MEMGET
(ms
, ms.OFFSET
+ var1
* ms.ELEMENTSIZE
+ 84, SINGLE))) 'CoastDeltaX&& = cmb(var1).Sp * COS(_D2R(cmb(var1).In)) * SIN(_D2R(cmb(var1).Hd))
CoastD.pX
= MEMGET
(ms
, ms.OFFSET
+ var1
* ms.ELEMENTSIZE
+ 76, SINGLE)_
* COS(D2R
(MEMGET
(ms
, ms.OFFSET
+ var1
* ms.ELEMENTSIZE
+ 84, SINGLE)))_
* SIN(D2R
(MEMGET
(ms
, ms.OFFSET
+ var1
* ms.ELEMENTSIZE
+ 80, SINGLE))) 'CoastDeltaY&& = cmb(var1).Sp * COS(_D2R(cmb(var1).In)) * COS(_D2R(cmb(var1).Hd))
CoastD.pY
= MEMGET
(ms
, ms.OFFSET
+ var1
* ms.ELEMENTSIZE
+ 76, SINGLE)_
* COS(D2R
(MEMGET
(ms
, ms.OFFSET
+ var1
* ms.ELEMENTSIZE
+ 84, SINGLE)))_
* COS(D2R
(MEMGET
(ms
, ms.OFFSET
+ var1
* ms.ELEMENTSIZE
+ 80, SINGLE)))
''determine coasting deltaXYZ using vector addition ...experimental but won't add accelerations...????
'CoastD = cmb(var1).ap: VecAdd CoastD, cmb(var1).op, -1
'Determine thrusting delta XYZ for MoveTurn, InterVade assumes coasting vector
'ThrstD.pZ = (Thrust(var1).Gs * 10000) * SIN(_D2R(Thrust(var1).Inc))
ThrstD.pZ
= (MEMGET
(mt
, mt.OFFSET
+ var1
* mt.ELEMENTSIZE
+ 8, SINGLE) * 10000)_
* SIN(D2R
(MEMGET
(mt
, mt.OFFSET
+ var1
* mt.ELEMENTSIZE
+ 4, SINGLE))) 'ThrstD.pX = (Thrust(var1).Gs * 10000) * COS(_D2R(Thrust(var1).Inc)) * SIN(_D2R(Thrust(var1).Azi))
ThrstD.pX
= (MEMGET
(mt
, mt.OFFSET
+ var1
* mt.ELEMENTSIZE
+ 8, SINGLE) * 10000)_
* COS(D2R
(MEMGET
(mt
, mt.OFFSET
+ var1
* mt.ELEMENTSIZE
+ 4, SINGLE)))_
* SIN(D2R
(MEMGET
(mt
, mt.OFFSET
+ var1
* mt.ELEMENTSIZE
, SINGLE))) 'ThrstD.pY = (Thrust(var1).Gs * 10000) * COS(_D2R(Thrust(var1).Inc)) * COS(_D2R(Thrust(var1).Azi))
ThrstD.pY
= (MEMGET
(mt
, mt.OFFSET
+ var1
* mt.ELEMENTSIZE
+ 8, SINGLE) * 10000)_
* COS(D2R
(MEMGET
(mt
, mt.OFFSET
+ var1
* mt.ELEMENTSIZE
+ 4, SINGLE)))_
* COS(D2R
(MEMGET
(mt
, mt.OFFSET
+ var1
* mt.ELEMENTSIZE
, SINGLE)))
'Sum Cumulative Coordinates
TotalD = CoastD: VecAdd TotalD, ThrstD, 1
'Update unit coordinates
IF var2
= "T" THEN ' Permanent position change for MoveTurn 'cmb(var1).ap.pX = cmb(var1).ap.pX + TotalDeltaX&&
cmb(var1).ap.pX = MEMGET(ms, ms.OFFSET + var1 * ms.ELEMENTSIZE + 52, INTEGER64) + TotalD.pX
'cmb(var1).ap.pY = cmb(var1).ap.pY + TotalDeltaY&&
cmb(var1).ap.pY = MEMGET(ms, ms.OFFSET + var1 * ms.ELEMENTSIZE + 60, INTEGER64) + TotalD.pY
'cmb(var1).ap.pZ = cmb(var1).ap.pZ + TotalDeltaZ&&
cmb(var1).ap.pZ = MEMGET(ms, ms.OFFSET + var1 * ms.ELEMENTSIZE + 68, INTEGER64) + TotalD.pZ
Grav_Well var1
ELSEIF var2
= "I" THEN ' Temporary data for InterVade 'soltemp.pX = cmb(var1).ap.pX + TotalDeltaX&&
soltemp.pX = MEMGET(ms, ms.OFFSET + var1 * ms.ELEMENTSIZE + 52, INTEGER64) + TotalD.pX
'soltemp.pY = cmb(var1).ap.pY + TotalDeltaY&&
soltemp.pY = MEMGET(ms, ms.OFFSET + var1 * ms.ELEMENTSIZE + 60, INTEGER64) + TotalD.pY
'soltemp.pZ = cmb(var1).ap.pZ + TotalDeltaZ&&
soltemp.pZ = MEMGET(ms, ms.OFFSET + var1 * ms.ELEMENTSIZE + 68, INTEGER64) + TotalD.pZ
MEMFREE ms: MEMFREE mt
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
DialogBox
"You're about to delete " + RTRIM$(cmb
(vpoint
).Nam
) + ". Continue?", 400, 200, 100, clr&
(4), clr&
(15) Con_Blok 450, 225, 120, 32, "Yes [enter]", 0, clr&(4)
Con_Blok 630, 225, 120, 32, "No [Esc]", 0, clr&(4)
DISPLAY
Cancel_AI vpoint
Mouse_Loop 0, 0
mouse_left = MOUSEBUTTON(1)
CASE 450 TO 570 ' delete with mouseclick on "Yes" dl% = -1
CASE 630 TO 750 ' abort delete with mouseclick on "No" IF x$
= CHR$(13) THEN dl%
= -1 ' delete with ENTER FOR p
= vpoint
TO units
' pancake the variables down on deleted unit cmb(p) = cmb(p + 1)
Thrust(p) = Thrust(p + 1)
Sensor(p, p) = Sensor(p + 1, p + 1)
cmb(p).id = p
FREEIMAGE ship_box(units) ' free data box memory
vpoint = vpoint - 1 ' decrement the active counter avoiding subscript range fault
vpoint = 1
vpoint = 0
EXIT FOR ' let redims handle the rest units = units - 1 ' decrement unit counter
REDIM PRESERVE Thrust
(units
) AS Maneuver
REDIM PRESERVE Sensor
(units
, units
) AS BYTE
Refresh
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'superimpose a screen centered input box for various input routines
'call syntax: DialogBox <heading string>, box x, box y, y position, bounding box color, text color
T& = NEWIMAGE(xsiz, ysiz, 32) ' define box
DEST T&
COLOR tcol
, clr&
(0) ' set text color with black background FOR x
= 0 TO 5 ' draw bounding box 3 pixels thick LINE (0 + x
, 0 + x
)-(WIDTH(T&
) - 1 - x
, HEIGHT
(T&
) - 1 - x
), clr&
(0), B
LINE (0 + x
, 0 + x
)-(WIDTH(T&
) - 1 - x
, HEIGHT
(T&
) - 1 - x
), bcol
, B
l
= WIDTH(T&
) / 2 - (LEN(heading
) * 8) / 2 ' set heading position PRINTSTRING (l, 31), heading, T& ' print heading
PUTIMAGE
(WIDTH(A&
) / 2 - WIDTH(T&
) / 2, ypos
), T&
, A&
' display box DEST A&
FREEIMAGE T&
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'**************************************************************************************************
DEST ship_box(x)
IF x
= vpoint
THEN ' Active white others aqua IF READBIT
(Sensor
(vpoint
, x
), 0) OR cmb
(x
).status
= 0 THEN
IF Pyth
(cmb
(vpoint
).ap
, cmb
(x
).ap
) > 1500000000 THEN
IF READBIT
(Sensor
(vpoint
, x
), 0) THEN IF cmb
(x
).status
= 0 THEN ' has unit been destroyed? IF x
= vpoint
THEN ' was destroyed unit active? ct% = 0
DO ' find next available unit to be active vpoint = vpoint + 1
IF vpoint
> units
THEN vpoint
= 1 ct% = ct% + 1
IF ct%
= units
THEN ' if all units destroyed center on primary vpoint = 0
UDest x ' if destroyed set movement to zero
IF x
= vpoint
THEN ' Active unit title line PRINT "X:";: TruncCoord cmb
(x
).ap.pX:
PRINT " ";
' Absolute coordinate position IF Thrust
(x
).Gs
> cmb
(x
).MaxG
THEN COLOR clr&
(12) ' Red speed if overdrive subscript out of range when loading new ships??? PRINT INT((cmb
(x
).Sp
/ 1000) * 100) / 100;
' round to 100th km for display IF x
= vpoint
THEN ' Return to original colors IF READBIT
(Sensor
(vpoint
, x
), 0) OR cmb
(x
).status
= 0 THEN d = Bearing(x)
LOCATE , 11:
PRINT " ";
"Z=";
INT(Slope!
(cmb
(x
).ap
, cmb
(vpoint
).ap
) * 100) / 100;
"";
IF Pyth
(cmb
(vpoint
).ap
, cmb
(x
).ap
) < 10000000 THEN PRINT USING "###.###"; Pyth
(cmb
(vpoint
).ap
, cmb
(x
).ap
) / KMtoAU;:
PRINT "AU" collision
= NOT collision
PUTIMAGE (0, 63), cancel&, ship_box(x)
PUTIMAGE (0, 63), evade&, ship_box(x)
PUTIMAGE (49, 63), intercept&, ship_box(x)
IF READBIT
(Sensor
(vpoint
, x
), 1) THEN PRINTSTRING (3, 79), ">>Target Locked<<", ship_box(x)
b = 600000
b = 150000
IF Pyth
(cmb
(vpoint
).ap
, cmb
(x
).ap
) <= b
THEN PUTIMAGE (273, 63), TLoc, ship_box(x)
PUTIMAGE (273, 63), TLocn, ship_box(x)
PUTIMAGE (0, 63), flight&, ship_box(x)
LINE (0, 0)-(289, 95), clr&
(4), B
'**************************************************************************************************
c% = 0: g% = 0
IF units
>= 6 THEN ' if enough units to fill display area lp% = 6 ' then fill it
lp% = units ' otherwise only use what you got
g% = g% + 1
IF units
<= 6 THEN shipoff
= 0 PUTIMAGE (0, c%), ship_box(y + shipoff), A& ' invalid handle error thrown once
c% = c% + 96
DEST A&
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB EditShip
(var
AS BYTE
)
u$ = "Editing new vessel"
PanelBlank 280, 578, 64, 32, &HFF0F0F0F
Con_Blok 280, 578, 64, 32, "Editing", 1, &H508C5B4C
u$ = "Editing " + TRIM$(cmb(vpoint).Nam)
t% = 400: r% = 5
DialogBox u$, t%, 250, 100, &HFF8C5B4C, clr&(15)
in1$ = "Enter new value or press ENTER to default"
PRINTSTRING (l, 320), in1$, A&
DISPLAY
col%
= ((WIDTH(A&
) / 2) - (t%
/ 2)) / 8 + 4 IF n$
<> "" THEN cmb
(vpoint
).Nam
= n$
IF mg$
<> "" THEN cmb
(vpoint
).MaxG
= VAL(mg$
) IF xp$
<> "" THEN cmb
(vpoint
).ap.pX
= VAL(xp$
) IF yp$
<> "" THEN cmb
(vpoint
).ap.pY
= VAL(yp$
) IF zp$
<> "" THEN cmb
(vpoint
).ap.pZ
= VAL(zp$
) INPUT "Speed (kps):"; sp$
IF sp$
<> "" THEN cmb
(vpoint
).Sp
= VAL(sp$
) * 1000 INPUT "Inclination:"; in$
b = 0
INPUT "Scout/military sensors? y/n ", mil$
cmb(vpoint).mil = -1: b = -1
cmb(vpoint).mil = 0: b = -1
b = -1
IF mg$
<> "" THEN cmb
(vpoint
).MaxG
= VAL(mg$
)
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB FCirc
(CX
AS INTEGER64
, CY
AS INTEGER64
, RR
AS INTEGER64
, C
AS UNSIGNED
LONG) DIM R
AS INTEGER64
, RError
AS INTEGER64
R
= ABS(RR
) ' radius value along positive x RError = -R ' opposite side of circle? negative x
X = R ' point along positive x position
Y = 0 ' starting at the equator
LINE (CX
- X
, CY
)-(CX
+ X
, CY
), C
, BF
' draw equatorial line RError = RError + Y * 2 + 1
LINE (CX
- Y
, CY
- X
)-(CX
+ Y
, CY
- X
), C
, BF
LINE (CX
- Y
, CY
+ X
)-(CX
+ Y
, CY
+ X
), C
, BF
X = X - 1
RError = RError - X * 2
Y = Y + 1
LINE (CX
- X
, CY
- Y
)-(CX
+ X
, CY
- Y
), C
, BF
LINE (CX
- X
, CY
+ Y
)-(CX
+ X
, CY
+ Y
), C
, BF
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Accepts a planetary body index (var) and finds the index of its parent body
IF hvns
(var
).parnt
= hvns
(x
).nam
THEN p
= x
FindParent = p
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'routine to choose planet- input box
'DIM unitpoints for startpoint, midpoint and endpoint
'FlightPlan to be called on vpoint each turn while bstat=3
'check movement of end point and update, also update midpoint
'acceleration until at or past updated midpoint, spread mathematically over remaining distance
'deceleration after midpoint, spread mathematically over remaining distance.
Coming
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
DEST A&
PUTIMAGE (0, 0), strfld, A&
Prnt TRIM$(ttl), 6, -6, 250, 100, 48, 0, &HFF5050A0
Prnt "Classic Traveller starship maneuvers", 2, -2, 320, 200, 16, 0, &HFF505040
PRINTSTRING (200, 250), "Ditch the compasses and protractors! CT-Vector will handle the starship maneuvers, and even do it in 3D.", A&
PRINTSTRING (200, 270), "If you know a star system's name and path you may load it now, or press [enter] to default to Sol", A&
T& = NEWIMAGE(950, 200, 32)
DEST T&
LINE (0 + x
, 0 + x
)-(949 - x
, 199 - x
), &HFF5050A0, B
PUTIMAGE (150, 290), T&, A&
DEST A&
INPUT "Input {path/filename}.tss or [enter] to default to Sol :", sys$
sys$ = "systems/Sol.tss"
sys$ = TRIM$(sys$)
sys$ = TRIM$(sys$) + ".tss"
sys$ = "systems/" + TRIM$(sys$)
'load file into hvns() array
FOR x
= 1 TO orbs
' Load data array oryr = yr
oryr = yr + (dy / 365)
FREEIMAGE T&
LOCATE 22, 25:
PRINT "File does not exist. Please check your path and file name." t$ = ttl + " " + sys$
TITLE t$
FREEIMAGE strfld
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Apply gravity perturbations of nearby massive bodies
'Grav_Well call should probably go in CoordUpdate after AbsXYZ is set
IF cmb
(var
).status
> 0 THEN ' if unit (var) is destroyed there's no point in doing this DIM grav
AS Maneuver
' grav influence of every body in system DIM mdpnt
AS unitpoint
' midpoint of ship's vector DIM Ppnt
AS unitpoint
' planetary gravity centers xdr! = 0: ydr! = 0: zdr! = 0
'locate turn vector midpoint- now * 0.5, was / 2
mdpnt.pX = cmb(var).op.pX + (cmb(var).ap.pX - cmb(var).op.pX) * 0.5
mdpnt.pY = cmb(var).op.pY + (cmb(var).ap.pY - cmb(var).op.pY) * 0.5
mdpnt.pZ = cmb(var).op.pZ + (cmb(var).ap.pZ - cmb(var).op.pZ) * 0.5
'Iterate all bodies in system
'find distance to massive body o from unit's vector mid point
Ppnt = hvns(O).ps
ds## = Pyth(Ppnt, mdpnt) ' distance between bodies, use float variable
IF ds##
< hvns
(O
).radi
THEN ds##
= hvns
(O
).radi
'compute gravitational force exerted upon unit at distance
'multiply density by Earth volumes for G value then divide by square of distance
'divide by 26687 setting one Earth mass to one G @ Earth radius
radius## = hvns(O).radi ' convert radii to float variable
grav.Gs = ((hvns(O).dens * ((4 / 3) * PI * (radius## * radius## * radius##))) / 26687) / (ds## * ds##)
'get relative offset positions of ship vector midpoint to gravity well source to obtain source of G force vector
Pull = hvns(O).ps: VecAdd Pull, mdpnt, -1
grav.Azi = Azimuth!(Pull.pX, Pull.pY) ' Azimuth bearing of perturbation
grav.Inc = Slope!(Ppnt, mdpnt) ' Declination of perturbation
'add vector to a vector tally
zgrav!
= (grav.Gs
* 10000) * SIN(D2R
(grav.Inc
)) xgrav!
= (grav.Gs
* 10000) * COS(D2R
(grav.Inc
)) * SIN(D2R
(grav.Azi
)) ygrav!
= (grav.Gs
* 10000) * COS(D2R
(grav.Inc
)) * COS(D2R
(grav.Azi
)) xdr! = xdr! + xgrav!
ydr! = ydr! + ygrav!
zdr! = zdr! + zgrav!
'apply the combined vector to unit
cmb(var).ap.pX = cmb(var).ap.pX + ROUND(xdr!)
cmb(var).ap.pY = cmb(var).ap.pY + ROUND(ydr!)
cmb(var).ap.pZ = cmb(var).ap.pZ + ROUND(zdr!)
'temporary for watch variable of active unit- need to exprapolate out the Maneuver data
'find the distance of xdr!, ydr! & zdr!
xu.pX = xdr!: xu.pY = ydr!: xu.pZ = zdr!
Gwat.Gs = HYPOT(HYPOT(xdr!, ydr!), zdr!) / 10000
Gwat.Azi = Azimuth!(xdr!, ydr!)
Gwat.Inc = Slope!(xu, cmb(var).ap)
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB IncMeter
(var
AS BYTE
, vecin
AS BYTE
)
'togs bit 5= inclinometer display
'Display inclinometer scale
c& = RGBA32(127, 127, 127, 127)
a = 0: b = 180: c = -90: d = -1
a = 0: b = 180: c = -90: d = -1
a = 180: b = 360: c = -270: d = 1
y = 800
Prnt
STR$((whl
+ c
) * d
), 2.8, 2.8, ((y
+ 20) * SIN(D2R
(whl
))) - 60, (y
+ 20) * COS(D2R
(whl
)), 24, 0, c&
y = 850
y = 870
y = 890
LINE (900 * SIN(D2R
(whl
)), 900 * COS(D2R
(whl
)))-(y
* SIN(D2R
(whl
)), y
* COS(D2R
(whl
))), c&
'Display unit inclination arrow
IF cmb
(vpoint
).In
>= 0 THEN ' Moving with or toward the zenith of the plane IF cmb
(vpoint
).Hd
<= 180 THEN ' right side zdeg!
= ABS(cmb
(vpoint
).In
- 90) zdeg!
= ABS(270 - NOT SGN(d
) * cmb
(vpoint
).In
) ELSE ' Moving toward the nadir of the plane IF cmb
(vpoint
).Hd
> 180 THEN ' left side zdeg!
= ABS(270 - NOT SGN(d
) * cmb
(vpoint
).In
) zdeg!
= ABS(cmb
(vpoint
).In
- 90) LINE (850 * SIN(D2R
(zdeg!
- 1)), 850 * COS(D2R
(zdeg!
- 1)))-(900 * SIN(D2R
(zdeg!
)), 900 * COS(D2R
(zdeg!
))), RGBA32
(127, 127, 127, 200) LINE (900 * SIN(D2R
(zdeg!
)), 900 * COS(D2R
(zdeg!
)))-(850 * SIN(D2R
(zdeg!
+ 1)), 850 * COS(D2R
(zdeg!
+ 1))), RGBA32
(127, 127, 127, 200)
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'"The others are as archaic as dinosaurs compared to InterVadeII, a whole new approach..."
'-Dr. Richard Daystrom ;)
'and this one's turning out just about as well...
' Conduct evade/intercept calculations
' tar = target unit: tar is also carried in cmb(sol).bogey
' sol is solution unit, i.e. unit executing the nav solution
' mode is mode of call 0 from MoveTurn or 1+ from MouseOps
' MoveTurn mode (0) automatically applies computed maneuvers
' MouseOps mode queries user to accept solution upon initiation
' mode is now carried in cmb(sol).bstat for automation
' 1=evade
' 2=intercept
'typical syntax: InterVadeII cmb(x).bogey, cmb(x).id, [0 - 2]
'we can later expand mode mode to include flightplan maneuvers
'using .bogey to hold planet index.
'We cannot know the future, so we must use the past as the basis of calculation
DIM origin
AS unitpoint
' used as 0,0,0 base for Pyth distance calculations DIM tarpos
AS unitpoint
' target unit position DIM solpos
AS unitpoint
' solution unit position DIM tarmov
AS unitpoint
' last target movement vector DIM solmov
AS unitpoint
' last solution movement vector DIM tarfut
AS unitpoint
' projected future target position DIM solfut
AS unitpoint
' projected future solution position DIM difmov
AS unitpoint
' DIM clsmov
AS unitpoint
' origin.pX = 0: origin.pY = 0: origin.pZ = 0
tarpos = cmb(tar).ap: solpos = cmb(sol).ap
tarmov = cmb(tar).ap: VecAdd tarmov, cmb(tar).op, -1 ' compute last target movement vector (target velocity)
solmov = cmb(sol).ap: VecAdd solmov, cmb(sol).op, -1 ' compute last solution movement vector (solution velocity)
tarfut = tarpos: VecAdd tarfut, tarmov, 1 ' compute projected future target position
solfut = solpos: VecAdd solfut, solmov, 1 ' compute projected future solution position Do we need this? the whole point is to change it
SELECT CASE mode
' is unit evading or intercepting? '_____________________________________________________________________________________________________________________________EVADE
'what movement vector (solmov) maximizes distance between tarfut and solfut
'take a break from intercept
'_________________________________________________________________________________________________________________________INTERCEPT
CASE IS = 2 'TO INTERCEPT will move to intercept, but need timely braking thrust 'need a match vector AND a close vector to intercept, subject to maxG of solution unit
clsmov = tarfut: VecAdd clsmov, solfut, -1 'now clsmov has the cartesian vector to close range with the target this turn
difmov = solmov: VecAdd difmov, tarmov, -1 'now difmov has the cartesian vector that adjusts to the target movement this turn
VecAdd clsmov, difmov, 1 'combine the two ...and this is the vector to close with target's future position
uclsmov = clsmov: VecNorm uclsmov
usolmov = solmov: VecNorm usolmov
dotP&& = uclsmov.pX * usolmov.pX + uclsmov.pY * usolmov.pY + uclsmov.pZ * usolmov.pZ '<<<<DOT PRODUCT equation if needed
'dotP&& = clsmov.pX * solmov.pX + clsmov.pY * solmov.pY + clsmov.pZ * solmov.pZ '<<<<DOT PRODUCT equation if needed
T2m## = Pyth(origin, difmov) / (cmb(sol).MaxG * 10000) 'turns to match target speed
T2c## = Pyth(origin, clsmov) / (cmb(sol).MaxG * 10000)
d2m## = Pyth(origin, clsmov) ' distance between future points (kms)
vav## = (Pyth(origin, solmov) + Pyth(origin, tarmov)) / 2
IF d2m##
/ vav##
<= T2m##
+ 1 THEN l% = -1
l% = 1
l% = 1
'apply results to Thrust of solution unit
Thrust(sol).Azi = Azimuth!(clsmov.pX * l%, clsmov.pY * l%)
Thrust(sol).Inc = Slope!(tarfut, solfut) * l%
IF Pyth
(solfut
, tarfut
) < cmb
(sol
).MaxG
* 10000 THEN Thrust(sol).Gs = Pyth(solfut, tarfut) / 10000
Thrust(sol).Gs = cmb(sol).MaxG
'dotP&& = tarmov.pX * solmov.pX + tarmov.pY * solmov.pY + tarmov.pZ * solmov.pZ '<<<<DOT PRODUCT equation if needed
's = (v * t) - (.5 * a * t ^ 2) 'where
'Deceleration = v^2 - u^2 / 2s 'Where, v = The Final Velocity u = The Initial Velocity s = Distance
'Time[s] = 2 * ((Distance[m] / Acceleration[m/s^2])^.5)
'Distance[m] = Acceleration[m/s^2] * Time[s]^2 / 4
'Acceleration[m/s^2] = 4 * Distance[m] / Time[s]^2
'Deceleration Distance[m] = Acceleration[m/s^2] * Time[sec]^2 / 2
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Load star system file
'call syntax: DialogBox <heading string>, box x, box y, y position, bounding box color, text color
DialogBox "LOAD NEW STAR SYSTEM", 400, 250, 50, &HFF2C9B2C, clr&(15)
in1$ = "Enter path and filename of system"
PRINTSTRING (l, 113), in1$, A&
DISPLAY
fn$
= "systems\" + fn$
+ ".tss" Turncount = 0
PlanetMove 1 ' planets to date positions
PRINT "File not found, check path and name."
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
DialogBox "LOAD NEW VESSEL GROUP", 400, 250, 50, &HFF2C9B2C, clr&(15)
in1$ = "Enter filename of ships"
PRINTSTRING (l, 113), in1$, A&
DISPLAY
fn$
= "ships/" + fn$
+ ".tvg" FOR x
= 1 TO units
' erase old ship data displays FREEIMAGE ship_box(x)
REDIM Sensor
(units
, units
) ship_box(x) = NEWIMAGE(290, 96, 32)
Turncount = 0: vpoint = 1: shipoff = 0
FOR x
= 1 TO units
' nested loop to avoid planet/star collisions here IF Pyth
(cmb
(x
).ap
, hvns
(y
).ps
) < hvns
(p
).radi
THEN 'inside a body's radius? then move it DO ' loop to accomodate large stars/GGs cmb(x).ap.pX = cmb(x).ap.pX + 100000 ' Move ship 100K coreward and trailing
cmb(x).ap.pY = cmb(x).ap.pY + 100000
LOOP UNTIL Pyth
(cmb
(x
).ap
, hvns
(y
).ps
) > hvns
(p
).radi
'stop once the unit's clear VCS
PRINT "File not found, check path and name."
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
t% = 400: r% = 2
DialogBox "LOAD SCENARIO", t%, 250, 50, &HFF8C5B4C, clr&(15)
DISPLAY
INPUT "Enter a scenario name: ", fl$
IF TRIM$
(fl$
) = "auto" THEN fl$
= "autosave/auto" vl$ = "scenarios\" + TRIM$(fl$) + ".tvg" ' Vessel group #2
pl$ = "scenarios\" + TRIM$(fl$) + ".tss" ' Planets #1
sl$ = "scenarios\" + TRIM$(fl$) + ".tgn" ' saved state #4
tl$ = "scenarios\" + TRIM$(fl$) + ".tvt" ' Thrust keeper (.tvt) #3
tt$ = "scenarios\" + TRIM$(fl$) + ".ttl" ' Sensor state keeper #5
ERASE hvns
, cmb
, Thrust
, Sensor
' reset environment/ remove TLock IF FILEEXISTS
(tl$
) THEN ' important but not fatal if missing INPUT #4, Turncount
, oryr
, vpoint
, shipoff
IF FILEEXISTS
(tt$
) THEN ' remove entire file structure TLock subsumed by Sensor GET #5, ((x
- 1) * units
) + y
, Sensor
(x
, y
) Turn2Clock Turncount
Refresh
'essential file(s) are not present, abort
PRINT "Essential files missing, check filename."
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
DEST flight& ' Create flightplan button
COLOR , RGBA32
(22, 166, 211, 255) PRINTSTRING (0, 0), "FLIGHTPLAN", flight&
DEST evade& ' Create evade button
COLOR , RGBA32
(244, 11, 17, 255) PRINTSTRING (0, 0), "EVADE", evade&
DEST intercept& ' Create intercept button
COLOR , RGBA32
(17, 139, 17, 255) PRINTSTRING (0, 0), "INTERCEPT", intercept&
DEST cancel& ' Create cancel button
COLOR , RGBA32
(67, 67, 150, 255) PRINTSTRING (0, 0), "CANCEL", cancel&
DEST XZ& ' 64x32 Create Zoom extents control
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(62, 30), clr&
(4), B
PRINTSTRING (8, 8), "Zoom", XZ&
PRINTSTRING (48, 8), "X", XZ&
DEST IZ& ' 64x32 Create Zoom in control
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(62, 30), clr&
(4), B
PRINTSTRING (8, 8), "Zoom", IZ&
PRINTSTRING (48, 8), "+", IZ&
DEST OZ& ' 64x32 Create Zoom out control
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(62, 30), clr&
(4), B
PRINTSTRING (8, 8), "Zoom", OZ&
PRINTSTRING (48, 8), "-", OZ&
DEST RG& ' 56x32 Create Range band toggle
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(54, 30), clr&
(4), B
c& = RGBA(252, 252, 84, 100)
FCirc 28, 16, 20, RGBA(252, 252, 84, 100)
c& = RGBA(252, 84, 84, 100)
FCirc 28, 16, 12, RGBA(0, 0, 0, 0)
FCirc 28, 16, 12, RGBA(252, 84, 84, 200)
PRINTMODE KEEPBACKGROUND
PRINTSTRING (8, 8), "R", RG&
PRINTSTRING (16, 8), "ange", RG&
DEST OB& ' 56x32 Create Orbit track toggle
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(54, 30), clr&
(4), B
PRINTMODE KEEPBACKGROUND
PRINTSTRING (8, 8), "O", OB&
PRINTSTRING (16, 8), "rbit", OB&
DEST GD& ' 48x32 Create Grid toggle
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(46, 30), clr&
(4), B
LINE (0, h
)-(47, h
), clr&
(8), BF
LINE (h
, 0)-(h
, 31), clr&
(8), BF
PRINTMODE KEEPBACKGROUND
PRINTSTRING (8, 8), "G", GD&
PRINTSTRING (16, 8), "rid", GD&
DEST AZ& ' 40x32 Create Azimuth toggle
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(38, 30), clr&
(4), B
outerx
= (14 * SIN(D2R
(whl
/ 10))) + 20 outery
= (14 * COS(D2R
(whl
/ 10))) + 16 innerx
= (12 * SIN(D2R
(whl
/ 10))) + 20 innery
= (12 * COS(D2R
(whl
/ 10))) + 16 LINE (outerx
, outery
)-(innerx
, innery
), clr&
(5) ' draw tick PRINTMODE KEEPBACKGROUND
PRINTSTRING (8, 8), "A", AZ&
PRINTSTRING (16, 8), "zi", AZ&
DEST IN& ' 40x32 Create Inclinometer toggle
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(38, 30), clr&
(4), B
outerx
= (14 * SIN(D2R
(whl
/ 10))) + 20 outery
= (14 * COS(D2R
(whl
/ 10))) + 16 innerx
= (12 * SIN(D2R
(whl
/ 10))) + 20 innery
= (12 * COS(D2R
(whl
/ 10))) + 16 LINE (outerx
, outery
)-(innerx
, innery
), clr&
(8) ' draw tick LINE (20, 16)-((14 * SIN(D2R
(135))) + 20, (14 * COS(D2R
(135))) + 16), clr&
(8) PRINTMODE KEEPBACKGROUND
PRINTSTRING (8, 8), "I", IN&
PRINTSTRING (16, 8), "nc", IN&
DEST JP& ' 48x32 Create Jump envelope toggle
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(46, 30), clr&
(4), B
FCirc 24, 16, 12, RGBA(150, 116, 116, 200)
PRINTMODE KEEPBACKGROUND
PRINTSTRING (8, 8), "J", JP&
PRINTSTRING (16, 8), "ump", JP&
DEST DI& ' 48x32 Create Jump Diameter button
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(46, 30), clr&
(4), B
PRINTMODE KEEPBACKGROUND
PRINTSTRING (8, 8), "D", DI&
PRINTSTRING (16, 8), "iam.", DI&
DEST DN& ' 48x32 Create Jump Density button
COLOR clr&
(0), RGBA32
(72, 128, 222, 255) LINE (1, 1)-(46, 30), clr&
(4), B
'density graphic
PRINTMODE KEEPBACKGROUND
PRINTSTRING (8, 8), "D", DN&
PRINTSTRING (16, 8), "ens.", DN&
DEST QT& ' 48x32 Create Quit (program) button
COLOR clr&
(0), RGBA32
(255, 0, 50, 255) LINE (1, 1)-(46, 30), clr&
(0), B
PRINTSTRING (8, 8), "Q", QT&
PRINTSTRING (16, 8), "uit", QT&
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Azimuth wheel image
DEST AW&
WINDOW (-1000, 1000)-(1000, -1000) CLEARCOLOR RGB(0, 0, 0)
FOR whl
= 0 TO 359 ' iterate through azimuth wheel IF whl
MOD 45 = 0 THEN ' 45 degree tick and number y = 900
Prnt
STR$(whl
), 2.8, 2.8, (y
+ 20) * SIN(D2R
(whl
)) - 60, (y
+ 20) * COS(D2R
(whl
)), 24, 0, &H7FA800A8 y = 950
y = 970
y = 990
'Draw azimuth tick
LINE (1000 * SIN(D2R
(whl
)), 1000 * COS(D2R
(whl
)))-(y
* SIN(D2R
(whl
)), y
* COS(D2R
(whl
))), &H7FA800A8
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
Refresh ' initial display refresh
DO ' outer loop running computations when inputs DO ' inner loop waiting for inputs while no change shipoff = 0: of%% = 0
of%% = -1
Mouse_Loop of%%, units
mouse_left = MOUSEBUTTON(1)
mouse_right = MOUSEBUTTON(2)
DELAY .2
Mouse_Ops mouse_x, mouse_y
in = -1
DELAY .2
Place_Ship mouse_x, mouse_y
ZoomFac = 1
in = -1
IF x$
= CHR$(66) OR x$
= CHR$(98) THEN togs
= TOGGLEBIT
(togs
, 10) ' "B" belt/ring togs = TOGGLEBIT(togs, 1)
zangle = Ozang
Ozang = zangle: zangle = 0
vpoint = vpoint + 1
IF vpoint
> units
THEN vpoint
= 1: shipoff
= 0 IF units
> 6 AND vpoint
> 6 THEN shipoff
= vpoint
- 6 IF cmb
(vpoint
).status
= 0 THEN vpoint
= vpoint
+ 1 IF vpoint
> units
THEN vpoint
= 1 vpoint = vpoint - 1
IF vpoint
< 1 THEN vpoint
= units: shipoff
= units
- 6 IF units
> 6 AND vpoint
<= shipoff
THEN shipoff
= vpoint
- 1 IF cmb
(vpoint
).status
= 0 THEN vpoint
= vpoint
- 1 IF vpoint
< 1 THEN vpoint
= units
KEYCLEAR
OriScreen vpoint ' keep up with ori-screen animation while waiting
DispShipData ' update ship data display via mouse wheel while waiting
DISPLAY
LIMIT 50
in = 0
Refresh
LIMIT 50
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'-------------------------ALGORITHM--------------------------------------------------CLEARED
' SUB: Mouse_Loop
'
' Purpose:
' Primary mouse input loop. Controls mousewheel scrolling and conditions
' x,y position data.
'
' Passed Variables:
' var sends whether data list is extensive enough for using offset printing values
' var2 sends maximum allowed offset value
'
'------------------------------------------------------------------------------------
DO WHILE MOUSEINPUT
' scan for changes in mouse position and save to global variables shipoff = shipoff + MOUSEWHEEL ' mousewheel offset determines starting element to print
IF shipoff
< 0 THEN shipoff
= 0 ' don't go beyond bottom of array IF shipoff
+ 6 > var2
THEN shipoff
= var2
- 6 ' don't go beyond the end of the array IF MOUSEBUTTON
(1) OR MOUSEBUTTON
(2) THEN mouse_y = MOUSEY ' get y on mouse click
mouse_x = MOUSEX ' get x on mouse click
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
CASE 0 TO 559 ' Left text display DELAY .2
SELECT CASE ypos
' Divide left into top and bottom SELECT CASE xpos
' Divide upper left into ship and center display 'ship data display
y
= INT(ypos
/ 96) + 1 ' unit # range - modify by shipoff for proper unit y1
= INT(ypos
/ 16) + 1 ' row # of mouse click IF y
+ shipoff
<> vpoint
AND y1
MOD 6 = 5 THEN 'not vpoint and 5th line of unit data IF y
+ shipoff
= cmb
(vpoint
).bogey
THEN ' Cancel was clicked cmb(vpoint).bogey = 0 ' unit no longer a solution target
cmb(vpoint).bstat = 0
cmb(vpoint).bogey = y + shipoff
cmb(vpoint).bstat = 1
cmb(vpoint).bstat = 2
InterVadeII y + shipoff, vpoint, cmb(vpoint).bstat 'then evade/intercept call
b = 600000 ' military sensor range
b = 150000 ' civilian sensor range
IF Pyth
(cmb
(vpoint
).ap
, cmb
(y
+ shipoff
).ap
) < b
THEN Sensor(vpoint, y + shipoff) = SETBIT(Sensor(vpoint, y + shipoff), 1)
vpoint = y + shipoff
FlightPlan
vpoint = y + shipoff ' otherwise set new vpoint
'center display
'Upper center screen area
'OriScreen area
' buttons tier 1
NewVector2
Coming 'VectorBrake
MoveTurn 1
MTurnUndo 1
EditShip 0
DelShip
Load_Scenario
Save_Scenario -1
' buttons tier 2
PanelBlank 0, 614, 64, 32, &HFF0F0F0F
Con_Blok 0, 614, 64, 32, "Thrust 0", 0, &H502C9B2C
DISPLAY
DELAY .5
Thrust(vpoint).Gs = 0
Coming
Coming
Coming
AddShip
Purge
Load_System
Save_System
' buttons tier 3
VectorBrake 'Coming
Coming
Coming
Coming
Help
IF cmb
(vpoint
).status
= 3 THEN cmb(vpoint).status = 1
EditShip 1
Thrust(vpoint).Gs = 0
cmb(vpoint).MaxG = 0
cmb(vpoint).status = 3
Load_Ships
Save_Ships
CASE 560 TO 1179 ' Right graphics screen 'DELAY .2
' find relative sensor screen coordinates of mouse click
WindowMouseX = (xpos - 560) * (2000 / 620) - 1000 ' xpos was mouse_x
WindowMouseY = ((ypos - 18) * (2000 / 620) - 1000) * -1 'ypos was mouse_y
' check to see if click is close to any combat units
q! = Prop!
clk.pX = WindowMouseX / q! ' get screen click x position
clk.pY
= WindowMouseY
* SIN(_D2R(zangle
)) / q!
'get screen click y position prox = vpoint
IF a
<> vpoint
THEN ' if not active unit IF PythXY
(clk
, dcs
(a
)) < PythXY
(clk
, dcs
(vpoint
)) THEN 'if closer to 'a' then active IF PythXY
(clk
, dcs
(a
)) < PythXY
(clk
, dcs
(prox
)) THEN 'if closer to 'a' then any other 'a' tested prox = a ' set proximity unit
'IF a <> vpoint THEN ' if not active unit
' IF PythXY(clk, dcs(a)) < PythXY(clk, dcs(vpoint)) THEN 'if closer to 'a' then active
' prox = a
' FOR b = 1 TO units
' IF PythXY(clk, dcs(b)) < PythXY(clk, dcs(prox)) THEN 'if closer to 'a' then any other 'a' tested
' prox = b ' set proximity unit
' END IF
' NEXT b
' END IF
'END IF
vpoint = prox ' set active to closest proximity unit
ZoomFac = 1 ' Zoom to extents
ZoomFac = ZoomFac / .5 ' Zoom in
ZoomFac = ZoomFac * .5 ' Zoom out
togs = TOGGLEBIT(togs, 4) ' Range toggle
togs = TOGGLEBIT(togs, 7) ' Orbit toggle
togs = TOGGLEBIT(togs, 3) ' Grid toggle
togs = TOGGLEBIT(togs, 2) ' Azimuth wheel toggle
togs = TOGGLEBIT(togs, 5) ' Inclinometer toggle
togs = TOGGLEBIT(togs, 6) ' Jump zone toggle
IF READBIT
(togs
, 6) THEN ' if jump zone then togs = TOGGLEBIT(togs, 9) ' Diameter/Density toggle
Save_Scenario 0
CASE 1204 TO 1244 ' Z-pan slider 1204-1244 4-654 togs = SETBIT(togs, 1)
zangle = -90
togs = SETBIT(togs, 1)
zangle = ((ypos - 329) / 310) * 90
togs = RESETBIT(togs, 1)
zangle = 0
togs = SETBIT(togs, 1)
zangle = ((ypos - 329) / 310) * 90
togs = SETBIT(togs, 1)
zangle = 90
togs = TOGGLEBIT(togs, 1)
zangle = Ozang
Ozang = zangle: zangle = 0
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB MoveTurn
(var
AS BYTE
)
'Apply all unit movements
Turncount = Turncount + 1
Turn2Clock Turncount
' store previous turn for future turn undo
'm = MEM(cmb())
'c = 1
'DO ' move all unit's current data to old data block
' MEMCOPY m, m.OFFSET + c * m.ELEMENTSIZE + 52, 37 TO m, m.OFFSET + c * m.ELEMENTSIZE + 15
' c = c + 1
'LOOP UNTIL c = units + 1
c = 1
IF cmb
(c
).status
> 0 THEN ' if unit destroyed skip the computations m = MEM(cmb())
ms = MEM(start)
mf = MEM(finis)
MEMCOPY m
, m.OFFSET
+ c
* m.ELEMENTSIZE
+ 52, 24 TO ms
, ms.OFFSET
'same as... 'start = cmb(x).ap
IF MEMGET
(m
, m.OFFSET
+ c
* m.ELEMENTSIZE
+ 90, BYTE
) > 0 THEN 'same as... 'IF cmb(c).bstat > 0 THEN
InterVadeII MEMGET(m, m.OFFSET + c * m.ELEMENTSIZE + 89, BYTE), c, MEMGET(m, m.OFFSET + c * m.ELEMENTSIZE + 90, BYTE) 'same as...
'InterVadeII cmb(c).bogey, c, cmb(c).bstat
'***********
MEMCOPY m
, m.OFFSET
+ c
* m.ELEMENTSIZE
+ 52, 37 TO m
, m.OFFSET
+ c
* m.ELEMENTSIZE
+ 15 'same as... 'cmb(c).op = cmb(c).ap
'***********
CoordUpdate c, "T" ' Update unit position
ColCheck c ' check for collision with star/planet
MEMCOPY m
, m.OFFSET
+ c
* m.ELEMENTSIZE
+ 52, 24 TO mf
, mf.OFFSET
'same as... 'finis = cmb(x).ap
MEMPUT m
, m.OFFSET
+ c
* m.ELEMENTSIZE
+ 76, Pyth
(start
, finis
) AS SINGLE 'same as... 'cmb(c).Sp = Pyth(start, finis)
MEMPUT m
, m.OFFSET
+ c
* m.ELEMENTSIZE
+ 80, Azimuth!
(finis.pX
- start.pX
, finis.pY
- start.pY
) AS SINGLE 'same as... 'cmb(c).Hd = Azimuth!(finis.pX - start.pX, finis.pY - start.pY)
MEMPUT m
, m.OFFSET
+ c
* m.ELEMENTSIZE
+ 84, Slope!
(finis
, start
) AS SINGLE 'same as... 'cmb(c).In = Slope!(finis, start)
c = c + 1
PlanetMove 1
togs = RESETBIT(togs, 0) ' clear turn undo flag
PanelBlank 140, 578, 64, 32, &HFF0F0F0F
Con_Blok 140, 578, 64, 32, "Applied", 0, &H502C9B2C
DISPLAY
DELAY .2
MEMFREE m: MEMFREE ms: MEMFREE mf
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB MTurnUndo
(var
AS BYTE
)
'put "cannot undo" message here, if desired. Otherwise just disallow second consecutive undo
Turncount = Turncount - 1
Turn2Clock Turncount
DIM m
AS MEM
' move old ship data block back to current data block m = MEM(cmb())
c = 1
MEMCOPY m
, m.OFFSET
+ c
* m.ELEMENTSIZE
+ 15, 37 TO m
, m.OFFSET
+ c
* m.ELEMENTSIZE
+ 52 c = c + 1
MEMFREE m
PlanetMove -1 ' back peddle the planets
togs = SETBIT(togs, 0) ' set turn undo flag
PanelBlank 210, 578, 64, 32, &HFF0F0F0F
Con_Blok 210, 578, 64, 32, "Undone", 0, &H502C9B2C
DISPLAY
DELAY .2
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Text based vector input
'Input new thrust data for active unit.
'Data is used to adjust heading & speed for that unit.
cmb(vpoint).bstat = 0: cmb(vpoint).bogey = 0 ' taking back control from AI
DialogBox "ENTER NEW VECTOR", 400, 250, 50, &HFF2C9B2C, clr&(15)
VectorBrake
Thrust
(vpoint
).Azi
= VAL(x$
) INPUT "New Inclination:"; Thrust
(vpoint
).Inc
INPUT "New Acceleration:"; Thrust
(vpoint
).Gs
IF Thrust
(vpoint
).Gs
> cmb
(vpoint
).MaxG
THEN PRINT "Confirm overdrive" DISPLAY
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
PanelBlank 0, 578, 64, 32, &HFF0F0F0F ' dim vector button
Con_Blok 0, 578, 64, 32, "Vector", 1, &H502C9B2C
togs = RESETBIT(togs, 1) ' reset back to overhead view
zangle = 0
Refresh
'Conduct graphic based vector input
SST& = NEWIMAGE(620, 620, 32) ' Vector input overlay
DEST SST&
VIEW (0, 0)-(619, 619), clr&
(0), clr&
(3) ' set graphics port full image SS& w/box WINDOW (-1000, 1000)-(1000, -1000) ' set relative cartesian coords
cmb(vpoint).bstat = 0: cmb(vpoint).bogey = 0 ' taking back control from AI
LIMIT 60
Mouse_Loop 0, 0
CLEARCOLOR RGBA(0, 0, 0, 0)
IF NOT READBIT
(togs
, 2) THEN ' draw azimuth if not already enabled AzimuthWheel -1
CIRCLE (0, 0), x
, clr&
(4) ' Draw thrust percentage circle PRINTMODE KEEPBACKGROUND
PRINTSTRING
(310 + (x
/ 200) * 62, 294), STR$((x
/ 800) * cmb
(vpoint
).MaxG
) + "Gs", SST&
mosX = (MOUSEX - 560) * (2000 / 620) - 1000 ' Set relative coordinates
mosY = ((MOUSEY - 18) * (2000 / 620) - 1000) * -1
az = Azimuth!(mosX, mosY)
ds = HYPOT(mosX, mosY)
IF ABS(mosX
) < 1000 AND ABS(mosY
) < 1000 THEN ' If mouse is in window then draw vector rays LINE (0, 0)-(mosX
, mosY
), clr&
(14) PRINTSTRING
(3, 3), "Azi. " + STR$(az
), SST&
' Echo info in top left corner PRINTSTRING
(3, 21), "Acceleration " + STR$(INT((ds
* cmb
(vpoint
).MaxG
/ 800) * 100) / 100) + " Gs", SST&
Thrust(vpoint).Azi = az ' Set azimuth heading
Thrust(vpoint).Gs = ds * cmb(vpoint).MaxG / 800 ' Apply percentage of 800 radius circle as thrust
DO UNTIL NOT MOUSEBUTTON
(1) ' Clear the mouse button buffer LIMIT 60
CLEARCOLOR RGBA(0, 0, 0, 0)
IncMeter -1, -1
mos.pX = (MOUSEX - 560) * (2000 / 620) - 1000 ' Set relative coordinates
mos.pZ = ((MOUSEY - 18) * (2000 / 620) - 1000) * -1
az = Azimuth!(mos.pX, mos.pZ)
COLOR RGBA32
(127, 127, 127, 255) PRINTSTRING
(3, 21), "Inclination= " + STR$((az
- 90) * -1) + " deg.", SST&
LINE (0, 0)-(1000, 0), clr&
(4) PRINTSTRING (3, 21), "Inclination= 0 ", SST&
PRINTSTRING (3, 37), "click left half for 0", SST&
Thrust(vpoint).Inc = 0
Thrust(vpoint).Inc = (az - 90) * -1 ' Set inclination
PUTIMAGE (560, 18), SS&, A& ' Erase previous rays
PUTIMAGE (560, 18), SST&, A& ' draw new ray
DISPLAY
PUTIMAGE (560, 18), SS&, A& ' Erase previous rays
PUTIMAGE (560, 18), SST&, A& ' draw new ray
DISPLAY
PUTIMAGE (560, 18), SS&, A& ' return to normal
DISPLAY
FREEIMAGE SST&
DO UNTIL NOT MOUSEBUTTON
(1) ' Clear the mouse button buffer WHILE MOUSEINPUT:
WEND ' to prevent changing active unit LOOP ' by accidental click through
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB OriScreen
(var
AS BYTE
)
'Display orientation graphic
'place and move stars according to heading and speed
IF ovar
> units
THEN ovar
= units
IF ovar
<> var
THEN ' if new active unit FOR x
= 1 TO 12 ' Random star placement starx
(x
) = (INT(RND(1) * 254)) - 127 stary
(x
) = (INT(RND(1) * 254)) - 127 ovar = var ' retain active unit # to keep stars
DEST ORI&
WINDOW (-127, 127)-(127, -127) IF cmb
(var
).Hd
>= 180 THEN starhd
= INT(cmb
(var
).Hd
- 180) IF cmb
(var
).Hd
< 180 THEN starhd
= INT(cmb
(var
).Hd
+ 180) sp = 0
sp = cmb(var).Sp / 10000
xm
= sp
* SIN(D2R
(starhd
)) ' Removed INT as it is in PSET below ym
= sp
* COS(D2R
(starhd
)) FOR x
= 1 TO 12 ' iterate through stars IF starx
(x
) > 127 THEN starx
(x
) = -127 ' recycle those that leave screen to the opposite side IF starx
(x
) < -127 THEN starx
(x
) = 127 IF stary
(x
) > 127 THEN stary
(x
) = -127 IF stary
(x
) < -127 THEN stary
(x
) = 127 starx(x) = starx(x) + xm
stary(x) = stary(x) + ym
LINE (-127, 127)-(127, -127), clr&
(4), B
PRINTMODE KEEPBACKGROUND
PRINTSTRING
(127 - LEN((_TRIM$(cmb
(var
).Nam
))) * 4, 2), cmb
(var
).Nam
, ORI&
RotoZoom2 127, 127, ShpO, 1, 1, Thrust(var).Azi
RotoZoom2 127, 127, ShpT, 1, 1, Thrust(var).Azi
PUTIMAGE (295, 325)-(543, 573), ORI&, A&
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Background blank to mark and mask button use and/or changes
CN& = NEWIMAGE(xsiz, ysiz, 32) ' active button overlay
DEST CN&
COLOR , col
' set overlay background color PUTIMAGE (xpos, ypos), CN&, A& ' cover button
FREEIMAGE CN&
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Moves active ship, on right click, to new x,y coordinate on the screen.
'Use <E>dit to set new z coordinate.
CASE 560 TO 1199 ' Right graphics screen ' find relative sensor screen coordinates of mouse click
WindowMouseX = (xpos - 560) * (2000 / 620) - 1000 ' xpos was mouse_x
WindowMouseY = ((ypos - 18) * (2000 / 620) - 1000) * -1 'ypos was mouse_y
'WindowMouseX & Y both divided by results of Prop! give .Abs offsets from active position
q! = Prop!
'cmb(vpoint).ap.pX = (WindowMouseX / q!) + cmb(vpoint).ap.pX 'This is the old way that works well
'cmb(vpoint).ap.pY = (WindowMouseY / q!) + cmb(vpoint).ap.pY 'but only in zangle=0
'TRANSFORMATION MATRIX CALCULATION- extending ship placement into 3D based upon display plane
'account for zangle by defining new screen plane, don't have a clue how to go about it...yet
'transformation should probably occur at the windowmouse/q! element and then add to cmb(vpoint).ap
cmb(vpoint).ap.pX = (WindowMouseX / q!) + cmb(vpoint).ap.pX ' x-axis stays the same at all times
WMY_Ycomp
= WindowMouseY
* COS(_D2R(-zangle
)) WMY_Zcomp
= WindowMouseY
* -SIN(_D2R(-zangle
)) cmb(vpoint).ap.pY = WMY_Ycomp / q! + cmb(vpoint).ap.pY
cmb(vpoint).ap.pZ = WMY_Zcomp / q! + cmb(vpoint).ap.pZ
q2! = Prop!
ZoomFac = ZoomFac * (q! / q2!) ' reset zoom factor to new limits
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
T& = NEWIMAGE(248, 315, 32)
DEST T&
LINE (0, 0)-(247, 314), clr&
(4), B
PRINTSTRING (156, 2), "AU", T&
PRINTSTRING (202, 2), "Brng", T&
x = 0: yp = 2
x = x + 1
IF hvns
(x
).star
<> 2 THEN ' don't show planetoid belts or rings IF hvns
(x
).rank
< 3 THEN ' show only main planets bb& = &H1F7F7F7F
bb& = &HFF000000
ds
= INT((Pyth
(cmb
(vpoint
).ap
, hvns
(x
).ps
) / KMtoAU
) * 100) / 100 br
= INT(Azimuth!
(rcp
(x
).pX
, rcp
(x
).pY
) * 10) / 10 PRINT TRIM$
(hvns
(x
).nam
);
SPC(16 - LEN(TRIM$
(hvns
(x
).nam
)));
yp = yp + 1
PUTIMAGE (295, 5)-(543, 320), T&, A&
DEST A&
FREEIMAGE T&
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB PlanetMove
(var
AS BYTE
)
'Using orbital period figures, move the planets and their satellites
'along their orbit tracks. Convert orbital periods into 1000 sec turns
'divide 360 by the number of turns to get an azimuth change value.
'Azimuth change can be applied to update x,y,z of moving planet.
'At this point the exact same azimuth update should be applied to the
'satellites relative to the primary, the same as their parent. Only
'then can the azimuth changes of the satellites be applied relative to
'their parent planets. Also called for initial date setup.
'var=turncount (1 for normal turn, -1 for undo)
'outermost iteration should be for .rank
FOR x
= 2 TO 4 ' rank iteration, rank 1 primary doesn't move FOR v
= 1 TO orbs
' iterate all bodies IF hvns
(v
).star
<> 2 THEN ' don't move belt/ring systems except relative to parent 'compute new x,y,z for body v of x rank relative to primary/parent
c = hvns(FindParent(v)).ps: t = hvns(v).ps
d&& = Pyth(t, c)
przaz## = Azimuth!(t.pX - c.pX, t.pY - c.pY) 'get present azimuth
IF Turncount
= 0 THEN ' Initial date setup IF oryr
> 0 THEN ' If year/day not zero compute rotation from baseline rot = oryr / hvns(v).oprd ' Divide years from baseline by orbital period of body
IF rot
<> INT(rot
) THEN rot
= rot
- INT(rot
) 'discard all full periods and get remainder prdtrnaz## = (rot * 360) ' multiply remainder by 360 for azimuth change
ELSE ' Not initial setup so compute turn change prdtrnaz## = 360 / (hvns(v).oprd * 31557.6 * var) 'azimuth change / turn negative .oprd yields retrograde motion
' \/ \/ \/ add azimuth change to present azimuth or subtract with if newaz!<0 then newaz=newaz+360 for opposite rotation
newaz## = przaz## + prdtrnaz##
oldx&& = hvns(v).ps.pX ' preserve old x,y,z temporarily for
oldy&& = hvns(v).ps.pY ' baseline satellite movement calculation
oldz&& = hvns(v).ps.pZ
hvns
(v
).ps.pX
= (hvns
(v
).orad
* SIN(D2R
(newaz##
))) + c.pX
hvns
(v
).ps.pY
= (hvns
(v
).orad
* COS(D2R
(newaz##
))) + c.pY
'put new planet Z position here if the option for tilted orbits is later added
'reiterate to pick out the children to drag along
IF hvns
(s
).parnt
= hvns
(v
).nam
THEN 'apply same motion as parent relative to parent's primary
hvns(s).ps.pX = hvns(s).ps.pX + (hvns(v).ps.pX - oldx&&)
hvns(s).ps.pY = hvns(s).ps.pY + (hvns(v).ps.pY - oldy&&)
hvns(s).ps.pZ = hvns(s).ps.pZ + (hvns(v).ps.pZ - oldz&&)
END IF 'end belt/ring test
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'------------------------------------------------------------------------------------
' SUB: Prnt (adaptation of Petr's excellent approach to text resizing)
'
' Purpose:
' Display text as resizable and recolorable images that have been previously
' defined in the main module.
'
' Passed parameters:
' text sends string value to be printed
' wsize sends width size of text to be displayed: 1=original
' hsize sends height size of text to be displayed: 1=original
' StartX sends upper left x position for PUTIMAGE
' StartY sends upper left y position for PUTIMAGE
' Xspace sends horizontal spacing
' Yspace sends vertical spacing
' col sends color of character
'
'------------------------------------------------------------------------------------
x = StartX
y = StartY
x = x + Xspace
y = y + Yspace
ColoredChar = swapcolor(chr_img(ch), &HFFF5F5F5, col) ' colorize character:
_PUTIMAGE (x
, y
)-(x
+ (wsize
* 8), y
- (hsize
* 16)), ColoredChar
, 0
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'keep it in proportion...
'find the relative offsets of all units to the active unit and
'resize to keep all in the picture, subject to zoom factor override.
DIM deltamax
AS INTEGER64
' carries the widest axial separation of units in km
IF units
> 1 THEN ' multiple units present deltamax = 1000
x = 0
x = x + 1
IF cmb
(x
).status
> 0 AND x
<> vpoint
THEN ' skip if active, destroyed or immobile IF ABS(dcs
(x
).pX
) > deltamax
THEN deltamax
= ABS(dcs
(x
).pX
) 'X limits IF ABS(dcs
(x
).pY
) > deltamax
THEN deltamax
= ABS(dcs
(x
).pY
) 'Y limits ELSE ' only single unit present deltamax = 1000000: ZoomFac = 1
Prop! = 800 * (ZoomFac / deltamax) ' all units on screen subject to zoom factor
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Remove wrecked vessels from list if not desired
ct = 0
I$ = cmb(vpoint).Nam ' preserve an active unit identifier
ct = ct + 1 ' count the number if units to remove
IF ct
= 0 THEN ' No destroyed units? EXIT SUB ' leave without unnecessary processing n% = units - ct ' dim sufficient temp variables
DIM tmpthrs
(n%
) AS Maneuver
DIM tmpsens
(n%
, n%
) AS BYTE
y = 0
FOR x
= 1 TO units
' keep all existing units in temps y = y + 1
tmpshp(y) = cmb(x)
tmpthrs(y) = Thrust(x)
tmpsens(x, q) = Sensor(x, q)
units = n% ' redimension primary variables
FOR x
= 1 TO units
' Move temps back into primary variables cmb(x) = tmpshp(x)
Thrust(x) = tmpthrs(x)
Sensor(x, y) = tmpsens(x, y)
cmb(x).id = x
IF cmb
(x
).Nam
= I$
THEN vpoint
= x
' set active to new position a = units + 1: b = n% + ct
FOR x
= a
TO b
' free abandoned ship display memory
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Use to find distance between two 3D points
'Also calculate speed/magnitude of updated vectors
Pyth
= HYPOT
(HYPOT
(ABS(var1.pX
- var2.pX
), ABS(var1.pY
- var2.pY
)), ABS(var1.pZ
- var2.pZ
))
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Use to find distance between two 2D points
'Also calculate speed/magnitude of updated vectors
PythXY
= HYPOT
(ABS(var1.pX
- var2.pX
), ABS(var1.pY
- var2.pY
))
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
FUNCTION RayTrac##
(var1
AS unitpoint
, var2
AS unitpoint
, var3
AS unitpoint
, var4
AS INTEGER64
)
'Same algorithm as in ColCheck with following substitutions
'strt=var1 : first ship
'nd= var2 : second ship
'sphr=var3 : planet position
' var4 : planet radius
'checking only for intersection of body in line of sight, not impact position
dx## = var2.pX - var1.pX: dy## = var2.pY - var1.pY: dz## = var2.pZ - var1.pZ
A## = (dx## * dx##) + (dy## * dy##) + (dz## * dz##)
B## = 2 * dx## * (var1.pX - var3.pX) + 2 * dy## * (var1.pY - var3.pY) + 2 * dz## * (var1.pZ - var3.pZ)
C## = (var3.pX * var3.pX) + (var3.pY * var3.pY) + (var3.pZ * var3.pZ) + (var1.pX * var1.pX) + (var1.pY * var1.pY) +_
(var1.pZ * var1.pZ) + -2 * (var3.pX * var1.pX + var3.pY * var1.pY + var3.pZ * var1.pZ) - (var4 * var4)
disabc## = (B## * B##) - 4 * A## * C## ' if disabc## < 0 then no intersection =0 tangent >0 intersects two points
RayTrac## = disabc##
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
VCS ' Set viewpoint coordinate system
SensorMask ' determine sensor occlusions
ScreenLimits ' Open sensor display viewport
SensorScreen ' Display sensor data
DispShipData ' Print unit positions, speeds and headings
ButtonBlock ' control panel
PlanetDist ' show main planet bearings and distances
DISPLAY
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'------------------------------------------------------------------------------------CLEARED
' SUB: RotoZoom2 (author Bplus of QB64 forum, not my own creation, but damn useful)
'
' Purpose:
' Locate and display image, scaling and/or rotating the displayed image around
' its central point.
'
' Passed parameters:
' X, Y sends the center point of where the image is to be displayed
' Image sends the source image handle
' xScale and yScale send width and height stretching parameters 1=original size
' Rotation sends rotation of image in degrees 0=east, 270=north
'
'------------------------------------------------------------------------------------
W&
= WIDTH(Image&
): H&
= HEIGHT
(Image&
) px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
sinr!
= SIN(-Rotation
/ 57.2957795131): cosr!
= COS(-Rotation
/ 57.2957795131) x2& = (px(i&) * cosr! + sinr! * py(i&)) * xScale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * yScale + Y
px(i&) = x2&: py(i&) = y2&
MAPTRIANGLE
(0, 0)-(0, H&
- 1)-(W&
- 1, H&
- 1), Image&
TO(px
(0), py
(0))-(px
(1), py
(1))-(px
(2), py
(2)) MAPTRIANGLE
(0, 0)-(W&
- 1, 0)-(W&
- 1, H&
- 1), Image&
TO(px
(0), py
(0))-(px
(3), py
(3))-(px
(2), py
(2))
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB Save_Scenario
(var
AS BYTE
)
'Save present system state and vessel group
t% = 400: r% = 2
DialogBox "SAVING PRESENT SCENARIO", t%, 250, 50, &HFF8C5B4C, clr&(15)
DISPLAY
INPUT "Enter a scenario name: ", fl$
fl$ = "autosave/auto"
vl$ = "scenarios/" + TRIM$(fl$) + ".tvg"
pl$ = "scenarios/" + TRIM$(fl$) + ".tss"
sl$ = "scenarios/" + TRIM$(fl$) + ".tgn"
tl$ = "scenarios/" + TRIM$(fl$) + ".tvt"
tt$ = "scenarios/" + TRIM$(fl$) + ".ttl"
WRITE #4, Turncount
, oryr
, vpoint
, shipoff
PUT #5, ((x
- 1) * units
) + y
, Sensor
(x
, y
)
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Save the present ship scenario
'call syntax: DialogBox <heading string>, box x, box y, y position, bounding box color, text color
t% = 400
DialogBox "SAVING PRESENT VESSEL(S) & POSITION(S)", t%, 250, 50, &HFF8C5B4C, clr&(15)
DISPLAY
INPUT "Enter a vessel group name: ", fl$
fl$ = "ships\" + fl$ + ".tvg"
'add thrust file
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
t% = 600
DialogBox "SAVING SYSTEM", t%, 250, 50, &HFF8C5B4C, clr&(15)
in1$ = "Enter system name or press ENTER to default to " + TRIM$(hvns(1).nam)
PRINTSTRING (l, 217), in1$, A&
col%
= ((WIDTH(A&
) / 2) - (t%
/ 2)) / 8 + 4 DISPLAY
n$ = TRIM$(n$)
n$ = TRIM$(hvns(1).nam)
sys$ = "systems/" + n$ + ".tss"
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'0=black,1=blue,2=green,3=aqua,4=red,5=purple,6=brown,7=white
'8=gray, +8=bright color, except 14=yellow,
DEST A&
COLOR , RGBA32
(15, 15, 15, 10) c = 3 'color variable (local)
PRINTSTRING
(560, 0), "Turn #" + STR$(Turncount
), A&
' Turn and time elapsed IF eth
OR Turncount
> 3 THEN tm$
= tm$
+ TRIM$
(STR$(eth
)) + "h " IF Turncount
> 0 THEN tm$
= tm$
+ TRIM$
(STR$(etm
)) + "m " + TRIM$
(STR$(ets
)) + "s" PRINTSTRING (672, 0), tm$, A&
SELECT CASE zangle
' set galactic orientation strings to rotation angle bt$ = "NADIR facing rimward"
bb$ = "ZENITH facing rimward"
bt$ = "COREWARD"
bb$ = "RIMWARD"
bt$ = "ZENITH facing coreward"
bb$ = "NADIR facing coreward"
bt$ = "COREWARD"
bb$ = "RIMWARD"
PRINTSTRING (839, 0), bt$, A& ' Galactic orientation screen top
PRINTSTRING (839, 639), bb$, A& ' Galactic orientation screen bottom
FOR x
= 1 TO 8 ' Galactic orientation screen right PRINTSTRING
(1187, 249 + (x
* 16)), MID$("TRAILING", x
, 1), A&
FOR x
= 1 TO 8 ' Galactic orientation screen left PRINTSTRING
(547, 249 + (x
* 16)), MID$("SPINWARD", x
, 1), A&
OriScreen vpoint
ZPanner
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Determine which units may be sensor occluded by planetary bodies.
'this must be refreshed each turn, but we should do something to
'avoid it each display loop. Sensor(x,y) will handle display loop.
'Sensor occlusion will break target locks.
'Determine which units are visible to others
FOR x
= 1 TO units
' Active unit iteration x=active FOR y
= 1 TO units
' Passive unit iteration y=passive Sensor(x, y) = RESETBIT(Sensor(x, y), 0)
IF x
<> y
THEN ' if unit is self then skip and leave at zero FOR z
= 1 TO orbs
' Planetary body iteration IF hvns
(z
).star
<> 2 THEN ' Skip belt/ring systems IF Pyth
(rcs
(x
), rcp
(z
)) < Pyth
(rcs
(x
), rcs
(y
)) THEN ' is planet closer to active than passive? IF Pyth
(rcs
(y
), rcp
(z
)) < Pyth
(rcs
(x
), rcs
(y
)) THEN ' is planet closer to passive than active? 'We've now determined that the planet is generally
'within the separation radius of both units simultaneously
'so that we won't waste processing resources in ray tracing
'distant objects.
IF RayTrac##
(rcs
(x
), rcs
(y
), rcp
(z
), hvns
(z
).radi
) < 0 THEN 'if ray trace indicates LOS then 'do nothing as above reset has already made passives visible by default
Sensor(x, y) = SETBIT(Sensor(x, y), 0) ' Passive is sensor occluded and not visible to Active
IF READBIT
(Sensor
(x
, y
), 1) THEN Sensor
(x
, y
) = RESETBIT
(Sensor
(x
, y
), 1) 'no target lock if occluded END IF ' end is planet between? END IF ' end is planet close? END IF ' end belt/ring test NEXT z
' end planetary body iteration END IF ' end self unit skip NEXT y
' end passive unit iteration NEXT x
' end active unit iteration
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Graphic navigation screen
SCREEN SS&
' set output to sensor screen display DEST SS&
c = 4
VIEW (1, 1)-(618, 618), clr&
(0), clr&
(c
) ' set graphics port full image SS& w/box WINDOW (-1000, 1000)-(1000, -1000) ' set relative cartesian coords AzimuthWheel READBIT(togs, 2)
IncMeter READBIT(togs, 5), 0
LINE (0, 50)-(0, 25), clr&
(c
) ' draw active unit reference point xhair LINE (0, -25)-(0, -50), clr&
(c
) LINE (-50, 0)-(-25, 0), clr&
(c
) LINE (25, 0)-(50, 0), clr&
(c
)
SysMap ' draw system details
'SysMapII
'Dynamic scale grid display
q! = Prop!
IF READBIT
(togs
, 3) THEN ' If grid toggle is TRUE dynagrid = .001 ' start at 1 meters grid size
IF (q!
* dynagrid
) > 60 THEN ' adjust the number to change the grid behaviour dynagrid = dynagrid * 10 ' jump by power of 10 when necessary
g = 0: c = 0
COLOR RGBA32
(255, 255, 255, 40) ' semi-transparent white for grid by 10s COLOR RGBA32
(255, 255, 255, 15) ' semi-transparent white for grid LINE (-1000, g
)-(1000, g
) ' horizontal grid lines IF g
> 0 THEN LINE (-1000, (-1 * g
))-(1000, (-1 * g
)) LINE (g
, -1000)-(g
, 1000) ' vertical grid lines IF g
> 0 THEN LINE ((-1 * g
), -1000)-((-1 * g
), 1000) g = g + (q! * dynagrid)
c = c + 1
scalelegend$
= "grid=" + STR$(dynagrid
) + " km" Prnt scalelegend$, 2.8, 2.8, -990, -950, 24, 0, &H48FFFFFF 'print legend in lower left corner
'UNIT PLACEMENTS, VECTORS, RANGES AND ID Draw each unit and index number on screen
'Translate/Transform variables
DIM UDisp
AS unitpoint
' proportional dcs unit placement DIM IDisp
AS unitpoint
' vector indicator DIM VDisp
AS unitpoint
' vector indicator transformation
shipcl& = clr&(2) ' set default ship name color to green (going)
FOR x
= 1 TO units
' Iterate through all ships UDisp = dcs(x): VecMult UDisp, q! ' unit positions for display
'This gives the vector tail displayed from zenith view
IDisp.pX
= rcs
(x
).pX
+ cmb
(x
).Sp
* COS(D2R
(cmb
(x
).In
)) * SIN(D2R
(cmb
(x
).Hd
)) ' IDisp.pY
= rcs
(x
).pY
+ cmb
(x
).Sp
* COS(D2R
(cmb
(x
).In
)) * COS(D2R
(cmb
(x
).Hd
)) ' IDisp.pZ
= rcs
(x
).pZ
+ cmb
(x
).Sp
* SIN(D2R
(cmb
(x
).In
)) ' 'This skews the vector tail relative to the dcs plane, coordinate transformation of IDisp
VDisp.pX = IDisp.pX * q!
VDisp.pY
= (IDisp.pY
* COS(D2R
(zangle
)) + IDisp.pZ
* SIN(_D2R(zangle
))) * q!
VDisp.pZ
= (IDisp.pY
* -SIN(D2R
(zangle
)) + IDisp.pZ
* COS(D2R
(zangle
))) * q!
'maybe this could go in CoordUpdate; resets target lock bit if beyond 3 light seconds
IF Pyth
(cmb
(vpoint
).ap
, cmb
(x
).ap
) > 900000 THEN Sensor
(vpoint
, x
) = RESETBIT
(Sensor
(vpoint
, x
), 1)
'put an out of frame if then here also
IF ABS(UDisp.pX
) > 1300 AND ABS(UDisp.pY
) > 1300 THEN ' skip draw if out of frame IF READBIT
(Sensor
(vpoint
, x
), 0) THEN ' If ship x is invisible to active unit then skip display ELSE ' if not occluded then display it c = 7
IF dcs
(x
).pZ
> dcs
(vpoint
).pZ
THEN c
= 9 ' zenith color (blue shift) IF dcs
(x
).pZ
< dcs
(vpoint
).pZ
THEN c
= 12 ' nadir color (red shift)
IF cmb
(x
).status
> 0 THEN ' Draw point box and name LINE (UDisp.pX
- 5, UDisp.pY
+ 5)-(UDisp.pX
+ 5, UDisp.pY
- 5), clr&
(c
), BF
IF x
<> vpoint
AND READBIT
(Sensor
(vpoint
, x
), 1) THEN 'Draw target "X box" lock indicator if targeted by active LINE (UDisp.pX
- 20, UDisp.pY
+ 20)-(UDisp.pX
+ 20, UDisp.pY
- 20), &H3FFC5454, B
LINE (UDisp.pX
- 20, UDisp.pY
+ 20)-(UDisp.pX
+ 20, UDisp.pY
- 20), &H3FFC5454 LINE (UDisp.pX
+ 20, UDisp.pY
+ 20)-(UDisp.pX
- 20, UDisp.pY
- 20), &H3FFC5454 IF x
= vpoint
AND cmb
(x
).status
<> 3 THEN ' bright green unless damaged shipcl& = clr&(10)
Prnt cmb(x).Nam, 2.8, 2.8, UDisp.pX + 10, UDisp.pY - 10, 24, 0, shipcl&
shipcl& = clr&(2)
IF cmb
(x
).status
= 3 THEN ' red if damaged and drifting, active or otherwise shipcl& = clr&(4)
Prnt cmb(x).Nam, 2.8, 2.8, UDisp.pX + 10, UDisp.pY - 10, 24, 0, shipcl&
shipcl& = clr&(2)
ELSE ' green undamaged non-active units Prnt cmb(x).Nam, 2.8, 2.8, UDisp.pX + 10, UDisp.pY - 10, 24, 0, shipcl&
shipcl& = clr&(2)
' VECTOR INDICATORS adjusted for Z-pan
IF x
= vpoint
THEN ' draw active unit's vector indicator LINE (0, 0)-(VDisp.pX
, VDisp.pY
), RGB32
(222, 188, 17) LINE (UDisp.pX
, UDisp.pY
)-(VDisp.pX
, VDisp.pY
), RGB32
(17, 188, 222) END IF ' end Sensor(vpoint,x) check END IF ' end out of frame skip
' RANGING BANDS & CIRCLES
IF READBIT
(togs
, 4) THEN ' if range toggle is true IF x
= vpoint
THEN ' Draw ranging circles of active unit FCirc 0, 0, 500000 * q!, RGBA(252, 252, 84, 5) 'Medium range band clr&(14)w/alpha
FCirc 0, 0, 250000 * q!, RGBA(252, 84, 84, 20) 'Short range band
dtct = 600000 ' military detection range
dtct = 150000 ' civilian detection range
CIRCLE (0, 0), dtct
* q!
, clr&
(8) ' minimum detection range .5 or 2 light seconds CIRCLE (0, 0), 900000 * q!
, clr&
(4) ' maximum detection range 3 light seconds
'Grav watcher- upper right sensor screen
PRINTMODE KEEPBACKGROUND
COLOR RGBA
(0, 255, 0, 50) 'clr&(2) PRINTSTRING
(550, 5), STR$(_ROUND(Gwat.Gs
* 100) / 100), SS&
PRINTSTRING
(550, 21), STR$(Gwat.Azi
), SS&
PRINTSTRING
(550, 37), STR$(Gwat.Inc
), SS&
DEST A& ' return output to main screen
PUTIMAGE (560, 18), SS&, A& ' update sensor screen to mainscreen
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Debugging setup- to be replaced by file inputs eventually
units = a
REDIM cmb
(a
) AS ship
' set up ships (units) REDIM Thrust
(units
) AS Maneuver
' unit accelerations/vector REDIM Sensor
(units
, units
) AS BYTE
' Sensor ops- planetary obscuration array, who can see who? FOR x
= 1 TO units
' Ship data display handle array ship_box(x) = NEWIMAGE(290, 96, 32)
FOR x
= 1 TO units
' initialize unit data cmb(x).op = cmb(x).ap
cmb(x).status = 1
Thrust
(x
).Azi
= INT(RND(1) * 360) ' random orientation
'Initial planet position determined by date
PlanetMove 1
'Put units randomly around a random body
LOOP UNTIL hvns
(pl%
).star
<> 2 ' don't place in belt/ring 'or place around a specific body
'pl% = 3 'Terra/Earth
AZ
= RND * 360 ' random azimuth placement ds
= RND * 500 + 40 ' random distance in radii of body cmb
(y
).ap.pX
= (hvns
(pl%
).radi
* ds
) * SIN(D2R
(AZ
)) + hvns
(pl%
).ps.pX
cmb
(y
).ap.pY
= (hvns
(pl%
).radi
* ds
) * COS(D2R
(AZ
)) + hvns
(pl%
).ps.pY
cmb(y).ap.pZ = hvns(pl%).radi * dz
'cmb(y).ap.pZ = 0
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'returns degree declination of var1 point relative to var2
D = HYPOT(var1.pX - var2.pX, var1.pY - var2.pY) ' distance on X,Y plane
Slope! = R2D(ATAN2(var1.pZ - var2.pZ, D))
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
FUNCTION swapcolor
(handle&
, oldcolor~&
, newcolor~&
)
'Petr's character color swapping function, called from SUB Prnt
x& = x& + 4
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Displays the star system, called from SUB SensorScreen
DIM g!
' holds result of Prop! call for this display loop DIM OT
AS unitpoint
' locates orbit tracks & belt/ring systems g! = Prop!
'Iterate through all system bodies
'on jump toggle display diameters- rejecting those out of frame
IF READBIT
(togs
, 6) AND hvns
(p
).star
<> 2 THEN ' jump zones toggled & not asteroid belt IF READBIT
(togs
, 9) THEN l!
= hvns
(p
).dens
ELSE l!
= 1 'density or diameter jump zone '100 diameters/densities
bug = FrameSect(rcs(vpoint), rcp(p), hvns(p).radi * 200 * l!, g!)
FCirc (dcp(p).pX) * g!, (dcp(p).pY) * g!, (hvns(p).radi * 200 * l!) * g!, RGBA(150, 116, 116, 10)
'10 diameters/densities
bug = FrameSect(rcs(vpoint), rcp(p), hvns(p).radi * 20 * l!, g!)
FCirc (dcp(p).pX) * g!, (dcp(p).pY) * g!, (hvns(p).radi * 20 * l!) * g!, RGBA(200, 116, 116, 5)
'If star then build star and star corona otherwise set planet color
IF hvns
(p
).star
= -1 THEN ' if a star then build star corona 'DETERMINE ANY STELLAR CLASS CONSTANTS HERE- use them in place of 50000
bug = FrameSect(rcs(vpoint), rcp(p), hvns(p).radi + (30 * 50000), g!)
bug = FrameSect(rcs(vpoint), rcp(p), hvns(p).radi + (x * 50000), g!)
FCirc (dcp(p).pX) * g!, (dcp(p).pY) * g!, (hvns(p).radi + (x * 50000)) * g!, RGBA32(127, 127, 227, 30 - x)
c& = &HFFFC5454 ' star photosphere color
c& = &HFF545454 ' planet color
'find orbit track center
OT = rcp(FindParent(p))
OT.pX = 0: OT.pY = 0: OT.pZ = 0
'display orbit tracks
IF READBIT
(togs
, 7) THEN ' if orbit toggle is true IF READBIT
(togs
, 1) THEN ' if Z-pan toggle is true 'adjust so orbit track center moves with parent body
'draw all orbit tracks as some may be visible on extreme Z-pan
CIRCLE (OT.pX
* g!
, (OT.pY
* (COS(D2R
(zangle
))) + (OT.pZ
* SIN(D2R
(zangle
)))) * g!
),_
hvns
(p
).orad
* g!
, RGBA
(111, 72, 233, 70), , , 1 * COS(D2R
(zangle
)) bug = FrameSect(rcs(vpoint), rcp(FindParent(p)), hvns(p).orad, g!)
IF bug
= 3 THEN 'exclude circles that don't intersect view port to speed zoom in CIRCLE (OT.pX
* g!
, OT.pY
* g!
), hvns
(p
).orad
* g!
, RGBA
(111, 72, 233, 70)
'display gravity zones
IF READBIT
(togs
, 8) THEN ' if grav zone toggle is true grv! = 0
radius## = hvns(p).radi
dsx## = hvns(p).dens * ((4 / 3) * PI * (radius## * radius## * radius##)) / 26687
grv! = grv! + .25
ds## = (dsx## / grv!) ^ .5
bug = FrameSect(rcs(vpoint), rcp(p), ds##, g!)
CIRCLE (dcp
(p
).pX
* g!
, dcp
(p
).pY
* g!
), ds##
* g!
, RGBA
(0, 255, 0, 25) END IF 'end belt/ring test
'display star/planet body, rejecting those that are out of frame
bug = FrameSect(dcs(vpoint), dcp(p), hvns(p).radi, g!)
FCirc dcp(p).pX * g!, dcp(p).pY * g!, hvns(p).radi * g!, c&
CIRCLE (dcp
(p
).pX
* g!
, dcp
(p
).pY
* g!
), hvns
(p
).radi
* g!
, &HFF777777
'display name if there's room
IF g!
> .0003 AND hvns
(p
).rank
= 3 THEN ' drop satellite names first IF g!
> .00000003 AND hvns
(p
).rank
= 2 THEN ' Then drop planets names IF hvns
(p
).star
THEN ' always keep star names visible END IF ' end planet out of frame reject 'Display planetoid belts and rings
IF hvns
(p
).orad
* 2 * g!
> 100 THEN aster& = &H087F7F7F ' belt/ring color
IF hvns
(p
).dens
> 0 THEN ' belt/ring width- stored in dens element wid = hvns(p).dens / 2
wid = .15
inbnd&& = (hvns(p).orad - (hvns(p).orad * wid)) 'inner limit of planetoid/ring belt wid% orbital radius
outbnd&& = (hvns(p).orad + (hvns(p).orad * wid)) 'outer limit of planetoid/ring belt wid% orbital radius
bug = FrameSect(rcs(vpoint), rcp(FindParent(p)), outbnd&&, g!)
rng
= INT(outbnd&&
- inbnd&&
) 'If belt/ring fills frame, then exclude it for speed & clarity.
bugin = FrameSect(rcs(vpoint), rcp(FindParent(p)), inbnd&&, g!)
bugout = FrameSect(rcs(vpoint), rcp(FindParent(p)), outbnd&&, g!)
'Don't display belt/ring when fully encompassing screen
'PUT A LOW ALPHA CALL TO [GOSUB print_name] HERE
'B& = NEWIMAGE(620, 620, 32)
'DEST B&
'CLEARCOLOR RGBA32(0, 0, 0, 0)
'Prnt hvns(p).nam, 14, 14, 100, 280, 24, 0, &H7000FF70
'DEST SS&
'PUTIMAGE , B&, SS&
'FREEIMAGE B&
'Don't display when belt/ring is beyond screen
IF READBIT
(togs
, 1) THEN ' if Z-pan toggle is true CIRCLE (OT.pX
* g!
, (OT.pY
* (COS(D2R
(zangle
))) + (OT.pZ
* SIN(D2R
(zangle
)))) * g!
), (inbnd&&
+ pb
) * g!
, aster&
, , , 1 * COS(D2R
(zangle
)) bug = FrameSect(rcs(vpoint), rcp(FindParent(p)), (inbnd&& + pb), g!)
CIRCLE (OT.pX
* g!
, OT.pY
* g!
), (inbnd&&
+ pb
) * g!
, aster&
END IF ' end full frame exclusion END IF ' end planetary or belt display
print_name:
fl$ = ""
fl = -1
fl$
= fl$
+ MID$(hvns
(p
).nam
, n
, 1) fl = 1
fl$ = hvns(p).nam
Prnt fl$, 3.5 * fl, 3.5 * fl, (dcp(p).pX * g!) + (hvns(p).radi * g! * .7), (dcp(p).pY * g!) - (hvns(p).radi * g! * .7), 24, 0, RGBA32(200, 67, 55, 170)
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'REDESIGN IN PROGRESS...
DIM g!
' holds result of Prop! call for this display loop DIM OBC
AS unitpoint
' locates center of orbits & belt/ring systems
g! = Prop!
ctr = rcs(vpoint)
FOR p
= 1 TO orbs
' iterate through all bodies
'ptr = dcp(p)
'find orbit/belt/ring track center
OBC = rcp(FindParent(p))
OBC.pX = 0: OBC.pY = 0: OBC.pZ = 0
'Planetary rendering
'Orbit tracks
IF READBIT
(togs
, 7) THEN ' if orbit toggle is true p_ot = FrameSect(ctr, rcp(FindParent(p)), hvns(p).orad, g!)
IF READBIT
(togs
, 1) THEN ' if Z-pan toggle is true 'adjust so orbit track center moves with parent body
'draw all orbit tracks as some may be visible on extreme Z-pan
CIRCLE (OBC.pX
* g!
, (OBC.pY
* (COS(D2R
(zangle
))) + (OBC.pZ
* SIN(D2R
(zangle
)))) * g!
),_
hvns
(p
).orad
* g!
, RGBA
(111, 72, 233, 70), , , 1 * COS(D2R
(zangle
)) IF p_ot
= 3 THEN 'exclude circles that don't intersect view port to speed zoom in CIRCLE (OBC.pX
* g!
, OBC.pY
* g!
), hvns
(p
).orad
* g!
, RGBA
(111, 72, 233, 70)
IF READBIT
(togs
, 9) THEN l!
= hvns
(p
).dens
ELSE l!
= 1 'density or diameter jump zone p_jmp100% = FrameSect(ctr, rcp(p), hvns(p).radi * 200 * l!, g!)
p_jmp10% = FrameSect(ctr, rcp(p), hvns(p).radi * 20 * l!, g!)
p_rad% = FrameSect(ctr, rcp(p), hvns(p).radi, g!)
IF READBIT
(togs
, 6) THEN ' Jump zones activated IF p_jmp100%
> 1 THEN ' 100 diameters/densities FCirc (dcp(p).pX) * g!, (dcp(p).pY) * g!, (hvns(p).radi * 200 * l!) * g!, RGBA(150, 116, 116, 10)
IF p_jmp10%
> 1 THEN ' 10 diameters/densities FCirc (dcp(p).pX) * g!, (dcp(p).pY) * g!, (hvns(p).radi * 20 * l!) * g!, RGBA(200, 116, 116, 5)
'ADD STELLAR CLASS CORONA EFFECTS HERE AND PUT IN PLACE OF 50000
p_cron% = FrameSect(ctr, rcp(p), hvns(p).radi + (30 * 50000), g!)
p_cr_bd% = FrameSect(ctr, rcp(p), hvns(p).radi + (x * 50000), g!)
FCirc (dcp(p).pX) * g!, (dcp(p).pY) * g!, (hvns(p).radi + (x * 50000)) * g!, RGBA32(127, 127, 227, 31 - x)
c& = &HFFFC5454 ' star photosphere color
c& = &HFF545454 ' planet color
FCirc dcp(p).pX * g!, dcp(p).pY * g!, hvns(p).radi * g!, c&
CIRCLE (dcp
(p
).pX
* g!
, dcp
(p
).pY
* g!
), hvns
(p
).radi
* g!
, &HFF777777 'display name if there's room
IF g!
> .0003 AND hvns
(p
).rank
= 3 THEN ' drop satellite names first IF g!
> .00000003 AND hvns
(p
).rank
= 2 THEN ' Then drop planets names IF hvns
(p
).star
THEN ' always keep star names visible
'Belt/ring rendering
IF READBIT
(togs
, 10) THEN ' belt/ring toggle IF hvns
(p
).orad
* 2 * g!
> 100 THEN ' only draw if big enough to see aster& = &H087F7F7F ' belt/ring color
IF hvns
(p
).dens
> 0 THEN ' belt/ring width- stored in dens element wid = hvns(p).dens / 2
wid = .15
inbnd&& = hvns(p).orad - (hvns(p).orad * wid)
outbnd&& = hvns(p).orad + (hvns(p).orad * wid)
p_bi% = FrameSect(ctr, rcp(FindParent(p)), inbnd&&, g!)
p_bo% = FrameSect(ctr, rcp(FindParent(p)), outbnd&&, g!)
IF p_bo%
> 0 OR p_bi%
<> 1 THEN ' outer boundary within frame 'fully within the confines of the belt/ring
rng&&
= INT(outbnd&&
- inbnd&&
) IF READBIT
(togs
, 1) THEN ' if Z-pan toggle is true CIRCLE (OBC.pX
* g!
, (OBC.pY
* (COS(D2R
(zangle
))) + (OBC.pZ
* SIN(D2R
(zangle
)))) * g!
),_
(inbnd&&
+ pb
) * g!
, aster&
, , , 1 * COS(D2R
(zangle
)) frm_chk = FrameSect(ctr, rcp(FindParent(p)), (inbnd&& + pb), g!)
CIRCLE (OBC.pX
* g!
, OBC.pY
* g!
), (inbnd&&
+ pb
) * g!
, aster&
print_name:
fl$ = ""
fl = -1
fl$
= fl$
+ MID$(hvns
(p
).nam
, n
, 1) fl = 1
fl$ = hvns(p).nam
Prnt fl$, 3.5 * fl, 3.5 * fl, (dcp(p).pX * g!) + (hvns(p).radi * g! * .7), (dcp(p).pY * g!) - (hvns(p).radi * g! * .7), 24, 0, RGBA32(200, 67, 55, 170)
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Determine feature's relation to active's viewport
'SYNTAX: FrameSect(active unitpoint, feature center unitpoint, feature radius, result of Prop! call)
Sact = 1415 / ratio ' gives display sphere radius
dist## = PythXY(active, feature) ' distance between active unit and feature center point
'dist## = Pyth(active, feature) ' distance between active unit and feature center point
IF dist##
> Sact
+ range
THEN FrameSect
= 0 ' feature is beyond display IF dist##
< range
- Sact
THEN FrameSect
= 1 ' feature encompasses entire display IF dist##
< Sact
- range
THEN FrameSect
= 2 ' feature is encompassed by display IF dist##
< Sact
+ range
AND dist##
> range
- Sact
THEN FrameSect
= 3 ' feature intersects display
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
s = var * 1000 ' convert turns to seconds
etd
= INT(s
/ 86400) ' elapsed time days eth
= INT((s
- etd
* 86400) / 3600) ' elapsed time hours etm
= INT((s
- (etd
* 86400 + eth
* 3600)) / 60) ' elapsed time minutes ets = s - (etd * 86400 + eth * 3600 + etm * 60) ' elapsed time seconds
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB TruncCoord
(var
AS INTEGER64
)
'convert long coordinates to abbreviated versions
x$
= STR$(INT(var
/ 1000000)) + "M" x$
= STR$(INT(var
/ 1000000000)) + "G"
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'Unit (var) destroyed set all vectors to zero
cmb(var).ap = cmb(var).op
cmb(var).Sp = 0
Thrust(var).Azi = 0
Thrust(var).Inc = 0
Thrust(var).Gs = 0
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'// VCS - Viewpoint Coordinate System
'// local coordinate system centered on active unit
'// used to improve action of SensorMask and MouseOps
'// sensor screen click active unit choices in the outer
'// system by reducing absolute coordinate number ranges.
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
REDIM rcs
(units
) AS unitpoint
' Relative Coordinate / Ship REDIM rcp
(orbs
) AS unitpoint
' Relative Coordinate / Planet REDIM dcs
(units
) AS unitpoint
' Display Coordinate / Ship REDIM dcp
(orbs
) AS unitpoint
' Display Coordinate / Planet DIM ms
AS MEM: ms
= MEM
(cmb
()) DIM mp
AS MEM: mp
= MEM
(hvns
()) DIM msr
AS MEM: msr
= MEM
(rcs
()) DIM msd
AS MEM: msd
= MEM
(dcs
()) DIM mpr
AS MEM: mpr
= MEM
(rcp
()) DIM mpd
AS MEM: mpd
= MEM
(dcp
())
IF READBIT
(togs
, 1) THEN ' if Z-pan toggle is true then alternate Z view coordinates c = 1
t&& = MEMGET(ms, ms.OFFSET + c * ms.ELEMENTSIZE + 52, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 52, INTEGER64)
MEMPUT msr, msr.OFFSET + c * msr.ELEMENTSIZE, t&& 'SAME AS
'rcs(c).pX = (cmb(c).ap.pX - cmb(vpoint).ap.pX)
t&& = MEMGET(ms, ms.OFFSET + c * ms.ELEMENTSIZE + 60, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 60, INTEGER64)
MEMPUT msr, msr.OFFSET + c * msr.ELEMENTSIZE + 8, t&& 'SAME AS
'rcs(c).pY = (cmb(c).ap.pY - cmb(vpoint).ap.pY)
t&& = MEMGET(ms, ms.OFFSET + c * ms.ELEMENTSIZE + 68, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 68, INTEGER64)
MEMPUT msr, msr.OFFSET + c * msr.ELEMENTSIZE + 16, t&& 'SAME AS
'rcs(c).pZ = (cmb(c).ap.pZ - cmb(vpoint).ap.pZ)
MEMCOPY msr
, msr.OFFSET
+ c
* msr.ELEMENTSIZE
, 8 TO msd
, msd.OFFSET
+ c
* msd.ELEMENTSIZE
'SAME AS 'dcs(c).pX = rcs(c).pX
t&&
= (MEMGET
(msr
, msr.OFFSET
+ c
* msr.ELEMENTSIZE
+ 8, INTEGER64
) * COS(D2R
(zangle
)))_
+ ((MEMGET
(msr
, msr.OFFSET
+ c
* msr.ELEMENTSIZE
+ 16, INTEGER64
)) * SIN(D2R
(zangle
))) MEMPUT msd, msd.OFFSET + c * msd.ELEMENTSIZE + 8, t&& 'SAME AS
'dcs(c).pY = (rcs(c).pY * COS(_D2R(zangle))) + ((rcs(c).pZ) * SIN(_D2R(zangle)))
t&&
= (MEMGET
(msr
, msr.OFFSET
+ c
* msr.ELEMENTSIZE
+ 8, INTEGER64
) * -SIN(D2R
(zangle
)))_
+ ((MEMGET
(msr
, msr.OFFSET
+ c
* msr.ELEMENTSIZE
+ 16, INTEGER64
)) * COS(D2R
(zangle
))) MEMPUT msd, msd.OFFSET + c * msd.ELEMENTSIZE + 16, t&& 'SAME AS
'dcs(c).pZ = (rcs(c).pY * -SIN(D2R(zangle))) + (rcs(c).pZ * COS(D2R(zangle)))
c = c + 1
c = 1
t&& = MEMGET(mp, mp.OFFSET + c * mp.ELEMENTSIZE + 75, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 52, INTEGER64)
MEMPUT mpr, mpr.OFFSET + c * mpr.ELEMENTSIZE, t&& 'SAME AS
'rcp(c).pX = (hvns(c).ps.pX - cmb(vpoint).ap.pX)
t&& = MEMGET(mp, mp.OFFSET + c * mp.ELEMENTSIZE + 83, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 60, INTEGER64)
MEMPUT mpr, mpr.OFFSET + c * mpr.ELEMENTSIZE + 8, t&& 'SAME AS
'rcp(c).pY = (hvns(c).ps.pY - cmb(vpoint).ap.pY)
t&& = MEMGET(mp, mp.OFFSET + c * mp.ELEMENTSIZE + 91, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 68, INTEGER64)
MEMPUT mpr, mpr.OFFSET + c * mpr.ELEMENTSIZE + 16, t&& 'SAME AS
'rcp(c).pZ = (hvns(c).ps.pZ - cmb(vpoint).ap.pZ)
MEMCOPY mpr
, mpr.OFFSET
+ c
* mpr.ELEMENTSIZE
, 8 TO mpd
, mpd.OFFSET
+ c
* mpd.ELEMENTSIZE
'SAME AS 'dcp(c).pX = rcp(c).pX
t&&
= (MEMGET
(mpr
, mpr.OFFSET
+ c
* mpr.ELEMENTSIZE
+ 8, INTEGER64
) * COS(D2R
(zangle
)))_
+ ((MEMGET
(mpr
, mpr.OFFSET
+ c
* mpr.ELEMENTSIZE
+ 16, INTEGER64
)) * SIN(D2R
(zangle
))) MEMPUT mpd, mpd.OFFSET + c * mpd.ELEMENTSIZE + 8, t&& 'SAME AS
'dcp(c).pY = (rcp(c).pY * COS(_D2R(zangle))) + ((rcp(c).pZ) * SIN(_D2R(zangle)))
t&&
= (MEMGET
(mpr
, mpr.OFFSET
+ c
* mpr.ELEMENTSIZE
+ 8, INTEGER64
) * -SIN(D2R
(zangle
)))_
+ ((MEMGET
(mpr
, mpr.OFFSET
+ c
* mpr.ELEMENTSIZE
+ 16, INTEGER64
)) * COS(D2R
(zangle
))) MEMPUT mpd, mpd.OFFSET + c * mpd.ELEMENTSIZE + 16, t&& 'SAME AS
'dcp(c).pZ = (rcp(c).pY * -SIN(D2R(zangle))) + (rcp(c).pZ * COS(D2R(zangle)))
c = c + 1
ELSE ' Top down 2D coordinates c = 1
t&& = MEMGET(ms, ms.OFFSET + c * ms.ELEMENTSIZE + 52, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 52, INTEGER64)
MEMPUT msr, msr.OFFSET + c * msr.ELEMENTSIZE + 0, t&& 'rcs(c).pX = cmb(c).ap.pX - cmb(vpoint).ap.pX
t&& = MEMGET(ms, ms.OFFSET + c * ms.ELEMENTSIZE + 60, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 60, INTEGER64)
MEMPUT msr, msr.OFFSET + c * msr.ELEMENTSIZE + 8, t&& 'rcs(c).pY = cmb(c).ap.pY - cmb(vpoint).ap.pY
t&& = MEMGET(ms, ms.OFFSET + c * ms.ELEMENTSIZE + 68, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 68, INTEGER64)
MEMPUT msr, msr.OFFSET + c * msr.ELEMENTSIZE + 16, t&& 'rcs(c).pZ = cmb(c).ap.pZ - cmb(vpoint).ap.pZ
MEMCOPY msr
, msr.OFFSET
+ c
* msr.ELEMENTSIZE
, 24 TO msd
, msd.OFFSET
+ c
* msd.ELEMENTSIZE
'dcs(c) = rcs(c) c = c + 1
c = 1
t&& = MEMGET(mp, mp.OFFSET + c * mp.ELEMENTSIZE + 75, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 52, INTEGER64)
MEMPUT mpr, mpr.OFFSET + c * mpr.ELEMENTSIZE, t&& 'rcp(y).pX = hvns(y).ps.pX - cmb(vpoint).ap.pX
t&& = MEMGET(mp, mp.OFFSET + c * mp.ELEMENTSIZE + 83, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 60, INTEGER64)
MEMPUT mpr, mpr.OFFSET + c * mpr.ELEMENTSIZE + 8, t&& 'rcp(y).pY = hvns(y).ps.pY - cmb(vpoint).ap.pY
t&& = MEMGET(mp, mp.OFFSET + c * mp.ELEMENTSIZE + 91, INTEGER64) - MEMGET(ms, ms.OFFSET + vpoint * ms.ELEMENTSIZE + 68, INTEGER64)
MEMPUT mpr, mpr.OFFSET + c * mpr.ELEMENTSIZE + 16, t&& 'rcp(y).pZ = hvns(y).ps.pZ - cmb(vpoint).ap.pZ
MEMCOPY mpr
, mpr.OFFSET
+ c
* mpr.ELEMENTSIZE
, 24 TO mpd
, mpd.OFFSET
+ c
* mpd.ELEMENTSIZE
'dcp(y) = rcp(y) c = c + 1
MEMFREE ms: MEMFREE mp: MEMFREE msr: MEMFREE msd: MEMFREE mpr: MEMFREE mpd:
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
PanelBlank 0, 650, 64, 32, &HFF0F0F0F
Con_Blok 0, 650, 64, 32, "Applied", 0, &H502C9B2C
DISPLAY
DELAY .5
IF cmb
(vpoint
).Hd
>= 180 THEN Thrust
(vpoint
).Azi
= cmb
(vpoint
).Hd
- 180 IF cmb
(vpoint
).Hd
< 180 THEN Thrust
(vpoint
).Azi
= cmb
(vpoint
).Hd
+ 180 Thrust(vpoint).Inc = -cmb(vpoint).In
IF cmb
(vpoint
).Sp
/ 10000 < Thrust
(vpoint
).Gs
THEN Thrust(vpoint).Gs = cmb(vpoint).Sp / 10000
IF Thrust
(vpoint
).Gs
> cmb
(vpoint
).MaxG
THEN Thrust(vpoint).Gs = cmb(vpoint).MaxG
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
DEST ZS&
LINE (0, 0)-(39, 649), clr&
(4), B
' red border LINE (2, 2)-(37, 15), clr&
(8), BF
' top button LINE (2, 317)-(37, 332), clr&
(8), BF
' centering button LINE (2, 634)-(37, 647), clr&
(8), BF
' bottom button IF READBIT
(togs
, 1) THEN ' if Z-pan toggle is true yp = ((zangle / 90) * 310) + 325
LINE (1, yp
)-(6, yp
- 5), clr&
(12) ' arrow indicator LINE (1, yp
)-(6, yp
+ 5), clr&
(12) PRINTMODE KEEPBACKGROUND
PRINTSTRING
(10, yp
- 8), TRIM$
(STR$(INT(90 - zangle
))) + CHR$(248) 'degree value and degree symbol PUTIMAGE (1204, 4), ZS&, A&
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
DialogBox "HELP", 1200, 650, 25, &HFF4CCB9C, clr&(15)
DISPLAY
PRINTSTRING (0, 639), "Press any key to continue...", A&
DISPLAY
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
var.pX = var.pX + (var2.pX * var3) ' add (or subtract) two vectors defined by unitpoint
var.pY = var.pY + (var2.pY * var3) ' var= base vector, var2= vector to add
var.pZ = var.pZ + (var2.pZ * var3) ' var3 multiple of var2 to add (-sign to subtract)
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'multiply vector by scalar value
vec.pX = vec.pX * multiplier
vec.pY = vec.pY * multiplier
vec.pZ = vec.pZ * multiplier
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
SUB VecNorm
(var
AS unitpoint
)
'convert var to unit vector
m
= SQR(var.pX
* var.pX
+ var.pY
* var.pY
+ var.pZ
* var.pZ
) var.pX = var.pX / m
var.pY = var.pY / m
var.pZ = var.pZ / m
'±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
FREEIMAGE SS&
FREEIMAGE AW&
FREEIMAGE ZS&
FREEIMAGE ORI&
FREEIMAGE flight&
FREEIMAGE evade&
FREEIMAGE intercept&
FREEIMAGE cancel&
FREEIMAGE XZ&
FREEIMAGE IZ&
FREEIMAGE OZ&
FREEIMAGE RG&
FREEIMAGE OB&
FREEIMAGE GD&
FREEIMAGE AZ&
FREEIMAGE IN&
FREEIMAGE JP&
FREEIMAGE DI&
FREEIMAGE DN&
FREEIMAGE QT&
FREEIMAGE ShpT
FREEIMAGE ShpO
FREEIMAGE TLoc
FREEIMAGE TLocn