View difference between Paste ID: 0K3iyd6A and DDPxPRfS
SHOW: | | - or go back to the newest paste.
1
if warpdriveCommons then os.unloadAPI("warpdriveCommons") end
2
if not os.loadAPI("warpdrive/warpdriveCommons") then error("missing warpdriveCommons") end
3
local w = warpdriveCommons.w
4
5
local data
6
7
----------- Ship support
8
9
local miningLaser
10
local laserCamera
11
local laserGuideEnabled = true
12
local useMiningLaserOffset = true
13
local forwardBackMov =0
14
local leftRightMov = 0
15
local ship
16
local ship_front = 0
17
local ship_right = 0
18
local ship_up = 0
19
local ship_back = 0
20
local ship_left = 0
21
local ship_down = 0
22
local ship_isInHyper = false
23
local ship_x, ship_y, ship_z = 0, 0, 0
24
local ship_xTarget, ship_yTarget, ship_zTarget = 0, 0, 0
25
local ship_actualDistance = 0
26
local ship_energyRequired = 0
27
local ship_movement = { 0, 0, 0 }
28
local ship_rotationSteps = 0
29
local ship_indexPlayer = 0
30
local ship_arrayPlayers = { }
31
local ship_indexTarget = 0
32
33
local lx = 0
34
local ly = 0
35
local lz = 0
36
37
function ship_read(parData)
38
  data = parData
39
end
40
41
function ship_name(parName)
42
  if ship == nil or ship.isInterfaced() == nil then
43
    return ''
44
  end
45
  return ship.name(parName)
46
end
47
48
function ship_boot()
49
  if ship == nil or ship.isInterfaced() == nil then
50
    return
51
  end
52
  
53
  w.setColorNormal()
54
  w.writeLn("Booting Ship")
55
  
56
  w.write("- acquiring parameters: ")
57
  ship_front, ship_right, ship_up = ship.dim_positive()
58
  ship_back, ship_left, ship_down = ship.dim_negative()
59
  ship_isInHyper = ship.isInHyperspace()
60
  ship_movement = { ship.movement() }
61
  ship_rotationSteps = ship.rotationSteps()
62
  w.setColorSuccess()
63
  w.writeLn("ok")
64
  
65
  w.setColorNormal()
66
  w.write("- checking assembly   : ")
67
  local timeout = 10
68
  local isValid, message
69
  repeat
70
    isValid, message = ship.getAssemblyStatus()
71
    w.sleep(0.05)
72
    timeout = timeout - 1
73
  until isValid == true or timeout < 0
74
  if timeout < 0 then
75
    w.setColorWarning()
76
    w.writeLn("failed")
77
    w.writeLn(message)
78
    w.setColorNormal()
79
    w.sleep(6)
80
    -- don't reboot as the player might need to set new dimensions to fix it
81
  else
82
    w.setColorSuccess()
83
    w.writeLn("passed")
84
  end
85
  w.sleep(0.2)
86
  
87
  w.setColorNormal()
88
  w.write("- celestial position  : ")
89
  timeout = 10
90
  local pos
91
  repeat
92
    pos = ship.getLocalPosition()
93
    w.sleep(0.05)
94
    timeout = timeout - 1
95
  until pos ~= nil or timeout < 0
96
  if timeout < 0 then
97
    w.setColorWarning()
98
    w.writeLn("failed")
99
    w.writeLn("")
100
    w.writeLn("Something is wrong here, rebooting...")
101
    w.setColorNormal()
102
    w.sleep(2)
103
    w.reboot()
104
  else
105
    w.setColorSuccess()
106
    w.writeLn("triangulated")
107
  end
108
  ship_updateMovementStats()
109
  w.sleep(0.2)
110
  
111
  w.setColorNormal()
112
  w.write("- integrity check     : ")
113
  timeout = 10
114
  local shipSize
115
  repeat
116
    shipSize = ship.getShipSize()
117
    w.sleep(0.05)
118
    timeout = timeout - 1
119
  until (shipSize ~= nil and shipSize ~= 0) or timeout < 0
120
  if timeout < 0 then
121
    w.setColorWarning()
122
    w.writeLn("ongoing...")
123
    w.setColorNormal()
124
    w.sleep(2)
125
  else
126
    w.setColorSuccess()
127
    w.writeLn("passed")
128
  end
129
  
130
  ship.enable(true)
131
  ship.command("IDLE", true)
