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