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