132
  w.sleep(0.3)
133
end
134
135
function ship_writeMovement(prefix)
136
  local message = prefix
137
  local count = 0
138
  if ship_movement[1] > 0 then
139
    message = message .. w.format_integer(ship_movement[1]) .. " front"
140
    count = count + 1
141
  elseif ship_movement[1] < 0 then
142
    message = message .. w.format_integer(- ship_movement[1]) .. " back"
143
    count = count + 1
144
  end
145
  if ship_movement[2] > 0 then
146
    if count > 0 then message = message .. ", " end
147
    message = message .. w.format_integer(ship_movement[2]) .. " up"
148
    count = count + 1
149
  elseif ship_movement[2] < 0 then
150
    if count > 0 then message = message .. ", " end
151
    message = message .. w.format_integer(- ship_movement[2]) .. " down"
152
    count = count + 1
153
  end
154
  if ship_movement[3] > 0 then
155
    if count > 0 then message = message .. ", " end
156
    message = message .. w.format_integer(ship_movement[3]) .. " right"
157
    count = count + 1
158
  elseif ship_movement[3] < 0 then
159
    if count > 0 then message = message .. ", " end
160
    message = message .. w.format_integer(- ship_movement[3]) .. " left"
161
    count = count + 1
162
  end
163
  
164
  if ship_rotationSteps == 1 then
165
    if count > 0 then message = message .. ", " end
166
    message = message .. "Turn right"
167
    count = count + 1
168
  elseif ship_rotationSteps == 2 then
169
    if count > 0 then message = message .. ", " end
170
    message = message .. "Turn back"
171
    count = count + 1
172
  elseif ship_rotationSteps == 3 then
173
    if count > 0 then message = message .. ", " end
174
    message = message .. "Turn left"
175
    count = count + 1
176
  end
177
  
178
  if count == 0 then
179
    message = message .. "(none)"
180
  end
181
  w.writeLn(message)
182
end
183
184
function ship_writeRotation()
185
  if ship_rotationSteps == 0 then
186
    w.writeLn(" Rotation         = Front    ")
187
  elseif ship_rotationSteps == 1 then
188
    w.writeLn(" Rotation         = Right +90")
189
  elseif ship_rotationSteps == 2 then
190
    w.writeLn(" Rotation         = Back 180 ")
191
  elseif ship_rotationSteps == 3 then
192
    w.writeLn(" Rotation         = Left -90 ")
193
  end
194
end
195
196
function ship_updateMovementStats()
197
  -- get current position
198
  ship_x, ship_y, ship_z = ship.getLocalPosition()
199
  if ship_x == nil then
200
    ship_x, ship_y, ship_z = 0, 0, 0
201
  end
202
  
203
  -- compute movement
204
  local dx, dy, dz = ship.getOrientation()
205
  if dx == nil then
206
    dx, dy, dz = 0, 0, 0
207
  end
208
  local worldMovement = { x = 0, y = 0, z = 0 }
209
  worldMovement.x = dx * ship_movement[1] - dz * ship_movement[3]
210
  worldMovement.y = ship_movement[2]
211
  worldMovement.z = dz * ship_movement[1] + dx * ship_movement[3]
212
  ship_actualDistance = math.ceil(math.sqrt(worldMovement.x * worldMovement.x + worldMovement.y * worldMovement.y + worldMovement.z * worldMovement.z))
213
  ship_xTarget = ship_x + worldMovement.x
214
  ship_yTarget = ship_y + worldMovement.y
215
  ship_zTarget = ship_z + worldMovement.z
216
  
217
  -- update energy requirement
218
  local success, result = ship.getEnergyRequired()
219
  if success then
220
    ship_energyRequired = result
221
  else
222
    w.status_showWarning(result)
223
  end
224
end
225
226
function ship_warp()
227
  -- rs.setOutput(alarm_side, true)
228
  if w.input_readConfirmation("Engage jump drive? (Y/n)") then
229
    -- rs.setOutput(alarm_side, false)
230
    ship.command("MANUAL", false)
231
    ship.movement(ship_movement[1], ship_movement[2], ship_movement[3])
232
    ship.rotationSteps(ship_rotationSteps)
233
    ship.command("MANUAL", true)
234
    -- ship = nil
235
  end
236
  -- rs.setOutput(alarm_side, false)
237
end
238
239
function ship_page_setMovement()
240
  -- force manual jump so we get proper max jump distance
