REM This is an example of a more complex program, which spawns procedural waves. REM The waves become progressively harder, and the wave delay is controlled by `cell1[0]` LET wave = 0 LET timeout = @time + 120000 DO LET remaining = timeout - @time PRINT "[red]Enemies[white] approaching: " PRINT ceil(remaining / 1000), " s" PRINT_FLUSH_GLOBAL(mission) wait(0.5) LOOP WHILE remaining > 0 WHILE true wave = wave + 1 READ(difficulty, cell1, 3) difficulty = difficulty - 1 LET progression_mult = 5 - difficulty / 2 LET units_mult = 0.5 + difficulty / 2 LET max_progression = 8 + difficulty * 2 LET progression = POW(wave / progression_mult, 0.75) REM TODO: optimize duplicate operations progression = MIN(progression / 2 + rand(progression / 2), max_progression) LET units = 2 + SQRT(progression) * 4 + RAND(progression * 2) units = MIN(CEIL(units * units_mult), 20) LET tank_units = FLOOR(RAND(units)) LET mech_units = FLOOR(RAND(units - tank_units)) LET air_units = units - tank_units - mech_units LET spawnx = 30 LET spawnairx = 30 LET spawny = 50 GOSUB spawn_tank GOSUB spawn_mech GOSUB spawn_air WRITE(wave, cell1, 1) READ(timeout, cell1, 0) timeout = @time + timeout * 1000 DO LET remaining = timeout - @time PRINT "[yellow]Wave ", wave, "[white] - " PRINT "Next wave: ", ceil(remaining / 1000), " s" PRINT_FLUSH_GLOBAL(mission) wait(0.5) LOOP WHILE remaining > 0 WEND spawn_tank: FOR spawned = 1 TO tank_units LET roll = rand(progression) IF roll >= 3 THEN IF roll >= 4 THEN SPAWN(@conquer, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 5.75 ELSE SPAWN(@vanquish, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 3.5 END IF ELSE IF roll >= 2 THEN SPAWN(@precept, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 3.25 ELSE REM Small units can unclump easily IF roll >= 1 THEN SPAWN(@locus, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 1.0 ELSE SPAWN(@stell, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 1.0 END IF END IF END IF IF spawnx < 10 THEN spawnx = 10 END IF NEXT spawned RETURN spawn_mech: FOR spawned = 1 TO mech_units LET roll = rand(progression) IF roll >= 3 THEN IF roll >= 4 THEN SPAWN(@collaris, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 5.5 ELSE SPAWN(@tecta, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 2.87 END IF ELSE IF roll >= 2 THEN SPAWN(@anthicus, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 2.62 ELSE IF roll >= 1 THEN SPAWN(@cleroi, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 1.0 ELSE SPAWN(@merui, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 1.0 END IF END IF END IF IF spawnx < 10 THEN spawnx = 10 END IF NEXT spawned RETURN spawn_air: FOR spawned = 1 TO air_units LET roll = rand(progression) IF roll >= 3 THEN IF roll >= 4 THEN SPAWN(@disrupt, spawnairx, spawny, 0, @crux, _) spawnairx = spawnairx - 5.75 ELSE SPAWN(@quell, spawnairx, spawny, 0, @crux, _) spawnairx = spawnairx - 4.5 END IF ELSE IF roll >= 2 THEN SPAWN(@obviate, spawnairx, spawny, 0, @crux, _) spawnairx = spawnairx - 3.12 ELSE IF roll >= 1 THEN SPAWN(@avert, spawnairx, spawny, 0, @crux, _) spawnairx = spawnairx - 1 ELSE REM The elude is the only non-air unit SPAWN(@elude, spawnx, spawny, 0, @crux, _) spawnx = spawnx - 1 END IF END IF END IF IF spawnx < 10 THEN spawnx = 10 END IF IF spawnairx < 5 THEN spawnairx = 5 END IF NEXT spawned RETURN