11
11
-- Enemies[Normal|Default]: Normal amount of enemies. Recommended for a normal crew.
12
12
-- Enemies[Hard]: More enemies. Recommended if you have multiple player-controlled ships.
13
13
-- Enemies[Extreme]: Many enemies. Inexperienced player crews will pretty surely be overwhelmed.
14
+ -- Setting[Time]: Sets up how much time the players have for the scenario
15
+ -- Time[Unlimited|Default]: No time limit
16
+ -- Time[20min]: Automatic loss after 20 minutes
17
+ -- Time[30min]: Automatic loss after 30 minutes
18
+ -- Time[60min]: Automatic loss after 60 minutes
19
+ -- Setting[PlayerShip]: Sets the default player ship
20
+ -- PlayerShip[Atlantis|Default]: Powerful ship with sidewards missile tubes. Requires more advanced play.
21
+ -- PlayerShip[Phobos M3P]: Simpler, less powerful ship. But easier to handler. Recommended for new crews.
14
22
15
23
--- Scenario
16
24
-- @script scenario_00_basic
@@ -30,8 +38,81 @@ require("utils.lua")
30
38
local enemyList
31
39
local friendlyList
32
40
local stationList
41
+ local playerList
33
42
local addWavesToGMPosition -- If set to true, add wave will require GM to click on the map to position, where the wave should be spawned.
34
43
44
+ local gametimeleft = nil -- Maximum game time in seconds.
45
+ local timewarning = nil -- Used for checking when to give a warning, and to update it so the warning happens once.
46
+
47
+ local ship_names = {
48
+ " SS Epsilon" ,
49
+ " Ironic Gentleman" ,
50
+ " Binary Sunset" ,
51
+ " USS Roddenberry" ,
52
+ " Earthship Sagan" ,
53
+ " Explorer" ,
54
+ " ISV Phantom" ,
55
+ " Keelhaul" ,
56
+ " Peacekeeper" ,
57
+ " WarMonger" ,
58
+ " Death Bringer" ,
59
+ " Executor" ,
60
+ " Excaliber" ,
61
+ " Voyager" ,
62
+ " Khan's Wrath" ,
63
+ " Kronos' Savior" ,
64
+ " HMS Captor" ,
65
+ " Imperial Stature" ,
66
+ " ESS Hellfire" ,
67
+ " Helen's Fury" ,
68
+ " Venus' Light" ,
69
+ " Blackbeard's Way" ,
70
+ " ISV Monitor" ,
71
+ " Argent" ,
72
+ " Echo One" ,
73
+ " Earth's Might" ,
74
+ " ESS Tomahawk" ,
75
+ " Sabretooth" ,
76
+ " Hiro-maru" ,
77
+ " USS Nimoy" ,
78
+ " Earthship Tyson" ,
79
+ " Destiny's Tear" ,
80
+ " HMS SuperNova" ,
81
+ " Alma del Terra" ,
82
+ " DreadHeart" ,
83
+ " Devil's Maw" ,
84
+ " Cougar's Claw" ,
85
+ " Blood-oath" ,
86
+ " Imperial Fist" ,
87
+ " HMS Promise" ,
88
+ " ESS Catalyst" ,
89
+ " Hercules Ascendant" ,
90
+ " Heavens Mercy" ,
91
+ " HMS Adams" ,
92
+ " Explorer" ,
93
+ " Discovery" ,
94
+ " Stratosphere" ,
95
+ " USS Kelly" ,
96
+ " HMS Honour" ,
97
+ " Devilfish" ,
98
+ " Minnow" ,
99
+ " Earthship Nye" ,
100
+ " Starcruiser Solo" ,
101
+ " Starcruiser Reynolds" ,
102
+ " Starcruiser Hunt" ,
103
+ " Starcruiser Lipinski" ,
104
+ " Starcruiser Tylor" ,
105
+ " Starcruiser Kato" ,
106
+ " Starcruiser Picard" ,
107
+ " Starcruiser Janeway" ,
108
+ " Starcruiser Archer" ,
109
+ " Starcruiser Sisko" ,
110
+ " Starcruiser Kirk" ,
111
+ " Aluminum Falcon" ,
112
+ " SS Essess" ,
113
+ " Jenny"
114
+ }
115
+
35
116
--- Wrapper to adding an enemy wave
36
117
--
37
118
-- This wrapper either calls addWaveInner directly (when on random wave positioning)
@@ -211,11 +292,17 @@ end
211
292
--- Initialize scenario.
212
293
function init ()
213
294
-- Spawn a player Atlantis.
214
- player = PlayerSpaceship ():setFaction (" Human Navy" ):setTemplate (" Atlantis" )
295
+ player = PlayerSpaceship ():setFaction (" Human Navy" ):setTemplate (getScenarioSetting (" PlayerShip" ))
296
+ player :setCallSign (ship_names [irandom (1 , # ship_names )])
215
297
216
298
enemyList = {}
217
299
friendlyList = {}
218
300
stationList = {}
301
+ playerList = {player }
302
+
303
+ onNewPlayerShip (function (ship )
304
+ table.insert (playerList , ship )
305
+ end )
219
306
220
307
addWavesToGMPosition = false
221
308
@@ -282,6 +369,17 @@ function init()
282
369
local enemy_group_count = counts [getScenarioSetting (" Enemies" )]
283
370
assert (enemy_group_count , " unknown enemies setting: " .. getScenarioSetting (" Enemies" ) .. " could not set enemy_group_count" )
284
371
372
+ local timesetting = {
373
+ [" Unlimited" ] = nil ,
374
+ [" 20min" ] = 20 * 60 ,
375
+ [" 30min" ] = 30 * 60 ,
376
+ [" 60min" ] = 60 * 60 ,
377
+ }
378
+ gametimeleft = timesetting [getScenarioSetting (" Time" )]
379
+ if gametimeleft ~= nil then
380
+ timewarning = gametimeleft
381
+ end
382
+
285
383
-- If not in the Empty variation, spawn the corresponding number of random
286
384
-- enemy waves at distributed random headings and semi-random distances
287
385
-- relative to the players' spawn point.
@@ -366,25 +464,46 @@ function init()
366
464
367
465
-- Spawn random neutral transports.
368
466
Script ():run (" util_random_transports.lua" )
467
+
468
+
469
+ local station = friendlyList [1 ]
470
+ if gametimeleft ~= nil then
471
+ station :sendCommsMessage (
472
+ player , string.format (_ ([[ %s, your objective is to fend off the incoming Kraylor attack.
473
+
474
+ Please inform your Captain and crew that you have a total of %d minutes for this mission.
475
+
476
+ The mission started at the arrival of this message.
477
+
478
+ Good luck.]] ), player :getCallSign (), gametimeleft / 60 )
479
+ )
480
+ else
481
+ station :sendCommsMessage (
482
+ player , string.format (_ ([[ %s, your objective is to fend off the incoming Kraylor attack.
483
+
484
+ Good luck.]] ), player :getCallSign ())
485
+ )
486
+ end
487
+ end
488
+
489
+ function countValid (objectList )
490
+ local object_count = 0
491
+ for i_ , object in ipairs (objectList ) do
492
+ if object :isValid () then
493
+ object_count = object_count + 1
494
+ end
495
+ end
496
+ return object_count
369
497
end
370
498
371
499
--- Update.
372
500
--
373
501
-- @tparam number delta the time delta (in seconds)
374
502
function update (delta )
375
503
-- Count all surviving enemies and allies.
376
- local enemy_count = 0
377
- for i_ , enemy in ipairs (enemyList ) do
378
- if enemy :isValid () then
379
- enemy_count = enemy_count + 1
380
- end
381
- end
382
- local friendly_count = 0
383
- for i_ , friendly in ipairs (friendlyList ) do
384
- if friendly :isValid () then
385
- friendly_count = friendly_count + 1
386
- end
387
- end
504
+ local enemy_count = countValid (enemyList )
505
+ local friendly_count = countValid (friendlyList )
506
+ local player_count = countValid (playerList )
388
507
389
508
-- If not playing the Empty variation, declare victory for the
390
509
-- Humans (players) once all enemies are destroyed. Note that players can win
@@ -394,11 +513,44 @@ function update(delta)
394
513
-- a Human victory.
395
514
if (enemy_count == 0 and getScenarioSetting (" Enemies" ) ~= " Empty" ) then
396
515
victory (" Human Navy" )
516
+ if gametimeleft ~= nil then
517
+ local text = string.format (_ (" Mission: SUCCESS (%d seconds left)" ), math.floor (gametimeleft ))
518
+ globalMessage (text )
519
+ setBanner (text )
520
+ return
521
+ end
522
+ end
523
+
524
+ if gametimeleft ~= nil then
525
+ gametimeleft = gametimeleft - delta
526
+ if gametimeleft < 0 then
527
+ victory (" Kraylor" )
528
+ local text = _ (" Mission: FAILED (time has run out)" )
529
+ globalMessage (text )
530
+ setBanner (text )
531
+ return
532
+ end
533
+ if gametimeleft < timewarning then
534
+ if timewarning <= 1 * 60 then -- Less then 1 minutes left.
535
+ friendlyList [1 ]:sendCommsMessage (player , string.format (_ ([[ %s, you have %d minute remaining.]] ), player :getCallSign (), timewarning / 60 ))
536
+ timewarning = timewarning - 2 * 60
537
+ elseif timewarning <= 5 * 60 then -- Less then 5 minutes left. Warn ever 2 minutes instead of every 5.
538
+ friendlyList [1 ]:sendCommsMessage (player , string.format (_ ([[ %s, you have %d minutes remaining.]] ), player :getCallSign (), timewarning / 60 ))
539
+ timewarning = timewarning - 2 * 60
540
+ else
541
+ friendlyList [1 ]:sendCommsMessage (player , string.format (_ ([[ %s, you have %d minutes remaining of mission time.]] ), player :getCallSign (), timewarning / 60 ))
542
+ timewarning = timewarning - 5 * 60
543
+ end
544
+ end
397
545
end
398
546
399
547
-- If all allies are destroyed, the Humans (players) lose.
400
548
if friendly_count == 0 then
401
549
victory (" Kraylor" )
550
+ local text = _ (" Mission: FAILED (no friendlies left)" )
551
+ globalMessage (text )
552
+ setBanner (text )
553
+ return
402
554
else
403
555
-- As the battle continues, award reputation based on
404
556
-- the players' progress and number of surviving allies.
@@ -408,4 +560,18 @@ function update(delta)
408
560
end
409
561
end
410
562
end
563
+
564
+ -- If last player ship is destroyed, the Humans (players) lose.
565
+ if player_count == 0 then
566
+ victory (" Kraylor" )
567
+ local text = _ (" Mission: FAILED (all your ships destroyed)" )
568
+ globalMessage (text )
569
+ setBanner (text )
570
+ return
571
+ end
572
+
573
+ -- Set banner for cinematic and top down views.
574
+ if gametimeleft ~= nil then
575
+ setBanner (string.format (_ (" Mission in progress - Time left: %d:%02d - Enemies: %d" ), math.floor (gametimeleft / 60 ), math.floor (gametimeleft % 60 ), enemy_count ))
576
+ end
411
577
end
0 commit comments