241
  ship.command("MANUAL", false)
242
  
243
  local success, maxJumpDistance = ship.getMaxJumpDistance()
244
  if success ~= true then
245
    w.status_showWarning("" .. maxJumpDistance)
246
    return
247
  end
248
  
249
  w.page_begin("<==== Set ship movement ====>")
250
  w.setCursorPos(1, 3)
251
  w.setColorNormal()
252
  ship_writeMovement("Current movement is ")
253
  w.setCursorPos(1, 5)
254
  
255
  ship_movement[1] = ship_page_setDistanceAxis(4, "Forward/back", "Forward", "Backward", ship_movement[1], math.abs(ship_front + ship_back  + 1), maxJumpDistance)
256
  ship_movement[2] = ship_page_setDistanceAxis(6, "Up/down"     , "Up"     , "Down"    , ship_movement[2], math.abs(ship_up    + ship_down  + 1), maxJumpDistance)
257
  ship_movement[3] = ship_page_setDistanceAxis(8, "Right/left"  , "Right"  , "Left"    , ship_movement[3], math.abs(ship_left  + ship_right + 1), maxJumpDistance)
258
  ship_movement = { ship.movement(ship_movement[1], ship_movement[2], ship_movement[3]) }
259
  ship_updateMovementStats()
260
end
261
262
function ship_page_setDistanceAxis(line, axis, positive, negative, userEntry, shipLength, maxJumpDistance)
263
  local maximumDistance = math.floor(shipLength + maxJumpDistance)
264
  w.setCursorPos(1, line + 2)
265
  w.setColorHelp()
266
  w.writeFullLine(" Enter between " .. math.floor( shipLength + 1) .. " and " ..  maximumDistance .. " to move " ..  positive .. ".")
267
  w.writeFullLine(" Enter 0 to keep position on this axis.")
268
  w.writeFullLine(" Enter between " .. -maximumDistance .. " and " .. math.floor(-shipLength - 1) .. " to move " ..  negative .. ".")
269
  
270
  repeat
271
    w.setCursorPos(1, line)
272
    w.setColorNormal()
273
    w.write(axis .. " movement: ")
274
    userEntry = w.input_readInteger(userEntry)
275
    if userEntry ~= 0 and (math.abs(userEntry) <= shipLength or math.abs(userEntry) > maximumDistance) then
276
      w.status_showWarning("Wrong distance. Try again.")
277
    end
278
  until userEntry == 0 or (math.abs(userEntry) > shipLength and math.abs(userEntry) <= maximumDistance)
279
  w.setCursorPos(1, line + 2)
280
  w.clearLine()
281
  w.setCursorPos(1, line + 3)
282
  w.clearLine()
283
  w.setCursorPos(1, line + 4)
284
  w.clearLine()
285
  
286
  return userEntry
287
end
288
289
function ship_page_setRotation()
290
  local inputAbort = false
291
  w.page_begin("<==== Set ship rotation ====>")
292
  w.setCursorPos(1, 8)
293
  w.setColorHelp()
294
  w.writeFullLine(" Select ship rotation (Up, Down, Left, Right).")
295
  w.writeFullLine(" Select Front to keep current orientation.")
296
  w.writeFullLine(" Press Enter to save your selection.")
297
  repeat
298
    w.setCursorPos(1, 3)
299
    w.setColorNormal()
300
    ship_writeRotation()
301
    local params = { os.pullEventRaw() }
302
    local eventName = params[1]
303
    local address = params[2]
304
    if address == nil then address = "none" end
305
    if eventName == "key" then
306
      local keycode = params[2]
307
      if keycode == 200 then
308
        ship_rotationSteps = 0
309
      elseif keycode == 203 then
310
        ship_rotationSteps = 3
311
      elseif keycode == 205 then
312
        ship_rotationSteps = 1
313
      elseif keycode == 208 then
314
        ship_rotationSteps = 2
315
      elseif keycode == 28 then
316
        inputAbort = true
317
      else
318
        w.status_showWarning("Key " .. keycode .. " is invalid")
319
      end
320
    elseif eventName == "terminate" then
321
      inputAbort = true
322
    elseif not w.event_handler(eventName, params[2]) then
323
      w.status_showWarning("Event '" .. eventName .. "', " .. address .. " is unsupported")
324
    end
325
  until inputAbort
326
  ship_rotationSteps = ship.rotationSteps(ship_rotationSteps)
