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