327
end
328
329
function ship_page_setDimensions()
330
  w.page_begin("<==== Set ship dimensions ====>")
331
  w.setCursorPos(1, 14)
332
  w.setColorHelp()
333
  w.writeFullLine(" Enter ship size in blocks (0-9).")
334
  w.writeFullLine(" First block next to Ship counts as 1.")
335
  w.writeFullLine(" ")
336
  w.writeFullLine(" Press Enter to save your selection.")
337
  
338
  w.setCursorPos(1, 3)
339
  w.setColorNormal()
340
  w.write(" Front (".. w.format_integer(ship_front) ..") : ")
341
  ship_front = w.input_readInteger(ship_front)
342
  w.write(" Right (".. w.format_integer(ship_right) ..") : ")
343
  ship_right = w.input_readInteger(ship_right)
344
  w.write(" Up    (".. w.format_integer(ship_up) ..") : ")
345
  ship_up = w.input_readInteger(ship_up)
346
  w.write(" Back  (".. w.format_integer(ship_back) ..") : ")
347
  ship_back = w.input_readInteger(ship_back)
348
  w.write(" Left  (".. w.format_integer(ship_left) ..") : ")
349
  ship_left = w.input_readInteger(ship_left)
350
  w.write(" Down  (".. w.format_integer(ship_down) ..") : ")
351
  ship_down = w.input_readInteger(ship_down)
352
  w.write("Setting dimensions...")
353
  ship_front, ship_right, ship_up = ship.dim_positive(ship_front, ship_right, ship_up)
354
  ship_back, ship_left, ship_down = ship.dim_negative(ship_back, ship_left, ship_down)
355
end
356
357
function ship_page_summon() -- no longer used
358
  w.page_begin("<==== Summon players ====>")
359
  local stringPlayers = ship.getAttachedPlayers()
360
  if stringPlayers == "" then
361
    w.writeLn("~ no players registered ~")
362
    w.writeLn("")
363
    w.setColorHelp()
364
    w.writeFullLine(" Press enter to exit.")
365
    w.setColorNormal()
366
    w.input_readInteger("")
367
    return
368
  end
369
  local arrayPlayers = w.data_splitString(stringPlayers, ",")
370
  for i = 1, #arrayPlayers do
371
    w.writeLn(i .. ". " .. arrayPlayers[i])
372
  end
373
  w.setColorHelp()
374
  w.writeFullLine(" Enter player number")
375
  w.writeFullLine(" or press enter to summon everyone.")
376
  w.setColorNormal()
377
  
378
  w.write(":")
379
  ship.command("SUMMON", false)
380
  local input = w.input_readInteger("")
381
  if input == "" then
382
    ship.targetName("")
383
  else
384
    input = tonumber(input)
385
    ship.targetName(arrayPlayers[input - 1])
386
  end
387
  ship.command("SUMMON", true)
388
end
389
390
function ship_page_jumpToGate()
391
  w.page_begin("<==== Jump through Jumpgate ====>")
392
  w.writeLn("")
393
  w.writeLn("Your ship should be already inside a jumpgate")
394
  
395
  w.setCursorPos(1, 16)
396
  w.setColorHelp()
397
  w.writeFullLine(" Enter target jumpgate name (a-z, 0-9).")
398
  w.writeFullLine(" Press enter to save jumpgate name.")
399
  
400
  w.setCursorPos(1, 5)
401
  w.setColorNormal()
402
  w.write("Target jumpgate name: ")
403
  local targetName = w.input_readText("")
404
  -- rs.setOutput(alarm_side, true)
405
  if w.input_readConfirmation("Engage gate jumping? (Y/n)") then
406
    -- rs.setOutput(alarm_side, false)
407
    ship.command("GATE", false)
408
    ship.targetName(targetName)
409
    ship.command("GATE", true)
410
    -- ship = nil
411
  end
412
  -- rs.setOutput(alarm_side, false)
413
end
414
415
function ship_page_controls()
416
  w.page_begin(w.data_getName() .. " - Ship controls")
417
  if ship == nil or ship.isInterfaced() == nil then
418
    w.status_showWarning("No ship controller detected")
419
  else
420
    local isValid, message = ship.getAssemblyStatus()
421
    if isValid ~= true then
422
      w.status_showWarning(message)
423
    else
424
      local isEnabled = ship.enable()
425
      if not isEnabled then
426
        ship.command("MANUAL", false)
427
        ship_updateMovementStats()
428
      end
429
    end
430
    
431
    w.setCursorPos(1, 2)
432
    w.writeLn("Ship:")
433
    w.writeLn(" Current position = " .. w.format_integer(ship_x) .. ", " .. w.format_integer(ship_y) .. ", " .. w.format_integer(ship_z))
434
    local energyStored, energyMax, energyUnits = ship.getEnergyStatus()
435
    if energyStored == nil then energyStored = 0 end
436
    if energyMax == nil or energyMax == 0 then energyMax = 1 end
437
    w.writeLn(" Energy           = " .. math.floor(energyStored / energyMax * 100) .. " % (" .. w.format_integer(energyStored) .. " " .. energyUnits .. ")")
438
    
439
    w.writeLn("")
440
    w.writeLn("Dimensions:")
441
    w.writeLn(" Front, Right, Up = " .. w.format_integer(ship_front) .. ", " .. w.format_integer(ship_right) .. ", " .. w.format_integer(ship_up) .. " blocks")
442
    w.writeLn(" Back, Left, Down = " .. w.format_integer(ship_back) .. ", " .. w.format_integer(ship_left) .. ", " .. w.format_integer(ship_down) .. " blocks")
443
    local shipMass, shipVolume = ship.getShipSize()
444
    if shipMass == nil then
445
      shipMass = 0
446
      shipVolume = 0
447
    end
448
    w.write(" Mass, Volume     = ")
449
    if shipMass == 0 then
450
      w.write("?")
451
    else
452
      w.write(w.format_integer(shipMass))
453
    end
454
    w.write(" tons, ")
455
    if shipVolume == 0 then
456
      w.write("?")
457
    else
458
      w.write(w.format_integer(shipVolume))
459
    end
460
    w.writeLn(" blocks")
461
    
462
    if isValid == true then
463
      w.writeLn("")
464
      w.writeLn("Warp data:")
465
      ship_writeMovement(" Movement         = ")
466
      w.writeLn(" Distance         = " .. w.format_integer(ship_actualDistance) .. " m (" .. w.format_integer(ship_energyRequired) .. " " .. energyUnits .. ", " .. math.floor(energyStored / ship_energyRequired) .. " jumps)")
467
      w.writeLn(" Target position  = " .. w.format_integer(ship_xTarget) .. ", " .. w.format_integer(ship_yTarget) .. ", " .. w.format_integer(ship_zTarget))
468
    end
469
  end
470
  
471
  w.setCursorPos(1, 16)
472
  w.setColorControl()
473
  w.writeFullLine(" set ship Name (N), dImensions (I), Movement (M)")
474
  if ship_isInHyper then
475
    w.writeFullLine(" Jump to move ship (M/J), exit Hyperspace (H)")
476
  else
477
    w.writeFullLine(" Jump to move ship (M/J), enter Hyperspace (H)")
478
  end
479
end
480
481
function ship_key_controls(character, keycode)
482
  if character == 'm' or character == 'M' then
483
    ship_page_setMovement()
484
    ship_page_setRotation()
485
    ship_warp()
486
    return true
487
  elseif character == 'i' or character == 'I' then
488
    ship_page_setDimensions()
489
    return true
490
  elseif character == 'j' or character == 'J' then
491
    ship_warp()
492
    return true
493
  elseif character == 'h' or character == 'H' then
494
    -- rs.setOutput(alarm_side, true)
495
    local isConfirmed
496
    if ship_isInHyper then
497
      isConfirmed = w.input_readConfirmation("Disengage hyperdrive? (Y/n)")
498
    else
499
      isConfirmed = w.input_readConfirmation("Engage hyperdrive? (Y/n)")
500
    end
501
    if isConfirmed then
502
      -- rs.setOutput(alarm_side, false)
503
      ship.command("HYPERDRIVE", true)
504
      ship_updateMovementStats()
505
      -- ship = nil
506
    end
507
    -- rs.setOutput(alarm_side, false)
508
    return true
509
  elseif character == 'n' or character == 'N' then
510
    w.data_setName()
511
    return true
512
  end
513
  return false
514
end
515
516
function ship_writeArray(arrayValues, indexSelected)
517
  if indexSelected then
518
    indexSelected = (indexSelected + #arrayValues) % #arrayValues
519
  end
520
  
521
  local indexSplit = math.ceil(#arrayValues / 2)
522
  for i = 1, indexSplit do
523
    if indexSelected and i == indexSelected + 1 then
524
      w.setColorSelected()
525
      w.write(">" .. string.sub(arrayValues[i] .. "                        ", 1, 24))
526
      w.setColorNormal()
527
    else
528
      w.write(" " .. string.sub(arrayValues[i] .. "                        ", 1, 24))
529
    end
530
    if arrayValues[i + indexSplit] ~= nil then
531
      if indexSelected and i + indexSplit == indexSelected + 1 then
532
        w.setColorSelected()
533
        w.writeLn(">" .. string.sub(arrayValues[i + indexSplit] .. "                        ", 1, 24))
534
        w.setColorNormal()
535
      else
536
        w.writeLn(" " .. arrayValues[i + indexSplit])
537
      end
538
    else
539
      w.writeLn("")
540
    end
541
  end
542
  return indexSelected
543
end
544
545
function ship_page_crew()
546
  w.page_begin(w.data_getName() .. " - Ship crew")
547
  if ship == nil or ship.isInterfaced() == nil then
548
    w.status_showWarning("No ship controller detected")
549
  else
550
    local isValid, message = ship.getAssemblyStatus()
551
    if isValid ~= true then
552
      w.status_showWarning(message)
553
    else
554
      w.writeLn("Attached players:")
555
      -- local stringPlayers, _ = ship.getAttachedPlayers()
556
      if stringPlayers == nil or stringPlayers == "" then
557
        stringPlayers = "~ no registered player ~"
558
      end
559
      ship_arrayPlayers = w.data_splitString(stringPlayers, ",")
560
      ship_indexPlayer = ship_writeArray(ship_arrayPlayers, ship_indexPlayer)
561
    end
562
  end
563
  
564
  w.setCursorPos(1, 16)
565
  w.setColorControl()
566
  w.writeFullLine(" Summon all crew (S)")
567
  w.writeFullLine(" select crew (Up, Down), summon slctd crew (enter)")
568
end
569
570
function ship_key_crew(character, keycode)
571
  if character == 's' or character == 'S' then -- S
572
    ship.command("SUMMON", false)
573
    ship.targetName("")
574
    ship.command("SUMMON", true)
575
    return true
576
  elseif keycode == 28 then -- Enter
577
    local namePlayer = ship_arrayPlayers[ship_indexPlayer + 1]
578
    ship.command("SUMMON", false)
579
    ship.targetName(namePlayer)
580
    ship.command("SUMMON", true)
581
    w.status_showSuccess("Engaging teleportation for " .. namePlayer .. "...")
582
    return true
583
  elseif keycode == 200 or keycode == 203 or character == '-' then -- Up or Left or -
584
    ship_indexPlayer = ship_indexPlayer - 1
585
    return true
586
  elseif keycode == 208 or keycode == 205 or character == '+' then -- Down or Right or +
587
    ship_indexPlayer = ship_indexPlayer + 1
588
    return true
589
  end
590
  return false
591
end
592
593
function ship_page_navigation()
594
  w.page_begin(w.data_getName() .. " - Ship navigation")
595
  if ship == nil or ship.isInterfaced() == nil then
596
    w.status_showWarning("No ship controller detected")
597
  else
598
    local isValid, message = ship.getAssemblyStatus()
599
    if isValid ~= true then
600
      w.status_showWarning(message)
601
    else
602
      local locationCurrent = "somewhere..."  -- @TODO ship.getLocation()
603
      w.writeLn("Current ship location        : " .. locationCurrent)
604
      w.writeLn("Jumpgates or beacons in range:")
605
      local stringTargets, _ = "not implemented", nil -- ship.getTargets()
606
      if stringTargets == nil or stringTargets == "" then
607
        stringTargets = "~ no beacon nor jumpgate in range ~"
608
      end
609
      local arrayTargets = w.data_splitString(stringTargets, ",")
610
      ship_indexTarget = ship_writeArray(arrayTargets, ship_indexTarget)
611
    end
612
  end
613
  
614
  w.setCursorPos(1, 16)
615
  w.setColorControl()
616
  w.writeFullLine(" select target (Up, Down), register target (enter)")
617
  w.writeFullLine(" jump through Gate (G)")
618
end
619
620
function ship_key_navigation(character, keycode)
621
  if keycode == 28 then -- Enter
622
--    local success, xxx = ship.xxx(ship_indexTarget)
623
--    if success then
624
--      w.status_showSuccess("Engaging jumpgate jump to " .. xxx .. "...")
625
--    else
626
--      w.status_showWarning("Failed to summon crew member")
627
--    end
628
    return true
629
--  elseif character == 'b' or character == 'B' then -- B
630
--    ship_page_jumpToBeacon()
631
--    return true
632
  elseif character == 'g' or character == 'G' then -- G
633
    ship_page_jumpToGate()
634
    return true
635
  elseif keycode == 200 or keycode == 203 or character == '-' then -- Up or Left or -
636
    ship_indexTarget = ship_indexTarget - 1
637
    return true
638
  elseif keycode == 208 or keycode == 205 or character == '+' then -- Down or Right or +
639
    ship_indexTarget = ship_indexTarget + 1
640
    return true
641
  end
642
  return false
643
end
644
645
function ship_register()
646
  w.device_register("warpdriveShipController",
647
      function(deviceType, address, wrap) ship = wrap end,
648
      function() end)
649
  w.device_register("warpdriveShipCore",
650
      function(deviceType, address, wrap) ship = wrap end,
651
      function() end)
652
  w.device_register("warpdriveMiningLaser", function(deviceType, address, wrap) miningLaser = wrap end, function() end) 
653
  w.device_register("warpdriveLaserCamera", function(deviceType, address, wrap) laserCamera = wrap end, function() end)
654
  w.event_register("shipCoreCooldownDone"  , function() w.status_showWarning("Ship core cooldown done")   return false end )
655
  w.event_register("laserScanning", function() laser_sendEvent() return false end )
656
  w.data_register("ship", ship_read, nil, ship_name)
657
end
658
659
----------- connections status
660
661
function connections_page(isBooting)
662
  w.page_begin(w.data_getName() .. " - Connections")
663
  
664
  w.writeLn("")
665
  
666
  local monitors = w.device_getMonitors()
667
  if #monitors == 0 then
668
    w.setColorDisabled()
669
    w.writeLn("No Monitor detected")
670
  elseif #monitors == 1 then
671
    w.setColorSuccess()
672
    w.writeLn("1 monitor detected")
673
  else
674
    w.setColorSuccess()
675
    w.writeLn(#monitors .. " Monitors detected")
676
  end
677
  
678
  if ship == nil or ship.isInterfaced() == nil then
679
    w.setColorDisabled()
680
    w.writeLn("No ship controller detected")
681
  else
682
    w.setColorSuccess()
683
    w.writeLn("Ship controller detected")
684
    if isBooting then
685
      ship_boot()
686
    end
687
  end
688
  
689
  w.writeLn("")
690
  w.setColorNormal()
691
  w.writeLn("This is a keyboard controlled user interface.")
692
  w.write("Key controls are written like so: ")
693
  w.setColorControl()
694
  w.write("Action (key)")
695
  w.setColorNormal()
696
  w.writeLn(".")
697
  w.write("For example, typing ")
698
  w.setColorControl()
699
  w.write(" 1 ")
700
  w.setColorNormal()
701
  w.writeLn(" will open Ship controls.")
702
end
703
704
function laser_guide_page()
705
  w.page_begin(w.data_getName() .. " - Laser Guidance") 
706
  if ship == nil or ship.isInterfaced() == nil then
707
    w.status_showWarning("No ship controller detected")
708
  elseif laserCamera == nil or laserCamera.isInterfaced() == nil then
709
	    w.status_showWarning("No laser camera detected")
710
  elseif laserCamera.laserMediumCount() < 1 then
711
		w.status_showWarning("No laser mediums detected")
712
713
  else
714
	if (miningLaser == nil or miningLaser.isInterfaced() == nil) then
715
		useMiningLaserOffset = false
716
		
717
	end
718
	laserGuideOn = "true"
719
	if (laserGuideEnabled) then
720
		laserGuideOn = "true"
721
	else
722
		laserGuideOn = "false"
723
	end
724
725-
	
725+
	local mx, my, mz = miningLaser.getLocalPosition()
726
	w.writeLn("Ship Core Must Face North or South To Function!") 
727
	w.writeLn("Laser Guidance Enabled = " .. laserGuideOn)
728
	w.writeLn("Mining Laser Offset Enabled = " .. tostring(useMiningLaserOffset))
729
	w.writeLn("Target Position = " .. " x:" .. lx .. " z:" .. lz) 
730
	w.writeLn("Vertical Mining Offset = " .. "down:" .. my-ly) 
731
732
	local forwardBack = " Forward, "
733
	local leftRight = " Right"
734
	if forwardBackMov < 0 then
735
		forwardBack = " Back, "
736
	end
737
	if leftRightMov < 0 then
738
		leftRight = " Left"
739
	end
740
	w.writeLn("Ship Movement = " .. math.abs(forwardBackMov) .. forwardBack .. math.abs(leftRightMov) .. leftRight)
741
  end
742
  
743
  w.setCursorPos(1, 16)
744
  w.setColorControl()
745
  w.writeFullLine("Toggle Laser Guidance (t), Clear Data (c)")
746
  w.writeFullLine("Mining Laser Offset (g)")
747
end
748
function laser_key(character, keycode)
749
  if character == 't' or character == 'T' then
750
	if laserGuideEnabled then
751
		laserGuideEnabled = false
752
	else
753
		laserGuideEnabled = true
754
	end
755
	return true
756
  elseif character == 'c' or character == 'C' then
757
	lx = 0
758
	ly = 0
759
	lz = 0
760
	leftRightMov = 0
761
	forwardBackMov = 0
762
	return true
763
  elseif character == 'g' or character == 'G' then
764
	if miningLaser == nil or miningLaser.isInterfaced() == nil then
765
		useMiningLaserOffset = false
766
		w.status_showWarning("No mining laser detected!")
767
	else
768
		if useMiningLaserOffset then
769
			useMiningLaserOffset = false
770
		else
771
			useMiningLaserOffset = true
772
		end
773
	end
774
	return true
775
  end
776
end
777
function laser_sendEvent()
778
	if (laserCamera ~= nil and laserCamera.isInterfaced()) then
779
		if (miningLaser == nil or miningLaser.isInterfaced() == nil) then
780
			useMiningLaserOffset = false
781
		end
782
		local resType, x, y, z, id, meta, res = laserCamera.getScanResult()
783
		lx = x
784
		ly = y
785
		lz = z
786
		ship.command("MANUAL", false)
787
		local success, maxJumpDistance = ship.getMaxJumpDistance()
788
		if success ~= true then
789
			w.status_showWarning("" .. maxJumpDistance)
790
			return
791
		end
792
		local rx, ry, rz = ship.getOrientation()
793
		minForwardBack = math.abs(ship_front+ship_back+1)
794
		minLeftRight = math.abs(ship_left+ship_right+1)
795
		if useMiningLaserOffset then
796
			local mx, my, mz = miningLaser.getLocalPosition()
797
			dx = x-mx
798
			dz = z-mz
799
		else
800
			local mx, my, mz = ship.getLocalPosition()
801
			dx = x-mx
802
			dz = z-mz
803
		end
804
		
805
		forwardBackMov = 0
806
		leftRightMov = 0
807
		
808
		if rx ~= 0 then
809
			forwardBackMov = dx*rx
810
			leftRightMov = dz*rx
811
		elseif rz ~= 0 then
812
			forwardBackMov = dz*rz
813
			leftRightMov = dx*rz
814
		end
815
		if math.abs(forwardBackMov) < minForwardBack and math.abs(leftRightMov) < minLeftRight then
816
			w.status_showWarning("The movement is too small!")
817
			return
818
		end
819
		forwardBackMov = forwardBackMov
820
		leftRightMov = leftRightMov*-1
821
		if laserGuideEnabled then
822
			ship.movement(forwardBackMov, 0, leftRightMov)
823
			ship.rotationSteps(0)
824
			ship.command("MANUAL", true)
825
		end
826
	end
827
end
828
----------- Boot sequence
829
830
w.page_setEndText("Home(0),Controls(1),Crew(2),Navigation(3),Laser(4)")
831
w.page_register('0', connections_page, nil)
832
w.page_register('1', ship_page_controls, ship_key_controls)
833
w.page_register('2', ship_page_crew, ship_key_crew)
834
w.page_register('3', ship_page_navigation, ship_key_navigation)
835
w.page_register('4', laser_guide_page, laser_key)
836
ship_register()
837
838
w.boot()
839
local success, message = pcall(w.run)
840
if not success then
841
  print("failed with message")
842
  print(message)
843
  w.sleep(3.0)
844
  print("rebooting...")
845
  w.reboot()
846
else
847
  if ship ~= nil then
848
    ship.command("OFFLINE", true)
849
    ship.enable(false)
850
  end
851
  
852
  w.close()
853
end