1-- Name: Chaos of War 2-- Description: Two, three or four species battle for ultimate dominion. Designed as a replayable player versus player (PVP) scenario for individuals or teams. Terrain is randomly symmetrically generated for every game. Use GM screen to adjust parameters 3--- 4--- Version 1 (debuted 23Jan2021 for online event) 5-- Type: Player vs Player with or without teams 6-- Variation[Easy]: More resources, services and reputation 7-- Variation[Hard]: Fewer resources, services and reputation 8 9-------------------------------------------------------------------------------------------------------- 10-- Note: This script requires a version of supply_drop.lua that handles the variable jump_freighter -- 11-- See pull request 1185 -- 12-------------------------------------------------------------------------------------------------------- 13 14require "utils.lua" 15 16function init() 17 scenario_version = "1.0.1" 18 print(string.format("Scenario version %s",scenario_version)) 19 print(_VERSION) 20 setVariations() 21 setConstants() 22 setStaticScienceDatabase() 23 setGMButtons() 24end 25function setVariations() 26 local svs = getScenarioVariation() --scenario variation string 27 if string.find(svs,"Easy") then 28 difficulty = .5 29 base_reputation = 50 30 elseif string.find(svs,"Hard") then 31 difficulty = 2 32 base_reputation = 10 33 else 34 difficulty = 1 --default (normal) 35 base_reputation = 20 36 end 37end 38function setConstants() 39 thresh = .2 --leading/trailing completion threshold percentage for game 40 game_time_limit = 45*60 -- Time limit for game; measured in seconds (example: 45*60 = 45 minutes) 41 max_game_time = game_time_limit 42 game_state = "paused" --then moves to "terrain generated" then to "running" 43 respawn_count = 0 44 respawn_type = "lindworm" 45 storage = getScriptStorage() 46 storage.gatherStats = gatherStats 47 player_team_count = 2 --default to 2. Can be 2, 3 or 4 48 ships_per_team = 2 --default to 2. Max varies based on team count 49 max_ships_per_team = {32,16,10,8} --engine supports 32 player ships 50 f2s = { --faction name to short name 51 ["Human Navy"] = "human", 52 ["Kraylor"] = "kraylor", 53 ["Exuari"] = "exuari", 54 ["Ktlitans"] = "ktlitan", 55 } 56 terrain_generated = false 57 generate_terrain_message_counter = 0 58 missile_availability = "unlimited" 59 defense_platform_count_index = 10 60 defense_platform_count_options = { 61 {count = 0, distance = 0, player = 4500}, 62 {count = 3, distance = 2000, player = 2500}, 63 {count = 4, distance = 2400, player = 3000}, 64 {count = 5, distance = 3000, player = 3500}, 65 {count = 6, distance = 4300, player = 2500}, 66 {count = 8, distance = 7000, player = 4000}, 67 {count = 9, distance = 7800, player = 4500}, 68 {count = 10, distance = 9000, player = 4000}, 69 {count = 12, distance = 10000, player = 4500}, 70 {count = "random", distance = 0, player = 0}, 71 } 72 dp_comms_data = { --defense platform comms data 73 weapon_available = { 74 Homing = random(1,13)<=(3-difficulty), 75 HVLI = random(1,13)<=(6-difficulty), 76 Mine = false, 77 Nuke = false, 78 EMP = false, 79 }, 80 services = { 81 supplydrop = "friend", 82 reinforcements = "friend", 83 jumpsupplydrop = "friend", 84 }, 85 service_cost = { 86 supplydrop = math.random(80,120), 87 reinforcements = math.random(125,175), 88 jumpsupplydrop = math.random(110,140), 89 }, 90 jump_overcharge = false, 91 probe_launch_repair = random(1,13)<=(3-difficulty), 92 hack_repair = random(1,13)<=(3-difficulty), 93 scan_repair = random(1,13)<=(3-difficulty), 94 combat_maneuver_repair= random(1,13)<=(3-difficulty), 95 self_destruct_repair = random(1,13)<=(3-difficulty), 96 tube_slow_down_repair = random(1,13)<=(3-difficulty), 97 reputation_cost_multipliers = { 98 friend = 1.0, 99 neutral = 3.0, 100 }, 101 goods = {}, 102 trade = {}, 103 } 104 defense_fleet_list = { 105 ["Small Station"] = { 106 {DF1 = "MT52 Hornet",DF2 = "MU52 Hornet",DF3 = "MT52 Hornet",DF4 = "MU52 Hornet",}, 107 {DF1 = "MT52 Hornet",DF2 = "MT52 Hornet",DF3 = "MT52 Hornet",DF4 = "MU52 Hornet",}, 108 {DF1 = "MT52 Hornet",DF2 = "MU52 Hornet",DF3 = "MU52 Hornet",DF4 = "Nirvana R5A",}, 109 }, 110 ["Medium Station"] = { 111 {DF1 = "Adder MK5",DF2 = "MU52 Hornet",DF3 = "MT52 Hornet",DF4 = "Adder MK4",DF5 = "Adder MK6",}, 112 {DF1 = "Adder MK5",DF2 = "MU52 Hornet",DF3 = "Nirvana R5A",DF4 = "Adder MK4",DF5 = "Adder MK6",}, 113 {DF1 = "Adder MK5",DF2 = "MU52 Hornet",DF3 = "Nirvana R5A",DF4 = "WX-Lindworm",DF5 = "Adder MK6",}, 114 }, 115 ["Large Station"] = { 116 {DF1 = "Adder MK5",DF2 = "MU52 Hornet",DF3 = "MT52 Hornet",DF4 = "Adder MK4",DF5 = "Adder MK6",DF6 = "Phobos T3",DF7 = "Adder MK7",DF8 = "Adder MK8",}, 117 {DF1 = "Adder MK5",DF2 = "MU52 Hornet",DF3 = "Adder MK9",DF4 = "Adder MK4",DF5 = "Adder MK6",DF6 = "Phobos T3",DF7 = "Adder MK7",DF8 = "Adder MK8",}, 118 {DF1 = "Adder MK5",DF2 = "MU52 Hornet",DF3 = "Nirvana R5A",DF4 = "Adder MK4",DF5 = "Adder MK6",DF6 = "Phobos T3",DF7 = "Adder MK7",DF8 = "Adder MK8",}, 119 }, 120 ["Huge Station"] = { 121 {DF1 = "Adder MK5",DF2 = "MU52 Hornet",DF3 = "MT52 Hornet",DF4 = "Adder MK4",DF5 = "Adder MK6",DF6 = "Phobos T3",DF7 = "Adder MK7",DF8 = "Adder MK8",DF9 = "Fiend G4",DF10 = "Stalker R7",DF11 = "Stalker Q7"}, 122 {DF1 = "Adder MK5",DF2 = "MU52 Hornet",DF3 = "Nirvana R5A",DF4 = "Adder MK4",DF5 = "Adder MK6",DF6 = "Phobos T3",DF7 = "Adder MK7",DF8 = "Adder MK8",DF9 = "Fiend G4",DF10 = "Stalker R7",DF11 = "Stalker Q7"}, 123 {DF1 = "Adder MK5",DF2 = "MU52 Hornet",DF3 = "Phobos T3",DF4 = "Adder MK4",DF5 = "Adder MK6",DF6 = "Phobos T3",DF7 = "Adder MK7",DF8 = "Adder MK8",DF9 = "Fiend G4",DF10 = "Stalker R7",DF11 = "Stalker Q7"}, 124 }, 125 } 126 station_list = {} 127 station_sensor_range = 20000 128 primary_station_size_index = 1 129 primary_station_size_options = {"random","Small Station","Medium Station","Large Station","Huge Station"} 130 primary_jammers = "random" 131 player_ship_types = "default" 132 custom_player_ship_type = "Heavy" 133 default_player_ship_sets = { 134 {"Crucible"}, 135 {"Maverick","Flavia P.Falcon"}, 136 {"Atlantis","Phobos M3P","Crucible"}, 137 {"Atlantis","Maverick","Phobos M3P","Flavia P.Falcon"}, 138 {"Atlantis","Player Cruiser","Maverick","Crucible","Phobos M3P"}, 139 {"Atlantis","Hathcock","Flavia P.Falcon","Player Missile Cr.","Maverick","Phobos M3P"}, 140 {"Atlantis","Repulse","Maverick","Player Missile Cr.","Phobos M3P","Flavia P.Falcon","Crucible"}, 141 {"Atlantis","Player Cruiser","Hathcock","Player Fighter","Phobos M3P","Maverick","Crucible","Flavia P.Falcon"}, 142 {"Atlantis","Player Cruiser","Repulse","Player Missile Cr.","Player Fighter","Phobos M3P","Crucible","Flavia P.Falcon","Maverick"}, 143 {"Atlantis","Player Cruiser","Piranha","Player Missile Cr.","Player Fighter","Phobos M3P","Crucible","Flavia P.Falcon","Maverick","Phobos M3P"}, 144 {"Atlantis","Player Cruiser","Hathcock","Repulse","Player Fighter","Player Missile Cr.","Crucible","Flavia P.Falcon","Maverick","Phobos M3P","Flavia P.Falcon"}, 145 {"Atlantis","Player Cruiser","Piranha","Repulse","Player Fighter","Player Missile Cr.","Crucible","Flavia P.Falcon","Maverick","Phobos M3P","Flavia P.Falcon","Phobos M3P"}, 146 {"Atlantis","Player Cruiser","Piranha","Hathcock","Player Fighter","Player Missile Cr.","Crucible","Flavia P.Falcon","Maverick","Phobos M3P","Flavia P.Falcon","Phobos M3P","Crucible"}, 147 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Player Missile Cr.","Crucible","Flavia P.Falcon","Maverick","Phobos M3P","Flavia P.Falcon","Phobos M3P","Crucible","Player Fighter"}, 148 {"Atlantis","Player Cruiser","Hathcock","Repulse","Nautilus","Player Missile Cr.","Crucible","Flavia P.Falcon","Maverick","Phobos M3P","Flavia P.Falcon","Phobos M3P","Crucible","Player Fighter","MP52 Hornet"}, 149 {"Atlantis","Player Cruiser","Nautilus","Repulse","Piranha","Player Missile Cr.","Crucible","Flavia P.Falcon","Maverick","Phobos M3P","Flavia P.Falcon","Phobos M3P","Crucible","Player Fighter","MP52 Hornet","Maverick"}, 150 } 151 custom_player_ship_sets = { 152 ["Jump"] = { 153 {"Atlantis"}, 154 {"Atlantis","Player Cruiser"}, 155 {"Atlantis","Player Cruiser","Hathcock"}, 156 {"Atlantis","Player Cruiser","Hathcock","Repulse"}, 157 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha"}, 158 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus"}, 159 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus","Repulse"}, 160 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus","Repulse","Player Cruiser"}, 161 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus","Repulse","Player Cruiser","Piranha"}, 162 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus","Repulse","Player Cruiser","Piranha","Atlantis"}, 163 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus","Repulse","Player Cruiser","Piranha","Atlantis","Nautilus"}, 164 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus","Repulse","Player Cruiser","Piranha","Atlantis","Nautilus","Hathcock"}, 165 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus","Repulse","Player Cruiser","Piranha","Atlantis","Nautilus","Hathcock","Atlantis"}, 166 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus","Repulse","Player Cruiser","Piranha","Atlantis","Nautilus","Hathcock","Atlantis","Player Cruiser"}, 167 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus","Repulse","Player Cruiser","Piranha","Atlantis","Nautilus","Hathcock","Atlantis","Player Cruiser","Piranha"}, 168 {"Atlantis","Player Cruiser","Hathcock","Repulse","Piranha","Nautilus","Repulse","Player Cruiser","Piranha","Atlantis","Nautilus","Hathcock","Atlantis","Player Cruiser","Piranha","Hathcock"}, 169 }, 170 ["Warp"] = { 171 {"Crucible"}, 172 {"Crucible","Maverick"}, 173 {"Crucible","Maverick","Phobos M3P"}, 174 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon"}, 175 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet"}, 176 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr."}, 177 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr.","Maverick"}, 178 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr.","Maverick","Phobos M3P"}, 179 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr.","Maverick","Phobos M3P","Crucible"}, 180 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr.","Maverick","Phobos M3P","Crucible","MP52 Hornet"}, 181 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr.","Maverick","Phobos M3P","Crucible","MP52 Hornet","Player Missile Cr."}, 182 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr.","Maverick","Phobos M3P","Crucible","MP52 Hornet","Player Missile Cr.","Flavia P.Falcon"}, 183 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr.","Maverick","Phobos M3P","Crucible","MP52 Hornet","Player Missile Cr.","Flavia P.Falcon","Player Missile Cr."}, 184 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr.","Maverick","Phobos M3P","Crucible","MP52 Hornet","Player Missile Cr.","Flavia P.Falcon","Player Missile Cr.","Maverick"}, 185 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr.","Maverick","Phobos M3P","Crucible","MP52 Hornet","Player Missile Cr.","Flavia P.Falcon","Player Missile Cr.","Maverick","Crucible"}, 186 {"Crucible","Maverick","Phobos M3P","Flavia P.Falcon","MP52 Hornet","Player Missile Cr.","Maverick","Phobos M3P","Crucible","MP52 Hornet","Player Missile Cr.","Flavia P.Falcon","Player Missile Cr.","Maverick","Crucible","Phobos M3P"}, 187 }, 188 ["Heavy"] = { 189 {"Maverick"}, 190 {"Maverick","Crucible"}, 191 {"Maverick","Crucible","Atlantis"}, 192 {"Maverick","Crucible","Atlantis","Player Missile Cr."}, 193 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser"}, 194 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha"}, 195 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha","Maverick"}, 196 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha","Maverick","Player Missile Cr."}, 197 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha","Maverick","Player Missile Cr.","Atlantis"}, 198 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha","Maverick","Player Missile Cr.","Atlantis","Crucible"}, 199 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha","Maverick","Player Missile Cr.","Atlantis","Crucible","Player Cruiser"}, 200 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha","Maverick","Player Missile Cr.","Atlantis","Crucible","Player Cruiser","Piranha"}, 201 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha","Maverick","Player Missile Cr.","Atlantis","Crucible","Player Cruiser","Piranha","Crucible"}, 202 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha","Maverick","Player Missile Cr.","Atlantis","Crucible","Player Cruiser","Piranha","Crucible","Atlantis"}, 203 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha","Maverick","Player Missile Cr.","Atlantis","Crucible","Player Cruiser","Piranha","Crucible","Atlantis","Maverick"}, 204 {"Maverick","Crucible","Atlantis","Player Missile Cr.","Player Cruiser","Piranha","Maverick","Player Missile Cr.","Atlantis","Crucible","Player Cruiser","Piranha","Crucible","Atlantis","Maverick","Player Missile Cr."}, 205 }, 206 ["Light"] = { 207 {"Phobos M3P"}, 208 {"Phobos M3P","MP52 Hornet"}, 209 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon"}, 210 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock"}, 211 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus"}, 212 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse"}, 213 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse","Flavia P. Falcon"}, 214 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse","Flavia P. Falcon","MP52 Hornet"}, 215 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse","Flavia P. Falcon","MP52 Hornet","Phobos M3P"}, 216 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse","Flavia P. Falcon","MP52 Hornet","Phobos M3P","Repulse"}, 217 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse","Flavia P. Falcon","MP52 Hornet","Phobos M3P","Repulse","Hathcock"}, 218 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse","Flavia P. Falcon","MP52 Hornet","Phobos M3P","Repulse","Hathcock","Nautilus"}, 219 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse","Flavia P. Falcon","MP52 Hornet","Phobos M3P","Repulse","Hathcock","Nautilus","Flavia P. Falcon"}, 220 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse","Flavia P. Falcon","MP52 Hornet","Phobos M3P","Repulse","Hathcock","Nautilus","Flavia P. Falcon","Phobos M3P"}, 221 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse","Flavia P. Falcon","MP52 Hornet","Phobos M3P","Repulse","Hathcock","Nautilus","Flavia P. Falcon","Phobos M3P","MP52 Hornet"}, 222 {"Phobos M3P","MP52 Hornet","Flavia P.Falcon","Hathcock","Nautilus","Repulse","Flavia P. Falcon","MP52 Hornet","Phobos M3P","Repulse","Hathcock","Nautilus","Flavia P. Falcon","Phobos M3P","MP52 Hornet","Repulse"}, 223 }, 224 ["Custom"] = { 225 {"Holmes"}, 226 {"Holmes","Phobos T2"}, 227 {"Holmes","Phobos T2","Striker LX"}, 228 {"Holmes","Phobos T2","Striker LX","Maverick XP"}, 229 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus"}, 230 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse"}, 231 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse","Flavia P. Falcon"}, 232 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse","Flavia P. Falcon","Player Fighter"}, 233 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse","Flavia P. Falcon","Player Fighter","Phobos M3P"}, 234 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse","Flavia P. Falcon","Player Fighter","Phobos M3P","Repulse"}, 235 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse","Flavia P. Falcon","Player Fighter","Phobos M3P","Repulse","Hathcock"}, 236 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse","Flavia P. Falcon","Player Fighter","Phobos M3P","Repulse","Hathcock","Nautilus"}, 237 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse","Flavia P. Falcon","Player Fighter","Phobos M3P","Repulse","Hathcock","Nautilus","Flavia P. Falcon"}, 238 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse","Flavia P. Falcon","Player Fighter","Phobos M3P","Repulse","Hathcock","Nautilus","Flavia P. Falcon","Phobos M3P"}, 239 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse","Flavia P. Falcon","Player Fighter","Phobos M3P","Repulse","Hathcock","Nautilus","Flavia P. Falcon","Phobos M3P","MP52 Hornet"}, 240 {"Holmes","Phobos T2","Striker LX","Maverick XP","Focus","Repulse","Flavia P. Falcon","Player Fighter","Phobos M3P","Repulse","Hathcock","Nautilus","Flavia P. Falcon","Phobos M3P","MP52 Hornet","Repulse"}, 241 } 242 } 243 rwc_player_ship_names = { --rwc: random within category 244 ["Atlantis"] = {"Formidable","Thrasher","Punisher","Vorpal","Protang","Drummond","Parchim","Coronado"}, 245 ["Benedict"] = {"Elizabeth","Ford","Avenger","Washington","Lincoln","Garibaldi","Eisenhower"}, 246 ["Crucible"] = {"Sling", "Stark", "Torrid", "Kicker", "Flummox"}, 247 ["Ender"] = {"Mongo","Godzilla","Leviathan","Kraken","Jupiter","Saturn"}, 248 ["Flavia P.Falcon"] = {"Ladyhawke","Hunter","Seeker","Gyrefalcon","Kestrel","Magpie","Bandit","Buccaneer"}, 249 ["Hathcock"] = {"Hayha", "Waldron", "Plunkett", "Mawhinney", "Furlong", "Zaytsev", "Pavlichenko", "Fett", "Hawkeye", "Hanzo"}, 250 ["Kiriya"] = {"Cavour","Reagan","Gaulle","Paulo","Truman","Stennis","Kuznetsov","Roosevelt","Vinson","Old Salt"}, 251 ["MP52 Hornet"] = {"Dragonfly","Scarab","Mantis","Yellow Jacket","Jimminy","Flik","Thorny","Buzz"}, 252 ["Maverick"] = {"Angel", "Thunderbird", "Roaster", "Magnifier", "Hedge"}, 253 ["Nautilus"] = {"October", "Abdiel", "Manxman", "Newcon", "Nusret", "Pluton", "Amiral", "Amur", "Heinkel", "Dornier"}, 254 ["Phobos M3P"] = {"Blinder","Shadow","Distortion","Diemos","Ganymede","Castillo","Thebe","Retrograde"}, 255 ["Piranha"] = {"Razor","Biter","Ripper","Voracious","Carnivorous","Characid","Vulture","Predator"}, 256 ["Player Cruiser"] = {"Excelsior","Velociraptor","Thunder","Kona","Encounter","Perth","Aspern","Panther"}, 257 ["Player Fighter"] = {"Buzzer","Flitter","Zippiticus","Hopper","Molt","Stinger","Stripe"}, 258 ["Player Missile Cr."] = {"Projectus","Hurlmeister","Flinger","Ovod","Amatola","Nakhimov","Antigone"}, 259 ["Repulse"] = {"Fiddler","Brinks","Loomis","Mowag","Patria","Pandur","Terrex","Komatsu","Eitan"}, 260 ["Striker"] = {"Sparrow","Sizzle","Squawk","Crow","Phoenix","Snowbird","Hawk"}, 261 ["ZX-Lindworm"] = {"Seagull","Catapult","Blowhard","Flapper","Nixie","Pixie","Tinkerbell"}, 262 ["Unknown"] = {"Foregone","Righteous","Masher","Lancer","Horizon","Osiris","Athena","Poseidon","Heracles","Constitution","Stargazer","Horatio","Socrates","Galileo","Newton","Beethoven","Rabin","Spector","Akira","Thunderchild","Ambassador","Adelphi","Exeter","Ghandi","Valdemar","Yamaguchi","Zhukov","Andromeda","Drake","Prokofiev","Antares","Apollo","Ajax","Clement","Bradbury","Gage","Buran","Kearsarge","Cheyenne","Ahwahnee","Constellation","Gettysburg","Hathaway","Magellan","Farragut","Kongo","Lexington","Potempkin","Yorktown","Daedalus","Archon","Carolina","Essex","Danube","Gander","Ganges","Mekong","Orinoco","Rubicon","Shenandoah","Volga","Yangtzee Kiang","Yukon","Valiant","Deneva","Arcos","LaSalle","Al-Batani","Cairo","Charlseton","Crazy Horse","Crockett","Fearless","Fredrickson","Gorkon","Hood","Lakota","Malinche","Melbourne","Freedom","Concorde","Firebrand","Galaxy","Challenger","Odyssey","Trinculo","Venture","Yamato","Hokule'a","Tripoli","Hope","Nobel","Pasteur","Bellerophon","Voyager","Istanbul","Constantinople","Havana","Sarajevo","Korolev","Goddard","Luna","Titan","Mediterranean","Lalo","Wyoming","Merced","Trieste","Miranda","Brattain","Helin","Lantree","Majestic","Reliant","Saratoga","ShirKahr","Sitak","Tian An Men","Trial","Nebula","Bonchune","Capricorn","Hera","Honshu","Interceptor","Leeds","Merrimack","Prometheus","Proxima","Sutherland","T'Kumbra","Ulysses","New Orleans","Kyushu","Renegade","Rutledge","Thomas Paine","Niagra","Princeton","Wellington","Norway","Budapest","Nova","Equinox","Rhode Island","Columbia","Oberth","Biko","Cochraine","Copernicus","Grissom","Pegasus","Raman","Yosemite","Renaissance","Aries","Maryland","Rigel","Akagi","Tolstoy","Yeager","Sequoia","Sovereign","Soyuz","Bozeman","Springfield","Chekov","Steamrunner","Appalachia","Surak","Zapata","Sydney","Jenolen","Nash","Wambundu","Fleming","Wells","Relativity","Yorkshire","Denver","Zodiac","Centaur","Cortez","Republic","Peregrine","Calypso","Cousteau","Waverider","Scimitar"}, 263 } 264 player_ship_stats = { 265 ["Atlantis"] = { strength = 52, cargo = 6, distance = 400, long_range_radar = 30000, short_range_radar = 5000, probes = 10, long_jump = 50, short_jump = 5, warp = 0, stock = true, }, 266 ["Benedict"] = { strength = 10, cargo = 9, distance = 400, long_range_radar = 30000, short_range_radar = 5000, probes = 10, long_jump = 90, short_jump = 5, warp = 0, stock = true, }, 267 ["Crucible"] = { strength = 45, cargo = 5, distance = 200, long_range_radar = 20000, short_range_radar = 6000, probes = 9, long_jump = 0, short_jump = 0, warp = 750, stock = true, }, 268 ["Ender"] = { strength = 100, cargo = 20, distance = 2000,long_range_radar = 45000, short_range_radar = 7000, probes = 12, long_jump = 50, short_jump = 5, warp = 0, stock = true, }, 269 ["Flavia P.Falcon"] = { strength = 13, cargo = 15, distance = 200, long_range_radar = 40000, short_range_radar = 5000, probes = 8, long_jump = 0, short_jump = 0, warp = 500, stock = true, }, 270 ["Hathcock"] = { strength = 30, cargo = 6, distance = 200, long_range_radar = 35000, short_range_radar = 6000, probes = 8, long_jump = 60, short_jump = 6, warp = 0, stock = true, }, 271 ["Kiriya"] = { strength = 10, cargo = 9, distance = 400, long_range_radar = 35000, short_range_radar = 5000, probes = 10, long_jump = 0, short_jump = 0, warp = 750, stock = true, }, 272 ["Maverick"] = { strength = 45, cargo = 5, distance = 200, long_range_radar = 20000, short_range_radar = 4000, probes = 9, long_jump = 0, short_jump = 0, warp = 800, stock = true, }, 273 ["MP52 Hornet"] = { strength = 7, cargo = 3, distance = 100, long_range_radar = 18000, short_range_radar = 4000, probes = 5, long_jump = 0, short_jump = 0, warp = 1000, stock = true, }, 274 ["Nautilus"] = { strength = 12, cargo = 7, distance = 200, long_range_radar = 22000, short_range_radar = 4000, probes = 10, long_jump = 70, short_jump = 5, warp = 0, stock = true, }, 275 ["Phobos M3P"] = { strength = 19, cargo = 10, distance = 200, long_range_radar = 25000, short_range_radar = 5000, probes = 6, long_jump = 0, short_jump = 0, warp = 900, stock = true, }, 276 ["Piranha"] = { strength = 16, cargo = 8, distance = 200, long_range_radar = 25000, short_range_radar = 6000, probes = 6, long_jump = 50, short_jump = 5, warp = 0, stock = true, }, 277 ["Player Cruiser"] = { strength = 40, cargo = 6, distance = 400, long_range_radar = 30000, short_range_radar = 5000, probes = 10, long_jump = 80, short_jump = 5, warp = 0, stock = true, }, 278 ["Player Missile Cr."] = { strength = 45, cargo = 8, distance = 200, long_range_radar = 35000, short_range_radar = 6000, probes = 9, long_jump = 0, short_jump = 0, warp = 800, stock = true, }, 279 ["Player Fighter"] = { strength = 7, cargo = 3, distance = 100, long_range_radar = 15000, short_range_radar = 4500, probes = 4, long_jump = 40, short_jump = 3, warp = 0, stock = true, }, 280 ["Repulse"] = { strength = 14, cargo = 12, distance = 200, long_range_radar = 38000, short_range_radar = 5000, probes = 8, long_jump = 50, short_jump = 5, warp = 0, stock = true, }, 281 ["Striker"] = { strength = 8, cargo = 4, distance = 200, long_range_radar = 35000, short_range_radar = 5000, probes = 6, long_jump = 40, short_jump = 3, warp = 0, stock = true, }, 282 ["ZX-Lindworm"] = { strength = 8, cargo = 3, distance = 100, long_range_radar = 18000, short_range_radar = 5500, probes = 4, long_jump = 0, short_jump = 0, warp = 950, stock = true, }, 283 -- Stock above, custom below 284 ["Focus"] = { strength = 35, cargo = 4, distance = 200, long_range_radar = 32000, short_range_radar = 5000, probes = 8, long_jump = 25, short_jump = 2.5, warp = 0, stock = false, }, 285 ["Holmes"] = { strength = 35, cargo = 6, distance = 200, long_range_radar = 35000, short_range_radar = 4000, probes = 8, long_jump = 0, short_jump = 0, warp = 750, stock = false, }, 286 ["Maverick XP"] = { strength = 23, cargo = 5, distance = 200, long_range_radar = 25000, short_range_radar = 7000, probes = 10, long_jump = 20, short_jump = 2, warp = 0, stock = false, }, 287 ["Phobos T2"] = { strength = 19, cargo = 9, distance = 200, long_range_radar = 25000, short_range_radar = 5000, probes = 5, long_jump = 25, short_jump = 2, warp = 0, stock = false, }, 288 ["Striker LX"] = { strength = 16, cargo = 4, distance = 200, long_range_radar = 20000, short_range_radar = 4000, probes = 7, long_jump = 20, short_jump = 2, warp = 0, stock = false, }, 289 } 290 npc_ships = false 291 npc_lower = 30 292 npc_upper = 60 293 scientist_list = {} 294 scientist_count = 0 295 scientist_score_value = 10 296 scientist_names = { --fictional 297 "Gertrude Goodall", 298 "John Kruger", 299 "Lisa Forsythe", 300 "Ethan Williams", 301 "Ameilia Martinez", 302 "Felix Mertens", 303 "Marie Novak", 304 "Mathias Evans", 305 "Clara Heikkinen", 306 "Vicente Martin", 307 "Catalina Fischer", 308 "Marek Varga", 309 "Ewa Olsen", 310 "Oscar Stewart", 311 "Alva Rodriguez", 312 "Aiden Johansson", 313 "Zoey Smith", 314 "Jorge Romero", 315 "Rosa Wong", 316 "Julian Acharya", 317 "Hannah Ginting", 318 "Anton Dewala", 319 "Camille Silva", 320 "Aleksi Gideon", 321 "Ella Dasgupta", 322 "Gunnar Smirnov", 323 "Telma Lozano", 324 "Kaito Fabroa", 325 "Misaki Kapia", 326 "Ronald Sanada", 327 "Janice Tesfaye", 328 "Alvaro Hassan", 329 "Valeria Dinh", 330 "Sergei Mokri", 331 "Yulia Karga", 332 "Arnav Dixon", 333 "Sanvi Saetan", 334 } 335 scientist_topics = { 336 "Mathematics", 337 "Miniaturization", 338 "Exotic materials", 339 "Warp theory", 340 "Particle theory", 341 "Power systems", 342 "Energy fields", 343 "Subatomic physics", 344 "Stellar phenomena", 345 "Gravity dynamics", 346 "Information science", 347 "Computer protocols", 348 } 349 upgrade_requirements = { 350 "talk", --talk 351 "talk primary", --talk then upgrade at primary station 352 "meet", --meet 353 "meet primary", --meet then upgrade at primary station 354 "transport", --transport to primary station 355 "confer", --transport to primary station, then confer with another scientist 356 } 357 upgrade_list = { 358 {action = hullStrengthUpgrade, name = "hull strength upgrade"}, 359 {action = shieldStrengthUpgrade, name = "shield strength upgrade"}, 360 {action = missileLoadSpeedUpgrade, name = "missile load speed upgrade"}, 361 {action = beamDamageUpgrade, name = "beam damage upgrade"}, 362 {action = beamRangeUpgrade, name = "beam range upgrade"}, 363 {action = batteryEfficiencyUpgrade, name = "battery efficiency upgrade"}, 364 {action = fasterImpulseUpgrade, name = "faster impulse upgrade"}, 365 {action = longerSensorsUpgrade, name = "longer sensor range upgrade"}, 366 {action = fasterSpinUpgrade, name = "faster maneuvering speed upgrade"}, 367 } 368 upgrade_automated_applications = { 369 "single", --automatically applied only to the player that completed the requirements 370 "players", --automatically applied to allied players 371 "all", --automatically applied to players and NPCs (where applicable) 372 } 373 prefix_length = 0 374 suffix_index = 0 375 formation_delta = { 376 ["square"] = { 377 x = {0,1,0,-1, 0,1,-1, 1,-1,2,0,-2, 0,2,-2, 2,-2,2, 2,-2,-2,1,-1, 1,-1,0, 0,3,-3,1, 1,3,-3,-1,-1, 3,-3,2, 2,3,-3,-2,-2, 3,-3,3, 3,-3,-3,4,0,-4, 0,4,-4, 4,-4,-4,-4,-4,-4,-4,-4,4, 4,4, 4,4, 4, 1,-1, 2,-2, 3,-3,1,-1,2,-2,3,-3,5,-5,0, 0,5, 5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,5, 5,5, 5,5, 5,5, 5, 1,-1, 2,-2, 3,-3, 4,-4,1,-1,2,-2,3,-3,4,-4}, 378 y = {0,0,1, 0,-1,1,-1,-1, 1,0,2, 0,-2,2,-2,-2, 2,1,-1, 1,-1,2, 2,-2,-2,3,-3,0, 0,3,-3,1, 1, 3,-3,-1,-1,3,-3,2, 2, 3,-3,-2,-2,3,-3, 3,-3,0,4, 0,-4,4,-4,-4, 4, 1,-1, 2,-2, 3,-3,1,-1,2,-2,3,-3,-4,-4,-4,-4,-4,-4,4, 4,4, 4,4, 4,0, 0,5,-5,5,-5, 5,-5, 1,-1, 2,-2, 3,-3, 4,-4,1,-1,2,-2,3,-3,4,-4,-5,-5,-5,-5,-5,-5,-5,-5,5, 5,5, 5,5, 5,5, 5}, 379 }, 380 ["hexagonal"] = { 381 x = {0,2,-2,1,-1, 1,-1,4,-4,0, 0,2,-2,-2, 2,3,-3, 3,-3,6,-6,1,-1, 1,-1,3,-3, 3,-3,4,-4, 4,-4,5,-5, 5,-5,8,-8,4,-4, 4,-4,5,5 ,-5,-5,2, 2,-2,-2,0, 0,6, 6,-6,-6,7, 7,-7,-7,10,-10,5, 5,-5,-5,6, 6,-6,-6,7, 7,-7,-7,8, 8,-8,-8,9, 9,-9,-9,3, 3,-3,-3,1, 1,-1,-1,12,-12,6,-6, 6,-6,7,-7, 7,-7,8,-8, 8,-8,9,-9, 9,-9,10,-10,10,-10,11,-11,11,-11,4,-4, 4,-4,2,-2, 2,-2,0, 0}, 382 y = {0,0, 0,1, 1,-1,-1,0, 0,2,-2,2,-2, 2,-2,1,-1,-1, 1,0, 0,3, 3,-3,-3,3,-3,-3, 3,2,-2,-2, 2,1,-1,-1, 1,0, 0,4,-4,-4, 4,3,-3, 3,-3,4,-4, 4,-4,4,-4,2,-2, 2,-2,1,-1, 1,-1, 0, 0,5,-5, 5,-5,4,-4, 4,-4,3,-3, 3,-7,2,-2, 2,-2,1,-1, 1,-1,5,-5, 5,-5,5,-5, 5,-5, 0, 0,6, 6,-6,-6,5, 5,-5,-5,4, 4,-4,-4,3, 3,-3,-3, 2, 2,-2, -2, 1, 1,-1, -1,6, 6,-6,-6,6, 6,-6,-6,6,-6}, 383 }, 384 } 385 fleet_group = { 386 ["adder"] = "Adders", 387 ["Adders"] = "adder", 388 ["missiler"] = "Missilers", 389 ["Missilers"] = "missiler", 390 ["beamer"] = "Beamers", 391 ["Beamers"] = "beamer", 392 ["frigate"] = "Frigates", 393 ["Frigates"] = "frigate", 394 ["chaser"] = "Chasers", 395 ["Chasers"] = "chaser", 396 ["fighter"] = "Fighters", 397 ["Fighters"] = "fighter", 398 ["drone"] = "Drones", 399 ["Drones"] = "drone", 400 } 401 ship_template = { --ordered by relative strength 402 ["Gnat"] = {strength = 2, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = true, unusual = false, base = false, create = gnat}, 403 ["Lite Drone"] = {strength = 3, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = true, unusual = false, base = false, create = droneLite}, 404 ["Jacket Drone"] = {strength = 4, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = true, unusual = false, base = false, create = droneJacket}, 405 ["Ktlitan Drone"] = {strength = 4, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = true, unusual = false, base = false, create = stockTemplate}, 406 ["Heavy Drone"] = {strength = 5, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = true, unusual = false, base = false, create = droneHeavy}, 407 ["Adder MK3"] = {strength = 5, adder = true, missiler = false, beamer = false, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 408 ["MT52 Hornet"] = {strength = 5, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = false, unusual = false, base = false, create = stockTemplate}, 409 ["MU52 Hornet"] = {strength = 5, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = false, unusual = false, base = false, create = stockTemplate}, 410 ["MV52 Hornet"] = {strength = 6, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = false, unusual = false, base = false, create = hornetMV52}, 411 ["Adder MK4"] = {strength = 6, adder = true, missiler = false, beamer = false, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 412 ["Fighter"] = {strength = 6, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = false, unusual = false, base = false, create = stockTemplate}, 413 ["Ktlitan Fighter"] = {strength = 6, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = false, unusual = false, base = false, create = stockTemplate}, 414 ["K2 Fighter"] = {strength = 7, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = false, unusual = false, base = false, create = k2fighter}, 415 ["Adder MK5"] = {strength = 7, adder = true, missiler = false, beamer = false, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 416 ["WX-Lindworm"] = {strength = 7, adder = false, missiler = true, beamer = false, frigate = false, chaser = false, fighter = true, drone = false, unusual = false, base = false, create = stockTemplate}, 417 ["K3 Fighter"] = {strength = 8, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = true, drone = false, unusual = false, base = false, create = k3fighter}, 418 ["Adder MK6"] = {strength = 8, adder = true, missiler = false, beamer = false, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 419 ["Ktlitan Scout"] = {strength = 8, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 420 ["WZ-Lindworm"] = {strength = 9, adder = false, missiler = true, beamer = false, frigate = false, chaser = false, fighter = true, drone = false, unusual = false, base = false, create = wzLindworm}, 421 ["Adder MK7"] = {strength = 9, adder = true, missiler = false, beamer = false, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 422 ["Adder MK8"] = {strength = 10, adder = true, missiler = false, beamer = false, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 423 ["Adder MK9"] = {strength = 11, adder = true, missiler = false, beamer = false, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 424 ["Nirvana R3"] = {strength = 12, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 425 ["Phobos R2"] = {strength = 13, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = phobosR2}, 426 ["Missile Cruiser"] = {strength = 14, adder = false, missiler = true, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 427 ["Waddle 5"] = {strength = 15, adder = true, missiler = false, beamer = false, frigate = false, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = waddle5}, 428 ["Jade 5"] = {strength = 15, adder = true, missiler = false, beamer = false, frigate = false, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = jade5}, 429 ["Phobos T3"] = {strength = 15, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 430 ["Piranha F8"] = {strength = 15, adder = false, missiler = true, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 431 ["Piranha F12"] = {strength = 15, adder = false, missiler = true, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 432 ["Piranha F12.M"] = {strength = 16, adder = false, missiler = true, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 433 ["Phobos M3"] = {strength = 16, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 434 ["Farco 3"] = {strength = 16, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = farco3}, 435 ["Farco 5"] = {strength = 16, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = farco5}, 436 ["Karnack"] = {strength = 17, adder = false, missiler = false, beamer = true, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 437 ["Gunship"] = {strength = 17, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 438 ["Phobos T4"] = {strength = 18, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = phobosT4}, 439 ["Cruiser"] = {strength = 18, adder = true, missiler = false, beamer = true, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 440 ["Nirvana R5"] = {strength = 19, adder = false, missiler = false, beamer = true, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 441 ["Farco 8"] = {strength = 19, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = farco8}, 442 ["Ktlitan Worker"] = {strength = 20, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 443 ["Nirvana R5A"] = {strength = 20, adder = false, missiler = false, beamer = true, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 444 ["Adv. Gunship"] = {strength = 20, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 445 ["Farco 11"] = {strength = 21, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = farco11}, 446 ["Storm"] = {strength = 22, adder = false, missiler = true, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 447 ["Stalker R5"] = {strength = 22, adder = false, missiler = false, beamer = true, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 448 ["Stalker Q5"] = {strength = 22, adder = false, missiler = false, beamer = true, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 449 ["Farco 13"] = {strength = 24, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = farco13}, 450 ["Ranus U"] = {strength = 25, adder = false, missiler = true, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 451 ["Stalker Q7"] = {strength = 25, adder = false, missiler = false, beamer = true, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 452 ["Stalker R7"] = {strength = 25, adder = false, missiler = false, beamer = true, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 453 ["Whirlwind"] = {strength = 26, adder = false, missiler = true, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = whirlwind}, 454 ["Adv. Striker"] = {strength = 27, adder = false, missiler = false, beamer = true, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 455 ["Elara P2"] = {strength = 28, adder = false, missiler = false, beamer = false, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 456 ["Tempest"] = {strength = 30, adder = false, missiler = true, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = tempest}, 457 ["Strikeship"] = {strength = 30, adder = false, missiler = false, beamer = true, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 458 ["Fiend G3"] = {strength = 33, adder = false, missiler = false, beamer = false, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 459 ["Fiend G4"] = {strength = 35, adder = false, missiler = false, beamer = false, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 460 ["Cucaracha"] = {strength = 36, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = cucaracha}, 461 ["Fiend G5"] = {strength = 37, adder = false, missiler = false, beamer = false, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 462 ["Fiend G6"] = {strength = 39, adder = false, missiler = false, beamer = false, frigate = true, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 463 ["Predator"] = {strength = 42, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = predator}, 464 ["Ktlitan Breaker"] = {strength = 45, adder = false, missiler = false, beamer = false, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 465 ["Hurricane"] = {strength = 46, adder = false, missiler = true, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = hurricane}, 466 ["Ktlitan Feeder"] = {strength = 48, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 467 ["Atlantis X23"] = {strength = 50, adder = false, missiler = false, beamer = false, frigate = false, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 468 ["K2 Breaker"] = {strength = 55, adder = false, missiler = false, beamer = false, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = k2breaker}, 469 ["Ktlitan Destroyer"] = {strength = 50, adder = false, missiler = false, beamer = false, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 470 ["Atlantis Y42"] = {strength = 60, adder = false, missiler = false, beamer = false, frigate = false, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = atlantisY42}, 471 ["Blockade Runner"] = {strength = 65, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 472 ["Starhammer II"] = {strength = 70, adder = false, missiler = false, beamer = false, frigate = false, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 473 ["Enforcer"] = {strength = 75, adder = false, missiler = false, beamer = false, frigate = true, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = enforcer}, 474 ["Dreadnought"] = {strength = 80, adder = false, missiler = false, beamer = true, frigate = false, chaser = false, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 475 ["Starhammer III"] = {strength = 85, adder = false, missiler = false, beamer = false, frigate = false, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = starhammerIII}, 476 ["Starhammer V"] = {strength = 90, adder = false, missiler = false, beamer = false, frigate = false, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = starhammerV}, 477 ["Battlestation"] = {strength = 100,adder = false, missiler = false, beamer = true, frigate = false, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 478 ["Tyr"] = {strength = 150,adder = false, missiler = false, beamer = true, frigate = false, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = tyr}, 479 ["Odin"] = {strength = 250,adder = false, missiler = false, beamer = false, frigate = false, chaser = true, fighter = false, drone = false, unusual = false, base = false, create = stockTemplate}, 480 } 481 control_code_stem = { --All control codes must use capital letters or they will not work. 482 "ALWAYS", 483 "BLACK", 484 "BLUE", 485 "BRIGHT", 486 "BROWN", 487 "CHAIN", 488 "CHURCH", 489 "DOORWAY", 490 "DULL", 491 "ELBOW", 492 "EMPTY", 493 "EPSILON", 494 "FLOWER", 495 "FLY", 496 "FROZEN", 497 "GREEN", 498 "GLOW", 499 "HAMMER", 500 "INK", 501 "JUMP", 502 "KEY", 503 "LETTER", 504 "LIST", 505 "MORNING", 506 "NEXT", 507 "OPEN", 508 "ORANGE", 509 "OUTSIDE", 510 "PURPLE", 511 "QUARTER", 512 "QUIET", 513 "RED", 514 "SHINE", 515 "SIGMA", 516 "STAR", 517 "STREET", 518 "TOKEN", 519 "THIRSTY", 520 "UNDER", 521 "VANISH", 522 "WHITE", 523 "WRENCH", 524 "YELLOW", 525 } 526 healthCheckTimerInterval = 10 527 healthCheckTimer = healthCheckTimerInterval 528 commonGoods = {"food","medicine","nickel","platinum","gold","dilithium","tritanium","luxury","cobalt","impulse","warp","shield","tractor","repulsor","beam","optic","robotic","filament","transporter","sensor","communication","autodoc","lifter","android","nanites","software","circuit","battery"} 529 componentGoods = {"impulse","warp","shield","tractor","repulsor","beam","optic","robotic","filament","transporter","sensor","communication","autodoc","lifter","android","nanites","software","circuit","battery"} 530 mineralGoods = {"nickel","platinum","gold","dilithium","tritanium","cobalt"} 531end 532function setStaticScienceDatabase() 533-------------------------------------------------------------------------------------- 534-- Generic station descriptions: text and details from shipTemplates_stations.lua -- 535-------------------------------------------------------------------------------------- 536 local station_db = queryScienceDatabase("Stations") 537 if station_db == nil then 538 station_db = ScienceDatabase():setName("Stations") 539 station_db:setLongDescription("Stations are places for ships to dock, get repaired and replenished, interact with station personnel, etc. They are like oases, service stations, villages, towns, cities, etc.") 540 station_db:addEntry("Small") 541 local small_station_db = queryScienceDatabase("Stations","Small") 542 small_station_db:setLongDescription("Stations of this size are often used as research outposts, listening stations, and security checkpoints. Crews turn over frequently in a small station's cramped accommodatations, but they are small enough to look like ships on many long-range sensors, and organized raiders sometimes take advantage of this by placing small stations in nebulae to serve as raiding bases. They are lightly shielded and vulnerable to swarming assaults.") 543 small_station_db:setImage("radartrace_smallstation.png") 544 small_station_db:setKeyValue("Class","Small") 545 small_station_db:setKeyValue("Size",300) 546 small_station_db:setKeyValue("Shield",300) 547 small_station_db:setKeyValue("Hull",150) 548 station_db:addEntry("Medium") 549 local medium_station_db = queryScienceDatabase("Stations","Medium") 550 medium_station_db:setLongDescription("Large enough to accommodate small crews for extended periods of times, stations of this size are often trading posts, refuelling bases, mining operations, and forward military bases. While their shields are strong, concerted attacks by many ships can bring them down quickly.") 551 medium_station_db:setImage("radartrace_mediumstation.png") 552 medium_station_db:setKeyValue("Class","Medium") 553 medium_station_db:setKeyValue("Size",1000) 554 medium_station_db:setKeyValue("Shield",800) 555 medium_station_db:setKeyValue("Hull",400) 556 station_db:addEntry("Large") 557 local large_station_db = queryScienceDatabase("Stations","Large") 558 large_station_db:setLongDescription("These spaceborne communities often represent permanent bases in a sector. Stations of this size can be military installations, commercial hubs, deep-space settlements, and small shipyards. Only a concentrated attack can penetrate a large station's shields, and its hull can withstand all but the most powerful weaponry.") 559 large_station_db:setImage("radartrace_largestation.png") 560 large_station_db:setKeyValue("Class","Large") 561 large_station_db:setKeyValue("Size",1300) 562 large_station_db:setKeyValue("Shield","1000/1000/1000") 563 large_station_db:setKeyValue("Hull",500) 564 station_db:addEntry("Huge") 565 local huge_station_db = queryScienceDatabase("Stations","Huge") 566 huge_station_db:setLongDescription("The size of a sprawling town, stations at this scale represent a faction's center of spaceborne power in a region. They serve many functions at once and represent an extensive investment of time, money, and labor. A huge station's shields and thick hull can keep it intact long enough for reinforcements to arrive, even when faced with an ongoing siege or massive, perfectly coordinated assault.") 567 huge_station_db:setImage("radartrace_hugestation.png") 568 huge_station_db:setKeyValue("Class","Huge") 569 huge_station_db:setKeyValue("Size",1500) 570 huge_station_db:setKeyValue("Shield","1200/1200/1200/1200") 571 huge_station_db:setKeyValue("Hull",800) 572 end 573----------------------------------------------------------------------------------- 574-- Template ship category descriptions: text from other shipTemplates... files -- 575----------------------------------------------------------------------------------- 576 local ships_db = queryScienceDatabase("Ships") 577 local fighter_db = queryScienceDatabase("Ships","Starfighter") 578 local generic_starfighter_description = "Starfighters are single to 3 person small ships. These are most commonly used as light firepower roles.\nThey are common in larger groups, and need a close by station or support ship, as they lack long time life support.\nIt's rare to see starfighters with more then one shield section.\n\nOne of the most well known starfighters is the X-Wing.\n\nStarfighters come in 3 subclasses:\n* Interceptors: Fast, low on firepower, high on manouverability\n* Gunship: Equipped with more weapons, but trades in manouverability because of it.\n* Bomber: Slowest of all starfighters, but pack a large punch in a small package. Usually come without any lasers, but the largers bombers have been known to deliver nukes." 579 fighter_db:setLongDescription(generic_starfighter_description) 580 local frigate_db = queryScienceDatabase("Ships","Frigate") 581 local generic_frigate_description = "Frigates are one size up from starfighters. They require a crew from 3 to 20 people.\nThink, Firefly, millennium falcon, slave I (Boba fett's ship).\n\nThey generally have 2 or more shield sections, but hardly ever more than 4.\n\nThis class of ships is normally not fitted with jump or warp drives. But in some cases ships are modified to include these, or for certain roles it is built in.\n\nThey are divided in 3 different sub-classes:\n* Cruiser: Weaponized frigates, focused on combat. These come in various roles.\n* Light transport: Small transports, like transporting up to 50 soldiers in spartan conditions or a few diplomats in luxury. Depending on the role it can have some weaponry.\n* Support: Support types come in many varieties. They are simply a frigate hull fitted with whatever was needed. Anything from mine-layers to science vessels." 582 frigate_db:setLongDescription(generic_frigate_description) 583 local corvette_db = queryScienceDatabase("Ships","Corvette") 584 local generic_corvette_description = "Corvettes are the common large ships. Larger then a frigate, smaller then a dreadnaught.\nThey generally have 4 or more shield sections. Run with a crew of 20 to 250.\nThis class generally has jumpdrives or warpdrives. But lack the maneuverability that is seen in frigates.\n\nThey come in 3 different subclasses:\n* Destroyer: Combat oriented ships. No science, no transport. Just death in a large package.\n* Support: Large scale support roles. Drone carriers fall in this category, as well as mobile repair centers.\n* Freighter: Large scale transport ships. Most common here are the jump freighters, using specialized jumpdrives to cross large distances with large amounts of cargo." 585 corvette_db:setLongDescription(generic_corvette_description) 586 local dreadnought_db = queryScienceDatabase("Ships","Dreadnought") 587 dreadnought_db:setLongDescription("Dreadnoughts are the largest ships.\nThey are so large and uncommon that every type is pretty much their own subclass.\nThey usually come with 6 or more shield sections, require a crew of 250+ to operate.\n\nThink: Stardestroyer.") 588-------------------------- 589-- Stock player ships -- 590-------------------------- 591 local stock_db = ships_db:addEntry("Mainstream") 592 stock_db = queryScienceDatabase("Ships","Mainstream") 593 stock_db:setLongDescription("Mainstream ships are those ship types that are commonly available to crews serving on the front lines or in well established areas") 594---- Starfighters 595 local fighter_stock_db = stock_db:addEntry("Starfighter") 596 fighter_stock_db:setLongDescription(generic_starfighter_description) 597-- MP52 Hornet 598 fighter_stock_db:addEntry("MP52 Hornet") 599 local mp52_hornet_db = queryScienceDatabase("Ships","Mainstream","Starfighter","MP52 Hornet") 600 mp52_hornet_db:setLongDescription("The MP52 Hornet is a significantly upgraded version of MU52 Hornet, with nearly twice the hull strength, nearly three times the shielding, better acceleration, impulse boosters, and a second laser cannon.") 601 mp52_hornet_db:setKeyValue("Class","Starfighter") 602 mp52_hornet_db:setKeyValue("Sub-class","Interceptor") 603 mp52_hornet_db:setKeyValue("Size","30") 604 mp52_hornet_db:setKeyValue("Shield","60") 605 mp52_hornet_db:setKeyValue("Hull","70") 606 mp52_hornet_db:setKeyValue("Repair Crew",1) 607 mp52_hornet_db:setKeyValue("Warp Speed","60 U/min") --1000 (added for scenario) 608 mp52_hornet_db:setKeyValue("Battery Capacity",400) 609 mp52_hornet_db:setKeyValue("Sensor Ranges","Long: 18 U / Short: 4 U") 610 mp52_hornet_db:setKeyValue("Move speed","7.5 U/min") --125 (value * 60 / 1000 = units per minute) 611 mp52_hornet_db:setKeyValue("Turn speed","32 deg/sec") 612 mp52_hornet_db:setKeyValue("Beam weapon 355:30","Rng:.9 Dmg:2.5 Cyc:4") 613 mp52_hornet_db:setKeyValue("Beam weapon 5:30","Rng:.9 Dmg:2.5 Cyc:4") 614 mp52_hornet_db:setImage("radar_fighter.png") 615-- Player Fighter 616 fighter_stock_db:addEntry("Player Fighter") 617 local player_fighter_db = queryScienceDatabase("Ships","Mainstream","Starfighter","Player Fighter") 618 player_fighter_db:setLongDescription("A fairly standard fighter with strong beams and a tube for HVLIs. The sensors aren't that great, but it often has a warp drive bolted on making it extraordinarily fast") 619 player_fighter_db:setKeyValue("Class","Starfighter") 620 player_fighter_db:setKeyValue("Size","40") 621 player_fighter_db:setKeyValue("Shield","40") 622 player_fighter_db:setKeyValue("Hull","60") 623 player_fighter_db:setKeyValue("Repair Crew",3) 624 player_fighter_db:setKeyValue("Warp Speed","60 U/min") --1000 (added for scenario) 625 player_fighter_db:setKeyValue("Battery Capacity",400) 626 player_fighter_db:setKeyValue("Sensor Ranges","Long: 15 U / Short: 4.5 U") 627 player_fighter_db:setKeyValue("Move speed","6.6 U/min") --110 (value * 60 / 1000 = units per minute) 628 player_fighter_db:setKeyValue("Turn speed","20 deg/sec") 629 player_fighter_db:setKeyValue("Beam weapon 0:40","Rng:.5 Dmg:4 Cyc:6") --modified for scenario: added short forward beam so others balance 630 player_fighter_db:setKeyValue("Beam weapon 10:40","Rng:1 Dmg:8 Cyc:6") 631 player_fighter_db:setKeyValue("Beam weapon 350:40","Rng:1 Dmg:8 Cyc:6") 632 player_fighter_db:setKeyValue("Tube 0","10 sec") 633 player_fighter_db:setKeyValue("Storage HVLI","4") 634 player_fighter_db:setImage("radar_fighter.png") 635-- Striker 636 fighter_stock_db:addEntry("Striker") 637 local striker_db = queryScienceDatabase("Ships","Mainstream","Starfighter","Striker") 638 striker_db:setLongDescription("The Striker is the predecessor to the advanced striker, slow but agile, but does not do an extreme amount of damage, and lacks in shields") 639 striker_db:setKeyValue("Class","Starfighter") 640 striker_db:setKeyValue("Size","140") 641 striker_db:setKeyValue("Shield","50/30") 642 striker_db:setKeyValue("Hull","120") 643 striker_db:setKeyValue("Repair Crew",2) 644 striker_db:setKeyValue("Jump Range","3 - 40 U") --modified for scenario 645 striker_db:setKeyValue("Battery Capacity",500) 646 striker_db:setKeyValue("Sensor Ranges","Long: 35 U / Short: 5 U") 647 striker_db:setKeyValue("Move speed","2.7 U/min") --45 648 striker_db:setKeyValue("Turn speed","15 deg/sec") 649 striker_db:setKeyValue("Beam weapon 345:100","Rng:1 Dmg:6 Cyc:6 Tur:6") 650 striker_db:setKeyValue("Beam weapon 15:100","Rng:1 Dmg:6 Cyc:6 Tur:6") 651 striker_db:setImage("radar_adv_striker.png") 652-- ZX-Lindworm 653 fighter_stock_db:addEntry("ZX-Lindworm") 654 local zx_lindworm_db = queryScienceDatabase("Ships","Mainstream","Starfighter","ZX-Lindworm") 655 zx_lindworm_db:setLongDescription("The ZX model is an improvement on the WX-Lindworm with stronger hull and shields, faster impulse and tubes, more missiles and a single weak, turreted beam. The 'Worm' as it's often called, is a bomber-class starfighter. While one of the least-shielded starfighters in active duty, the Worm's launchers can pack quite a punch. Its goal is to fly in, destroy its target, and fly out or be destroyed.") 656 zx_lindworm_db:setKeyValue("Class","Starfighter") 657 zx_lindworm_db:setKeyValue("Sub-class","Bomber") 658 zx_lindworm_db:setKeyValue("Size","30") 659 zx_lindworm_db:setKeyValue("Shield","40") 660 zx_lindworm_db:setKeyValue("Hull","75") 661 zx_lindworm_db:setKeyValue("Repair Crew",1) 662 zx_lindworm_db:setKeyValue("Warp Speed","57 U/min") --950 (added for scenario) 663 zx_lindworm_db:setKeyValue("Battery Capacity",400) 664 zx_lindworm_db:setKeyValue("Sensor Ranges","Long: 18 U / Short: 5.5 U") 665 zx_lindworm_db:setKeyValue("Move speed","4.2 U/min") --70 (value * 60 / 1000 = units per minute) 666 zx_lindworm_db:setKeyValue("Turn speed","15 deg/sec") 667 zx_lindworm_db:setKeyValue("Beam weapon 180:270","Rng:.7 Dmg:2 Cyc:6") 668 zx_lindworm_db:setKeyValue("Small Tube 0","10 sec") 669 zx_lindworm_db:setKeyValue("Small Tube 359","10 sec") 670 zx_lindworm_db:setKeyValue("Small Tube 1","10 sec") 671 zx_lindworm_db:setKeyValue("Storage Homing","3") 672 zx_lindworm_db:setKeyValue("Storage HVLI","12") 673 zx_lindworm_db:setImage("radar_fighter.png") 674---- Frigates 675 local frigate_stock_db = stock_db:addEntry("Frigate") 676 frigate_stock_db:setLongDescription(generic_frigate_description) 677-- Flavia P.Falcon 678 frigate_stock_db:addEntry("Flavia P.Falcon") 679 local flavia_p_falcon_db = queryScienceDatabase("Ships","Mainstream","Frigate","Flavia P.Falcon") 680 flavia_p_falcon_db:setLongDescription("Popular among traders and smugglers, the Flavia is a small cargo and passenger transport. It's cheaper than a freighter for small loads and short distances, and is often used to carry high-value cargo discreetly.\n\nThe Flavia Falcon is a Flavia transport modified for faster flight, and adds rear-mounted lasers to keep enemies off its back.\n\nThe Flavia P.Falcon has a nuclear-capable rear-facing weapon tube and a warp drive.") 681 flavia_p_falcon_db:setKeyValue("Class","Frigate") 682 flavia_p_falcon_db:setKeyValue("Sub-class","Cruiser: Light Transport") 683 flavia_p_falcon_db:setKeyValue("Size","80") 684 flavia_p_falcon_db:setKeyValue("Shield","70/70") 685 flavia_p_falcon_db:setKeyValue("Hull","100") 686 flavia_p_falcon_db:setKeyValue("Repair Crew",8) 687 flavia_p_falcon_db:setKeyValue("Warp Speed","30 U/min") --500 688 flavia_p_falcon_db:setKeyValue("Sensor Ranges","Long: 40 U / Short: 5 U") 689 flavia_p_falcon_db:setKeyValue("Move speed","3.6 U/min") --60 690 flavia_p_falcon_db:setKeyValue("Turn speed","10 deg/sec") 691 flavia_p_falcon_db:setKeyValue("Beam weapon 170:40","Rng:1.2 Dmg:6 Cyc:6") 692 flavia_p_falcon_db:setKeyValue("Beam weapon 190:40","Rng:1.2 Dmg:6 Cyc:6") 693 flavia_p_falcon_db:setKeyValue("Tube 180","20 sec") 694 flavia_p_falcon_db:setKeyValue("Storage Homing","3") 695 flavia_p_falcon_db:setKeyValue("Storage Nuke","1") 696 flavia_p_falcon_db:setKeyValue("Storage Mine","1") 697 flavia_p_falcon_db:setKeyValue("Storage HVLI","5") 698 flavia_p_falcon_db:setImage("radar_tug.png") 699-- Hathcock 700 frigate_stock_db:addEntry("Hathcock") 701 local hathcock_db = queryScienceDatabase("Ships","Mainstream","Frigate","Hathcock") 702 hathcock_db:setLongDescription("Long range narrow beam and some point defense beams, broadside missiles. Agile for a frigate") 703 hathcock_db:setKeyValue("Class","Frigate") 704 hathcock_db:setKeyValue("Sub-class","Cruiser: Sniper") 705 hathcock_db:setKeyValue("Size","80") 706 hathcock_db:setKeyValue("Shield","70/70") 707 hathcock_db:setKeyValue("Hull","120") 708 hathcock_db:setKeyValue("Repair Crew",2) 709 hathcock_db:setKeyValue("Jump Range","6 - 60 U") --modified for scenario 710 hathcock_db:setKeyValue("Sensor Ranges","Long: 35 U / Short: 6 U") 711 hathcock_db:setKeyValue("Move speed","3 U/min") --50 712 hathcock_db:setKeyValue("Turn speed","15 deg/sec") 713 hathcock_db:setKeyValue("Beam weapon 0:4","Rng:1.4 Dmg:4 Cyc:6") 714 hathcock_db:setKeyValue("Beam weapon 0:20","Rng:1.2 Dmg:4 Cyc:6") 715 hathcock_db:setKeyValue("Beam weapon 0:60","Rng:1.0 Dmg:4 Cyc:6") 716 hathcock_db:setKeyValue("Beam weapon 0:90","Rng:0.8 Dmg:4 Cyc:6") 717 hathcock_db:setKeyValue("Tube 270","15 sec") 718 hathcock_db:setKeyValue("Tube 90","15 sec") 719 hathcock_db:setKeyValue("Storage Homing","4") 720 hathcock_db:setKeyValue("Storage Nuke","1") 721 hathcock_db:setKeyValue("Storage EMP","2") 722 hathcock_db:setKeyValue("Storage HVLI","8") 723 hathcock_db:setImage("radar_piranha.png") 724-- Nautilus 725 frigate_stock_db:addEntry("Nautilus") 726 local nautilus_db = queryScienceDatabase("Ships","Mainstream","Frigate","Nautilus") 727 nautilus_db:setLongDescription("Small mine laying vessel with minimal armament, shields and hull") 728 nautilus_db:setKeyValue("Class","Frigate") 729 nautilus_db:setKeyValue("Sub-class","Mine Layer") 730 nautilus_db:setKeyValue("Size","80") 731 nautilus_db:setKeyValue("Shield","60/60") 732 nautilus_db:setKeyValue("Hull","100") 733 nautilus_db:setKeyValue("Repair Crew",4) 734 nautilus_db:setKeyValue("Jump Range","5 - 70 U") --modified for scenario 735 nautilus_db:setKeyValue("Sensor Ranges","Long: 22 U / Short: 4 U") 736 nautilus_db:setKeyValue("Move speed","6 U/min") --100 737 nautilus_db:setKeyValue("Turn speed","10 deg/sec") 738 nautilus_db:setKeyValue("Beam weapon 35:90","Rng:1 Dmg:6 Cyc:6 Tur:6") 739 nautilus_db:setKeyValue("Beam weapon 325:90","Rng:1 Dmg:6 Cyc:6 Tur:6") 740 nautilus_db:setKeyValue("Tube 180","10 sec / Mine") 741 nautilus_db:setKeyValue(" Tube 180","10 sec / Mine") 742 nautilus_db:setKeyValue(" Tube 180","10 sec / Mine") 743 nautilus_db:setKeyValue("Storage Mine","12") 744 nautilus_db:setImage("radar_tug.png") 745-- Phobos M3P 746 frigate_stock_db:addEntry("Phobos M3P") 747 local phobos_m3p_db = queryScienceDatabase("Ships","Mainstream","Frigate","Phobos M3P") 748 phobos_m3p_db:setLongDescription("Player variant of the Phobos M3. Not as strong as the Atlantis, but has front firing tubes, making it an easier to use ship in some scenarios.") 749 phobos_m3p_db:setKeyValue("Class","Frigate") 750 phobos_m3p_db:setKeyValue("Sub-class","Cruiser") 751 phobos_m3p_db:setKeyValue("Size","80") 752 phobos_m3p_db:setKeyValue("Shield","100/100") 753 phobos_m3p_db:setKeyValue("Hull","200") 754 phobos_m3p_db:setKeyValue("Repair Crew",3) 755 phobos_m3p_db:setKeyValue("Warp Speed","54 U/min") --900 (added for scenario) 756 phobos_m3p_db:setKeyValue("Sensor Ranges","Long: 25 U / Short: 5 U") 757 phobos_m3p_db:setKeyValue("Move speed","4.8 U/min") --80 758 phobos_m3p_db:setKeyValue("Turn speed","10 deg/sec") 759 phobos_m3p_db:setKeyValue("Beam weapon 345:90","Rng:1.2 Dmg:6 Cyc:8") 760 phobos_m3p_db:setKeyValue("Beam weapon 15:90","Rng:1.2 Dmg:6 Cyc:8") 761 phobos_m3p_db:setKeyValue("Tube 359","10 sec") 762 phobos_m3p_db:setKeyValue("Tube 1","10 sec") 763 phobos_m3p_db:setKeyValue("Tube 180","10 sec / Mine") 764 phobos_m3p_db:setKeyValue("Storage Homing","10") 765 phobos_m3p_db:setKeyValue("Storage Nuke","2") 766 phobos_m3p_db:setKeyValue("Storage Mine","4") 767 phobos_m3p_db:setKeyValue("Storage EMP","3") 768 phobos_m3p_db:setKeyValue("Storage HVLI","20") 769 phobos_m3p_db:setImage("radar_cruiser.png") 770-- Piranha 771 frigate_stock_db:addEntry("Piranha") 772 local piranha_db = queryScienceDatabase("Ships","Mainstream","Frigate","Piranha") 773 piranha_db:setLongDescription("This combat-specialized Piranha F12 adds mine-laying tubes, combat maneuvering systems, and a jump drive.") 774 piranha_db:setKeyValue("Class","Frigate") 775 piranha_db:setKeyValue("Sub-class","Cruiser: Light Artillery") 776 piranha_db:setKeyValue("Size","80") 777 piranha_db:setKeyValue("Shield","70/70") 778 piranha_db:setKeyValue("Hull","120") 779 piranha_db:setKeyValue("Repair Crew",2) 780 piranha_db:setKeyValue("Jump Range","5 - 50 U") 781 piranha_db:setKeyValue("Sensor Ranges","Long: 25 U / Short: 6 U") 782 piranha_db:setKeyValue("Move speed","3.6 U/min") --60 783 piranha_db:setKeyValue("Turn speed","10 deg/sec") 784 piranha_db:setKeyValue("Large Tube 270","8 sec / Homing,HVLI") 785 piranha_db:setKeyValue("Tube 270","8 sec") 786 piranha_db:setKeyValue(" LargeTube 270","8 sec / Homing,HVLI") 787 piranha_db:setKeyValue("Large Tube 90","8 sec / Homing,HVLI") 788 piranha_db:setKeyValue("Tube 90","8 sec") 789 piranha_db:setKeyValue(" LargeTube 90","8 sec / Homing,HVLI") 790 piranha_db:setKeyValue("Tube 170","8 sec / Mine") 791 piranha_db:setKeyValue("Tube 190","8 sec / Mine") 792 piranha_db:setKeyValue("Storage Homing","12") 793 piranha_db:setKeyValue("Storage Nuke","6") 794 piranha_db:setKeyValue("Storage Mine","8") 795 piranha_db:setKeyValue("Storage HVLI","20") 796 piranha_db:setImage("radar_piranha.png") 797-- Repulse 798 frigate_stock_db:addEntry("Repulse") 799 local repulse_db = queryScienceDatabase("Ships","Mainstream","Frigate","Repulse") 800 repulse_db:setLongDescription("A Flavia P. Falcon with better hull and shields, a jump drive, two turreted beams covering both sides and a forward and rear tube. The nukes and mines are gone") 801 repulse_db:setKeyValue("Class","Frigate") 802 repulse_db:setKeyValue("Sub-class","Cruiser: Armored Transport") 803 repulse_db:setKeyValue("Size","80") 804 repulse_db:setKeyValue("Shield","80/80") 805 repulse_db:setKeyValue("Hull","120") 806 repulse_db:setKeyValue("Repair Crew",8) 807 repulse_db:setKeyValue("Jump Range","5 - 50 U") 808 repulse_db:setKeyValue("Sensor Ranges","Long: 38 U / Short: 5 U") 809 repulse_db:setKeyValue("Move speed","3.3 U/min") --55 810 repulse_db:setKeyValue("Turn speed","9 deg/sec") 811 repulse_db:setKeyValue("Beam weapon 90:200","Rng:1.2 Dmg:5 Cyc:6") 812 repulse_db:setKeyValue("Beam weapon 270:200","Rng:1.2 Dmg:5 Cyc:6") 813 repulse_db:setKeyValue("Tube 0","20 sec") 814 repulse_db:setKeyValue("Tube 180","20 sec") 815 repulse_db:setKeyValue("Storage Homing","4") 816 repulse_db:setKeyValue("Storage HVLI","6") 817 repulse_db:setImage("radar_tug.png") 818---- Corvettes 819 local corvette_stock_db = stock_db:addEntry("Corvette") 820 corvette_stock_db:setLongDescription(generic_corvette_description) 821-- Atlantis 822 corvette_stock_db:addEntry("Atlantis") 823 local atlantis_db = queryScienceDatabase("Ships","Mainstream","Corvette","Atlantis") 824 atlantis_db:setLongDescription("A refitted Atlantis X23 for more general tasks. The large shield system has been replaced with an advanced combat maneuvering systems and improved impulse engines. Its missile loadout is also more diverse. Mistaking the modified Atlantis for an Atlantis X23 would be a deadly mistake.") 825 atlantis_db:setKeyValue("Class","Corvette") 826 atlantis_db:setKeyValue("Sub-class","Destroyer") 827 atlantis_db:setKeyValue("Size","200") 828 atlantis_db:setKeyValue("Shield","200/200") 829 atlantis_db:setKeyValue("Hull","250") 830 atlantis_db:setKeyValue("Repair Crew",3) 831 atlantis_db:setKeyValue("Jump Range","5 - 50 U") 832 atlantis_db:setKeyValue("Sensor Ranges","Long: 30 U / Short: 5 U") 833 atlantis_db:setKeyValue("Move speed","5.4 U/min") --100 834 atlantis_db:setKeyValue("Turn speed","10 deg/sec") 835 atlantis_db:setKeyValue("Beam weapon 340:100","Rng:1.5 Dmg:8 Cyc:6") 836 atlantis_db:setKeyValue("Beam weapon 20:100","Rng:1.5 Dmg:8 Cyc:6") 837 atlantis_db:setKeyValue("Tube 270","10 sec") 838 atlantis_db:setKeyValue(" Tube 270","10 sec") 839 atlantis_db:setKeyValue("Tube 90","10 sec") 840 atlantis_db:setKeyValue(" Tube 90","10 sec") 841 atlantis_db:setKeyValue("Tube 180","10 sec / Mine") 842 atlantis_db:setKeyValue("Storage Homing","12") 843 atlantis_db:setKeyValue("Storage Nuke","4") 844 atlantis_db:setKeyValue("Storage Mine","8") 845 atlantis_db:setKeyValue("Storage EMP","6") 846 atlantis_db:setKeyValue("Storage HVLI","20") 847 atlantis_db:setImage("radar_dread.png") 848-- Benedict 849 corvette_stock_db:addEntry("Benedict") 850 local benedict_db = queryScienceDatabase("Ships","Mainstream","Corvette","Benedict") 851 benedict_db:setLongDescription("Benedict is Jump Carrier with a shorter range, but with stronger shields and hull and with minimal armament") 852 benedict_db:setKeyValue("Class","Corvette") 853 benedict_db:setKeyValue("Sub-class","Freighter/Carrier") 854 benedict_db:setKeyValue("Size","200") 855 benedict_db:setKeyValue("Shield","70/70") 856 benedict_db:setKeyValue("Hull","200") 857 benedict_db:setKeyValue("Repair Crew",6) 858 benedict_db:setKeyValue("Jump Range","5 - 90 U") 859 benedict_db:setKeyValue("Sensor Ranges","Long: 30 U / Short: 5 U") 860 benedict_db:setKeyValue("Move speed","3.6 U/min") --60 861 benedict_db:setKeyValue("Turn speed","6 deg/sec") 862 benedict_db:setKeyValue("Beam weapon 0:90","Rng:1.5 Dmg:4 Cyc:6 Tur:6") 863 benedict_db:setKeyValue("Beam weapon 180:90","Rng:1.5 Dmg:4 Cyc:6 Tur:6") 864 benedict_db:setImage("radar_transport.png") 865-- Crucible 866 corvette_stock_db:addEntry("Crucible") 867 local crucible_db = queryScienceDatabase("Ships","Mainstream","Corvette","Crucible") 868 crucible_db:setLongDescription("A number of missile tubes range around this ship. Beams were deemed lower priority, though they are still present. Stronger defenses than a frigate, but not as strong as the Atlantis") 869 crucible_db:setKeyValue("Class","Corvette") 870 crucible_db:setKeyValue("Sub-class","Popper") 871 crucible_db:setKeyValue("Size","80") 872 crucible_db:setKeyValue("Shield","160/160") 873 crucible_db:setKeyValue("Hull","160") 874 crucible_db:setKeyValue("Repair Crew",4) 875 crucible_db:setKeyValue("Warp Speed","45 U/min") --750 876 crucible_db:setKeyValue("Sensor Ranges","Long: 20 U / Short: 6 U") 877 crucible_db:setKeyValue("Move speed","4.8 U/min") --80 878 crucible_db:setKeyValue("Turn speed","15 deg/sec") 879 crucible_db:setKeyValue("Beam weapon 330:70","Rng:1 Dmg:5 Cyc:6") 880 crucible_db:setKeyValue("Beam weapon 30:70","Rng:1 Dmg:5 Cyc:6") 881 crucible_db:setKeyValue("Small Tube 0","8 sec / HVLI") 882 crucible_db:setKeyValue("Tube 0","8 sec / HVLI") 883 crucible_db:setKeyValue("Large Tube 0","8 sec / HVLI") 884 crucible_db:setKeyValue("Tube 270","8 sec") 885 crucible_db:setKeyValue("Tube 90","8 sec") 886 crucible_db:setKeyValue("Tube 180","8 sec / Mine") 887 crucible_db:setKeyValue("Storage Missiles","H:8 N:4 M:6 E:6 L:24") 888 crucible_db:setImage("radar_laser.png") 889-- Kiriya 890 corvette_stock_db:addEntry("Kiriya") 891 local kiriya_db = queryScienceDatabase("Ships","Mainstream","Corvette","Kiriya") 892 kiriya_db:setLongDescription("Kiriya is Warp Carrier based on the jump carrier with stronger shields and hull and with minimal armament") 893 kiriya_db:setKeyValue("Class","Corvette") 894 kiriya_db:setKeyValue("Sub-class","Freighter/Carrier") 895 kiriya_db:setKeyValue("Size","200") 896 kiriya_db:setKeyValue("Shield","70/70") 897 kiriya_db:setKeyValue("Hull","200") 898 kiriya_db:setKeyValue("Repair Crew",6) 899 kiriya_db:setKeyValue("Warp Speed","45 U/min") --750 900 kiriya_db:setKeyValue("Sensor Ranges","Long: 35 U / Short: 5 U") 901 kiriya_db:setKeyValue("Move speed","3.6 U/min") --60 902 kiriya_db:setKeyValue("Turn speed","6 deg/sec") 903 kiriya_db:setKeyValue("Beam weapon 0:90","Rng:1.5 Dmg:4 Cyc:6 Tur:6") 904 kiriya_db:setKeyValue("Beam weapon 180:90","Rng:1.5 Dmg:4 Cyc:6 Tur:6") 905 kiriya_db:setImage("radar_transport.png") 906-- Maverick 907 corvette_stock_db:addEntry("Maverick") 908 local maverick_db = queryScienceDatabase("Ships","Mainstream","Corvette","Maverick") 909 maverick_db:setLongDescription("A number of beams bristle from various points on this gunner. Missiles were deemed lower priority, though they are still present. Stronger defenses than a frigate, but not as strong as the Atlantis") 910 maverick_db:setKeyValue("Class","Corvette") 911 maverick_db:setKeyValue("Sub-class","Gunner") 912 maverick_db:setKeyValue("Size","80") 913 maverick_db:setKeyValue("Shield","160/160") 914 maverick_db:setKeyValue("Hull","160") 915 maverick_db:setKeyValue("Repair Crew",4) 916 maverick_db:setKeyValue("Warp Speed","48 U/min") --800 917 maverick_db:setKeyValue("Sensor Ranges","Long: 20 U / Short: 4 U") 918 maverick_db:setKeyValue("Move speed","4.8 U/min") --80 919 maverick_db:setKeyValue("Turn speed","15 deg/sec") 920 maverick_db:setKeyValue("Beam weapon 0:10","Rng:2 Dmg:6 Cyc:6") 921 maverick_db:setKeyValue("Beam weapon 340:90","Rng:1.5 Dmg:8 Cyc:6") 922 maverick_db:setKeyValue("Beam weapon 20:90","Rng:1.5 Dmg:8 Cyc:6") 923 maverick_db:setKeyValue("Beam weapon 290:40","Rng:1 Dmg:6 Cyc:4") 924 maverick_db:setKeyValue("Beam weapon 70:40","Rng:1 Dmg:6 Cyc:4") 925 maverick_db:setKeyValue("Beam weapon 180:180","Rng:.8 Dmg:4 Cyc:6 Tur:.5") 926 maverick_db:setKeyValue("Tube 270","8 sec") 927 maverick_db:setKeyValue("Tube 90","8 sec") 928 maverick_db:setKeyValue("Tube 180","8 sec / Mine") 929 maverick_db:setKeyValue("Storage Missiles","H:6 N:2 M:2 E:4 L:10") 930 maverick_db:setImage("radar_laser.png") 931-- Player Cruiser 932 corvette_stock_db:addEntry("Player Cruiser") 933 local player_cruiser_db = queryScienceDatabase("Ships","Mainstream","Corvette","Player Cruiser") 934 player_cruiser_db:setLongDescription("A fairly standard cruiser. Stronger than average beams, weaker than average shields, farther than average jump drive range") 935 player_cruiser_db:setKeyValue("Class","Corvette") 936 player_cruiser_db:setKeyValue("Size","200") 937 player_cruiser_db:setKeyValue("Shield","80/80") 938 player_cruiser_db:setKeyValue("Hull","200") 939 player_cruiser_db:setKeyValue("Repair Crew",3) 940 player_cruiser_db:setKeyValue("Jump Range","5 - 80 U") --modified for scenario 941 player_cruiser_db:setKeyValue("Sensor Ranges","Long: 30 U / Short: 5 U") 942 player_cruiser_db:setKeyValue("Move speed","5.4 U/min") --90 943 player_cruiser_db:setKeyValue("Turn speed","10 deg/sec") 944 player_cruiser_db:setKeyValue("Beam weapon 345:90","Rng:1 Dmg:10 Cyc:6") 945 player_cruiser_db:setKeyValue("Beam weapon 15:90","Rng:1 Dmg:10 Cyc:6") 946 player_cruiser_db:setKeyValue("Tube 355","8 sec") 947 player_cruiser_db:setKeyValue("Tube 5","8 sec") 948 player_cruiser_db:setKeyValue("Tube 180","8 sec / Mine") 949 player_cruiser_db:setKeyValue("Storage Homing","12") 950 player_cruiser_db:setKeyValue("Storage Nuke","4") 951 player_cruiser_db:setKeyValue("Storage Mine","8") 952 player_cruiser_db:setKeyValue("Storage EMP","6") 953 player_cruiser_db:setImage("radar_cruiser.png") 954-- Player Missile Cruiser 955 corvette_stock_db:addEntry("Player Missile Cr.") 956 local player_missile_cruiser_db = queryScienceDatabase("Ships","Mainstream","Corvette","Player Missile Cr.") 957 player_missile_cruiser_db:setLongDescription("It's all about the missiles for this model. Broadside tubes shoot homing missiles (30!), front, homing, EMP and nuke. Comparatively weak shields, especially in the rear. Sluggish impulse drive.") 958 player_missile_cruiser_db:setKeyValue("Class","Corvette") 959 player_missile_cruiser_db:setKeyValue("Size","100") 960 player_missile_cruiser_db:setKeyValue("Shield","110/70") 961 player_missile_cruiser_db:setKeyValue("Hull","200") 962 player_missile_cruiser_db:setKeyValue("Repair Crew",3) 963 player_missile_cruiser_db:setKeyValue("Warp Speed","48 U/min") --800 964 player_missile_cruiser_db:setKeyValue("Sensor Ranges","Long: 35 U / Short: 6 U") 965 player_missile_cruiser_db:setKeyValue("Move speed","3.6 U/min") --60 966 player_missile_cruiser_db:setKeyValue("Turn speed","8 deg/sec") 967 player_missile_cruiser_db:setKeyValue("Tube 0","8 sec") 968 player_missile_cruiser_db:setKeyValue(" Tube 0","8 sec") 969 player_missile_cruiser_db:setKeyValue("Tube 90","8 sec / Homing") 970 player_missile_cruiser_db:setKeyValue(" Tube 90","8 sec / Homing") 971 player_missile_cruiser_db:setKeyValue("Tube 270","8 sec / Homing") 972 player_missile_cruiser_db:setKeyValue(" Tube 270","8 sec / Homing") 973 player_missile_cruiser_db:setKeyValue("Tube 180","8 sec / Mine") 974 player_missile_cruiser_db:setKeyValue("Storage Homing","30") 975 player_missile_cruiser_db:setKeyValue("Storage Nuke","8") 976 player_missile_cruiser_db:setKeyValue("Storage Mine","12") 977 player_missile_cruiser_db:setKeyValue("Storage EMP","10") 978 player_missile_cruiser_db:setImage("radar_cruiser.png") 979--------------------------- 980-- Custom player ships -- 981--------------------------- 982 local prototype_db = ships_db:addEntry("Prototype") 983 prototype_db = queryScienceDatabase("Ships","Prototype") 984 prototype_db:setLongDescription("Prototype ships are those that are under development or are otherwise considered experimental. Some have been through several iterations after being tested in the field. Many have been scrapped due to poor design, the ravages of space or perhaps the simple passage of time.") 985 prototype_db:setImage("gui/icons/station-engineering.png") 986---- Starfighters 987 local fighter_prototype_db = prototype_db:addEntry("Starfighter") 988 fighter_prototype_db:setLongDescription(generic_starfighter_description) 989-- Striker LX 990 fighter_prototype_db:addEntry("Striker LX") 991 local striker_lx_db = queryScienceDatabase("Ships","Prototype","Starfighter","Striker LX") 992 striker_lx_db:setLongDescription("The Striker is the predecessor to the advanced striker, slow but agile, but does not do an extreme amount of damage, and lacks in shields. The Striker LX is a modification of the Striker: stronger shields, more energy, jump drive (vs none), faster impulse, slower turret, two rear tubes (vs none)") 993 striker_lx_db:setKeyValue("Class","Starfighter") 994 striker_lx_db:setKeyValue("Sub-class","Patrol") 995 striker_lx_db:setKeyValue("Size","140") 996 striker_lx_db:setKeyValue("Shield","100/100") 997 striker_lx_db:setKeyValue("Hull","100") 998 striker_lx_db:setKeyValue("Repair Crew",3) 999 striker_lx_db:setKeyValue("Battery Capacity",600) 1000 striker_lx_db:setKeyValue("Jump Range","2 - 20 U") 1001 striker_lx_db:setKeyValue("Sensor Ranges","Long: 20 U / Short: 4 U") 1002 striker_lx_db:setKeyValue("Move speed","3.9 U/min") --65 (value * 60 / 1000 = units per minute) 1003 striker_lx_db:setKeyValue("Turn speed","35 deg/sec") 1004 striker_lx_db:setKeyValue("Beam weapon 345:100","Rng:1.1 Dmg:6.5 Cyc:6 Tur:.2") 1005 striker_lx_db:setKeyValue("Beam weapon 15:100","Rng:1.1 Dmg:6.5 Cyc:6 Tur:.2") 1006 striker_lx_db:setKeyValue("Tube 180","10 sec") 1007 striker_lx_db:setKeyValue(" Tube 180","10 sec") 1008 striker_lx_db:setKeyValue("Storage Homing","4") 1009 striker_lx_db:setKeyValue("Storage Nuke","2") 1010 striker_lx_db:setKeyValue("Storage Mine","3") 1011 striker_lx_db:setKeyValue("Storage EMP","3") 1012 striker_lx_db:setKeyValue("Storage HVLI","6") 1013 striker_lx_db:setImage("radar_adv_striker.png") 1014---- Frigates 1015 local frigate_prototype_db = prototype_db:addEntry("Frigate") 1016 frigate_prototype_db:setLongDescription(generic_frigate_description) 1017-- Phobos T2 1018 frigate_prototype_db:addEntry("Phobos T2") 1019 local phobos_t2_db = queryScienceDatabase("Ships","Prototype","Frigate","Phobos T2") 1020 phobos_t2_db:setLongDescription("Based on Phobos M3P with these differences: more repair crew, a jump drive, faster spin, stronger front shield, weaker rear shield, less maximum energy, turreted and faster beams, one fewer tube forward, and fewer missiles") 1021 phobos_t2_db:setKeyValue("Class","Frigate") 1022 phobos_t2_db:setKeyValue("Sub-class","Cruiser") 1023 phobos_t2_db:setKeyValue("Size","80") 1024 phobos_t2_db:setKeyValue("Shield","120/80") 1025 phobos_t2_db:setKeyValue("Hull","200") 1026 phobos_t2_db:setKeyValue("Repair Crew",4) 1027 phobos_t2_db:setKeyValue("Battery Capacity",800) 1028 phobos_t2_db:setKeyValue("Jump Range","2 - 25 U") 1029 phobos_t2_db:setKeyValue("Sensor Ranges","Long: 25 U / Short: 5 U") 1030 phobos_t2_db:setKeyValue("Move speed","4.8 U/min") --80 1031 phobos_t2_db:setKeyValue("Turn speed","20 deg/sec") 1032 phobos_t2_db:setKeyValue("Beam weapon 330:40","Rng:1.2 Dmg:6 Cyc:4 Tur:.2") 1033 phobos_t2_db:setKeyValue("Beam weapon 30:40","Rng:1.2 Dmg:6 Cyc:4 Tur:.2") 1034 phobos_t2_db:setKeyValue("Tube 0","10 sec") 1035 phobos_t2_db:setKeyValue("Tube 180","10 sec / Mine") 1036 phobos_t2_db:setKeyValue("Storage Homing",8) 1037 phobos_t2_db:setKeyValue("Storage Nuke",2) 1038 phobos_t2_db:setKeyValue("Storage Mine",4) 1039 phobos_t2_db:setKeyValue("Storage EMP",3) 1040 phobos_t2_db:setKeyValue("Storage HVLI",16) 1041 phobos_t2_db:setImage("radar_cruiser.png") 1042---- Corvettes 1043 local corvette_prototype_db = prototype_db:addEntry("Corvette") 1044 corvette_prototype_db:setLongDescription(generic_corvette_description) 1045-- Focus 1046 corvette_prototype_db:addEntry("Focus") 1047 local focus_db = queryScienceDatabase("Ships","Prototype","Corvette","Focus") 1048 focus_db:setLongDescription("Adjusted Crucible: short jump drive (no warp), faster impulse and spin, weaker shields and hull, narrower beams, fewer tubes. The large tube accomodates nukes, EMPs and homing missiles") 1049 focus_db:setKeyValue("Class","Corvette") 1050 focus_db:setKeyValue("Sub-class","Popper") 1051 focus_db:setKeyValue("Size","200") 1052 focus_db:setKeyValue("Shield","100/100") 1053 focus_db:setKeyValue("Hull","100") 1054 focus_db:setKeyValue("Repair Crew",4) 1055 focus_db:setKeyValue("Jump Range","2.5 - 25 U") 1056 focus_db:setKeyValue("Sensor Ranges","Long: 32 U / Short: 5 U") 1057 focus_db:setKeyValue("Move speed","4.2 U/min") --70 1058 focus_db:setKeyValue("Turn speed","20 deg/sec") 1059 focus_db:setKeyValue("Beam weapon 340:60","Rng:1 Dmg:5 Cyc:6") 1060 focus_db:setKeyValue("Beam weapon 20:60","Rng:1 Dmg:5 Cyc:6") 1061 focus_db:setKeyValue("Small Tube 0","8 sec / HVLI") 1062 focus_db:setKeyValue("Tube 0","8 sec / HVLI") 1063 focus_db:setKeyValue("Large Tube 0","8 sec") 1064 focus_db:setKeyValue("Tube 180","8 sec / Mine") 1065 focus_db:setKeyValue("Storage Homing",8) 1066 focus_db:setKeyValue("Storage Nuke",1) 1067 focus_db:setKeyValue("Storage Mine",6) 1068 focus_db:setKeyValue("Storage EMP",2) 1069 focus_db:setKeyValue("Storage HVLI",24) 1070 focus_db:setImage("radar_laser.png") 1071-- Holmes 1072 corvette_prototype_db:addEntry("Holmes") 1073 local holmes_db = queryScienceDatabase("Ships","Prototype","Corvette","Holmes") 1074 holmes_db:setLongDescription("Revised Crucible: weaker shields, side beams, fewer tubes, fewer missiles, EMPs and Nukes in front middle tube and large homing missiles") 1075 holmes_db:setKeyValue("Class","Corvette") 1076 holmes_db:setKeyValue("Sub-class","Popper") 1077 holmes_db:setKeyValue("Size","200") 1078 holmes_db:setKeyValue("Shield","160/160") 1079 holmes_db:setKeyValue("Hull","160") 1080 holmes_db:setKeyValue("Repair Crew",4) 1081 holmes_db:setKeyValue("Warp Speed","45.0 U/min") --750 1082 holmes_db:setKeyValue("Sensor Ranges","Long: 35 U / Short: 4 U") 1083 holmes_db:setKeyValue("Move speed","4.2 U/min") --70 1084 holmes_db:setKeyValue("Turn speed","15 deg/sec") 1085 holmes_db:setKeyValue("Beam weapon 275:50","Rng:.9 Dmg:5 Cyc:6") 1086 holmes_db:setKeyValue("Beam weapon 265:50","Rng:.9 Dmg:5 Cyc:6") 1087 holmes_db:setKeyValue("Beam weapon 85:50","Rng:.9 Dmg:5 Cyc:6") 1088 holmes_db:setKeyValue("Beam weapon 95:50","Rng:.9 Dmg:5 Cyc:6") 1089 holmes_db:setKeyValue("Small Tube 0","8 sec / Homing") 1090 holmes_db:setKeyValue("Tube 0","8 sec / Homing") 1091 holmes_db:setKeyValue("Large Tube 0","8 sec / Homing") 1092 holmes_db:setKeyValue("Tube 180","8 sec / Mine") 1093 holmes_db:setKeyValue("Storage Homing",10) 1094 holmes_db:setKeyValue("Storage Mine",6) 1095 holmes_db:setImage("radar_laser.png") 1096-- Maverick XP 1097 corvette_prototype_db:addEntry("Maverick XP") 1098 local maverick_xp_db = queryScienceDatabase("Ships","Prototype","Corvette","Maverick XP") 1099 maverick_xp_db:setLongDescription("Based on Maverick: slower impulse, jump (no warp), one heavy slow turreted beam (not 6 beams)") 1100 maverick_xp_db:setKeyValue("Class","Corvette") 1101 maverick_xp_db:setKeyValue("Sub-class","Gunner") 1102 maverick_xp_db:setKeyValue("Size","200") 1103 maverick_xp_db:setKeyValue("Shield","160/160") 1104 maverick_xp_db:setKeyValue("Hull","160") 1105 maverick_xp_db:setKeyValue("Repair Crew",4) 1106 maverick_xp_db:setKeyValue("Jump Range","2 - 20 U") 1107 maverick_xp_db:setKeyValue("Sensor Ranges","Long: 25 U / Short: 7 U") 1108 maverick_xp_db:setKeyValue("Move speed","3.9 U/min") --65 1109 maverick_xp_db:setKeyValue("Turn speed","15 deg/sec") 1110 maverick_xp_db:setKeyValue("Beam weapon 0:270","Rng:1 Dmg:20 Cyc:20 Tur:.2") 1111 maverick_xp_db:setKeyValue("Tube 270","8 sec") 1112 maverick_xp_db:setKeyValue("Tube 90","8 sec") 1113 maverick_xp_db:setKeyValue("Tube 180","8 sec / Mine") 1114 maverick_xp_db:setKeyValue("Storage Homing",6) 1115 maverick_xp_db:setKeyValue("Storage Nuke",2) 1116 maverick_xp_db:setKeyValue("Storage Mine",2) 1117 maverick_xp_db:setKeyValue("Storage EMP",4) 1118 maverick_xp_db:setKeyValue("Storage HVLI",10) 1119 maverick_xp_db:setImage("radar_laser.png") 1120 1121end 1122------------------ 1123-- GM Buttons -- 1124------------------ 1125function setGMButtons() 1126 mainGMButtons = mainGMButtonsDuringPause 1127 mainGMButtons() 1128end 1129function mainGMButtonsDuringPause() 1130 clearGMFunctions() 1131 addGMFunction(string.format("Version %s",scenario_version),function() 1132 local version_message = string.format("Scenario version %s\n LUA version %s",scenario_version,_VERSION) 1133 addGMMessage(version_message) 1134 print(version_message) 1135 end) 1136 if not terrain_generated then 1137 addGMFunction(string.format("+Player Teams: %i",player_team_count),setPlayerTeamCount) 1138 addGMFunction(string.format("+Player Ships: %i (%i)",ships_per_team,ships_per_team*player_team_count),setPlayerShipCount) 1139 addGMFunction(string.format("+P.Ship Types: %s",player_ship_types),setPlayerShipTypes) 1140 local button_label = "+NPC Ships: 0" 1141 if npc_ships then 1142 button_label = string.format("+NPC Ships: %i-%i",npc_lower,npc_upper) 1143 end 1144 addGMFunction(button_label,setNPCShips) 1145 addGMFunction("+Terrain",setTerrainParameters) 1146 addGMFunction(string.format("Respawn: %s",respawn_type),function() 1147 if respawn_type == "lindworm" then 1148 respawn_type = "self" 1149 elseif respawn_type == "self" then 1150 respawn_type = "lindworm" 1151 end 1152 mainGMButtons() 1153 end) 1154 else 1155 addGMFunction("Show control codes",showControlCodes) 1156 addGMFunction("Show Human codes",showHumanCodes) 1157 addGMFunction("Show Kraylor codes",showKraylorCodes) 1158 if exuari_angle ~= nil then 1159 addGMFunction("Show Exuari codes",showExuariCodes) 1160 end 1161 if ktlitan_angle ~= nil then 1162 addGMFunction("Show Ktlitan codes",showKtlitanCodes) 1163 end 1164 end 1165 addGMFunction(string.format("+Stn Sensors %iU",station_sensor_range/1000),setStationSensorRange) 1166 addGMFunction(string.format("+Game Time %i",game_time_limit/60),setGameTimeLimit) 1167end 1168function mainGMButtonsAfterPause() 1169 clearGMFunctions() 1170 addGMFunction(string.format("Version %s",scenario_version),function() 1171 local version_message = string.format("Scenario version %s\n LUA version %s",scenario_version,_VERSION) 1172 addGMMessage(version_message) 1173 print(version_message) 1174 end) 1175 addGMFunction("Show control codes",showControlCodes) 1176 addGMFunction("Show Human codes",showHumanCodes) 1177 addGMFunction("Show Kraylor codes",showKraylorCodes) 1178 if exuari_angle ~= nil then 1179 addGMFunction("Show Exuari codes",showExuariCodes) 1180 end 1181 if ktlitan_angle ~= nil then 1182 addGMFunction("Show Ktlitan codes",showKtlitanCodes) 1183 end 1184 addGMFunction("Statistics Summary",function() 1185 local stat_list = gatherStats() 1186 local out = "Current Scores:" 1187 out = out .. string.format("\n Human Navy: %.2f (%.1f%%)",stat_list.human.weighted_score,stat_list.human.weighted_score/original_score["Human Navy"]*100) 1188 out = out .. string.format("\n Kraylor: %.2f (%.1f%%)",stat_list.kraylor.weighted_score,stat_list.kraylor.weighted_score/original_score["Kraylor"]*100) 1189 if exuari_angle ~= nil then 1190 out = out .. string.format("\n Exuari: %.2f (%.1f%%)",stat_list.exuari.weighted_score,stat_list.exuari.weighted_score/original_score["Exuari"]*100) 1191 end 1192 if ktlitan_angle ~= nil then 1193 out = out .. string.format("\n Ktlitans: %.2f (%.1f%%)",stat_list.ktlitan.weighted_score,stat_list.ktlitan.weighted_score/original_score["Ktlitans"]*100) 1194 end 1195 local out = out .. "\nOriginal scores:" 1196 out = out .. string.format("\n Human Navy: %.2f",original_score["Human Navy"]) 1197 out = out .. string.format("\n Kraylor: %.2f",original_score["Kraylor"]) 1198 if exuari_angle ~= nil then 1199 out = out .. string.format("\n Exuari: %.2f",original_score["Exuari"]) 1200 end 1201 if ktlitan_angle ~= nil then 1202 out = out .. string.format("\n Ktlitans: %.2f",original_score["Ktlitans"]) 1203 end 1204 addGMMessage(out) 1205 end) 1206 addGMFunction("Statistics Details",function() 1207 local stat_list = gatherStats() 1208 out = "Human Navy:\n Stations: (score value, type, name)" 1209 print("Human Navy:") 1210 print(" Stations: (score value, type, name)") 1211 for name, details in pairs(stat_list.human.station) do 1212 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1213 print(" ",details.score_value,details.template_type,name) 1214 end 1215 local weighted_stations = stat_list.human.station_score_total * stat_list.weight.station 1216 out = out .. string.format("\n Station Total:%i Weight:%.1f Weighted total:%.2f",stat_list.human.station_score_total,stat_list.weight.station,weighted_stations) 1217 print(" Station Total:",stat_list.human.station_score_total,"Weight:",stat_list.weight.station,"Weighted Total:",weighted_stations) 1218 out = out .. "\n Player Ships: (score value, type, name)" 1219 print(" Player Ships: (score value, type, name)") 1220 for name, details in pairs(stat_list.human.ship) do 1221 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1222 print(" ",details.score_value,details.template_type,name) 1223 end 1224 local weighted_players = stat_list.human.ship_score_total * stat_list.weight.ship 1225 out = out .. string.format("\n Player Ship Total:%i Weight:%.1f Weighted total:%.2f",stat_list.human.ship_score_total,stat_list.weight.ship,weighted_players) 1226 print(" Player Ship Total:",stat_list.human.ship_score_total,"Weight:",stat_list.weight.ship,"Weighted Total:",weighted_players) 1227 out = out .. "\n NPC Assets: score value, type, name (location)" 1228 print(" NPC Assets: score value, type, name (location)") 1229 for name, details in pairs(stat_list.human.npc) do 1230 if details.template_type ~= nil then 1231 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1232 print(" ",details.score_value,details.template_type,name) 1233 elseif details.topic ~= nil then 1234 out = out .. string.format("\n %i %s %s (%s)",details.score_value,details.topic,name,details.location_name) 1235 print(" ",details.score_value,details.topic,name,"(" .. details.location_name .. ")") 1236 end 1237 end 1238 local weighted_npcs = stat_list.human.npc_score_total * stat_list.weight.npc 1239 out = out .. string.format("\n NPC Asset Total:%i Weight:%.1f Weighted total:%.2f",stat_list.human.npc_score_total,stat_list.weight.npc,weighted_npcs) 1240 print(" NPC Asset Total:",stat_list.human.npc_score_total,"Weight:",stat_list.weight.npc,"Weighted Total:",weighted_npcs) 1241 out = out .. string.format("\n----Human weighted total:%.1f Original:%.1f Change:%.2f%%",stat_list.human.weighted_score,original_score["Human Navy"],stat_list.human.weighted_score/original_score["Human Navy"]*100) 1242 print("----Human weighted total:",stat_list.human.weighted_score,"Original:",original_score["Human Navy"],"Change:",stat_list.human.weighted_score/original_score["Human Navy"]*100 .. "%") 1243 out = out .. "\nKraylor:\n Stations: (score value, type, name)" 1244 print("Kraylor:") 1245 print(" Stations: (score value, type, name)") 1246 for name, details in pairs(stat_list.kraylor.station) do 1247 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1248 print(" ",details.score_value,details.template_type,name) 1249 end 1250 local weighted_stations = stat_list.kraylor.station_score_total * stat_list.weight.station 1251 out = out .. string.format("\n Station Total:%i Weight:%.1f Weighted total:%.2f",stat_list.kraylor.station_score_total,stat_list.weight.station,weighted_stations) 1252 print(" Station Total:",stat_list.kraylor.station_score_total,"Weight:",stat_list.weight.station,"Weighted Total:",weighted_stations) 1253 out = out .. "\n Player Ships: (score value, type, name)" 1254 print(" Player Ships: (score value, type, name)") 1255 for name, details in pairs(stat_list.kraylor.ship) do 1256 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1257 print(" ",details.score_value,details.template_type,name) 1258 end 1259 local weighted_players = stat_list.kraylor.ship_score_total * stat_list.weight.ship 1260 out = out .. string.format("\n Player Ship Total:%i Weight:%.1f Weighted total:%.2f",stat_list.kraylor.ship_score_total,stat_list.weight.ship,weighted_players) 1261 print(" Player Ship Total:",stat_list.kraylor.ship_score_total,"Weight:",stat_list.weight.ship,"Weighted Total:",weighted_players) 1262 out = out .. "\n NPC Assets: score value, type, name (location)" 1263 print(" NPC Assets: score value, type, name (location)") 1264 for name, details in pairs(stat_list.kraylor.npc) do 1265 if details.template_type ~= nil then 1266 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1267 print(" ",details.score_value,details.template_type,name) 1268 elseif details.topic ~= nil then 1269 out = out .. string.format("\n %i %s %s (%s)",details.score_value,details.topic,name,details.location_name) 1270 print(" ",details.score_value,details.topic,name,"(" .. details.location_name .. ")") 1271 end 1272 end 1273 local weighted_npcs = stat_list.kraylor.npc_score_total * stat_list.weight.npc 1274 out = out .. string.format("\n NPC Asset Total:%i Weight:%.1f Weighted total:%.2f",stat_list.kraylor.npc_score_total,stat_list.weight.npc,weighted_npcs) 1275 print(" NPC Asset Total:",stat_list.kraylor.npc_score_total,"Weight:",stat_list.weight.npc,"Weighted Total:",weighted_npcs) 1276 out = out .. string.format("\n----Kraylor weighted total:%.1f Original:%.1f Change:%.2f%%",stat_list.kraylor.weighted_score,original_score["Kraylor"],stat_list.kraylor.weighted_score/original_score["Kraylor"]*100) 1277 print("----Kraylor weighted total:",stat_list.kraylor.weighted_score,"Original:",original_score["Kraylor"],"Change:",stat_list.kraylor.weighted_score/original_score["Kraylor"]*100 .. "%") 1278 if exuari_angle ~= nil then 1279 out = out .. "\nExuari:\n Stations: (score value, type, name)" 1280 print("Exuari:") 1281 print(" Stations: (score value, type, name)") 1282 for name, details in pairs(stat_list.exuari.station) do 1283 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1284 print(" ",details.score_value,details.template_type,name) 1285 end 1286 local weighted_stations = stat_list.exuari.station_score_total * stat_list.weight.station 1287 out = out .. string.format("\n Station Total:%i Weight:%.1f Weighted total:%.2f",stat_list.exuari.station_score_total,stat_list.weight.station,weighted_stations) 1288 print(" Station Total:",stat_list.exuari.station_score_total,"Weight:",stat_list.weight.station,"Weighted Total:",weighted_stations) 1289 out = out .. "\n Player Ships: (score value, type, name)" 1290 print(" Player Ships: (score value, type, name)") 1291 for name, details in pairs(stat_list.exuari.ship) do 1292 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1293 print(" ",details.score_value,details.template_type,name) 1294 end 1295 local weighted_players = stat_list.exuari.ship_score_total * stat_list.weight.ship 1296 out = out .. string.format("\n Player Ship Total:%i Weight:%.1f Weighted total:%.2f",stat_list.exuari.ship_score_total,stat_list.weight.ship,weighted_players) 1297 print(" Player Ship Total:",stat_list.exuari.ship_score_total,"Weight:",stat_list.weight.ship,"Weighted Total:",weighted_players) 1298 out = out .. "\n NPC Assets: score value, type, name (location)" 1299 print(" NPC Assets: score value, type, name (location)") 1300 for name, details in pairs(stat_list.exuari.npc) do 1301 if details.template_type ~= nil then 1302 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1303 print(" ",details.score_value,details.template_type,name) 1304 elseif details.topic ~= nil then 1305 out = out .. string.format("\n %i %s %s (%s)",details.score_value,details.topic,name,details.location_name) 1306 print(" ",details.score_value,details.topic,name,"(" .. details.location_name .. ")") 1307 end 1308 end 1309 local weighted_npcs = stat_list.exuari.npc_score_total * stat_list.weight.npc 1310 out = out .. string.format("\n NPC Asset Total:%i Weight:%.1f Weighted total:%.2f",stat_list.exuari.npc_score_total,stat_list.weight.npc,weighted_npcs) 1311 print(" NPC Asset Total:",stat_list.exuari.npc_score_total,"Weight:",stat_list.weight.npc,"Weighted Total:",weighted_npcs) 1312 out = out .. string.format("\n----Exuari weighted total:%.1f Original:%.1f Change:%.2f%%",stat_list.exuari.weighted_score,original_score["Exuari"],stat_list.exuari.weighted_score/original_score["Exuari"]*100) 1313 print("----Exuari weighted total:",stat_list.exuari.weighted_score,"Original:",original_score["Exuari"],"Change:",stat_list.exuari.weighted_score/original_score["Exuari"]*100 .. "%") 1314 end 1315 if ktlitan_angle ~= nil then 1316 out = out .. "\nKtlitan:\n Stations: (score value, type, name)" 1317 print("Ktlitan:") 1318 print(" Stations: (score value, type, name)") 1319 for name, details in pairs(stat_list.ktlitan.station) do 1320 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1321 print(" ",details.score_value,details.template_type,name) 1322 end 1323 local weighted_stations = stat_list.ktlitan.station_score_total * stat_list.weight.station 1324 out = out .. string.format("\n Station Total:%i Weight:%.1f Weighted total:%.2f",stat_list.ktlitan.station_score_total,stat_list.weight.station,weighted_stations) 1325 print(" Station Total:",stat_list.ktlitan.station_score_total,"Weight:",stat_list.weight.station,"Weighted Total:",weighted_stations) 1326 out = out .. "\n Player Ships: (score value, type, name)" 1327 print(" Player Ships: (score value, type, name)") 1328 for name, details in pairs(stat_list.ktlitan.ship) do 1329 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1330 print(" ",details.score_value,details.template_type,name) 1331 end 1332 local weighted_players = stat_list.ktlitan.ship_score_total * stat_list.weight.ship 1333 out = out .. string.format("\n Player Ship Total:%i Weight:%.1f Weighted total:%.2f",stat_list.ktlitan.ship_score_total,stat_list.weight.ship,weighted_players) 1334 print(" Player Ship Total:",stat_list.ktlitan.ship_score_total,"Weight:",stat_list.weight.ship,"Weighted Total:",weighted_players) 1335 out = out .. "\n NPC Assets: score value, type, name (location)" 1336 print(" NPC Assets: score value, type, name (location)") 1337 for name, details in pairs(stat_list.ktlitan.npc) do 1338 if details.template_type ~= nil then 1339 out = out .. string.format("\n %i %s %s",details.score_value,details.template_type,name) 1340 print(" ",details.score_value,details.template_type,name) 1341 elseif details.topic ~= nil then 1342 out = out .. string.format("\n %i %s %s (%s)",details.score_value,details.topic,name,details.location_name) 1343 print(" ",details.score_value,details.topic,name,"(" .. details.location_name .. ")") 1344 end 1345 end 1346 local weighted_npcs = stat_list.ktlitan.npc_score_total * stat_list.weight.npc 1347 out = out .. string.format("\n NPC Asset Total:%i Weight:%.1f Weighted total:%.2f",stat_list.ktlitan.npc_score_total,stat_list.weight.npc,weighted_npcs) 1348 print(" NPC Asset Total:",stat_list.ktlitan.npc_score_total,"Weight:",stat_list.weight.npc,"Weighted Total:",weighted_npcs) 1349 out = out .. string.format("\n----Ktlitan weighted total:%.1f Original:%.1f Change:%.2f%%",stat_list.ktlitan.weighted_score,original_score["Ktlitans"],stat_list.ktlitan.weighted_score/original_score["Ktlitans"]*100) 1350 print("----Ktlitan weighted total:",stat_list.ktlitan.weighted_score,"Original:",original_score["Ktlitans"],"Change:",stat_list.ktlitan.weighted_score/original_score["Ktlitans"]*100 .. "%") 1351 end 1352 addGMMessage(out) 1353 end) 1354end 1355-- Player related GM configuration functions 1356function setPlayerTeamCount() 1357 clearGMFunctions() 1358 addGMFunction("-Main from Teams",mainGMButtons) 1359 local button_label = "2" 1360 if player_team_count == 2 then 1361 button_label = button_label .. "*" 1362 end 1363 addGMFunction(button_label,function() 1364 player_team_count = 2 1365 mainGMButtons() 1366 end) 1367 local button_label = "3" 1368 if player_team_count == 3 then 1369 button_label = button_label .. "*" 1370 end 1371 addGMFunction(button_label,function() 1372 player_team_count = 3 1373 if ships_per_team > max_ships_per_team[player_team_count] then 1374 ships_per_team = max_ships_per_team[player_team_count] 1375 if player_ship_types == "spawned" then 1376 addGMMessage("Switching player ship type to default") 1377 player_ship_types = "default" 1378 end 1379 end 1380 mainGMButtons() 1381 end) 1382 local button_label = "4" 1383 if player_team_count == 4 then 1384 button_label = button_label .. "*" 1385 end 1386 addGMFunction(button_label,function() 1387 player_team_count = 4 1388 if ships_per_team > max_ships_per_team[player_team_count] then 1389 ships_per_team = max_ships_per_team[player_team_count] 1390 if player_ship_types == "spawned" then 1391 addGMMessage("Switching player ship type to default") 1392 player_ship_types = "default" 1393 end 1394 end 1395 mainGMButtons() 1396 end) 1397end 1398function setPlayerShipCount() 1399 clearGMFunctions() 1400 addGMFunction("-Main from Ships",mainGMButtons) 1401 if ships_per_team < max_ships_per_team[player_team_count] then 1402 addGMFunction(string.format("%i ships add -> %i",ships_per_team,ships_per_team + 1),function() 1403 ships_per_team = ships_per_team + 1 1404 if player_ship_types == "spawned" then 1405 addGMMessage("Switching player ship type to default") 1406 player_ship_types = "default" 1407 end 1408 setPlayerShipCount() 1409 end) 1410 end 1411 if ships_per_team > 1 then 1412 addGMFunction(string.format("%i ships del -> %i",ships_per_team,ships_per_team - 1),function() 1413 ships_per_team = ships_per_team - 1 1414 if player_ship_types == "spawned" then 1415 addGMMessage("Switching player ship type to default") 1416 player_ship_types = "default" 1417 end 1418 setPlayerShipCount() 1419 end) 1420 end 1421end 1422function setPlayerShipTypes() 1423 clearGMFunctions() 1424 addGMFunction("-Main from Ship Types",mainGMButtons) 1425 local button_label = "default" 1426 if player_ship_types == button_label then 1427 button_label = button_label .. "*" 1428 end 1429 addGMFunction(button_label,function() 1430 player_ship_types = "default" 1431 local player_plural = "players" 1432 local type_plural = "types" 1433 if ships_per_team == 1 then 1434 player_plural = "player" 1435 type_plural = "type" 1436 end 1437 local out = string.format("Default ship %s for a team of %i %s:",type_plural,ships_per_team,player_plural) 1438 for i=1,ships_per_team do 1439 out = out .. "\n " .. i .. ") " .. default_player_ship_sets[ships_per_team][i] 1440 end 1441 addGMMessage(out) 1442 setPlayerShipTypes() 1443 end) 1444 button_label = "spawned" 1445 if player_ship_types == button_label then 1446 button_label = button_label .. "*" 1447 end 1448 addGMFunction(button_label,function() 1449 player_ship_types = "spawned" 1450 local out = "Spawned ship type(s):" 1451 local player_count = 0 1452 for pidx=1,32 do 1453 local p = getPlayerShip(pidx) 1454 if p ~= nil and p:isValid() then 1455 player_count = player_count + 1 1456 out = out .. "\n " .. player_count .. ") " .. p:getTypeName() 1457 end 1458 end 1459 if player_count < ships_per_team then 1460 if player_count == 0 then 1461 out = string.format("%i player ships spawned. %i are required.\n\nUsing default ship set.\n\n%s",player_count,ships_per_team,out) 1462 elseif player_count == 1 then 1463 out = string.format("Only %i player ship spawned. %i are required.\n\nUsing default ship set.\n\n%s",player_count,ships_per_team,out) 1464 else 1465 out = string.format("Only %i player ships spawned. %i are required.\n\nUsing default ship set.\n\n%s",player_count,ships_per_team,out) 1466 end 1467 player_ship_types = "default" 1468 elseif player_count > ships_per_team then 1469 if ships_per_team == 1 then 1470 out = string.format("%i player ships spawned. Only %i is required.\n\nUsing default ship set.\n\n%s",player_count,ships_per_team,out) 1471 else 1472 out = string.format("%i player ships spawned. Only %i are required.\n\nUsing default ship set.\n\n%s",player_count,ships_per_team,out) 1473 end 1474 player_ship_types = "default" 1475 end 1476 addGMMessage(out) 1477 setPlayerShipTypes() 1478 end) 1479 button_label = "custom" 1480 if player_ship_types == button_label then 1481 button_label = button_label .. "*" 1482 end 1483 addGMFunction(string.format("+%s",button_label),setCustomPlayerShipSet) 1484end 1485function setCustomPlayerShipSet() 1486 clearGMFunctions() 1487 addGMFunction("-Main from Custom",mainGMButtons) 1488 addGMFunction("-Ship Types",setPlayerShipTypes) 1489 addGMFunction("+Customize Custom",setCustomSet) 1490 for ship_set_type,list in pairs(custom_player_ship_sets) do 1491 local button_label = ship_set_type 1492 if ship_set_type == custom_player_ship_type then 1493 button_label = button_label .. "*" 1494 end 1495 addGMFunction(button_label,function() 1496 player_ship_types = "custom" 1497 custom_player_ship_type = ship_set_type 1498 local out = "" 1499 if ships_per_team == 1 then 1500 out = string.format("Ship type set %s for %i player:",custom_player_ship_type,ships_per_team) 1501 else 1502 out = string.format("Ship type set %s for %i players:",custom_player_ship_type,ships_per_team) 1503 end 1504 for index, ship_type in ipairs(custom_player_ship_sets[custom_player_ship_type][ships_per_team]) do 1505-- print("index:",index,"ship type:",ship_type) 1506 out = out .. "\n " .. index .. ") " .. ship_type 1507 end 1508 addGMMessage(out) 1509 setCustomPlayerShipSet() 1510 end) 1511 end 1512end 1513function setCustomSet() 1514 clearGMFunctions() 1515 addGMFunction("-Main from Custom",mainGMButtons) 1516 addGMFunction("-Ship Types",setPlayerShipTypes) 1517 addGMFunction("-Custom Set",setCustomPlayerShipSet) 1518 if template_out == nil then 1519 template_out = custom_player_ship_sets["Custom"][ships_per_team][1] 1520 else 1521 local match_in_set = false 1522 for i=1,#custom_player_ship_sets["Custom"][ships_per_team] do 1523 if custom_player_ship_sets["Custom"][ships_per_team][i] == template_out then 1524 match_in_set = true 1525 end 1526 end 1527 if not match_in_set then 1528 template_out = custom_player_ship_sets["Custom"][ships_per_team][1] 1529 end 1530 end 1531 if template_in == nil then 1532 for name, details in pairs(player_ship_stats) do 1533 template_in = name 1534 break 1535 end 1536 end 1537 addGMFunction(string.format("+Out %s",template_out),setTemplateOut) 1538 addGMFunction(string.format("+In %s",template_in),setTemplateIn) 1539 addGMFunction("Swap",function() 1540 for i=1,#custom_player_ship_sets["Custom"][ships_per_team] do 1541 if custom_player_ship_sets["Custom"][ships_per_team][i] == template_out then 1542 custom_player_ship_sets["Custom"][ships_per_team][i] = template_in 1543 template_in = template_out 1544 template_out = custom_player_ship_sets["Custom"][ships_per_team][i] 1545 break 1546 end 1547 end 1548 setCustomSet() 1549 end) 1550end 1551function setTemplateOut() 1552 clearGMFunctions() 1553 table.sort(custom_player_ship_sets["Custom"][ships_per_team]) 1554 for i=1,#custom_player_ship_sets["Custom"][ships_per_team] do 1555 local button_label = custom_player_ship_sets["Custom"][ships_per_team][i] 1556 if template_out == custom_player_ship_sets["Custom"][ships_per_team][i] then 1557 button_label = button_label .. "*" 1558 end 1559 addGMFunction(button_label,function() 1560 template_out = custom_player_ship_sets["Custom"][ships_per_team][i] 1561 setCustomSet() 1562 end) 1563 end 1564end 1565function setTemplateIn() 1566 clearGMFunctions() 1567 local sorted_templates = {} 1568 for name, details in pairs(player_ship_stats) do 1569 table.insert(sorted_templates,name) 1570 end 1571 table.sort(sorted_templates) 1572 for _, name in ipairs(sorted_templates) do 1573 local button_label = name 1574 if template_in == name then 1575 button_label = button_label .. "*" 1576 end 1577 addGMFunction(button_label,function() 1578 template_in = name 1579 setCustomSet() 1580 end) 1581 end 1582end 1583-- Terrain related GM configuration functions 1584function setTerrainParameters() 1585 clearGMFunctions() 1586 addGMFunction("-Main from Terrain",mainGMButtons) 1587 if generate_terrain_message_counter % 5 == 0 then 1588 addGMMessage("Clicking the generate button will generate the terrain based on the number of player teams selected, the number of ships on a team and the terrain parameters selected.\n\nAfter you generate the terrain, you cannot change the player ships, or the terrain unless you restart the server.") 1589 end 1590 generate_terrain_message_counter = generate_terrain_message_counter + 1 1591 addGMFunction(string.format("Missiles: %s",missile_availability),setMissileAvailability) 1592 addGMFunction("+Primary Station",setPrimaryStationParameters) 1593 addGMFunction("Generate",function() 1594 generateTerrain() 1595 mainGMButtons() 1596 end) 1597end 1598function setStationSensorRange() 1599 clearGMFunctions() 1600 local button_label = "Zero" 1601 if station_sensor_range == 0 then 1602 button_label = button_label .. "*" 1603 end 1604 addGMFunction(button_label,function() 1605 station_sensor_range = 0 1606 mainGMButtons() 1607 end) 1608 button_label = "5U" 1609 if station_sensor_range == 5000 then 1610 button_label = button_label .. "*" 1611 end 1612 addGMFunction(button_label,function() 1613 station_sensor_range = 5000 1614 mainGMButtons() 1615 end) 1616 button_label = "10U" 1617 if station_sensor_range == 10000 then 1618 button_label = button_label .. "*" 1619 end 1620 addGMFunction(button_label,function() 1621 station_sensor_range = 10000 1622 mainGMButtons() 1623 end) 1624 button_label = "20U" 1625 if station_sensor_range == 20000 then 1626 button_label = button_label .. "*" 1627 end 1628 addGMFunction(button_label,function() 1629 station_sensor_range = 20000 1630 mainGMButtons() 1631 end) 1632 button_label = "30U" 1633 if station_sensor_range == 30000 then 1634 button_label = button_label .. "*" 1635 end 1636 addGMFunction(button_label,function() 1637 station_sensor_range = 30000 1638 mainGMButtons() 1639 end) 1640end 1641function setPrimaryStationParameters() 1642 clearGMFunctions() 1643 addGMFunction("-Main from Prm Stn",mainGMButtons) 1644 addGMFunction("-Terrain",setTerrainParameters) 1645 if defense_platform_count_options[defense_platform_count_index].count == "random" then 1646 addGMFunction("+Platforms: Random",setDefensePlatformCount) 1647 else 1648 addGMFunction(string.format("+Platforms: %i",defense_platform_count_options[defense_platform_count_index].count),setDefensePlatformCount) 1649 end 1650 if primary_station_size_index == 1 then 1651 addGMFunction("Random Size ->",function() 1652 primary_station_size_index = primary_station_size_index + 1 1653 setPrimaryStationParameters() 1654 end) 1655 else 1656 addGMFunction(string.format("%s ->",primary_station_size_options[primary_station_size_index]),function() 1657 primary_station_size_index = primary_station_size_index + 1 1658 if primary_station_size_index > #primary_station_size_options then 1659 primary_station_size_index = 1 1660 end 1661 setPrimaryStationParameters() 1662 end) 1663 end 1664 addGMFunction(string.format("Jammer: %s ->",primary_jammers),function() 1665 if primary_jammers == "random" then 1666 primary_jammers = "on" 1667 elseif primary_jammers == "on" then 1668 primary_jammers = "off" 1669 elseif primary_jammers == "off" then 1670 primary_jammers = "random" 1671 end 1672 setPrimaryStationParameters() 1673 end) 1674end 1675function setDefensePlatformCount() 1676 clearGMFunctions() 1677 addGMFunction("-Main from Platforms",mainGMButtons) 1678 addGMFunction("-Terrain",setTerrainParameters) 1679 addGMFunction("-Primary Station",setPrimaryStationParameters) 1680 if defense_platform_count_index < #defense_platform_count_options then 1681 if defense_platform_count_options[defense_platform_count_index + 1].count == "random" then 1682 addGMFunction(string.format("%i Platforms + -> Rnd",defense_platform_count_options[defense_platform_count_index].count),function() 1683 defense_platform_count_index = defense_platform_count_index + 1 1684 setDefensePlatformCount() 1685 end) 1686 else 1687 addGMFunction(string.format("%i Platforms + -> %i",defense_platform_count_options[defense_platform_count_index].count,defense_platform_count_options[defense_platform_count_index + 1].count),function() 1688 defense_platform_count_index = defense_platform_count_index + 1 1689 setDefensePlatformCount() 1690 end) 1691 end 1692 end 1693 if defense_platform_count_index > 1 then 1694 if defense_platform_count_options[defense_platform_count_index].count == "random" then 1695 addGMFunction(string.format("Rnd Platforms - -> %i",defense_platform_count_options[defense_platform_count_index - 1].count),function() 1696 defense_platform_count_index = defense_platform_count_index - 1 1697 setDefensePlatformCount() 1698 end) 1699 else 1700 addGMFunction(string.format("%i Platforms - -> %i",defense_platform_count_options[defense_platform_count_index].count,defense_platform_count_options[defense_platform_count_index - 1].count),function() 1701 defense_platform_count_index = defense_platform_count_index - 1 1702 setDefensePlatformCount() 1703 end) 1704 end 1705 end 1706end 1707-- Display player control codes 1708function showKraylorCodes() 1709 showControlCodes("Kraylor") 1710end 1711function showExuariCodes() 1712 showControlCodes("Exuari") 1713end 1714function showHumanCodes() 1715 showControlCodes("Human Navy") 1716end 1717function showKtlitanCodes() 1718 showControlCodes("Ktlitans") 1719end 1720function showControlCodes(faction_filter) 1721 local code_list = {} 1722 for pidx=1,32 do 1723 local p = getPlayerShip(pidx) 1724 if p ~= nil and p:isValid() then 1725 if faction_filter == "Kraylor" then 1726 if p:getFaction() == "Kraylor" then 1727 code_list[p:getCallSign()] = {code = p.control_code, faction = p:getFaction()} 1728 end 1729 elseif faction_filter == "Human Navy" then 1730 if p:getFaction() == "Human Navy" then 1731 code_list[p:getCallSign()] = {code = p.control_code, faction = p:getFaction()} 1732 end 1733 elseif faction_filter == "Exuari" then 1734 if p:getFaction() == "Exuari" then 1735 code_list[p:getCallSign()] = {code = p.control_code, faction = p:getFaction()} 1736 end 1737 elseif faction_filter == "Ktlitans" then 1738 if p:getFaction() == "Ktlitans" then 1739 code_list[p:getCallSign()] = {code = p.control_code, faction = p:getFaction()} 1740 end 1741 else 1742 code_list[p:getCallSign()] = {code = p.control_code, faction = p:getFaction()} 1743 end 1744 end 1745 end 1746 local sorted_names = {} 1747 for name in pairs(code_list) do 1748 table.insert(sorted_names,name) 1749 end 1750 table.sort(sorted_names) 1751 local output = "" 1752 for _, name in ipairs(sorted_names) do 1753 local faction = "" 1754 if code_list[name].faction == "Kraylor" then 1755 faction = " (Kraylor)" 1756 elseif code_list[name].faction == "Ktlitans" then 1757 faction = " (Ktlitan)" 1758 elseif code_list[name].faction == "Exuari" then 1759 faction = " (Exuari)" 1760 end 1761 output = output .. string.format("%s: %s %s\n",name,code_list[name].code,faction) 1762 end 1763 addGMMessage(output) 1764end 1765-- General configuration functions 1766function setGameTimeLimit() 1767 clearGMFunctions() 1768 addGMFunction("-Main from Time",mainGMButtons) 1769 if game_time_limit < 6000 then 1770 addGMFunction(string.format("%i Add 5 -> %i",game_time_limit/60,game_time_limit/60 + 5),function() 1771 game_time_limit = game_time_limit + 300 1772 max_game_time = game_time_limit 1773 setGameTimeLimit() 1774 end) 1775 end 1776 if game_time_limit > 300 then 1777 addGMFunction(string.format("%i Del 5 -> %i",game_time_limit/60,game_time_limit/60 - 5),function() 1778 game_time_limit = game_time_limit - 300 1779 max_game_time = game_time_limit 1780 setGameTimeLimit() 1781 end) 1782 end 1783end 1784function setMissileAvailability() 1785 clearGMFunctions() 1786 addGMFunction("-Main from Missiles",mainGMButtons) 1787 addGMFunction("-Terrain",setTerrainParameters) 1788 local button_label = "unlimited" 1789 if missile_availability == "unlimited" then 1790 button_label = button_label .. "*" 1791 end 1792 addGMFunction(button_label,function() 1793 missile_availability = "unlimited" 1794 setMissileAvailability() 1795 end) 1796 button_label = "outer limited" 1797 if missile_availability == "outer limited" then 1798 button_label = button_label .. "*" 1799 end 1800 addGMFunction(button_label,function() 1801 missile_availability = "outer limited" 1802 setMissileAvailability() 1803 end) 1804 button_label = "limited" 1805 if missile_availability == "limited" then 1806 button_label = button_label .. "*" 1807 end 1808 addGMFunction(button_label,function() 1809 missile_availability = "limited" 1810 setMissileAvailability() 1811 end) 1812end 1813function setNPCShips() 1814 clearGMFunctions() 1815 addGMFunction("-From NPC Strength",mainGMButtons) 1816 local button_label = "NPC Ships: No" 1817 if npc_ships then 1818 button_label = string.format("NPC Ships: %i-%i",npc_lower,npc_upper) 1819 end 1820 addGMFunction(button_label,function() 1821 if npc_ships then 1822 npc_ships = false 1823 else 1824 npc_ships = true 1825 end 1826 setNPCShips() 1827 end) 1828 if npc_ships then 1829 if npc_lower < npc_upper - 5 then 1830 addGMFunction(string.format("%i From Add -> %i",npc_lower,npc_lower + 5),function() 1831 npc_lower = npc_lower + 5 1832 setNPCShips() 1833 end) 1834 end 1835 if npc_lower > 10 then 1836 addGMFunction(string.format("%i From Del -> %i",npc_lower,npc_lower - 5),function() 1837 npc_lower = npc_lower - 5 1838 setNPCShips() 1839 end) 1840 end 1841 if npc_upper < 200 then 1842 addGMFunction(string.format("%i To Add -> %i",npc_upper,npc_upper + 5),function() 1843 npc_upper = npc_upper + 5 1844 setNPCShips() 1845 end) 1846 end 1847 if npc_upper > npc_lower + 5 then 1848 addGMFunction(string.format("%i To Del -> %i",npc_upper,npc_upper - 5),function() 1849 npc_upper = npc_upper - 5 1850 setNPCShips() 1851 end) 1852 end 1853 end 1854end 1855------------------------------------- 1856-- Generate terrain and stations -- 1857------------------------------------- 1858function generateTerrain() 1859-- Activities include: 1860-- Central terrain feature 1861-- Angle from center for each faction (used to place objects symmetrically) 1862-- Primary station and any defense platforms and/or defensive warp jammers 1863-- Positioning players around primary station 1864-- Placing other stations with varying capabilities and capacities 1865-- Wormholes, black holes, asteroids and nebulae 1866 if terrain_generated then 1867 return 1868 end 1869 terrain_generated = true 1870 terrain_center_x = random(200000,300000) 1871 terrain_center_y = random(100000,200000) 1872 local ta = Asteroid():setPosition(terrain_center_x,terrain_center_y) 1873 local terrain_center_sector = ta:getSectorName() 1874 addGMMessage(string.format("The center of the universe is in sector\n%s",terrain_center_sector)) 1875 ta:destroy() 1876 place_ref_list = {} 1877 human_ref_list = {} 1878 1879 -- decide what lives at the center of the universe 1880 local center_choice_list = {"Planet","Star","Black Hole"} 1881 local center_choice = center_choice_list[math.random(1,#center_choice_list)] 1882 if center_choice == "Planet" then 1883 local center_planet, center_radius = choosePlanet(math.random(2,3),terrain_center_x,terrain_center_y) 1884 table.insert(place_ref_list,center_planet) 1885 if random(1,100) <= 50 then 1886 local mx, my = vectorFromAngleNorth(random(0,360),center_radius + random(1000,2000)) 1887 local moon = choosePlanet(4,terrain_center_x + mx,terrain_center_y + my) 1888 moon:setOrbit(center_planet,random(200,400)) 1889 table.insert(place_ref_list,moon) 1890 end 1891 elseif center_choice == "Star" then 1892 local center_star, star_radius = choosePlanet(1,terrain_center_x,terrain_center_y) 1893 table.insert(place_ref_list,center_star) 1894 if random(1,100) <= 75 then 1895 local plx, ply = vectorFromAngleNorth(random(0,360),star_radius + random(8000,15000)) 1896 local orbit_planet, orbit_radius = choosePlanet(math.random(2,3),terrain_center_x + plx,terrain_center_y + ply) 1897 orbit_planet:setOrbit(center_star,random(800,2000)) 1898 table.insert(place_ref_list,orbit_planet) 1899 if random(1,100) <= 50 then 1900 local omx, omy = vectorFromAngleNorth(random(0,360),orbit_radius + random(1000,2000)) 1901 local orbit_moon = choosePlanet(4,terrain_center_x + plx + omx,terrain_center_y + ply + omy) 1902 orbit_moon:setOrbit(orbit_planet,random(200,400)) 1903 table.insert(place_ref_list,orbit_moon) 1904 end 1905 end 1906 elseif center_choice == "Black Hole" then 1907 local black_hole_names = { 1908 "Fornax A", 1909 "Sagittarius A", 1910 "Triangulum", 1911 "Cygnus X-3", 1912 "Messier 110", 1913 "Virgo A", 1914 "Andromeda", 1915 "Sombrero", 1916 "Great Annihilator", 1917 } 1918 table.insert(place_ref_list,BlackHole():setPosition(terrain_center_x,terrain_center_y):setCallSign(black_hole_names[math.random(1,#black_hole_names)])) 1919 end 1920 1921 -- Set angles 1922 faction_angle = {} 1923 npc_fleet = {} 1924 npc_fleet["Human Navy"] = {} 1925 npc_fleet["Kraylor"] = {} 1926 human_angle = random(0,360) 1927 faction_angle["Human Navy"] = human_angle 1928 local replicant_increment = 360/player_team_count 1929 kraylor_angle = (human_angle + replicant_increment) % 360 1930 faction_angle["Kraylor"] = kraylor_angle 1931 if player_team_count > 2 then 1932 exuari_angle = (kraylor_angle + replicant_increment) % 360 1933 faction_angle["Exuari"] = exuari_angle 1934 npc_fleet["Exuari"] = {} 1935 end 1936 if player_team_count > 3 then 1937 ktlitan_angle = (exuari_angle + replicant_increment) % 360 1938 faction_angle["Ktlitans"] = ktlitan_angle 1939 npc_fleet["Ktlitans"] = {} 1940 end 1941 1942 if respawn_type == "self" then 1943 death_penalty = {} 1944 death_penalty["Human Navy"] = 0 1945 death_penalty["Kraylor"] = 0 1946 if exuari_angle ~= nil then 1947 death_penalty["Exuari"] = 0 1948 end 1949 if ktlitan_angle ~= nil then 1950 death_penalty["Ktlitans"] = 0 1951 end 1952 end 1953 1954 -- Set primary stations 1955 local primary_station_distance = random(50000,100000) 1956 local primary_station_size = primary_station_size_options[primary_station_size_index] 1957 if primary_station_size == "random" then 1958 primary_station_size = szt() 1959 end 1960 base_station_value_list = { 1961 ["Huge Station"] = 10, 1962 ["Large Station"] = 5, 1963 ["Medium Station"] = 3, 1964 ["Small Station"] = 1, 1965 } 1966 faction_primary_station = {} 1967 local psx, psy = vectorFromAngleNorth(human_angle,primary_station_distance) 1968 station_primary_human = placeStation(terrain_center_x + psx, terrain_center_y + psy, "Random","Human Navy",primary_station_size) 1969 faction_primary_station["Human Navy"] = {x = terrain_center_x + psx, y = terrain_center_y + psy, station = station_primary_human} 1970 station_primary_human.score_value = base_station_value_list[primary_station_size] + 10 1971 station_list["Human Navy"] = {} 1972 table.insert(station_list["Human Navy"],station_primary_human) 1973 table.insert(place_ref_list,station_primary_human) 1974 table.insert(human_ref_list,station_primary_human) 1975 local unlimited_missiles = true 1976 if missile_availability == "limited" then 1977 unlimited_missiles = false 1978 end 1979 station_primary_human.comms_data = { 1980 friendlyness = random(75,100), 1981 weapon_cost = { 1982 Homing = math.random(1,6), 1983 Nuke = math.random(10,30), 1984 Mine = math.random(2,25), 1985 EMP = math.random(8,20), 1986 HVLI = math.random(1,4), 1987 }, 1988 weapon_available = { 1989 Homing = true, 1990 Nuke = true, 1991 Mine = true, 1992 EMP = true, 1993 HVLI = true, 1994 }, 1995 weapon_inventory = { 1996 Unlimited = unlimited_missiles, 1997 Homing = math.floor(math.random(10,50)/difficulty), 1998 Nuke = math.floor(math.random(5,30)/difficulty), 1999 Mine = math.floor(math.random(8,40)/difficulty), 2000 EMP = math.floor(math.random(6,34)/difficulty), 2001 HVLI = math.floor(math.random(15,70)/difficulty), 2002 }, 2003 services = { 2004 supplydrop = "friend", 2005 reinforcements = "friend", 2006 jumpsupplydrop = "friend", 2007 sensor_boost = "neutral", 2008 preorder = "friend", 2009 activatedefensefleet = "neutral", 2010 jumpovercharge = "neutral", 2011 jumpsupplydrop = "friend", 2012 }, 2013 service_cost = { 2014 supplydrop = math.random(80,120), 2015 reinforcements = math.random(125,175), 2016 hornetreinforcements = math.random(75,125), 2017 phobosreinforcements = math.random(175,225), 2018 jumpsupplydrop = math.random(110,140), 2019 activatedefensefleet = math.random(15,40), 2020 jumpovercharge = math.random(10,20), 2021 jumpsupplydrop = math.random(110,150), 2022 }, 2023 jump_overcharge = true, 2024 probe_launch_repair = true, 2025 hack_repair = true, 2026 scan_repair = true, 2027 combat_maneuver_repair= true, 2028 self_destruct_repair = true, 2029 tube_slow_down_repair = true, 2030 sensor_boost = {value = primary_station_distance-35000, cost = 0}, 2031 reputation_cost_multipliers = { 2032 friend = 1.0, 2033 neutral = 3.0, 2034 }, 2035 max_weapon_refill_amount = {friend = 1.0, neutral = 0.5 }, 2036 goods = { food = {quantity = 10, cost = 1}, 2037 medicine = {quantity = 10, cost = 5} }, 2038 trade = { food = false, medicine = false, luxury = false }, 2039 } 2040 station_primary_human.comms_data.idle_defense_fleet = defense_fleet_list[primary_station_size][math.random(1,#defense_fleet_list[primary_station_size])] 2041 psx, psy = vectorFromAngleNorth(kraylor_angle,primary_station_distance) 2042 station_primary_kraylor = placeStation(terrain_center_x + psx, terrain_center_y + psy, "Random","Kraylor",primary_station_size) 2043 faction_primary_station["Kraylor"] = {x = terrain_center_x + psx, y = terrain_center_y + psy, station = station_primary_kraylor} 2044 station_primary_kraylor.score_value = base_station_value_list[primary_station_size] + 10 2045 station_list["Kraylor"] = {} 2046 table.insert(station_list["Kraylor"],station_primary_kraylor) 2047 table.insert(place_ref_list,station_primary_kraylor) 2048 station_primary_kraylor.comms_data = station_primary_human.comms_data 2049 if exuari_angle ~= nil then 2050 psx, psy = vectorFromAngleNorth(exuari_angle,primary_station_distance) 2051 station_primary_exuari = placeStation(terrain_center_x + psx, terrain_center_y + psy, "Random","Exuari",primary_station_size) 2052 faction_primary_station["Exuari"] = {x = terrain_center_x + psx, y = terrain_center_y + psy, station = station_primary_exuari} 2053 station_primary_exuari.score_value = base_station_value_list[primary_station_size] + 10 2054 station_list["Exuari"] = {} 2055 table.insert(station_list["Exuari"],station_primary_exuari) 2056 table.insert(place_ref_list,station_primary_exuari) 2057 station_primary_exuari.comms_data = station_primary_human.comms_data 2058 end 2059 if ktlitan_angle ~= nil then 2060 psx, psy = vectorFromAngleNorth(ktlitan_angle,primary_station_distance) 2061 station_primary_ktlitan = placeStation(terrain_center_x + psx, terrain_center_y + psy, "Random","Ktlitans",primary_station_size) 2062 faction_primary_station["Ktlitans"] = {x = terrain_center_x + psx, y = terrain_center_y + psy, station = station_primary_ktlitan} 2063 station_primary_ktlitan.score_value = base_station_value_list[primary_station_size] + 10 2064 station_list["Ktlitans"] = {} 2065 table.insert(station_list["Ktlitans"],station_primary_ktlitan) 2066 table.insert(place_ref_list,station_primary_ktlitan) 2067 station_primary_ktlitan.comms_data = station_primary_human.comms_data 2068 end 2069 2070 -- Set defense platforms and jammers (if applicable) 2071 defense_platform_count = defense_platform_count_options[defense_platform_count_index].count 2072 defense_platform_distance = defense_platform_count_options[defense_platform_count_index].distance 2073 player_position_distance = defense_platform_count_options[defense_platform_count_index].player 2074 if defense_platform_count == "random" then 2075 local index = math.random(1,#defense_platform_count_options - 1) 2076 defense_platform_count = defense_platform_count_options[index].count 2077 defense_platform_distance = defense_platform_count_options[index].distance 2078 player_position_distance = defense_platform_count_options[index].player 2079 end 2080 if primary_jammers == "random" then 2081 primary_jammers = random(1,100) < 50 2082 else 2083 if primary_jammers == "on" then 2084 primary_jammers = true 2085 else 2086 primary_jammers = false 2087 end 2088 end 2089 local angle = human_angle 2090 local vx = 0 2091 local vy = 0 2092 unlimited_missiles = false 2093 if missile_availability == "unlimited" then 2094 unlimited_missiles = true 2095 end 2096 if defense_platform_count > 0 then 2097 local dp = nil 2098 angle = human_angle 2099 psx, psy = station_primary_human:getPosition() 2100 local dp_list = {} 2101 for i=1,defense_platform_count do 2102 vx, vy = vectorFromAngleNorth(angle,defense_platform_distance) 2103 dp = CpuShip():setTemplate("Defense platform"):setFaction("Human Navy"):setPosition(psx + vx,psy + vy):setScannedByFaction("Human Navy",true):setCallSign(string.format("HDP%i",i)):setDescription(string.format("%s defense platform %i",station_primary_human:getCallSign(),i)):orderRoaming() 2104 dp.score_value = 50 2105 table.insert(npc_fleet["Human Navy"],dp) 2106 dp:setCommsScript(""):setCommsFunction(commsDefensePlatform) 2107 dp.primary_station = station_primary_human 2108 if primary_jammers then 2109 vx, vy = vectorFromAngleNorth(angle,defense_platform_distance/2) 2110 WarpJammer():setPosition(psx + vx, psy + vy):setRange(defense_platform_distance/2 + 4000):setFaction("Human Navy") 2111 end 2112 dp.comms_data = { --defense platform comms data 2113 weapon_available = { 2114 Homing = random(1,13)<=(3-difficulty), 2115 HVLI = random(1,13)<=(6-difficulty), 2116 Mine = false, 2117 Nuke = false, 2118 EMP = false, 2119 }, 2120 weapon_inventory = { 2121 Unlimited = unlimited_missiles, 2122 Homing = math.floor(math.random(10,50)/difficulty), 2123 Nuke = 0, 2124 Mine = 0, 2125 EMP = 0, 2126 HVLI = math.floor(math.random(15,70)/difficulty), 2127 }, 2128 services = { 2129 supplydrop = "friend", 2130 reinforcements = "friend", 2131 jumpsupplydrop = "friend", 2132 }, 2133 service_cost = { 2134 supplydrop = math.random(80,120), 2135 reinforcements = math.random(125,175), 2136 jumpsupplydrop = math.random(110,140), 2137 }, 2138 jump_overcharge = false, 2139 probe_launch_repair = random(1,100) <= (20 - difficulty*2.5), 2140 hack_repair = random(1,100) <= (22 - difficulty*2.5), 2141 scan_repair = random(1,100) <= (30 - difficulty*2.5), 2142 combat_maneuver_repair= random(1,100) <= (15 - difficulty*2.5), 2143 self_destruct_repair = random(1,100) <= (25 - difficulty*2.5), 2144 tube_slow_down_repair = random(1,100) <= (18 - difficulty*2.5), 2145 reputation_cost_multipliers = { 2146 friend = 1.0, 2147 neutral = 3.0, 2148 }, 2149 } 2150 dp:setSharesEnergyWithDocked(random(1,100) <= (60 - difficulty*5)) 2151 dp:setRepairDocked(random(1,100) <= (50 - difficulty*5)) 2152 dp:setRestocksScanProbes(random(1,100) <= (40 - difficulty*5)) 2153 table.insert(dp_list,dp) 2154 table.insert(place_ref_list,dp) 2155 table.insert(human_ref_list,dp) 2156 angle = (angle + 360/defense_platform_count) % 360 2157 end 2158 angle = kraylor_angle 2159 psx, psy = station_primary_kraylor:getPosition() 2160 for i=1,defense_platform_count do 2161 vx, vy = vectorFromAngleNorth(angle,defense_platform_distance) 2162 dp = CpuShip():setTemplate("Defense platform"):setFaction("Kraylor"):setPosition(psx + vx,psy + vy):setScannedByFaction("Kraylor",true):setCallSign(string.format("KDP%i",i)):setDescription(string.format("%s defense platform %i",station_primary_kraylor:getCallSign(),i)):orderRoaming() 2163 dp.score_value = 50 2164 table.insert(npc_fleet["Kraylor"],dp) 2165 dp:setCommsScript(""):setCommsFunction(commsDefensePlatform) 2166 dp.primary_station = station_primary_kraylor 2167 if primary_jammers then 2168 vx, vy = vectorFromAngleNorth(angle,defense_platform_distance/2) 2169 WarpJammer():setPosition(psx + vx, psy + vy):setRange(defense_platform_distance/2 + 4000):setFaction("Kraylor") 2170 end 2171 dp.comms_data = dp_list[i].comms_data --replicate capabilities 2172 dp:setSharesEnergyWithDocked(dp_list[i]:getSharesEnergyWithDocked()) 2173 dp:setRepairDocked(dp_list[i]:getRepairDocked()) 2174 dp:setRestocksScanProbes(dp_list[i]:getRestocksScanProbes()) 2175 table.insert(place_ref_list,dp) 2176 angle = (angle + 360/defense_platform_count) % 360 2177 end 2178 if exuari_angle ~= nil then 2179 angle = exuari_angle 2180 psx, psy = station_primary_exuari:getPosition() 2181 for i=1,defense_platform_count do 2182 vx, vy = vectorFromAngleNorth(angle,defense_platform_distance) 2183 dp = CpuShip():setTemplate("Defense platform"):setFaction("Exuari"):setPosition(psx + vx,psy + vy):setScannedByFaction("Exuari",true):setCallSign(string.format("EDP%i",i)):setDescription(string.format("%s defense platform %i",station_primary_exuari:getCallSign(),i)):orderRoaming() 2184 dp.score_value = 50 2185 table.insert(npc_fleet["Exuari"],dp) 2186 dp:setCommsScript(""):setCommsFunction(commsDefensePlatform) 2187 dp.primary_station = station_primary_exuari 2188 if primary_jammers then 2189 vx, vy = vectorFromAngleNorth(angle,defense_platform_distance/2) 2190 WarpJammer():setPosition(psx + vx, psy + vy):setRange(defense_platform_distance/2 + 4000):setFaction("Exuari") 2191 end 2192 dp.comms_data = dp_list[i].comms_data --replicate capabilities 2193 dp:setSharesEnergyWithDocked(dp_list[i]:getSharesEnergyWithDocked()) 2194 dp:setRepairDocked(dp_list[i]:getRepairDocked()) 2195 dp:setRestocksScanProbes(dp_list[i]:getRestocksScanProbes()) 2196 table.insert(place_ref_list,dp) 2197 angle = (angle + 360/defense_platform_count) % 360 2198 end 2199 end 2200 if ktlitan_angle ~= nil then 2201 angle = ktlitan_angle 2202 psx, psy = station_primary_ktlitan:getPosition() 2203 for i=1,defense_platform_count do 2204 vx, vy = vectorFromAngleNorth(angle,defense_platform_distance) 2205 dp = CpuShip():setTemplate("Defense platform"):setFaction("Ktlitans"):setPosition(psx + vx,psy + vy):setScannedByFaction("Ktlitans",true):setCallSign(string.format("BDP%i",i)):setDescription(string.format("%s defense platform %i",station_primary_ktlitan:getCallSign(),i)):orderRoaming() 2206 dp.score_value = 50 2207 table.insert(npc_fleet["Ktlitans"],dp) 2208 dp:setCommsScript(""):setCommsFunction(commsDefensePlatform) 2209 dp.primary_station = station_primary_ktlitan 2210 if primary_jammers then 2211 vx, vy = vectorFromAngleNorth(angle,defense_platform_distance/2) 2212 WarpJammer():setPosition(psx + vx, psy + vy):setRange(defense_platform_distance/2 + 4000):setFaction("Ktlitans") 2213 end 2214 dp.comms_data = dp_list[i].comms_data --replicate capabilities 2215 dp:setSharesEnergyWithDocked(dp_list[i]:getSharesEnergyWithDocked()) 2216 dp:setRepairDocked(dp_list[i]:getRepairDocked()) 2217 dp:setRestocksScanProbes(dp_list[i]:getRestocksScanProbes()) 2218 table.insert(place_ref_list,dp) 2219 angle = (angle + 360/defense_platform_count) % 360 2220 end 2221 end 2222 else --no defense platforms 2223 if primary_jammers then 2224 local jammer_distance = 4000 2225 local jammer_range = 8000 2226 angle = human_angle 2227 psx, psy = station_primary_human:getPosition() 2228 for i=1,4 do 2229 vx, vy = vectorFromAngleNorth(angle,jammer_distance) 2230 local wj = WarpJammer():setPosition(psx + vx, psy + vy):setRange(jammer_range):setFaction("Human Navy") 2231 table.insert(place_ref_list,wj) 2232 table.insert(human_ref_list,wj) 2233 angle = (angle + 90) % 360 2234 end 2235 angle = kraylor_angle 2236 psx, psy = station_primary_kraylor:getPosition() 2237 for i=1,4 do 2238 vx, vy = vectorFromAngleNorth(angle,jammer_distance) 2239 table.insert(place_ref_list,WarpJammer():setPosition(psx + vx, psy + vy):setRange(jammer_range):setFaction("Kraylor")) 2240 angle = (angle + 90) % 360 2241 end 2242 if exuari_angle ~= nil then 2243 angle = exuari_angle 2244 psx, psy = station_primary_exuari:getPosition() 2245 for i=1,4 do 2246 vx, vy = vectorFromAngleNorth(angle,jammer_distance) 2247 table.insert(place_ref_list,WarpJammer():setPosition(psx + vx, psy + vy):setRange(jammer_range):setFaction("Exuari")) 2248 angle = (angle + 90) % 360 2249 end 2250 end 2251 if ktlitan_angle ~= nil then 2252 angle = ktlitan_angle 2253 psx, psy = station_primary_ktlitan:getPosition() 2254 for i=1,4 do 2255 vx, vy = vectorFromAngleNorth(angle,jammer_distance) 2256 table.insert(place_ref_list,WarpJammer():setPosition(psx + vx, psy + vy):setRange(jammer_range):setFaction("Ktlitans")) 2257 angle = (angle + 90) % 360 2258 end 2259 end 2260 end 2261 end 2262 2263 -- Place players 2264 player_restart = {} 2265 if player_ship_types == "spawned" then 2266 local player_count = 0 2267 for pidx=1,32 do 2268 local p = getPlayerShip(pidx) 2269 if p ~= nil and p:isValid() then 2270 player_count = player_count + 1 2271 end 2272 end 2273 local out = "" 2274 if player_count < ships_per_team then 2275 if player_count == 0 then 2276 out = string.format("No player ships spawned. %i are required.\n\nUsing default ship set.",ships_per_team) 2277 elseif player_count == 1 then 2278 out = string.format("Only one player ship spawned. %i are required.\n\nUsing default ship set.",ships_per_team) 2279 else 2280 out = string.format("Only %i player ships spawned. %i are required.\n\nUsing default ship set.",player_count,ships_per_team) 2281 end 2282 player_ship_types = "default" 2283 addGMMessage(out) 2284 placeDefaultPlayerShips() 2285 elseif player_count > ships_per_team then 2286 if ships_per_team == 1 then 2287 out = string.format("%i player ships spawned. Only %i is required.\n\nUsing default ship set.",player_count,ships_per_team) 2288 else 2289 out = string.format("%i player ships spawned. Only %i are required.\n\nUsing default ship set.",player_count,ships_per_team) 2290 end 2291 player_ship_types = "default" 2292 addGMMessage(out) 2293 placeDefaultPlayerShips() 2294 end 2295 psx, psy = station_primary_human:getPosition() 2296 angle = human_angle 2297 for pidx=1,ships_per_team do 2298 local p = getPlayerShip(pidx) 2299 if p ~= nil and p:isValid() then 2300 setPlayer(p) 2301 startPlayerPosition(p,angle) 2302 local respawn_x, respawn_y = p:getPosition() 2303 p.respawn_x = respawn_x 2304 p.respawn_y = respawn_y 2305 player_restart[p:getCallSign()] = {self = p, template = p:getTypeName(), control_code = p.control_code, faction = p:getFaction(), respawn_x = respawn_x, respawn_y = respawn_y} 2306 angle = (angle + 360/ships_per_team) % 360 2307 else 2308 addGMMessage("One of the player ships spawned is not valid, switching to default ship set") 2309 player_ship_types = "default" 2310 break 2311 end 2312 end 2313 if player_ship_types == "default" then 2314 placeDefaultPlayerShips() 2315 else 2316 replicatePlayers("Kraylor") 2317 if exuari_angle ~= nil then 2318 replicatePlayers("Exuari") 2319 end 2320 if ktlitan_angle ~= nil then 2321 replicatePlayers("Ktlitans") 2322 end 2323 end 2324 elseif player_ship_types == "custom" then 2325 placeCustomPlayerShips() 2326 else --default 2327 placeDefaultPlayerShips() 2328 end 2329 for pidx=1,32 do 2330 local p = getPlayerShip(pidx) 2331 if p ~= nil and p:isValid() then 2332 table.insert(place_ref_list,p) 2333 if p:getFaction() == "Human Navy" then 2334 table.insert(human_ref_list,p) 2335 end 2336 end 2337 end 2338 2339 -- Place NPC ships (if applicable) 2340 local npc_fleet_count = 0 2341 if npc_ships then 2342 npc_fleet_count = math.random(1,ships_per_team) 2343 local fleet_index = 1 2344 local fleet_angle_increment = 360/npc_fleet_count 2345 for n=1,npc_fleet_count do 2346 local angle = (human_angle + n * fleet_angle_increment) % 360 2347 local fleet_strength = random(npc_lower,npc_upper) 2348 local pool_selectivity_choices = {"full","less/heavy","more/light"} 2349 pool_selectivity = pool_selectivity_choices[math.random(1,#pool_selectivity_choices)] 2350 local fleetComposition_choices = {"Random","Non-DB","Fighters","Chasers","Frigates","Beamers","Missilers","Adders","Drones"} 2351 fleetComposition = fleetComposition_choices[math.random(1,#fleetComposition_choices)] 2352 local fcx, fcy = vectorFromAngleNorth(angle,defense_platform_distance + 5000) 2353 psx, psy = station_primary_human:getPosition() 2354 local human_fleet = spawnRandomArmed(psx + fcx, psy + fcy, fleet_strength, fleet_index, nil, angle) 2355 fleet_index = fleet_index + 1 2356 for _, ship in ipairs(human_fleet) do 2357 ship.score_value = ship_template[ship:getTypeName()].strength 2358 ship:setScannedByFaction("Human Navy",true) 2359 table.insert(human_ref_list,ship) 2360 table.insert(place_ref_list,ship) 2361 table.insert(npc_fleet["Human Navy"],ship) 2362 end 2363 fleet_index = fleet_index + 1 2364 local fleet_prefix = generateCallSignPrefix() 2365 angle = (kraylor_angle + n * fleet_angle_increment) % 360 2366 for _, source_ship in ipairs(human_fleet) do 2367 local sx, sy = source_ship:getPosition() 2368 local obj_ref_angle = angleFromVectorNorth(sx, sy, terrain_center_x, terrain_center_y) 2369 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, sx, sy) 2370 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2371 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2372 local selected_template = source_ship:getTypeName() 2373 local ship = ship_template[selected_template].create("Kraylor",selected_template) 2374 ship.score_value = ship_template[selected_template].strength 2375 ship:setScannedByFaction("Kraylor",true) 2376 ship:setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2377 ship:setCallSign(generateCallSign(fleet_prefix)) 2378 ship:setCommsScript(""):setCommsFunction(commsShip) 2379 ship:orderIdle() 2380 ship:setHeading(angle) 2381 ship:setRotation(angle + 270) 2382 ship.fleetIndex = fleet_index 2383 table.insert(place_ref_list,ship) 2384 table.insert(npc_fleet["Kraylor"],ship) 2385 end 2386 if exuari_angle ~= nil then 2387 fleet_index = fleet_index + 1 2388 local fleet_prefix = generateCallSignPrefix() 2389 angle = (exuari_angle + n * fleet_angle_increment) % 360 2390 for _, source_ship in ipairs(human_fleet) do 2391 local sx, sy = source_ship:getPosition() 2392 local obj_ref_angle = angleFromVectorNorth(sx, sy, terrain_center_x, terrain_center_y) 2393 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, sx, sy) 2394 obj_ref_angle = (obj_ref_angle + replicant_increment * 2) % 360 2395 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2396 local selected_template = source_ship:getTypeName() 2397 local ship = ship_template[selected_template].create("Exuari",selected_template) 2398 ship.score_value = ship_template[selected_template].strength 2399 ship:setScannedByFaction("Exuari",true) 2400 ship:setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2401 ship:setCallSign(generateCallSign(fleet_prefix)) 2402 ship:setCommsScript(""):setCommsFunction(commsShip) 2403 ship:orderIdle() 2404 ship:setHeading(angle) 2405 ship:setRotation(angle + 270) 2406 ship.fleetIndex = fleet_index 2407 table.insert(place_ref_list,ship) 2408 table.insert(npc_fleet["Exuari"],ship) 2409 end 2410 end 2411 if ktlitan_angle ~= nil then 2412 fleet_index = fleet_index + 1 2413 local fleet_prefix = generateCallSignPrefix() 2414 angle = (ktlitan_angle + n * fleet_angle_increment) % 360 2415 for _, source_ship in ipairs(human_fleet) do 2416 local sx, sy = source_ship:getPosition() 2417 local obj_ref_angle = angleFromVectorNorth(sx, sy, terrain_center_x, terrain_center_y) 2418 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, sx, sy) 2419 obj_ref_angle = (obj_ref_angle + replicant_increment * 3) % 360 2420 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2421 local selected_template = source_ship:getTypeName() 2422 local ship = ship_template[selected_template].create("Ktlitans",selected_template) 2423 ship.score_value = ship_template[selected_template].strength 2424 ship:setScannedByFaction("Ktlitans",true) 2425 ship:setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2426 ship:setCallSign(generateCallSign(fleet_prefix)) 2427 ship:setCommsScript(""):setCommsFunction(commsShip) 2428 ship:orderIdle() 2429 ship:setHeading(angle) 2430 ship:setRotation(angle + 270) 2431 ship.fleetIndex = fleet_index 2432 table.insert(place_ref_list,ship) 2433 table.insert(npc_fleet["Ktlitans"],ship) 2434 end 2435 end 2436 end 2437 end 2438 2439 -- Place stations 2440 local candidate_x = 0 2441 local candidate_y = 0 2442 local center_x = 0 2443 local center_y = 0 2444 local perimeter = 0 2445 local avg_dist = 0 2446 local bubble = 2500 2447 local team_station_count_list = {50,25,16,12} 2448 local stretch_bound = 0 2449 for i=1,team_station_count_list[player_team_count] do 2450 center_x, center_y, perimeter, avg_dist = analyzeBlob(human_ref_list) 2451 stretch_bound = 5000 2452 repeat 2453 candidate_x, candidate_y = vectorFromAngleNorth(random(0,360),random(math.min(avg_dist,5000),math.min(perimeter,50000) + stretch_bound)) 2454 candidate_x = center_x + candidate_x 2455 candidate_y = center_y + candidate_y 2456 stretch_bound = stretch_bound + 500 2457 until(farEnough(place_ref_list,candidate_x,candidate_y,math.max(perimeter/i,15000))) 2458 local sr_size = szt() 2459 local pStation = placeStation(candidate_x, candidate_y, "Random","Human Navy",sr_size) 2460 table.insert(station_list["Human Navy"],pStation) 2461 pStation.score_value = base_station_value_list[sr_size] 2462 table.insert(place_ref_list,pStation) 2463 table.insert(human_ref_list,pStation) 2464 pStation.comms_data = { 2465 friendlyness = random(15,100), 2466 weapon_cost = { 2467 Homing = math.random(2,8), 2468 Nuke = math.random(12,30), 2469 Mine = math.random(3,28), 2470 EMP = math.random(9,25), 2471 HVLI = math.random(2,5), 2472 }, 2473 weapon_available = { 2474 Homing = random(1,13)<=(6-difficulty), 2475 HVLI = random(1,13)<=(6-difficulty), 2476 Mine = random(1,13)<=(5-difficulty), 2477 Nuke = random(1,13)<=(4-difficulty), 2478 EMP = random(1,13)<=(4-difficulty), 2479 }, 2480 weapon_inventory = { 2481 Unlimited = unlimited_missiles, 2482 Homing = math.floor(math.random(10,40)/difficulty), 2483 Nuke = math.floor(math.random(5,20)/difficulty), 2484 Mine = math.floor(math.random(8,30)/difficulty), 2485 EMP = math.floor(math.random(6,24)/difficulty), 2486 HVLI = math.floor(math.random(15,50)/difficulty), 2487 }, 2488 services = { 2489 supplydrop = "friend", 2490 reinforcements = "friend", 2491 jumpsupplydrop = "friend", 2492 sensor_boost = "neutral", 2493 preorder = "friend", 2494 activatedefensefleet = "neutral", 2495 jumpovercharge = "neutral", 2496 }, 2497 service_cost = { 2498 supplydrop = math.random(80,120), 2499 reinforcements = math.random(125,175), 2500 hornetreinforcements = math.random(75,125), 2501 phobosreinforcements = math.random(175,225), 2502 activatedefensefleet = math.random(15,40), 2503 jumpovercharge = math.random(10,20), 2504 jumpsupplydrop = math.random(110,140), 2505 }, 2506 jump_overcharge = random(1,100) <= (20 - difficulty*2.5), 2507 probe_launch_repair = random(1,100) <= (33 - difficulty*2.5), 2508 hack_repair = random(1,100) <= (42 - difficulty*2.5), 2509 scan_repair = random(1,100) <= (50 - difficulty*2.5), 2510 combat_maneuver_repair= random(1,100) <= (28 - difficulty*2.5), 2511 self_destruct_repair = random(1,100) <= (25 - difficulty*2.5), 2512 tube_slow_down_repair = random(1,100) <= (35 - difficulty*2.5), 2513 reputation_cost_multipliers = { 2514 friend = 1.0, 2515 neutral = 3.0, 2516 }, 2517 max_weapon_refill_amount = {friend = 1.0, neutral = 0.5 }, 2518 } 2519 pStation.comms_data.idle_defense_fleet = defense_fleet_list[sr_size][math.random(1,#defense_fleet_list[sr_size])] 2520 pStation:setSharesEnergyWithDocked(random(1,100) <= (50 - difficulty*5)) 2521 pStation:setRepairDocked(random(1,100) <= (40 - difficulty*5)) 2522 pStation:setRestocksScanProbes(random(1,100) <= (30 - difficulty*5)) 2523 if scientist_count < 5 then 2524 if random(1,100) < 20 then 2525 if scientist_list["Human Navy"] == nil then 2526 scientist_list["Human Navy"] = {} 2527 end 2528 table.insert( 2529 scientist_list["Human Navy"], 2530 { 2531 name = tableRemoveRandom(scientist_names), 2532 topic = tableRemoveRandom(scientist_topics), 2533 location = pStation, 2534 location_name = pStation:getCallSign(), 2535 score_value = scientist_score_value, 2536 upgrade_requirement = upgrade_requirements[math.random(1,#upgrade_requirements)], 2537 upgrade = tableRemoveRandom(upgrade_list), 2538 upgrade_automated_application = upgrade_automated_applications[math.random(1,#upgrade_automated_applications)], 2539 } 2540 ) 2541 scientist_count = scientist_count + 1 2542 end 2543 end 2544 2545 local obj_ref_angle = angleFromVectorNorth(candidate_x, candidate_y, terrain_center_x, terrain_center_y) 2546 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, candidate_x, candidate_y) 2547 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2548 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2549 pStation = placeStation(terrain_center_x + rep_x, terrain_center_y + rep_y, "Random","Kraylor",sr_size) 2550 table.insert(station_list["Kraylor"],pStation) 2551 pStation.score_value = base_station_value_list[sr_size] 2552 pStation.comms_data = human_ref_list[#human_ref_list].comms_data 2553 pStation:setSharesEnergyWithDocked(human_ref_list[#human_ref_list]:getSharesEnergyWithDocked()) 2554 pStation:setRepairDocked(human_ref_list[#human_ref_list]:getRepairDocked()) 2555 pStation:setRestocksScanProbes(human_ref_list[#human_ref_list]:getRestocksScanProbes()) 2556 table.insert(place_ref_list,pStation) 2557 if scientist_list["Human Navy"] ~= nil then 2558 if scientist_list["Kraylor"] == nil then 2559 scientist_list["Kraylor"] = {} 2560 end 2561 if #scientist_list["Kraylor"] < #scientist_list["Human Navy"] then 2562 table.insert( 2563 scientist_list["Kraylor"], 2564 { 2565 name = tableRemoveRandom(scientist_names), 2566 topic = scientist_list["Human Navy"][#scientist_list["Human Navy"]].topic, 2567 location = pStation, 2568 location_name = pStation:getCallSign(), 2569 score_value = scientist_score_value, 2570 upgrade_requirement = upgrade_requirements[math.random(1,#upgrade_requirements)], 2571 upgrade = scientist_list["Human Navy"][#scientist_list["Human Navy"]].upgrade, 2572 upgrade_automated_application = scientist_list["Human Navy"][#scientist_list["Human Navy"]].upgrade_automated_application, 2573 } 2574 ) 2575 end 2576 end 2577 if exuari_angle ~= nil then 2578 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2579 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2580 pStation = placeStation(terrain_center_x + rep_x, terrain_center_y + rep_y, "Random","Exuari",sr_size) 2581 table.insert(station_list["Exuari"],pStation) 2582 pStation.score_value = base_station_value_list[sr_size] 2583 pStation.comms_data = human_ref_list[#human_ref_list].comms_data 2584 pStation:setSharesEnergyWithDocked(human_ref_list[#human_ref_list]:getSharesEnergyWithDocked()) 2585 pStation:setRepairDocked(human_ref_list[#human_ref_list]:getRepairDocked()) 2586 pStation:setRestocksScanProbes(human_ref_list[#human_ref_list]:getRestocksScanProbes()) 2587 table.insert(place_ref_list,pStation) 2588 if scientist_list["Human Navy"] ~= nil then 2589 if scientist_list["Exuari"] == nil then 2590 scientist_list["Exuari"] = {} 2591 end 2592 if #scientist_list["Exuari"] < #scientist_list["Human Navy"] then 2593 table.insert( 2594 scientist_list["Exuari"], 2595 { 2596 name = tableRemoveRandom(scientist_names), 2597 topic = scientist_list["Human Navy"][#scientist_list["Human Navy"]].topic, 2598 location = pStation, 2599 location_name = pStation:getCallSign(), 2600 score_value = scientist_score_value, 2601 upgrade_requirement = upgrade_requirements[math.random(1,#upgrade_requirements)], 2602 upgrade = scientist_list["Human Navy"][#scientist_list["Human Navy"]].upgrade, 2603 upgrade_automated_application = scientist_list["Human Navy"][#scientist_list["Human Navy"]].upgrade_automated_application, 2604 } 2605 ) 2606 end 2607 end 2608 end 2609 if ktlitan_angle ~= nil then 2610 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2611 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2612 pStation = placeStation(terrain_center_x + rep_x, terrain_center_y + rep_y, "Random","Ktlitans",sr_size) 2613 table.insert(station_list["Ktlitans"],pStation) 2614 pStation.score_value = base_station_value_list[sr_size] 2615 pStation.comms_data = human_ref_list[#human_ref_list].comms_data 2616 pStation:setSharesEnergyWithDocked(human_ref_list[#human_ref_list]:getSharesEnergyWithDocked()) 2617 pStation:setRepairDocked(human_ref_list[#human_ref_list]:getRepairDocked()) 2618 pStation:setRestocksScanProbes(human_ref_list[#human_ref_list]:getRestocksScanProbes()) 2619 table.insert(place_ref_list,pStation) 2620 if scientist_list["Human Navy"] ~= nil then 2621 if scientist_list["Ktlitans"] == nil then 2622 scientist_list["Ktlitans"] = {} 2623 end 2624 if #scientist_list["Ktlitans"] < #scientist_list["Human Navy"] then 2625 table.insert( 2626 scientist_list["Ktlitans"], 2627 { 2628 name = tableRemoveRandom(scientist_names), 2629 topic = scientist_list["Human Navy"][#scientist_list["Human Navy"]].topic, 2630 location = pStation, 2631 location_name = pStation:getCallSign(), 2632 score_value = scientist_score_value, 2633 upgrade_requirement = upgrade_requirements[math.random(1,#upgrade_requirements)], 2634 upgrade = scientist_list["Human Navy"][#scientist_list["Human Navy"]].upgrade, 2635 upgrade_automated_application = scientist_list["Human Navy"][#scientist_list["Human Navy"]].upgrade_automated_application, 2636 } 2637 ) 2638 end 2639 end 2640 end 2641 end --station build loop 2642 2643 -- Build some wormholes if applicable 2644 local hole_list = {} 2645 local wormhole_count = math.random(0,3) 2646 if wormhole_count > 0 then 2647 for w=1,wormhole_count do 2648 center_x, center_y, perimeter, avg_dist = analyzeBlob(human_ref_list) 2649 stretch_bound = 5000 2650 bubble = 6000 2651 repeat 2652-- print("wormhole candidate numbers. average distance:",avg_dist,"perimeter:",perimeter) 2653 candidate_x, candidate_y = vectorFromAngleNorth(random(0,360),random(math.min(avg_dist,20000),math.min(perimeter,100000) + stretch_bound)) 2654 candidate_x = center_x + candidate_x 2655 candidate_y = center_y + candidate_y 2656 stretch_bound = stretch_bound + 500 2657 until(farEnough(place_ref_list,candidate_x,candidate_y,bubble)) 2658 local wormhole = WormHole():setPosition(candidate_x,candidate_y) 2659 table.insert(place_ref_list,wormhole) 2660 table.insert(human_ref_list,wormhole) 2661 table.insert(hole_list,wormhole) 2662 center_x, center_y, perimeter, avg_dist = analyzeBlob(human_ref_list) 2663 stretch_bound = 5000 2664 local target_candidate_x = 0 2665 local target_candidate_y = 0 2666 repeat 2667 target_candidate_x, target_candidate_y = vectorFromAngleNorth(random(0,360),random(avg_dist,50000 + perimeter + stretch_bound)) 2668 target_candidate_x = center_x + target_candidate_x 2669 target_candidate_y = center_y + target_candidate_y 2670 stretch_bound = stretch_bound + 500 2671 until(farEnough(place_ref_list,target_candidate_x,target_candidate_y,bubble)) 2672 local ta = VisualAsteroid():setPosition(target_candidate_x,target_candidate_y) 2673 table.insert(place_ref_list,ta) 2674 table.insert(human_ref_list,ta) 2675 wormhole:setTargetPosition(target_candidate_x,target_candidate_y) 2676 2677 local obj_ref_angle = angleFromVectorNorth(candidate_x, candidate_y, terrain_center_x, terrain_center_y) 2678 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, candidate_x, candidate_y) 2679 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2680 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2681 wormhole = WormHole():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2682 table.insert(place_ref_list,wormhole) 2683 table.insert(hole_list,wormhole) 2684 local target_ref_angle = angleFromVectorNorth(target_candidate_x, target_candidate_y, terrain_center_x, terrain_center_y) 2685 local target_ref_distance = distance(terrain_center_x, terrain_center_y, target_candidate_x, target_candidate_y) 2686 target_ref_angle = (target_ref_angle + replicant_increment) % 360 2687 rep_x, rep_y = vectorFromAngleNorth(target_ref_angle,target_ref_distance) 2688 wormhole:setTargetPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2689 2690 if exuari_angle ~= nil then 2691 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2692 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2693 wormhole = WormHole():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2694 table.insert(place_ref_list,wormhole) 2695 table.insert(hole_list,wormhole) 2696 target_ref_angle = (target_ref_angle + replicant_increment) % 360 2697 rep_x, rep_y = vectorFromAngleNorth(target_ref_angle,target_ref_distance) 2698 wormhole:setTargetPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2699 end 2700 if ktlitan_angle ~= nil then 2701 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2702 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2703 wormhole = WormHole():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2704 table.insert(place_ref_list,wormhole) 2705 table.insert(hole_list,wormhole) 2706 target_ref_angle = (target_ref_angle + replicant_increment) % 360 2707 rep_x, rep_y = vectorFromAngleNorth(target_ref_angle,target_ref_distance) 2708 wormhole:setTargetPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2709 end 2710 end 2711 end --wormhole build 2712 2713 -- Maybe sprinkle in some black holes 2714 local blackhole_count = math.random(0,6) 2715 if blackhole_count > 0 then 2716 for b=1,blackhole_count do 2717 center_x, center_y, perimeter, avg_dist = analyzeBlob(human_ref_list) 2718 stretch_bound = 5000 2719 bubble = 6000 2720 repeat 2721 candidate_x, candidate_y = vectorFromAngleNorth(random(0,360),random(math.min(avg_dist,20000),math.min(perimeter,100000) + stretch_bound)) 2722 candidate_x = center_x + candidate_x 2723 candidate_y = center_y + candidate_y 2724 stretch_bound = stretch_bound + 500 2725 until(farEnough(place_ref_list,candidate_x,candidate_y,bubble)) 2726 local blackhole = BlackHole():setPosition(candidate_x,candidate_y) 2727 table.insert(place_ref_list,blackhole) 2728 table.insert(human_ref_list,blackhole) 2729 table.insert(hole_list,blackhole) 2730 local obj_ref_angle = angleFromVectorNorth(candidate_x, candidate_y, terrain_center_x, terrain_center_y) 2731 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, candidate_x, candidate_y) 2732 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2733 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2734 blackhole = BlackHole():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2735 table.insert(place_ref_list,blackhole) 2736 table.insert(hole_list,blackhole) 2737 if exuari_angle ~= nil then 2738 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2739 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2740 blackhole = BlackHole():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2741 table.insert(place_ref_list,blackhole) 2742 table.insert(hole_list,blackhole) 2743 end 2744 if ktlitan_angle ~= nil then 2745 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2746 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2747 blackhole = BlackHole():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 2748 table.insert(place_ref_list,blackhole) 2749 table.insert(hole_list,blackhole) 2750 end 2751 end 2752 end --blackhole build 2753 2754 local mine_field_count = math.random(0,(6-player_team_count)) 2755 local mine_field_type_list = {"line","arc"} 2756 if mine_field_count > 0 then 2757 for m=1,mine_field_count do 2758 center_x, center_y, perimeter, avg_dist = analyzeBlob(human_ref_list) 2759 stretch_bound = 5000 2760 bubble = 6000 2761 repeat 2762 candidate_x, candidate_y = vectorFromAngleNorth(random(0,360),random(math.min(avg_dist,20000),math.min(perimeter,100000) + stretch_bound)) 2763 candidate_x = center_x + candidate_x 2764 candidate_y = center_y + candidate_y 2765 stretch_bound = stretch_bound + 500 2766 until(farEnough(place_ref_list,candidate_x,candidate_y,bubble)) 2767 local mine_field_type = mine_field_type_list[math.random(1,#mine_field_type_list)] 2768 local mine_list = {} 2769 local mine_ref_list = {} 2770 if mine_field_type == "line" then 2771 local mle_x, mle_y = vectorFromAngleNorth(random(0,360),random(8000,30000)) 2772 mine_list = createObjectsListOnLine(candidate_x + mle_x, candidate_y + mle_y, candidate_x, candidate_y, 1200, Mine, math.random(1,3)) 2773 for i=1,#mine_list do 2774 local tm = mine_list[i] 2775 local mx, my = tm:getPosition() 2776 if farEnough(place_ref_list,mx,my,1000) and farEnough(mine_ref_list,mx,my,1000) then 2777 table.insert(mine_ref_list,tm) 2778 local obj_ref_angle = angleFromVectorNorth(mx, my, terrain_center_x, terrain_center_y) 2779 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, mx, my) 2780 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2781 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2782 table.insert(mine_ref_list,Mine():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y)) 2783 if exuari_angle ~= nil then 2784 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2785 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2786 table.insert(mine_ref_list,Mine():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y)) 2787 end 2788 if ktlitan_angle ~= nil then 2789 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2790 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2791 table.insert(mine_ref_list,Mine():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y)) 2792 end 2793 else 2794 tm:destroy() 2795 end 2796 end 2797 for _, tm in ipairs(mine_ref_list) do 2798 table.insert(place_ref_list,tm) 2799 end 2800 elseif mine_field_type == "arc" then 2801 local arc_radius = random(8000,25000) 2802 local mid_angle = random(0,360) 2803 local spread = random(10,30) 2804 local angle = (mid_angle + (180 - spread) % 360) 2805 local mar_x, mar_y = vectorFromAngleNorth(angle,arc_radius) 2806 local mar_x = mar_x + candidate_x 2807 local mar_y = mar_y + candidate_y 2808 local final_angle = (mid_angle + (180 + spread)) % 360 2809 local mine_count = 0 2810 local mx, my = vectorFromAngleNorth(angle,arc_radius) 2811 local tm = Mine():setPosition(mar_x + mx, mar_y + my) 2812 table.insert(mine_list,tm) 2813 local angle_increment = 0 2814 repeat 2815 angle_increment = angle_increment + 0.1 2816 mx, my = vectorFromAngleNorth(angle + angle_increment,arc_radius) 2817 until(distance(tm,mar_x + mx, mar_y + my) > 1200) 2818 if final_angle <= angle then 2819 final_angle = final_angle + 360 2820 end 2821 repeat 2822 angle = angle + angle_increment 2823 mx, my = vectorFromAngleNorth(angle,arc_radius) 2824 tm = Mine():setPosition(mar_x + mx, mar_y + my) 2825 table.insert(mine_list,tm) 2826 until(angle > final_angle) 2827 for i=1,#mine_list do 2828 local tm = mine_list[i] 2829 local mx, my = tm:getPosition() 2830 if farEnough(place_ref_list,mx,my,1000) and farEnough(mine_ref_list,mx,my,1000) then 2831 table.insert(mine_ref_list,tm) 2832 local obj_ref_angle = angleFromVectorNorth(mx, my, terrain_center_x, terrain_center_y) 2833 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, mx, my) 2834 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2835 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2836 table.insert(mine_ref_list,Mine():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y)) 2837 if exuari_angle ~= nil then 2838 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2839 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2840 table.insert(mine_ref_list,Mine():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y)) 2841 end 2842 if ktlitan_angle ~= nil then 2843 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2844 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2845 table.insert(mine_ref_list,Mine():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y)) 2846 end 2847 else 2848 tm:destroy() 2849 end 2850 end 2851 for _, tm in ipairs(mine_ref_list) do 2852 table.insert(place_ref_list,tm) 2853 end 2854 end 2855 end 2856 end 2857 2858 -- Asteroid build 2859 local asteroid_field_count = math.random(2,(10-player_team_count)) 2860 local asteroid_field_type_list = {"blob","line","arc"} 2861 for a=1,asteroid_field_count do 2862 center_x, center_y, perimeter, avg_dist = analyzeBlob(human_ref_list) 2863 stretch_bound = 5000 2864 bubble = 6000 2865 repeat 2866 candidate_x, candidate_y = vectorFromAngleNorth(random(0,360),random(math.min(avg_dist,20000),math.min(perimeter,100000) + stretch_bound)) 2867 candidate_x = center_x + candidate_x 2868 candidate_y = center_y + candidate_y 2869 stretch_bound = stretch_bound + 500 2870 until(farEnough(place_ref_list,candidate_x,candidate_y,bubble)) 2871 local asteroid_field_type = asteroid_field_type_list[math.random(1,#asteroid_field_type_list)] 2872 local asteroid_list = {} 2873 local asteroid_ref_list = {} 2874 if asteroid_field_type == "blob" then 2875 local blob_count = math.random(10,30) 2876-- print("blob count:",blob_count) 2877 asteroid_list = placeRandomListAroundPoint(Asteroid,blob_count,100,15000,candidate_x,candidate_y) 2878 for i=1,#asteroid_list do 2879 local ta = asteroid_list[i] 2880 local ax, ay = ta:getPosition() 2881 local as = asteroidSize() 2882 if farEnough(place_ref_list,ax,ay,as) and farEnough(asteroid_ref_list,ax,ay,as) then 2883 ta:setSize(as) 2884 table.insert(asteroid_ref_list,ta) 2885 local obj_ref_angle = angleFromVectorNorth(ax, ay, terrain_center_x, terrain_center_y) 2886 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, ax, ay) 2887 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2888 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2889 table.insert(asteroid_ref_list,Asteroid():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y):setSize(as)) 2890 if exuari_angle ~= nil then 2891 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2892 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2893 table.insert(asteroid_ref_list,Asteroid():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y):setSize(as)) 2894 end 2895 if ktlitan_angle ~= nil then 2896 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2897 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2898 table.insert(asteroid_ref_list,Asteroid():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y):setSize(as)) 2899 end 2900 else 2901 ta:destroy() 2902 end 2903 end 2904 for _, ta in ipairs(asteroid_ref_list) do 2905 table.insert(place_ref_list,ta) 2906 end 2907 elseif asteroid_field_type == "line" then 2908-- print("asteroid line") 2909 local ale_x, ale_y = vectorFromAngleNorth(random(0,360),random(8000,30000)) 2910 asteroid_list = createObjectsListOnLine(candidate_x + ale_x, candidate_y + ale_y, candidate_x, candidate_y, random(500,900), Asteroid, 7, 25, 250) 2911 for i=1,#asteroid_list do 2912 local ta = asteroid_list[i] 2913 local ax, ay = ta:getPosition() 2914 local as = asteroidSize() 2915 if farEnough(place_ref_list,ax,ay,as) and farEnough(asteroid_ref_list,ax,ay,as) then 2916 ta:setSize(as) 2917 table.insert(asteroid_ref_list,ta) 2918 local obj_ref_angle = angleFromVectorNorth(ax, ay, terrain_center_x, terrain_center_y) 2919 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, ax, ay) 2920 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2921 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2922 table.insert(asteroid_ref_list,Asteroid():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y):setSize(as)) 2923 if exuari_angle ~= nil then 2924 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2925 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2926 table.insert(asteroid_ref_list,Asteroid():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y):setSize(as)) 2927 end 2928 if ktlitan_angle ~= nil then 2929 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2930 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2931 table.insert(asteroid_ref_list,Asteroid():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y):setSize(as)) 2932 end 2933 else 2934 ta:destroy() 2935 end 2936 end 2937 for _, ta in ipairs(asteroid_ref_list) do 2938 table.insert(place_ref_list,ta) 2939 end 2940 elseif asteroid_field_type == "arc" then 2941 local angle_to_radius = random(0,360) 2942 local radius_to_arc = random(8000,25000) 2943 local aar_x, aar_y = vectorFromAngleNorth(angle_to_radius,radius_to_arc) 2944 local spread = random(10,30) 2945 local number_in_arc = math.min(math.floor(spread * 2) + math.random(5,20),35) 2946-- print("asteroid arc number:",number_in_arc) 2947 asteroid_list = createRandomListAlongArc(Asteroid, number_in_arc, candidate_x + aar_x, candidate_y + aar_y, radius_to_arc, (angle_to_radius + (180-spread)) % 360, (angle_to_radius + (180+spread)) % 360, 1000) 2948 for i=1,#asteroid_list do 2949 local ta = asteroid_list[i] 2950 local ax, ay = ta:getPosition() 2951 local as = asteroidSize() 2952 if farEnough(place_ref_list,ax,ay,as) and farEnough(asteroid_ref_list,ax,ay,as) then 2953 ta:setSize(as) 2954 table.insert(asteroid_ref_list,ta) 2955 local obj_ref_angle = angleFromVectorNorth(ax, ay, terrain_center_x, terrain_center_y) 2956 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, ax, ay) 2957 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2958 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2959 table.insert(asteroid_ref_list,Asteroid():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y):setSize(as)) 2960 if exuari_angle ~= nil then 2961 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2962 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2963 table.insert(asteroid_ref_list,Asteroid():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y):setSize(as)) 2964 end 2965 if ktlitan_angle ~= nil then 2966 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 2967 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 2968 table.insert(asteroid_ref_list,Asteroid():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y):setSize(as)) 2969 end 2970 else 2971 ta:destroy() 2972 end 2973 end 2974 for _, ta in ipairs(asteroid_ref_list) do 2975 table.insert(place_ref_list,ta) 2976 end 2977 end 2978 end -- asteroid fields build 2979 2980 -- Nebula build 2981 local nebula_field_count = math.random(2,8) 2982 center_x, center_y, perimeter, avg_dist = analyzeBlob(human_ref_list) 2983 for n=1,nebula_field_count do 2984 stretch_bound = 5000 2985 bubble = 7000 2986 repeat 2987 candidate_x, candidate_y = vectorFromAngleNorth(random(0,360),random(math.min(avg_dist,20000),math.min(perimeter,100000) + stretch_bound)) 2988 candidate_x = center_x + candidate_x 2989 candidate_y = center_y + candidate_y 2990 stretch_bound = stretch_bound + 500 2991 until(farEnough(hole_list,candidate_x,candidate_y,bubble)) 2992 local neb = Nebula():setPosition(candidate_x,candidate_y) 2993 local nebula_field = {} 2994 table.insert(nebula_field,neb) 2995 local nebula_field_size = math.random(0,5) 2996 if nebula_field_size > 0 then 2997 for i=1,nebula_field_size do 2998 local na_x = 0 2999 local na_y = 0 3000 local nx = 0 3001 local ny = 0 3002 local attempts = 0 3003 repeat 3004 na_x, na_y = vectorFromAngleNorth(random(0,360),random(8000,9500)) 3005 nx, ny = nebula_field[math.random(1,#nebula_field)]:getPosition() 3006 attempts = attempts + 1 3007 until(farEnough(hole_list, na_x + nx, na_y + ny, bubble) or attempts > 50) 3008 if attempts <= 50 then 3009 neb = Nebula():setPosition(na_x + nx, na_y + ny) 3010 table.insert(nebula_field,neb) 3011 else 3012 break 3013 end 3014 end 3015 end 3016 for i=1,#nebula_field do 3017 candidate_x, candidate_y = nebula_field[i]:getPosition() 3018 local obj_ref_angle = angleFromVectorNorth(candidate_x, candidate_y, terrain_center_x, terrain_center_y) 3019 local obj_ref_distance = distance(terrain_center_x, terrain_center_y, candidate_x, candidate_y) 3020 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 3021 local rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 3022 Nebula():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 3023 if exuari_angle ~= nil then 3024 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 3025 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 3026 Nebula():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 3027 end 3028 if ktlitan_angle ~= nil then 3029 obj_ref_angle = (obj_ref_angle + replicant_increment) % 360 3030 rep_x, rep_y = vectorFromAngleNorth(obj_ref_angle,obj_ref_distance) 3031 Nebula():setPosition(terrain_center_x + rep_x, terrain_center_y + rep_y) 3032 end 3033 end 3034 end -- nebula field build 3035 game_state = "terrain generated" 3036 3037 -- Store (then print) original values for later comparison 3038 local stat_list = gatherStats() 3039 original_score = {} 3040 local out = "Original scores:" 3041 original_score["Human Navy"] = stat_list.human.weighted_score 3042 out = out .. string.format("\nHuman Navy: %.2f",stat_list.human.weighted_score) 3043 original_score["Kraylor"] = stat_list.kraylor.weighted_score 3044 out = out .. string.format("\nKraylor: %.2f",stat_list.kraylor.weighted_score) 3045 if exuari_angle ~= nil then 3046 original_score["Exuari"] = stat_list.exuari.weighted_score 3047 out = out .. string.format("\nExuari: %.2f",stat_list.exuari.weighted_score) 3048 end 3049 if ktlitan_angle ~= nil then 3050 original_score["Ktlitans"] = stat_list.ktlitan.weighted_score 3051 out = out .. string.format("\nKtlitans: %.2f",stat_list.ktlitan.weighted_score) 3052 end 3053 allowNewPlayerShips(false) 3054 print(out) 3055 3056 -- Provide summary terrain details in console log 3057 print("----- Terrain Info -----") 3058 print("Center:",terrain_center_sector,"featuring:",center_choice) 3059 print("Primary stations:",primary_station_size,"Jammers:",primary_jammers,"defense platforms:",defense_platform_count) 3060 local output_player_types = player_ship_types 3061 if player_ship_types == "custom" then 3062 output_player_types = output_player_types .. " (" .. custom_player_ship_type .. ")" 3063 end 3064 print("Teams:",player_team_count,"Player ships:",ships_per_team .. "(" .. ships_per_team*player_team_count .. ")","Player ship types:",output_player_types) 3065 print("NPC Fleets:",npc_fleet_count .. "(" .. npc_fleet_count*player_team_count .. ")") 3066 print("Wormholes:",wormhole_count .. "(" .. wormhole_count*player_team_count .. ")","Black holes:",blackhole_count .. "(" .. blackhole_count*player_team_count .. ")") 3067 print("Asteroid fields:",asteroid_field_count .. "(" .. asteroid_field_count*player_team_count .. ")","Nebula groups:",nebula_field_count .. "(" .. nebula_field_count*player_team_count .. ")") 3068end 3069function spawnRandomArmed(x, y, enemyStrength, fleetIndex, shape, angle) 3070--x and y are central spawn coordinates 3071--fleetIndex is the number of the fleet to be spawned 3072--sl (was) the score list, nl is the name list, bl is the boolean list 3073--spawn_distance optional - used for ambush or pyramid 3074--spawn_angle optional - used for ambush or pyramid 3075--px and py are the player coordinates or the pyramid fly towards point coordinates 3076 local sp = 1000 --spacing of spawned group 3077 if shape == nil then 3078 local shape_choices = {"square","hexagonal"} 3079 shape = shape_choices[math.random(1,#shape_choices)] 3080 end 3081 local enemy_position = 0 3082 local enemyList = {} 3083 local template_pool = getTemplatePool(enemyStrength) 3084 if #template_pool < 1 then 3085 addGMMessage("Empty Template pool: fix excludes or other criteria") 3086 return enemyList 3087 end 3088 local fleet_prefix = generateCallSignPrefix() 3089 while enemyStrength > 0 do 3090 local selected_template = template_pool[math.random(1,#template_pool)] 3091-- print("selected template:",selected_template) 3092-- print("base:",ship_template[selected_template].base) 3093 local ship = ship_template[selected_template].create("Human Navy",selected_template) 3094 ship:setCallSign(generateCallSign(fleet_prefix)) 3095 ship:setCommsScript(""):setCommsFunction(commsShip) 3096 ship:orderIdle() 3097 ship:setHeading(angle) 3098 ship:setRotation(angle + 270) 3099 enemy_position = enemy_position + 1 3100 ship:setPosition(x + formation_delta[shape].x[enemy_position] * sp, y + formation_delta[shape].y[enemy_position] * sp) 3101 ship.fleetIndex = fleetIndex 3102 table.insert(enemyList, ship) 3103 enemyStrength = enemyStrength - ship_template[selected_template].strength 3104 end 3105 return enemyList 3106end 3107function getTemplatePool(max_strength) 3108 local function getStrengthSort(tbl, sortFunction) 3109 local keys = {} 3110 for key in pairs(tbl) do 3111 table.insert(keys,key) 3112 end 3113 table.sort(keys, function(a,b) 3114 return sortFunction(tbl[a], tbl[b]) 3115 end) 3116 return keys 3117 end 3118 local ship_template_by_strength = getStrengthSort(ship_template, function(a,b) 3119 return a.strength > b.strength 3120 end) 3121 local template_pool = {} 3122-- print("fleet composition:",fleetComposition,"fleet group sub fleet composition:",fleet_group[fleetComposition]) 3123 if pool_selectivity == "less/heavy" then 3124 for _, current_ship_template in ipairs(ship_template_by_strength) do 3125-- print("currrent ship template:",current_ship_template,"strength:",ship_template[current_ship_template].strength,"max strength:",max_strength) 3126 if ship_template[current_ship_template].strength <= max_strength then 3127 if fleetComposition == "Non-DB" then 3128 if ship_template[current_ship_template].create ~= stockTemplate then 3129 table.insert(template_pool,current_ship_template) 3130 end 3131 elseif fleetComposition == "Random" then 3132 table.insert(template_pool,current_ship_template) 3133 else 3134 if ship_template[current_ship_template][fleet_group[fleetComposition]] then 3135 table.insert(template_pool,current_ship_template) 3136 end 3137 end 3138 end 3139 if #template_pool >= 5 then 3140 break 3141 end 3142 end 3143 elseif pool_selectivity == "more/light" then 3144 for i=#ship_template_by_strength,1,-1 do 3145 local current_ship_template = ship_template_by_strength[i] 3146-- print("currrent ship template:",current_ship_template,"strength:",ship_template[current_ship_template].strength,"max strength:",max_strength) 3147 if ship_template[current_ship_template].strength <= max_strength then 3148 if fleetComposition == "Non-DB" then 3149 if ship_template[current_ship_template].create ~= stockTemplate then 3150 table.insert(template_pool,current_ship_template) 3151 end 3152 elseif fleetComposition == "Random" then 3153 table.insert(template_pool,current_ship_template) 3154 else 3155 if ship_template[current_ship_template][fleet_group[fleetComposition]] then 3156 table.insert(template_pool,current_ship_template) 3157 end 3158 end 3159 end 3160 if #template_pool >= 20 then 3161 break 3162 end 3163 end 3164 else --full 3165 for current_ship_template, details in pairs(ship_template) do 3166 if details.strength <= max_strength then 3167 if fleetComposition == "Non-DB" then 3168 if ship_template[current_ship_template].create ~= stockTemplate then 3169 table.insert(template_pool,current_ship_template) 3170 end 3171 elseif fleetComposition == "Random" then 3172 table.insert(template_pool,current_ship_template) 3173 else 3174 if ship_template[current_ship_template][fleet_group[fleetComposition]] then 3175 table.insert(template_pool,current_ship_template) 3176 end 3177 end 3178 end 3179 end 3180 end 3181 --print("returning template pool containing these templates:") 3182 --for _, template in ipairs(template_pool) do 3183 -- print(template) 3184 --end 3185 return template_pool 3186end 3187function stockTemplate(enemyFaction,template) 3188 local ship = CpuShip():setFaction(enemyFaction):setTemplate(template):orderRoaming() 3189 ship:onTakingDamage(function(self,instigator) 3190 string.format("") --serious proton needs a global context 3191 if instigator ~= nil then 3192 self.damage_instigator = instigator 3193 end 3194 end) 3195 return ship 3196end 3197-------------------------------------------------------------------------------------------- 3198-- Additional enemy ships with some modifications from the original template parameters -- 3199-------------------------------------------------------------------------------------------- 3200function phobosR2(enemyFaction) 3201 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Phobos T3"):orderRoaming() 3202 ship:onTakingDamage(function(self,instigator) 3203 string.format("") --serious proton needs a global context 3204 if instigator ~= nil then 3205 self.damage_instigator = instigator 3206 end 3207 end) 3208 ship:setTypeName("Phobos R2") 3209 ship:setWeaponTubeCount(1) --one tube (vs 2) 3210 ship:setWeaponTubeDirection(0,0) 3211 ship:setImpulseMaxSpeed(55) --slower impulse (vs 60) 3212 ship:setRotationMaxSpeed(15) --faster maneuver (vs 10) 3213 local phobos_r2_db = queryScienceDatabase("Ships","Frigate","Phobos R2") 3214 if phobos_r2_db == nil then 3215 local frigate_db = queryScienceDatabase("Ships","Frigate") 3216 frigate_db:addEntry("Phobos R2") 3217 phobos_r2_db = queryScienceDatabase("Ships","Frigate","Phobos R2") 3218 addShipToDatabase( 3219 queryScienceDatabase("Ships","Frigate","Phobos T3"), --base ship database entry 3220 phobos_r2_db, --modified ship database entry 3221 ship, --ship just created, long description on the next line 3222 "The Phobos R2 model is very similar to the Phobos T3. It's got a faster turn speed, but only one missile tube", 3223 { 3224 {key = "Tube 0", value = "60 sec"}, --torpedo tube direction and load speed 3225 }, 3226 nil 3227 ) 3228 end 3229 return ship 3230end 3231function hornetMV52(enemyFaction) 3232 local ship = CpuShip():setFaction(enemyFaction):setTemplate("MT52 Hornet"):orderRoaming() 3233 ship:onTakingDamage(function(self,instigator) 3234 string.format("") --serious proton needs a global context 3235 if instigator ~= nil then 3236 self.damage_instigator = instigator 3237 end 3238 end) 3239 ship:setTypeName("MV52 Hornet") 3240 ship:setBeamWeapon(0, 30, 0, 1000.0, 4.0, 3.0) --longer and stronger beam (vs 700 & 3) 3241 ship:setRotationMaxSpeed(31) --faster maneuver (vs 30) 3242 ship:setImpulseMaxSpeed(130) --faster impulse (vs 120) 3243 local hornet_mv52_db = queryScienceDatabase("Ships","Starfighter","MV52 Hornet") 3244 if hornet_mv52_db == nil then 3245 local starfighter_db = queryScienceDatabase("Ships","Starfighter") 3246 starfighter_db:addEntry("MV52 Hornet") 3247 hornet_mv52_db = queryScienceDatabase("Ships","Starfighter","MV52 Hornet") 3248 addShipToDatabase( 3249 queryScienceDatabase("Ships","Starfighter","MT52 Hornet"), --base ship database entry 3250 hornet_mv52_db, --modified ship database entry 3251 ship, --ship just created, long description on the next line 3252 "The MV52 Hornet is very similar to the MT52 and MU52 models. The beam does more damage than both of the other Hornet models, it's max impulse speed is faster than both of the other Hornet models, it turns faster than the MT52, but slower than the MU52", 3253 nil, 3254 nil 3255 ) 3256 end 3257 return ship 3258end 3259function k2fighter(enemyFaction) 3260 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Ktlitan Fighter"):orderRoaming() 3261 ship:setTypeName("K2 Fighter") 3262 ship:setBeamWeapon(0, 60, 0, 1200.0, 2.5, 6) --beams cycle faster (vs 4.0) 3263 ship:setHullMax(65) --weaker hull (vs 70) 3264 ship:setHull(65) 3265 local k2_fighter_db = queryScienceDatabase("Ships","No Class","K2 Fighter") 3266 if k2_fighter_db == nil then 3267 local no_class_db = queryScienceDatabase("Ships","No Class") 3268 no_class_db:addEntry("K2 Fighter") 3269 k2_fighter_db = queryScienceDatabase("Ships","No Class","K2 Fighter") 3270 addShipToDatabase( 3271 queryScienceDatabase("Ships","No Class","Ktlitan Fighter"), --base ship database entry 3272 k2_fighter_db, --modified ship database entry 3273 ship, --ship just created, long description on the next line 3274 "Enterprising designers published this design specification based on salvaged Ktlitan Fighters. Comparatively, it's got beams that cycle faster, but the hull is a bit weaker.", 3275 nil, 3276 nil --jump range 3277 ) 3278 end 3279 return ship 3280end 3281function k3fighter(enemyFaction) 3282 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Ktlitan Fighter"):orderRoaming() 3283 ship:setTypeName("K3 Fighter") 3284 ship:setBeamWeapon(0, 60, 0, 1200.0, 2.5, 9) --beams cycle faster and damage more (vs 4.0 & 6) 3285 ship:setHullMax(60) --weaker hull (vs 70) 3286 ship:setHull(60) 3287 local k3_fighter_db = queryScienceDatabase("Ships","No Class","K3 Fighter") 3288 if k3_fighter_db == nil then 3289 local no_class_db = queryScienceDatabase("Ships","No Class") 3290 no_class_db:addEntry("K3 Fighter") 3291 k3_fighter_db = queryScienceDatabase("Ships","No Class","K3 Fighter") 3292 addShipToDatabase( 3293 queryScienceDatabase("Ships","No Class","Ktlitan Fighter"), --base ship database entry 3294 k3_fighter_db, --modified ship database entry 3295 ship, --ship just created, long description on the next line 3296 "Enterprising designers published this design specification based on salvaged Ktlitan Fighters. Comparatively, it's got beams that are stronger and that cycle faster, but the hull is weaker.", 3297 nil, 3298 nil --jump range 3299 ) 3300 end 3301 return ship 3302end 3303function waddle5(enemyFaction) 3304 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Adder MK5"):orderRoaming() 3305 ship:onTakingDamage(function(self,instigator) 3306 string.format("") --serious proton needs a global context 3307 if instigator ~= nil then 3308 self.damage_instigator = instigator 3309 end 3310 end) 3311 ship:setTypeName("Waddle 5") 3312 ship:setWarpDrive(true) 3313-- Index, Arc, Dir, Range, Cycle, Damage 3314 ship:setBeamWeapon(2, 70, -30, 600, 5.0, 2.0) --adjust beam direction to match starboard side (vs -35) 3315 local waddle_5_db = queryScienceDatabase("Ships","Starfighter","Waddle 5") 3316 if waddle_5_db == nil then 3317 local starfighter_db = queryScienceDatabase("Ships","Starfighter") 3318 starfighter_db:addEntry("Waddle 5") 3319 waddle_5_db = queryScienceDatabase("Ships","Starfighter","Waddle 5") 3320 addShipToDatabase( 3321 queryScienceDatabase("Ships","Starfighter","Adder MK5"), --base ship database entry 3322 waddle_5_db, --modified ship database entry 3323 ship, --ship just created, long description on the next line 3324 "Conversions R Us purchased a number of Adder MK 5 ships at auction and added warp drives to them to produce the Waddle 5", 3325 { 3326 {key = "Small tube 0", value = "15 sec"}, --torpedo tube direction and load speed 3327 }, 3328 nil --jump range 3329 ) 3330 end 3331 return ship 3332end 3333function jade5(enemyFaction) 3334 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Adder MK5"):orderRoaming() 3335 ship:onTakingDamage(function(self,instigator) 3336 string.format("") --serious proton needs a global context 3337 if instigator ~= nil then 3338 self.damage_instigator = instigator 3339 end 3340 end) 3341 ship:setTypeName("Jade 5") 3342 ship:setJumpDrive(true) 3343 ship:setJumpDriveRange(5000,35000) 3344-- Index, Arc, Dir, Range, Cycle, Damage 3345 ship:setBeamWeapon(2, 70, -30, 600, 5.0, 2.0) --adjust beam direction to match starboard side (vs -35) 3346 local jade_5_db = queryScienceDatabase("Ships","Starfighter","Jade 5") 3347 if jade_5_db == nil then 3348 local starfighter_db = queryScienceDatabase("Ships","Starfighter") 3349 starfighter_db:addEntry("Jade 5") 3350 jade_5_db = queryScienceDatabase("Ships","Starfighter","Jade 5") 3351 addShipToDatabase( 3352 queryScienceDatabase("Ships","Starfighter","Adder MK5"), --base ship database entry 3353 jade_5_db, --modified ship database entry 3354 ship, --ship just created, long description on the next line 3355 "Conversions R Us purchased a number of Adder MK 5 ships at auction and added jump drives to them to produce the Jade 5", 3356 { 3357 {key = "Small tube 0", value = "15 sec"}, --torpedo tube direction and load speed 3358 }, 3359 "5 - 35 U" --jump range 3360 ) 3361 end 3362 return ship 3363end 3364function droneLite(enemyFaction) 3365 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Ktlitan Drone"):orderRoaming() 3366 ship:setTypeName("Lite Drone") 3367 ship:setHullMax(20) --weaker hull (vs 30) 3368 ship:setHull(20) 3369 ship:setImpulseMaxSpeed(130) --faster impulse (vs 120) 3370 ship:setRotationMaxSpeed(20) --faster maneuver (vs 10) 3371 ship:setBeamWeapon(0,40,0,600,4,4) --weaker (vs 6) beam 3372 local drone_lite_db = queryScienceDatabase("Ships","No Class","Lite Drone") 3373 if drone_lite_db == nil then 3374 local no_class_db = queryScienceDatabase("Ships","No Class") 3375 no_class_db:addEntry("Lite Drone") 3376 drone_lite_db = queryScienceDatabase("Ships","No Class","Lite Drone") 3377 addShipToDatabase( 3378 queryScienceDatabase("Ships","No Class","Ktlitan Drone"), --base ship database entry 3379 drone_lite_db, --modified ship database entry 3380 ship, --ship just created, long description on the next line 3381 "The light drone was pieced together from scavenged parts of various damaged Ktlitan drones. Compared to the Ktlitan drone, the lite drone has a weaker hull, and a weaker beam, but a faster turn and impulse speed", 3382 nil, 3383 nil 3384 ) 3385 end 3386 return ship 3387end 3388function droneHeavy(enemyFaction) 3389 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Ktlitan Drone"):orderRoaming() 3390 ship:setTypeName("Heavy Drone") 3391 ship:setHullMax(40) --stronger hull (vs 30) 3392 ship:setHull(40) 3393 ship:setImpulseMaxSpeed(110) --slower impulse (vs 120) 3394 ship:setBeamWeapon(0,40,0,600,4,8) --stronger (vs 6) beam 3395 local drone_heavy_db = queryScienceDatabase("Ships","No Class","Heavy Drone") 3396 if drone_heavy_db == nil then 3397 local no_class_db = queryScienceDatabase("Ships","No Class") 3398 no_class_db:addEntry("Heavy Drone") 3399 drone_heavy_db = queryScienceDatabase("Ships","No Class","Heavy Drone") 3400 addShipToDatabase( 3401 queryScienceDatabase("Ships","No Class","Ktlitan Drone"), --base ship database entry 3402 drone_heavy_db, --modified ship database entry 3403 ship, --ship just created, long description on the next line 3404 "The heavy drone has a stronger hull and a stronger beam than the normal Ktlitan Drone, but it also moves slower", 3405 nil, 3406 nil 3407 ) 3408 end 3409 return ship 3410end 3411function droneJacket(enemyFaction) 3412 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Ktlitan Drone"):orderRoaming() 3413 ship:onTakingDamage(function(self,instigator) 3414 string.format("") --serious proton needs a global context 3415 if instigator ~= nil then 3416 self.damage_instigator = instigator 3417 end 3418 end) 3419 ship:setTypeName("Jacket Drone") 3420 ship:setShieldsMax(20) --stronger shields (vs none) 3421 ship:setShields(20) 3422 ship:setImpulseMaxSpeed(110) --slower impulse (vs 120) 3423 ship:setBeamWeapon(0,40,0,600,4,4) --weaker (vs 6) beam 3424 local drone_jacket_db = queryScienceDatabase("Ships","No Class","Jacket Drone") 3425 if drone_jacket_db == nil then 3426 local no_class_db = queryScienceDatabase("Ships","No Class") 3427 no_class_db:addEntry("Jacket Drone") 3428 drone_jacket_db = queryScienceDatabase("Ships","No Class","Jacket Drone") 3429 addShipToDatabase( 3430 queryScienceDatabase("Ships","No Class","Ktlitan Drone"), --base ship database entry 3431 drone_jacket_db, --modified ship database entry 3432 ship, --ship just created, long description on the next line 3433 "The Jacket Drone is a Ktlitan Drone with a shield. It's also slightly slower and has a slightly weaker beam due to the energy requirements of the added shield", 3434 nil, 3435 nil 3436 ) 3437 end 3438 return ship 3439end 3440function wzLindworm(enemyFaction) 3441 local ship = CpuShip():setFaction(enemyFaction):setTemplate("WX-Lindworm"):orderRoaming() 3442 ship:setTypeName("WZ-Lindworm") 3443 ship:setWeaponStorageMax("Nuke",2) --more nukes (vs 0) 3444 ship:setWeaponStorage("Nuke",2) 3445 ship:setWeaponStorageMax("Homing",4) --more homing (vs 1) 3446 ship:setWeaponStorage("Homing",4) 3447 ship:setWeaponStorageMax("HVLI",12) --more HVLI (vs 6) 3448 ship:setWeaponStorage("HVLI",12) 3449 ship:setRotationMaxSpeed(12) --slower maneuver (vs 15) 3450 ship:setHullMax(45) --weaker hull (vs 50) 3451 ship:setHull(45) 3452 local wz_lindworm_db = queryScienceDatabase("Ships","Starfighter","WZ-Lindworm") 3453 if wz_lindworm_db == nil then 3454 local starfighter_db = queryScienceDatabase("Ships","Starfighter") 3455 starfighter_db:addEntry("WZ-Lindworm") 3456 wz_lindworm_db = queryScienceDatabase("Ships","Starfighter","WZ-Lindworm") 3457 addShipToDatabase( 3458 queryScienceDatabase("Ships","Starfighter","WX-Lindworm"), --base ship database entry 3459 wz_lindworm_db, --modified ship database entry 3460 ship, --ship just created, long description on the next line 3461 "The WZ-Lindworm is essentially the stock WX-Lindworm with more HVLIs, more homing missiles and added nukes. They had to remove some of the armor to get the additional missiles to fit, so the hull is weaker. Also, the WZ turns a little more slowly than the WX. This little bomber packs quite a whallop.", 3462 { 3463 {key = "Small tube 0", value = "15 sec"}, --torpedo tube direction and load speed 3464 {key = "Small tube 1", value = "15 sec"}, --torpedo tube direction and load speed 3465 {key = "Small tube -1", value = "15 sec"}, --torpedo tube direction and load speed 3466 }, 3467 nil 3468 ) 3469 end 3470 return ship 3471end 3472function tempest(enemyFaction) 3473 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Piranha F12"):orderRoaming() 3474 ship:onTakingDamage(function(self,instigator) 3475 string.format("") --serious proton needs a global context 3476 if instigator ~= nil then 3477 self.damage_instigator = instigator 3478 end 3479 end) 3480 ship:setTypeName("Tempest") 3481 ship:setWeaponTubeCount(10) --four more tubes (vs 6) 3482 ship:setWeaponTubeDirection(0, -88) --5 per side 3483 ship:setWeaponTubeDirection(1, -89) --slight angle spread 3484 ship:setWeaponTubeDirection(3, 88) --3 for HVLI each side 3485 ship:setWeaponTubeDirection(4, 89) --2 for homing and nuke each side 3486 ship:setWeaponTubeDirection(6, -91) 3487 ship:setWeaponTubeDirection(7, -92) 3488 ship:setWeaponTubeDirection(8, 91) 3489 ship:setWeaponTubeDirection(9, 92) 3490 ship:setWeaponTubeExclusiveFor(7,"HVLI") 3491 ship:setWeaponTubeExclusiveFor(9,"HVLI") 3492 ship:setWeaponStorageMax("Homing",16) --more (vs 6) 3493 ship:setWeaponStorage("Homing", 16) 3494 ship:setWeaponStorageMax("Nuke",8) --more (vs 0) 3495 ship:setWeaponStorage("Nuke", 8) 3496 ship:setWeaponStorageMax("HVLI",34) --more (vs 20) 3497 ship:setWeaponStorage("HVLI", 34) 3498 local tempest_db = queryScienceDatabase("Ships","Frigate","Tempest") 3499 if tempest_db == nil then 3500 local frigate_db = queryScienceDatabase("Ships","Frigate") 3501 frigate_db:addEntry("Tempest") 3502 tempest_db = queryScienceDatabase("Ships","Frigate","Tempest") 3503 addShipToDatabase( 3504 queryScienceDatabase("Ships","Frigate","Piranha F12"), --base ship database entry 3505 tempest_db, --modified ship database entry 3506 ship, --ship just created, long description on the next line 3507 "Loosely based on the Piranha F12 model, the Tempest adds four more broadside tubes (two on each side), more HVLIs, more Homing missiles and 8 Nukes. The Tempest can strike fear into the hearts of your enemies. Get yourself one today!", 3508 { 3509 {key = "Large tube -88", value = "15 sec"}, --torpedo tube direction and load speed 3510 {key = "Tube -89", value = "15 sec"}, --torpedo tube direction and load speed 3511 {key = "Large tube -90", value = "15 sec"}, --torpedo tube direction and load speed 3512 {key = "Large tube 88", value = "15 sec"}, --torpedo tube direction and load speed 3513 {key = "Tube 89", value = "15 sec"}, --torpedo tube direction and load speed 3514 {key = "Large tube 90", value = "15 sec"}, --torpedo tube direction and load speed 3515 {key = "Tube -91", value = "15 sec"}, --torpedo tube direction and load speed 3516 {key = "Tube -92", value = "15 sec"}, --torpedo tube direction and load speed 3517 {key = "Tube 91", value = "15 sec"}, --torpedo tube direction and load speed 3518 {key = "Tube 92", value = "15 sec"}, --torpedo tube direction and load speed 3519 }, 3520 nil 3521 ) 3522 end 3523 return ship 3524end 3525function enforcer(enemyFaction) 3526 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Blockade Runner"):orderRoaming() 3527 ship:onTakingDamage(function(self,instigator) 3528 string.format("") --serious proton needs a global context 3529 if instigator ~= nil then 3530 self.damage_instigator = instigator 3531 end 3532 end) 3533 ship:setTypeName("Enforcer") 3534 ship:setRadarTrace("radar_ktlitan_destroyer.png") --different radar trace 3535 ship:setWarpDrive(true) --warp (vs none) 3536 ship:setWarpSpeed(600) 3537 ship:setImpulseMaxSpeed(100) --faster impulse (vs 60) 3538 ship:setRotationMaxSpeed(20) --faster maneuver (vs 15) 3539 ship:setShieldsMax(200,100,100) --stronger shields (vs 100,150) 3540 ship:setShields(200,100,100) 3541 ship:setHullMax(100) --stronger hull (vs 70) 3542 ship:setHull(100) 3543-- Index, Arc, Dir, Range, Cycle, Damage 3544 ship:setBeamWeapon(0, 30, -15, 1500, 6, 10) --narrower (vs 60), longer (vs 1000), stronger (vs 8) 3545 ship:setBeamWeapon(1, 30, 15, 1500, 6, 10) 3546 ship:setBeamWeapon(2, 0, 0, 0, 0, 0) --fewer (vs 4) 3547 ship:setBeamWeapon(3, 0, 0, 0, 0, 0) 3548 ship:setWeaponTubeCount(3) --more (vs 0) 3549 ship:setTubeSize(0,"large") --large (vs normal) 3550 ship:setWeaponTubeDirection(1,-30) 3551 ship:setWeaponTubeDirection(2, 30) 3552 ship:setWeaponStorageMax("Homing",18) --more (vs 0) 3553 ship:setWeaponStorage("Homing", 18) 3554 local enforcer_db = queryScienceDatabase("Ships","Frigate","Enforcer") 3555 if enforcer_db == nil then 3556 local frigate_db = queryScienceDatabase("Ships","Frigate") 3557 frigate_db:addEntry("Enforcer") 3558 enforcer_db = queryScienceDatabase("Ships","Frigate","Enforcer") 3559 addShipToDatabase( 3560 queryScienceDatabase("Ships","Frigate","Blockade Runner"), --base ship database entry 3561 enforcer_db, --modified ship database entry 3562 ship, --ship just created, long description on the next line 3563 "The Enforcer is a highly modified Blockade Runner. A warp drive was added and impulse engines boosted along with turning speed. Three missile tubes were added to shoot homing missiles, large ones straight ahead. Stronger shields and hull. Removed rear facing beams and strengthened front beams.", 3564 { 3565 {key = "Large tube 0", value = "20 sec"}, --torpedo tube direction and load speed 3566 {key = "Tube -30", value = "20 sec"}, --torpedo tube direction and load speed 3567 {key = "Tube 30", value = "20 sec"}, --torpedo tube direction and load speed 3568 }, 3569 nil 3570 ) 3571 enforcer_db:setImage("radar_ktlitan_destroyer.png") --override default radar image 3572 end 3573 return ship 3574end 3575function predator(enemyFaction) 3576 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Piranha F8"):orderRoaming() 3577 ship:onTakingDamage(function(self,instigator) 3578 string.format("") --serious proton needs a global context 3579 if instigator ~= nil then 3580 self.damage_instigator = instigator 3581 end 3582 end) 3583 ship:setTypeName("Predator") 3584 ship:setShieldsMax(100,100) --stronger shields (vs 30,30) 3585 ship:setShields(100,100) 3586 ship:setHullMax(80) --stronger hull (vs 70) 3587 ship:setHull(80) 3588 ship:setImpulseMaxSpeed(65) --faster impulse (vs 40) 3589 ship:setRotationMaxSpeed(15) --faster maneuver (vs 6) 3590 ship:setJumpDrive(true) 3591 ship:setJumpDriveRange(5000,35000) 3592-- Index, Arc, Dir, Range, Cycle, Damage 3593 ship:setBeamWeapon(0, 90, 0, 1000, 6, 4) --more (vs 0) 3594 ship:setBeamWeapon(1, 90, 180, 1000, 6, 4) 3595 ship:setWeaponTubeCount(8) --more (vs 3) 3596 ship:setWeaponTubeDirection(0,-60) 3597 ship:setWeaponTubeDirection(1,-90) 3598 ship:setWeaponTubeDirection(2,-90) 3599 ship:setWeaponTubeDirection(3, 60) 3600 ship:setWeaponTubeDirection(4, 90) 3601 ship:setWeaponTubeDirection(5, 90) 3602 ship:setWeaponTubeDirection(6,-120) 3603 ship:setWeaponTubeDirection(7, 120) 3604 ship:setWeaponTubeExclusiveFor(0,"Homing") 3605 ship:setWeaponTubeExclusiveFor(1,"Homing") 3606 ship:setWeaponTubeExclusiveFor(2,"Homing") 3607 ship:setWeaponTubeExclusiveFor(3,"Homing") 3608 ship:setWeaponTubeExclusiveFor(4,"Homing") 3609 ship:setWeaponTubeExclusiveFor(5,"Homing") 3610 ship:setWeaponTubeExclusiveFor(6,"Homing") 3611 ship:setWeaponTubeExclusiveFor(7,"Homing") 3612 ship:setWeaponStorageMax("Homing",32) --more (vs 5) 3613 ship:setWeaponStorage("Homing", 32) 3614 ship:setWeaponStorageMax("HVLI",0) --less (vs 10) 3615 ship:setWeaponStorage("HVLI", 0) 3616 ship:setRadarTrace("radar_missile_cruiser.png") --different radar trace 3617 local predator_db = queryScienceDatabase("Ships","Frigate","Predator") 3618 if predator_db == nil then 3619 local frigate_db = queryScienceDatabase("Ships","Frigate") 3620 frigate_db:addEntry("Predator") 3621 predator_db = queryScienceDatabase("Ships","Frigate","Predator") 3622 addShipToDatabase( 3623 queryScienceDatabase("Ships","Frigate","Piranha F8"), --base ship database entry 3624 predator_db, --modified ship database entry 3625 ship, --ship just created, long description on the next line 3626 "The Predator is a significantly improved Piranha F8. Stronger shields and hull, faster impulse and turning speeds, a jump drive, beam weapons, eight missile tubes pointing in six directions and a large number of homing missiles to shoot.", 3627 { 3628 {key = "Large tube -60", value = "12 sec"}, --torpedo tube direction and load speed 3629 {key = "Tube -90", value = "12 sec"}, --torpedo tube direction and load speed 3630 {key = "Large tube -90", value = "12 sec"}, --torpedo tube direction and load speed 3631 {key = "Large tube 60", value = "12 sec"}, --torpedo tube direction and load speed 3632 {key = "Tube 90", value = "12 sec"}, --torpedo tube direction and load speed 3633 {key = "Large tube 90", value = "12 sec"}, --torpedo tube direction and load speed 3634 {key = "Tube -120", value = "12 sec"}, --torpedo tube direction and load speed 3635 {key = "Tube 120", value = "12 sec"}, --torpedo tube direction and load speed 3636 }, 3637 "5 - 35 U" --jump range 3638 ) 3639 predator_db:setImage("radar_missile_cruiser.png") --override default radar image 3640 end 3641 return ship 3642end 3643function atlantisY42(enemyFaction) 3644 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Atlantis X23"):orderRoaming() 3645 ship:onTakingDamage(function(self,instigator) 3646 string.format("") --serious proton needs a global context 3647 if instigator ~= nil then 3648 self.damage_instigator = instigator 3649 end 3650 end) 3651 ship:setTypeName("Atlantis Y42") 3652 ship:setShieldsMax(300,200,300,200) --stronger shields (vs 200,200,200,200) 3653 ship:setShields(300,200,300,200) 3654 ship:setImpulseMaxSpeed(65) --faster impulse (vs 30) 3655 ship:setRotationMaxSpeed(15) --faster maneuver (vs 3.5) 3656-- Index, Arc, Dir, Range, Cycle, Damage 3657 ship:setBeamWeapon(2, 80, 190, 1500, 6, 8) --narrower (vs 100) 3658 ship:setBeamWeapon(3, 80, 170, 1500, 6, 8) --extra (vs 3 beams) 3659 ship:setWeaponStorageMax("Homing",16) --more (vs 4) 3660 ship:setWeaponStorage("Homing", 16) 3661 local atlantis_y42_db = queryScienceDatabase("Ships","Corvette","Atlantis Y42") 3662 if atlantis_y42_db == nil then 3663 local corvette_db = queryScienceDatabase("Ships","Corvette") 3664 corvette_db:addEntry("Atlantis Y42") 3665 atlantis_y42_db = queryScienceDatabase("Ships","Corvette","Atlantis Y42") 3666 addShipToDatabase( 3667 queryScienceDatabase("Ships","Corvette","Atlantis X23"), --base ship database entry 3668 atlantis_y42_db, --modified ship database entry 3669 ship, --ship just created, long description on the next line 3670 "The Atlantis Y42 improves on the Atlantis X23 with stronger shields, faster impulse and turn speeds, an extra beam in back and a larger missile stock", 3671 { 3672 {key = "Tube -90", value = "10 sec"}, --torpedo tube direction and load speed 3673 {key = " Tube -90", value = "10 sec"}, --torpedo tube direction and load speed 3674 {key = "Tube 90", value = "10 sec"}, --torpedo tube direction and load speed 3675 {key = " Tube 90", value = "10 sec"}, --torpedo tube direction and load speed 3676 }, 3677 "5 - 50 U" --jump range 3678 ) 3679 end 3680 return ship 3681end 3682function starhammerV(enemyFaction) 3683 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Starhammer II"):orderRoaming() 3684 ship:onTakingDamage(function(self,instigator) 3685 string.format("") --serious proton needs a global context 3686 if instigator ~= nil then 3687 self.damage_instigator = instigator 3688 end 3689 end) 3690 ship:setTypeName("Starhammer V") 3691 ship:setImpulseMaxSpeed(65) --faster impulse (vs 35) 3692 ship:setRotationMaxSpeed(15) --faster maneuver (vs 6) 3693 ship:setShieldsMax(450, 350, 250, 250, 350) --stronger shields (vs 450, 350, 150, 150, 350) 3694 ship:setShields(450, 350, 250, 250, 350) 3695-- Index, Arc, Dir, Range, Cycle, Damage 3696 ship:setBeamWeapon(4, 60, 180, 1500, 8, 11) --extra rear facing beam 3697 ship:setWeaponStorageMax("Homing",16) --more (vs 4) 3698 ship:setWeaponStorage("Homing", 16) 3699 ship:setWeaponStorageMax("HVLI",36) --more (vs 20) 3700 ship:setWeaponStorage("HVLI", 36) 3701 local starhammer_v_db = queryScienceDatabase("Ships","Corvette","Starhammer V") 3702 if starhammer_v_db == nil then 3703 local corvette_db = queryScienceDatabase("Ships","Corvette") 3704 corvette_db:addEntry("Starhammer V") 3705 starhammer_v_db = queryScienceDatabase("Ships","Corvette","Starhammer V") 3706 addShipToDatabase( 3707 queryScienceDatabase("Ships","Corvette","Starhammer II"), --base ship database entry 3708 starhammer_v_db, --modified ship database entry 3709 ship, --ship just created, long description on the next line 3710 "The Starhammer V recognizes common modifications made in the field to the Starhammer II: stronger shields, faster impulse and turning speeds, additional rear beam and more missiles to shoot. These changes make the Starhammer V a force to be reckoned with.", 3711 { 3712 {key = "Tube 0", value = "10 sec"}, --torpedo tube direction and load speed 3713 {key = " Tube 0", value = "10 sec"}, --torpedo tube direction and load speed 3714 }, 3715 "5 - 50 U" --jump range 3716 ) 3717 end 3718 return ship 3719end 3720function tyr(enemyFaction) 3721 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Battlestation"):orderRoaming() 3722 ship:onTakingDamage(function(self,instigator) 3723 string.format("") --serious proton needs a global context 3724 if instigator ~= nil then 3725 self.damage_instigator = instigator 3726 end 3727 end) 3728 ship:setTypeName("Tyr") 3729 ship:setImpulseMaxSpeed(50) --faster impulse (vs 30) 3730 ship:setRotationMaxSpeed(10) --faster maneuver (vs 1.5) 3731 ship:setShieldsMax(400, 300, 300, 400, 300, 300) --stronger shields (vs 300, 300, 300, 300, 300) 3732 ship:setShields(400, 300, 300, 400, 300, 300) 3733 ship:setHullMax(100) --stronger hull (vs 70) 3734 ship:setHull(100) 3735-- Index, Arc, Dir, Range, Cycle, Damage 3736 ship:setBeamWeapon(0, 90, -60, 2500, 6, 8) --stronger beams, broader coverage 3737 ship:setBeamWeapon(1, 90, -120, 2500, 6, 8) 3738 ship:setBeamWeapon(2, 90, 60, 2500, 6, 8) 3739 ship:setBeamWeapon(3, 90, 120, 2500, 6, 8) 3740 ship:setBeamWeapon(4, 90, -60, 2500, 6, 8) 3741 ship:setBeamWeapon(5, 90, -120, 2500, 6, 8) 3742 ship:setBeamWeapon(6, 90, 60, 2500, 6, 8) 3743 ship:setBeamWeapon(7, 90, 120, 2500, 6, 8) 3744 ship:setBeamWeapon(8, 90, -60, 2500, 6, 8) 3745 ship:setBeamWeapon(9, 90, -120, 2500, 6, 8) 3746 ship:setBeamWeapon(10, 90, 60, 2500, 6, 8) 3747 ship:setBeamWeapon(11, 90, 120, 2500, 6, 8) 3748 local tyr_db = queryScienceDatabase("Ships","Dreadnought","Tyr") 3749 if tyr_db == nil then 3750 local corvette_db = queryScienceDatabase("Ships","Dreadnought") 3751 corvette_db:addEntry("Tyr") 3752 tyr_db = queryScienceDatabase("Ships","Dreadnought","Tyr") 3753 addShipToDatabase( 3754 queryScienceDatabase("Ships","Dreadnought","Battlestation"), --base ship database entry 3755 tyr_db, --modified ship database entry 3756 ship, --ship just created, long description on the next line 3757 "The Tyr is the shipyard's answer to admiral konstatz' casual statement that the Battlestation model was too slow to be effective. The shipyards improved on the Battlestation by fitting the Tyr with more than twice the impulse speed and more than six times the turn speed. They threw in stronger shields and hull and wider beam coverage just to show that they could", 3758 nil, 3759 "5 - 50 U" --jump range 3760 ) 3761 end 3762 return ship 3763end 3764function gnat(enemyFaction) 3765 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Ktlitan Drone"):orderRoaming() 3766 ship:setTypeName("Gnat") 3767 ship:setHullMax(15) --weaker hull (vs 30) 3768 ship:setHull(15) 3769 ship:setImpulseMaxSpeed(140) --faster impulse (vs 120) 3770 ship:setRotationMaxSpeed(25) --faster maneuver (vs 10) 3771-- Index, Arc, Dir, Range, Cycle, Damage 3772 ship:setBeamWeapon(0, 40, 0, 600, 4, 3) --weaker (vs 6) beam 3773 local gnat_db = queryScienceDatabase("Ships","No Class","Gnat") 3774 if gnat_db == nil then 3775 local no_class_db = queryScienceDatabase("Ships","No Class") 3776 no_class_db:addEntry("Gnat") 3777 gnat_db = queryScienceDatabase("Ships","No Class","Gnat") 3778 addShipToDatabase( 3779 queryScienceDatabase("Ships","No Class","Ktlitan Drone"), --base ship database entry 3780 gnat_db, --modified ship database entry 3781 ship, --ship just created, long description on the next line 3782 "The Gnat is a nimbler version of the Ktlitan Drone. It's got half the hull, but it moves and turns faster", 3783 nil, 3784 nil --jump range 3785 ) 3786 end 3787 return ship 3788end 3789function cucaracha(enemyFaction) 3790 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Tug"):orderRoaming() 3791 ship:onTakingDamage(function(self,instigator) 3792 string.format("") --serious proton needs a global context 3793 if instigator ~= nil then 3794 self.damage_instigator = instigator 3795 end 3796 end) 3797 ship:setTypeName("Cucaracha") 3798 ship:setShieldsMax(200, 50, 50, 50, 50, 50) --stronger shields (vs 20) 3799 ship:setShields(200, 50, 50, 50, 50, 50) 3800 ship:setHullMax(100) --stronger hull (vs 50) 3801 ship:setHull(100) 3802 ship:setRotationMaxSpeed(20) --faster maneuver (vs 10) 3803 ship:setAcceleration(30) --faster acceleration (vs 15) 3804-- Index, Arc, Dir, Range, Cycle, Damage 3805 ship:setBeamWeapon(0, 60, 0, 1500, 6, 10) --extra rear facing beam 3806 local cucaracha_db = queryScienceDatabase("Ships","No Class","Cucaracha") 3807 if cucaracha_db == nil then 3808 local no_class_db = queryScienceDatabase("Ships","No Class") 3809 no_class_db:addEntry("Cucaracha") 3810 cucaracha_db = queryScienceDatabase("Ships","No Class","Cucaracha") 3811 addShipToDatabase( 3812 queryScienceDatabase("Ships","No Class","Tug"), --base ship database entry 3813 cucaracha_db, --modified ship database entry 3814 ship, --ship just created, long description on the next line 3815 "The Cucaracha is a quick ship built around the Tug model with heavy shields and a heavy beam designed to be difficult to squash", 3816 nil, 3817 nil --jump range 3818 ) 3819 end 3820 return ship 3821end 3822function starhammerIII(enemyFaction) 3823 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Starhammer II"):orderRoaming() 3824 ship:onTakingDamage(function(self,instigator) 3825 string.format("") --serious proton needs a global context 3826 if instigator ~= nil then 3827 self.damage_instigator = instigator 3828 end 3829 end) 3830 ship:setTypeName("Starhammer III") 3831-- Index, Arc, Dir, Range, Cycle, Damage 3832 ship:setBeamWeapon(4, 60, 180, 1500, 8, 11) --extra rear facing beam 3833 ship:setTubeSize(0,"large") 3834 ship:setWeaponStorageMax("Homing",16) --more (vs 4) 3835 ship:setWeaponStorage("Homing", 16) 3836 ship:setWeaponStorageMax("HVLI",36) --more (vs 20) 3837 ship:setWeaponStorage("HVLI", 36) 3838 local starhammer_iii_db = queryScienceDatabase("Ships","Corvette","Starhammer III") 3839 if starhammer_iii_db == nil then 3840 local corvette_db = queryScienceDatabase("Ships","Corvette") 3841 corvette_db:addEntry("Starhammer III") 3842 starhammer_iii_db = queryScienceDatabase("Ships","Corvette","Starhammer III") 3843 addShipToDatabase( 3844 queryScienceDatabase("Ships","Corvette","Starhammer II"), --base ship database entry 3845 starhammer_iii_db, --modified ship database entry 3846 ship, --ship just created, long description on the next line 3847 "The designers of the Starhammer III took the Starhammer II and added a rear facing beam, enlarged one of the missile tubes and added more missiles to fire", 3848 { 3849 {key = "Large tube 0", value = "10 sec"}, --torpedo tube direction and load speed 3850 {key = "Tube 0", value = "10 sec"}, --torpedo tube direction and load speed 3851 }, 3852 "5 - 50 U" --jump range 3853 ) 3854 end 3855 return ship 3856end 3857function k2breaker(enemyFaction) 3858 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Ktlitan Breaker"):orderRoaming() 3859 ship:onTakingDamage(function(self,instigator) 3860 string.format("") --serious proton needs a global context 3861 if instigator ~= nil then 3862 self.damage_instigator = instigator 3863 end 3864 end) 3865 ship:setTypeName("K2 Breaker") 3866 ship:setHullMax(200) --stronger hull (vs 120) 3867 ship:setHull(200) 3868 ship:setWeaponTubeCount(3) --more (vs 1) 3869 ship:setTubeSize(0,"large") --large (vs normal) 3870 ship:setWeaponTubeDirection(1,-30) 3871 ship:setWeaponTubeDirection(2, 30) 3872 ship:setWeaponTubeExclusiveFor(0,"HVLI") --only HVLI (vs any) 3873 ship:setWeaponStorageMax("Homing",16) --more (vs 0) 3874 ship:setWeaponStorage("Homing", 16) 3875 ship:setWeaponStorageMax("HVLI",8) --more (vs 5) 3876 ship:setWeaponStorage("HVLI", 8) 3877 local k2_breaker_db = queryScienceDatabase("Ships","No Class","K2 Breaker") 3878 if k2_breaker_db == nil then 3879 local no_class_db = queryScienceDatabase("Ships","No Class") 3880 no_class_db:addEntry("K2 Breaker") 3881 k2_breaker_db = queryScienceDatabase("Ships","No Class","K2 Breaker") 3882 addShipToDatabase( 3883 queryScienceDatabase("Ships","No Class","Ktlitan Breaker"), --base ship database entry 3884 k2_breaker_db, --modified ship database entry 3885 ship, --ship just created, long description on the next line 3886 "The K2 Breaker designers took the Ktlitan Breaker and beefed up the hull, added two bracketing tubes, enlarged the center tube and added more missiles to shoot. Should be good for a couple of enemy ships", 3887 { 3888 {key = "Large tube 0", value = "13 sec"}, --torpedo tube direction and load speed 3889 {key = "Tube -30", value = "13 sec"}, --torpedo tube direction and load speed 3890 {key = "Tube 30", value = "13 sec"}, --torpedo tube direction and load speed 3891 }, 3892 nil 3893 ) 3894 end 3895 return ship 3896end 3897function hurricane(enemyFaction) 3898 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Piranha F8"):orderRoaming() 3899 ship:onTakingDamage(function(self,instigator) 3900 string.format("") --serious proton needs a global context 3901 if instigator ~= nil then 3902 self.damage_instigator = instigator 3903 end 3904 end) 3905 ship:setTypeName("Hurricane") 3906 ship:setJumpDrive(true) 3907 ship:setJumpDriveRange(5000,40000) 3908 ship:setWeaponTubeCount(8) --more (vs 3) 3909 ship:setWeaponTubeExclusiveFor(1,"HVLI") --only HVLI (vs any) 3910 ship:setWeaponTubeDirection(1, 0) --forward (vs -90) 3911 ship:setTubeSize(3,"large") 3912 ship:setWeaponTubeDirection(3,-90) 3913 ship:setTubeSize(4,"small") 3914 ship:setWeaponTubeExclusiveFor(4,"Homing") 3915 ship:setWeaponTubeDirection(4,-15) 3916 ship:setTubeSize(5,"small") 3917 ship:setWeaponTubeExclusiveFor(5,"Homing") 3918 ship:setWeaponTubeDirection(5, 15) 3919 ship:setWeaponTubeExclusiveFor(6,"Homing") 3920 ship:setWeaponTubeDirection(6,-30) 3921 ship:setWeaponTubeExclusiveFor(7,"Homing") 3922 ship:setWeaponTubeDirection(7, 30) 3923 ship:setWeaponStorageMax("Homing",24) --more (vs 5) 3924 ship:setWeaponStorage("Homing", 24) 3925 local hurricane_db = queryScienceDatabase("Ships","Frigate","Hurricane") 3926 if hurricane_db == nil then 3927 local frigate_db = queryScienceDatabase("Ships","Frigate") 3928 frigate_db:addEntry("Hurricane") 3929 hurricane_db = queryScienceDatabase("Ships","Frigate","Hurricane") 3930 addShipToDatabase( 3931 queryScienceDatabase("Ships","Frigate","Piranha F8"), --base ship database entry 3932 hurricane_db, --modified ship database entry 3933 ship, --ship just created, long description on the next line 3934 "The Hurricane is designed to jump in and shower the target with missiles. It is based on the Piranha F8, but with a jump drive, five more tubes in various directions and sizes and lots more missiles to shoot", 3935 { 3936 {key = "Large tube 0", value = "12 sec"}, --torpedo tube direction and load speed 3937 {key = "Tube 0", value = "12 sec"}, --torpedo tube direction and load speed 3938 {key = "Large tube 90", value = "12 sec"}, --torpedo tube direction and load speed 3939 {key = "Large tube -90", value = "12 sec"}, --torpedo tube direction and load speed 3940 {key = "Small tube -15", value = "12 sec"}, --torpedo tube direction and load speed 3941 {key = "Small tube 15", value = "12 sec"}, --torpedo tube direction and load speed 3942 {key = "Tube -30", value = "12 sec"}, --torpedo tube direction and load speed 3943 {key = "Tube 30", value = "12 sec"}, --torpedo tube direction and load speed 3944 }, 3945 "5 - 40 U" --jump range 3946 ) 3947 end 3948 return ship 3949end 3950function phobosT4(enemyFaction) 3951 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Phobos T3"):orderRoaming() 3952 ship:onTakingDamage(function(self,instigator) 3953 string.format("") --serious proton needs a global context 3954 if instigator ~= nil then 3955 self.damage_instigator = instigator 3956 end 3957 end) 3958 ship:setTypeName("Phobos T4") 3959 ship:setRotationMaxSpeed(20) --faster maneuver (vs 10) 3960 ship:setShieldsMax(80,30) --stronger shields (vs 50,40) 3961 ship:setShields(80,30) 3962-- Index, Arc, Dir, Range, Cycle, Damage 3963 ship:setBeamWeapon(0, 90, -15, 1500, 6, 6) --longer (vs 1200), faster (vs 8) 3964 ship:setBeamWeapon(1, 90, 15, 1500, 6, 6) 3965 local phobos_t4_db = queryScienceDatabase("Ships","Frigate","Phobos T4") 3966 if phobos_t4_db == nil then 3967 local frigate_db = queryScienceDatabase("Ships","Frigate") 3968 frigate_db:addEntry("Phobos T4") 3969 phobos_t4_db = queryScienceDatabase("Ships","Frigate","Phobos T4") 3970 addShipToDatabase( 3971 queryScienceDatabase("Ships","Frigate","Phobos T3"), --base ship database entry 3972 phobos_t4_db, --modified ship database entry 3973 ship, --ship just created, long description on the next line 3974 "The Phobos T4 makes some simple improvements on the Phobos T3: faster maneuver, stronger front shields, though weaker rear shields and longer and faster beam weapons", 3975 { 3976 {key = "Tube -1", value = "60 sec"}, --torpedo tube direction and load speed 3977 {key = "Tube 1", value = "60 sec"}, --torpedo tube direction and load speed 3978 }, 3979 nil --jump range 3980 ) 3981 end 3982 return ship 3983end 3984function whirlwind(enemyFaction) 3985 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Storm"):orderRoaming() 3986 ship:onTakingDamage(function(self,instigator) 3987 string.format("") --serious proton needs a global context 3988 if instigator ~= nil then 3989 self.damage_instigator = instigator 3990 end 3991 end) 3992 ship:setTypeName("Whirlwind") 3993 ship:setWeaponTubeCount(9) --more (vs 5) 3994 ship:setWeaponTubeDirection(0,-90) --3 left, 3 right, 3 front (vs 5 front) 3995 ship:setWeaponTubeDirection(1,-92) 3996 ship:setWeaponTubeDirection(2,-88) 3997 ship:setWeaponTubeDirection(3, 90) 3998 ship:setWeaponTubeDirection(4, 92) 3999 ship:setWeaponTubeDirection(5, 88) 4000 ship:setWeaponTubeDirection(6, 0) 4001 ship:setWeaponTubeDirection(7, 2) 4002 ship:setWeaponTubeDirection(8, -2) 4003 ship:setWeaponStorageMax("Homing",36) --more (vs 15) 4004 ship:setWeaponStorage("Homing", 36) 4005 ship:setWeaponStorageMax("HVLI",36) --more (vs 15) 4006 ship:setWeaponStorage("HVLI", 36) 4007 local whirlwind_db = queryScienceDatabase("Ships","Frigate","Whirlwind") 4008 if whirlwind_db == nil then 4009 local frigate_db = queryScienceDatabase("Ships","Frigate") 4010 frigate_db:addEntry("Whirlwind") 4011 whirlwind_db = queryScienceDatabase("Ships","Frigate","Whirlwind") 4012 addShipToDatabase( 4013 queryScienceDatabase("Ships","Frigate","Storm"), --base ship database entry 4014 whirlwind_db, --modified ship database entry 4015 ship, --ship just created, long description on the next line 4016 "The Whirlwind, another heavy artillery cruiser, takes the Storm and adds tubes and missiles. It's as if the Storm swallowed a Pirahna and grew gills. Expect to see missiles, lots of missiles", 4017 { 4018 {key = "Tube -90", value = "15 sec"}, --torpedo tube direction and load speed 4019 {key = "Tube -92", value = "15 sec"}, --torpedo tube direction and load speed 4020 {key = "Tube -88", value = "15 sec"}, --torpedo tube direction and load speed 4021 {key = "Tube 90", value = "15 sec"}, --torpedo tube direction and load speed 4022 {key = "Tube 92", value = "15 sec"}, --torpedo tube direction and load speed 4023 {key = "Tube 88", value = "15 sec"}, --torpedo tube direction and load speed 4024 {key = "Tube 0", value = "15 sec"}, --torpedo tube direction and load speed 4025 {key = "Tube 2", value = "15 sec"}, --torpedo tube direction and load speed 4026 {key = "Tube -2", value = "15 sec"}, --torpedo tube direction and load speed 4027 }, 4028 nil --jump range 4029 ) 4030 end 4031 return ship 4032end 4033function farco3(enemyFaction) 4034 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Phobos T3"):orderRoaming() 4035 ship:onTakingDamage(function(self,instigator) 4036 string.format("") --serious proton needs a global context 4037 if instigator ~= nil then 4038 self.damage_instigator = instigator 4039 end 4040 end) 4041 ship:setTypeName("Farco 3") 4042 ship:setShieldsMax(60, 40) --stronger shields (vs 50, 40) 4043 ship:setShields(60, 40) 4044-- Index, Arc, Dir, Range, Cycle, Damage 4045 ship:setBeamWeapon(0, 90, -15, 1500, 5.0, 6.0) --longer (vs 1200), faster (vs 8) 4046 ship:setBeamWeapon(1, 90, 15, 1500, 5.0, 6.0) 4047 local farco_3_db = queryScienceDatabase("Ships","Frigate","Farco 3") 4048 if farco_3_db == nil then 4049 local frigate_db = queryScienceDatabase("Ships","Frigate") 4050 frigate_db:addEntry("Farco 3") 4051 farco_3_db = queryScienceDatabase("Ships","Frigate","Farco 3") 4052 addShipToDatabase( 4053 queryScienceDatabase("Ships","Frigate","Phobos T3"), --base ship database entry 4054 farco_3_db, --modified ship database entry 4055 ship, --ship just created, long description on the next line 4056 "The Farco models are evolutionary changes to the Phobos T3. In the case of the Farco 3, the beams are longer and faster and the shields are slightly stronger.", 4057 { 4058 {key = "Tube -1", value = "60 sec"}, --torpedo tube direction and load speed 4059 {key = "Tube 1", value = "60 sec"}, --torpedo tube direction and load speed 4060 }, 4061 nil --jump range 4062 ) 4063 end 4064 return ship 4065end 4066function farco5(enemyFaction) 4067 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Phobos T3"):orderRoaming() 4068 ship:onTakingDamage(function(self,instigator) 4069 string.format("") --serious proton needs a global context 4070 if instigator ~= nil then 4071 self.damage_instigator = instigator 4072 end 4073 end) 4074 ship:setTypeName("Farco 5") 4075 ship:setShieldsMax(60, 40) --stronger shields (vs 50, 40) 4076 ship:setShields(60, 40) 4077 ship:setTubeLoadTime(0,30) --faster (vs 60) 4078 ship:setTubeLoadTime(0,30) 4079 local farco_5_db = queryScienceDatabase("Ships","Frigate","Farco 5") 4080 if farco_5_db == nil then 4081 local frigate_db = queryScienceDatabase("Ships","Frigate") 4082 frigate_db:addEntry("Farco 5") 4083 farco_5_db = queryScienceDatabase("Ships","Frigate","Farco 5") 4084 addShipToDatabase( 4085 queryScienceDatabase("Ships","Frigate","Phobos T3"), --base ship database entry 4086 farco_5_db, --modified ship database entry 4087 ship, --ship just created, long description on the next line 4088 "The Farco models are evolutionary changes to the Phobos T3. In the case of the Farco 5, the tubes load faster and the shields are slightly stronger.", 4089 { 4090 {key = "Tube -1", value = "30 sec"}, --torpedo tube direction and load speed 4091 {key = "Tube 1", value = "30 sec"}, --torpedo tube direction and load speed 4092 }, 4093 nil --jump range 4094 ) 4095 end 4096 return ship 4097end 4098function farco8(enemyFaction) 4099 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Phobos T3"):orderRoaming() 4100 ship:onTakingDamage(function(self,instigator) 4101 string.format("") --serious proton needs a global context 4102 if instigator ~= nil then 4103 self.damage_instigator = instigator 4104 end 4105 end) 4106 ship:setTypeName("Farco 8") 4107 ship:setShieldsMax(80, 50) --stronger shields (vs 50, 40) 4108 ship:setShields(80, 50) 4109-- Index, Arc, Dir, Range, Cycle, Damage 4110 ship:setBeamWeapon(0, 90, -15, 1500, 5.0, 6.0) --longer (vs 1200), faster (vs 8) 4111 ship:setBeamWeapon(1, 90, 15, 1500, 5.0, 6.0) 4112 ship:setTubeLoadTime(0,30) --faster (vs 60) 4113 ship:setTubeLoadTime(0,30) 4114 local farco_8_db = queryScienceDatabase("Ships","Frigate","Farco 8") 4115 if farco_8_db == nil then 4116 local frigate_db = queryScienceDatabase("Ships","Frigate") 4117 frigate_db:addEntry("Farco 8") 4118 farco_8_db = queryScienceDatabase("Ships","Frigate","Farco 8") 4119 addShipToDatabase( 4120 queryScienceDatabase("Ships","Frigate","Phobos T3"), --base ship database entry 4121 farco_8_db, --modified ship database entry 4122 ship, --ship just created, long description on the next line 4123 "The Farco models are evolutionary changes to the Phobos T3. In the case of the Farco 8, the beams are longer and faster, the tubes load faster and the shields are stronger.", 4124 { 4125 {key = "Tube -1", value = "30 sec"}, --torpedo tube direction and load speed 4126 {key = "Tube 1", value = "30 sec"}, --torpedo tube direction and load speed 4127 }, 4128 nil --jump range 4129 ) 4130 end 4131 return ship 4132end 4133function farco11(enemyFaction) 4134 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Phobos T3"):orderRoaming() 4135 ship:onTakingDamage(function(self,instigator) 4136 string.format("") --serious proton needs a global context 4137 if instigator ~= nil then 4138 self.damage_instigator = instigator 4139 end 4140 end) 4141 ship:setTypeName("Farco 11") 4142 ship:setShieldsMax(80, 50) --stronger shields (vs 50, 40) 4143 ship:setShields(80, 50) 4144 ship:setRotationMaxSpeed(15) --faster maneuver (vs 10) 4145-- Index, Arc, Dir, Range, Cycle, Damage 4146 ship:setBeamWeapon(0, 90, -15, 1500, 5.0, 6.0) --longer (vs 1200), faster (vs 8) 4147 ship:setBeamWeapon(1, 90, 15, 1500, 5.0, 6.0) 4148 ship:setBeamWeapon(2, 20, 0, 1800, 5.0, 4.0) --additional sniping beam 4149 local farco_11_db = queryScienceDatabase("Ships","Frigate","Farco 11") 4150 if farco_11_db == nil then 4151 local frigate_db = queryScienceDatabase("Ships","Frigate") 4152 frigate_db:addEntry("Farco 11") 4153 farco_11_db = queryScienceDatabase("Ships","Frigate","Farco 11") 4154 addShipToDatabase( 4155 queryScienceDatabase("Ships","Frigate","Phobos T3"), --base ship database entry 4156 farco_11_db, --modified ship database entry 4157 ship, --ship just created, long description on the next line 4158 "The Farco models are evolutionary changes to the Phobos T3. In the case of the Farco 11, the maneuver speed is faster, the beams are longer and faster, there's an added longer sniping beam and the shields are stronger.", 4159 { 4160 {key = "Tube -1", value = "60 sec"}, --torpedo tube direction and load speed 4161 {key = "Tube 1", value = "60 sec"}, --torpedo tube direction and load speed 4162 }, 4163 nil --jump range 4164 ) 4165 end 4166 return ship 4167end 4168function farco13(enemyFaction) 4169 local ship = CpuShip():setFaction(enemyFaction):setTemplate("Phobos T3"):orderRoaming() 4170 ship:onTakingDamage(function(self,instigator) 4171 string.format("") --serious proton needs a global context 4172 if instigator ~= nil then 4173 self.damage_instigator = instigator 4174 end 4175 end) 4176 ship:setTypeName("Farco 13") 4177 ship:setShieldsMax(90, 70) --stronger shields (vs 50, 40) 4178 ship:setShields(90, 70) 4179 ship:setRotationMaxSpeed(15) --faster maneuver (vs 10) 4180-- Index, Arc, Dir, Range, Cycle, Damage 4181 ship:setBeamWeapon(0, 90, -15, 1500, 5.0, 6.0) --longer (vs 1200), faster (vs 8) 4182 ship:setBeamWeapon(1, 90, 15, 1500, 5.0, 6.0) 4183 ship:setBeamWeapon(2, 20, 0, 1800, 5.0, 4.0) --additional sniping beam 4184 ship:setTubeLoadTime(0,30) --faster (vs 60) 4185 ship:setTubeLoadTime(0,30) 4186 ship:setWeaponStorageMax("Homing",16) --more (vs 6) 4187 ship:setWeaponStorage("Homing", 16) 4188 ship:setWeaponStorageMax("HVLI",30) --more (vs 20) 4189 ship:setWeaponStorage("HVLI", 30) 4190 local farco_13_db = queryScienceDatabase("Ships","Frigate","Farco 13") 4191 if farco_13_db == nil then 4192 local frigate_db = queryScienceDatabase("Ships","Frigate") 4193 frigate_db:addEntry("Farco 13") 4194 farco_13_db = queryScienceDatabase("Ships","Frigate","Farco 13") 4195 addShipToDatabase( 4196 queryScienceDatabase("Ships","Frigate","Phobos T3"), --base ship database entry 4197 farco_13_db, --modified ship database entry 4198 ship, --ship just created, long description on the next line 4199 "The Farco models are evolutionary changes to the Phobos T3. In the case of the Farco 13, the maneuver speed is faster, the beams are longer and faster, there's an added longer sniping beam, the tubes load faster, there are more missiles and the shields are stronger.", 4200 { 4201 {key = "Tube -1", value = "30 sec"}, --torpedo tube direction and load speed 4202 {key = "Tube 1", value = "30 sec"}, --torpedo tube direction and load speed 4203 }, 4204 nil --jump range 4205 ) 4206 end 4207 return ship 4208end 4209function addShipToDatabase(base_db,modified_db,ship,description,tube_directions,jump_range) 4210 modified_db:setLongDescription(description) 4211 modified_db:setImage(base_db:getImage()) 4212 modified_db:setKeyValue("Class",base_db:getKeyValue("Class")) 4213 modified_db:setKeyValue("Sub-class",base_db:getKeyValue("Sub-class")) 4214 modified_db:setKeyValue("Size",base_db:getKeyValue("Size")) 4215 local shields = ship:getShieldCount() 4216 if shields > 0 then 4217 local shield_string = "" 4218 for i=1,shields do 4219 if shield_string == "" then 4220 shield_string = string.format("%i",math.floor(ship:getShieldMax(i-1))) 4221 else 4222 shield_string = string.format("%s/%i",shield_string,math.floor(ship:getShieldMax(i-1))) 4223 end 4224 end 4225 modified_db:setKeyValue("Shield",shield_string) 4226 end 4227 modified_db:setKeyValue("Hull",string.format("%i",math.floor(ship:getHullMax()))) 4228 modified_db:setKeyValue("Move speed",string.format("%.1f u/min",ship:getImpulseMaxSpeed()*60/1000)) 4229 modified_db:setKeyValue("Turn speed",string.format("%.1f deg/sec",ship:getRotationMaxSpeed())) 4230 if ship:hasJumpDrive() then 4231 if jump_range == nil then 4232 local base_jump_range = base_db:getKeyValue("Jump range") 4233 if base_jump_range ~= nil and base_jump_range ~= "" then 4234 modified_db:setKeyValue("Jump range",base_jump_range) 4235 else 4236 modified_db:setKeyValue("Jump range","5 - 50 u") 4237 end 4238 else 4239 modified_db:setKeyValue("Jump range",jump_range) 4240 end 4241 end 4242 if ship:hasWarpDrive() then 4243 modified_db:setKeyValue("Warp Speed",string.format("%.1f u/min",ship:getWarpSpeed()*60/1000)) 4244 end 4245 local key = "" 4246 if ship:getBeamWeaponRange(0) > 0 then 4247 local bi = 0 4248 repeat 4249 local beam_direction = ship:getBeamWeaponDirection(bi) 4250 if beam_direction > 315 and beam_direction < 360 then 4251 beam_direction = beam_direction - 360 4252 end 4253 key = string.format("Beam weapon %i:%i",ship:getBeamWeaponDirection(bi),ship:getBeamWeaponArc(bi)) 4254 while(modified_db:getKeyValue(key) ~= "") do 4255 key = " " .. key 4256 end 4257 modified_db:setKeyValue(key,string.format("%.1f Dmg / %.1f sec",ship:getBeamWeaponDamage(bi),ship:getBeamWeaponCycleTime(bi))) 4258 bi = bi + 1 4259 until(ship:getBeamWeaponRange(bi) < 1) 4260 end 4261 local tubes = ship:getWeaponTubeCount() 4262 if tubes > 0 then 4263 if tube_directions ~= nil then 4264 for i=1,#tube_directions do 4265 modified_db:setKeyValue(tube_directions[i].key,tube_directions[i].value) 4266 end 4267 end 4268 local missile_types = {'Homing', 'Nuke', 'Mine', 'EMP', 'HVLI'} 4269 for _, missile_type in ipairs(missile_types) do 4270 local max_storage = ship:getWeaponStorageMax(missile_type) 4271 if max_storage > 0 then 4272 modified_db:setKeyValue(string.format("Storage %s",missile_type),string.format("%i",max_storage)) 4273 end 4274 end 4275 end 4276end 4277-- Generate call sign functions 4278function generateCallSign(prefix,faction) 4279 if faction == nil then 4280 if prefix == nil then 4281 prefix = generateCallSignPrefix() 4282 end 4283 else 4284 if prefix == nil then 4285 prefix = getFactionPrefix(faction) 4286 else 4287 prefix = string.format("%s %s",getFactionPrefix(faction),prefix) 4288 end 4289 end 4290 suffix_index = suffix_index + math.random(1,3) 4291 if suffix_index > 99 then 4292 suffix_index = 1 4293 end 4294 return string.format("%s%i",prefix,suffix_index) 4295end 4296function generateCallSignPrefix(length) 4297 if call_sign_prefix_pool == nil then 4298 call_sign_prefix_pool = {} 4299 prefix_length = prefix_length + 1 4300 if prefix_length > 2 then 4301 prefix_length = 1 4302 end 4303 fillPrefixPool() 4304 end 4305 if length == nil then 4306 length = prefix_length 4307 end 4308 local prefix = "" 4309 for i=1,length do 4310 if #call_sign_prefix_pool < 1 then 4311 fillPrefixPool() 4312 end 4313 prefix = prefix .. tableRemoveRandom(call_sign_prefix_pool) 4314 end 4315 return prefix 4316end 4317function fillPrefixPool() 4318 for i=1,26 do 4319 table.insert(call_sign_prefix_pool,string.char(i+64)) 4320 end 4321end 4322function getFactionPrefix(faction) 4323 --get the faction names from another scenario if desired 4324 local faction_prefix = nil 4325 if faction == "Kraylor" then 4326 if kraylor_names == nil then 4327 setKraylorNames() 4328 else 4329 if #kraylor_names < 1 then 4330 setKraylorNames() 4331 end 4332 end 4333 local kraylor_name_choice = math.random(1,#kraylor_names) 4334 faction_prefix = kraylor_names[kraylor_name_choice] 4335 table.remove(kraylor_names,kraylor_name_choice) 4336 end 4337 if faction == "Exuari" then 4338 if exuari_names == nil then 4339 setExuariNames() 4340 else 4341 if #exuari_names < 1 then 4342 setExuariNames() 4343 end 4344 end 4345 local exuari_name_choice = math.random(1,#exuari_names) 4346 faction_prefix = exuari_names[exuari_name_choice] 4347 table.remove(exuari_names,exuari_name_choice) 4348 end 4349 if faction == "Ghosts" then 4350 if ghosts_names == nil then 4351 setGhostsNames() 4352 else 4353 if #ghosts_names < 1 then 4354 setGhostsNames() 4355 end 4356 end 4357 local ghosts_name_choice = math.random(1,#ghosts_names) 4358 faction_prefix = ghosts_names[ghosts_name_choice] 4359 table.remove(ghosts_names,ghosts_name_choice) 4360 end 4361 if faction == "Independent" then 4362 if independent_names == nil then 4363 setIndependentNames() 4364 else 4365 if #independent_names < 1 then 4366 setIndependentNames() 4367 end 4368 end 4369 local independent_name_choice = math.random(1,#independent_names) 4370 faction_prefix = independent_names[independent_name_choice] 4371 table.remove(independent_names,independent_name_choice) 4372 end 4373 if faction == "Human Navy" then 4374 if human_names == nil then 4375 setHumanNames() 4376 else 4377 if #human_names < 1 then 4378 setHumanNames() 4379 end 4380 end 4381 local human_name_choice = math.random(1,#human_names) 4382 faction_prefix = human_names[human_name_choice] 4383 table.remove(human_names,human_name_choice) 4384 end 4385 if faction_prefix == nil then 4386 faction_prefix = generateCallSignPrefix() 4387 end 4388 return faction_prefix 4389end 4390function setGhostsNames() 4391 ghosts_names = {} 4392 table.insert(ghosts_names,"Abstract") 4393 table.insert(ghosts_names,"Ada") 4394 table.insert(ghosts_names,"Assemble") 4395 table.insert(ghosts_names,"Assert") 4396 table.insert(ghosts_names,"Backup") 4397 table.insert(ghosts_names,"BASIC") 4398 table.insert(ghosts_names,"Big Iron") 4399 table.insert(ghosts_names,"BigEndian") 4400 table.insert(ghosts_names,"Binary") 4401 table.insert(ghosts_names,"Bit") 4402 table.insert(ghosts_names,"Block") 4403 table.insert(ghosts_names,"Boot") 4404 table.insert(ghosts_names,"Branch") 4405 table.insert(ghosts_names,"BTree") 4406 table.insert(ghosts_names,"Bubble") 4407 table.insert(ghosts_names,"Byte") 4408 table.insert(ghosts_names,"Capacitor") 4409 table.insert(ghosts_names,"Case") 4410 table.insert(ghosts_names,"Chad") 4411 table.insert(ghosts_names,"Charge") 4412 table.insert(ghosts_names,"COBOL") 4413 table.insert(ghosts_names,"Collate") 4414 table.insert(ghosts_names,"Compile") 4415 table.insert(ghosts_names,"Control") 4416 table.insert(ghosts_names,"Construct") 4417 table.insert(ghosts_names,"Cycle") 4418 table.insert(ghosts_names,"Data") 4419 table.insert(ghosts_names,"Debug") 4420 table.insert(ghosts_names,"Decimal") 4421 table.insert(ghosts_names,"Decision") 4422 table.insert(ghosts_names,"Default") 4423 table.insert(ghosts_names,"DIMM") 4424 table.insert(ghosts_names,"Displacement") 4425 table.insert(ghosts_names,"Edge") 4426 table.insert(ghosts_names,"Exit") 4427 table.insert(ghosts_names,"Factor") 4428 table.insert(ghosts_names,"Flag") 4429 table.insert(ghosts_names,"Float") 4430 table.insert(ghosts_names,"Flow") 4431 table.insert(ghosts_names,"FORTRAN") 4432 table.insert(ghosts_names,"Fullword") 4433 table.insert(ghosts_names,"GIGO") 4434 table.insert(ghosts_names,"Graph") 4435 table.insert(ghosts_names,"Hack") 4436 table.insert(ghosts_names,"Hash") 4437 table.insert(ghosts_names,"Halfword") 4438 table.insert(ghosts_names,"Hertz") 4439 table.insert(ghosts_names,"Hexadecimal") 4440 table.insert(ghosts_names,"Indicator") 4441 table.insert(ghosts_names,"Initialize") 4442 table.insert(ghosts_names,"Integer") 4443 table.insert(ghosts_names,"Integrate") 4444 table.insert(ghosts_names,"Interrupt") 4445 table.insert(ghosts_names,"Java") 4446 table.insert(ghosts_names,"Lisp") 4447 table.insert(ghosts_names,"List") 4448 table.insert(ghosts_names,"Logic") 4449 table.insert(ghosts_names,"Loop") 4450 table.insert(ghosts_names,"Lua") 4451 table.insert(ghosts_names,"Magnetic") 4452 table.insert(ghosts_names,"Mask") 4453 table.insert(ghosts_names,"Memory") 4454 table.insert(ghosts_names,"Mnemonic") 4455 table.insert(ghosts_names,"Micro") 4456 table.insert(ghosts_names,"Model") 4457 table.insert(ghosts_names,"Nibble") 4458 table.insert(ghosts_names,"Octal") 4459 table.insert(ghosts_names,"Order") 4460 table.insert(ghosts_names,"Operator") 4461 table.insert(ghosts_names,"Parameter") 4462 table.insert(ghosts_names,"Pascal") 4463 table.insert(ghosts_names,"Pattern") 4464 table.insert(ghosts_names,"Pixel") 4465 table.insert(ghosts_names,"Point") 4466 table.insert(ghosts_names,"Polygon") 4467 table.insert(ghosts_names,"Port") 4468 table.insert(ghosts_names,"Process") 4469 table.insert(ghosts_names,"RAM") 4470 table.insert(ghosts_names,"Raster") 4471 table.insert(ghosts_names,"Rate") 4472 table.insert(ghosts_names,"Redundant") 4473 table.insert(ghosts_names,"Reference") 4474 table.insert(ghosts_names,"Refresh") 4475 table.insert(ghosts_names,"Register") 4476 table.insert(ghosts_names,"Resistor") 4477 table.insert(ghosts_names,"ROM") 4478 table.insert(ghosts_names,"Routine") 4479 table.insert(ghosts_names,"Ruby") 4480 table.insert(ghosts_names,"SAAS") 4481 table.insert(ghosts_names,"Sequence") 4482 table.insert(ghosts_names,"Share") 4483 table.insert(ghosts_names,"Silicon") 4484 table.insert(ghosts_names,"SIMM") 4485 table.insert(ghosts_names,"Socket") 4486 table.insert(ghosts_names,"Sort") 4487 table.insert(ghosts_names,"Structure") 4488 table.insert(ghosts_names,"Switch") 4489 table.insert(ghosts_names,"Symbol") 4490 table.insert(ghosts_names,"Trace") 4491 table.insert(ghosts_names,"Transistor") 4492 table.insert(ghosts_names,"Value") 4493 table.insert(ghosts_names,"Vector") 4494 table.insert(ghosts_names,"Version") 4495 table.insert(ghosts_names,"View") 4496 table.insert(ghosts_names,"WYSIWYG") 4497 table.insert(ghosts_names,"XOR") 4498end 4499function setExuariNames() 4500 exuari_names = {} 4501 table.insert(exuari_names,"Astonester") 4502 table.insert(exuari_names,"Ametripox") 4503 table.insert(exuari_names,"Bakeltevex") 4504 table.insert(exuari_names,"Baropledax") 4505 table.insert(exuari_names,"Batongomox") 4506 table.insert(exuari_names,"Bekilvimix") 4507 table.insert(exuari_names,"Benoglopok") 4508 table.insert(exuari_names,"Bilontipur") 4509 table.insert(exuari_names,"Bolictimik") 4510 table.insert(exuari_names,"Bomagralax") 4511 table.insert(exuari_names,"Buteldefex") 4512 table.insert(exuari_names,"Catondinab") 4513 table.insert(exuari_names,"Chatorlonox") 4514 table.insert(exuari_names,"Culagromik") 4515 table.insert(exuari_names,"Dakimbinix") 4516 table.insert(exuari_names,"Degintalix") 4517 table.insert(exuari_names,"Dimabratax") 4518 table.insert(exuari_names,"Dokintifix") 4519 table.insert(exuari_names,"Dotandirex") 4520 table.insert(exuari_names,"Dupalgawax") 4521 table.insert(exuari_names,"Ekoftupex") 4522 table.insert(exuari_names,"Elidranov") 4523 table.insert(exuari_names,"Fakobrovox") 4524 table.insert(exuari_names,"Femoplabix") 4525 table.insert(exuari_names,"Fibatralax") 4526 table.insert(exuari_names,"Fomartoran") 4527 table.insert(exuari_names,"Gateldepex") 4528 table.insert(exuari_names,"Gamutrewal") 4529 table.insert(exuari_names,"Gesanterux") 4530 table.insert(exuari_names,"Gimardanax") 4531 table.insert(exuari_names,"Hamintinal") 4532 table.insert(exuari_names,"Holangavak") 4533 table.insert(exuari_names,"Igolpafik") 4534 table.insert(exuari_names,"Inoklomat") 4535 table.insert(exuari_names,"Jamewtibex") 4536 table.insert(exuari_names,"Jepospagox") 4537 table.insert(exuari_names,"Kajortonox") 4538 table.insert(exuari_names,"Kapogrinix") 4539 table.insert(exuari_names,"Kelitravax") 4540 table.insert(exuari_names,"Kipaldanax") 4541 table.insert(exuari_names,"Kodendevex") 4542 table.insert(exuari_names,"Kotelpedex") 4543 table.insert(exuari_names,"Kutandolak") 4544 table.insert(exuari_names,"Lakirtinix") 4545 table.insert(exuari_names,"Lapoldinek") 4546 table.insert(exuari_names,"Lavorbonox") 4547 table.insert(exuari_names,"Letirvinix") 4548 table.insert(exuari_names,"Lowibromax") 4549 table.insert(exuari_names,"Makintibix") 4550 table.insert(exuari_names,"Makorpohox") 4551 table.insert(exuari_names,"Matoprowox") 4552 table.insert(exuari_names,"Mefinketix") 4553 table.insert(exuari_names,"Motandobak") 4554 table.insert(exuari_names,"Nakustunux") 4555 table.insert(exuari_names,"Nequivonax") 4556 table.insert(exuari_names,"Nitaldavax") 4557 table.insert(exuari_names,"Nobaldorex") 4558 table.insert(exuari_names,"Obimpitix") 4559 table.insert(exuari_names,"Owaklanat") 4560 table.insert(exuari_names,"Pakendesik") 4561 table.insert(exuari_names,"Pazinderix") 4562 table.insert(exuari_names,"Pefoglamuk") 4563 table.insert(exuari_names,"Pekirdivix") 4564 table.insert(exuari_names,"Potarkadax") 4565 table.insert(exuari_names,"Pulendemex") 4566 table.insert(exuari_names,"Quatordunix") 4567 table.insert(exuari_names,"Rakurdumux") 4568 table.insert(exuari_names,"Ralombenik") 4569 table.insert(exuari_names,"Regosporak") 4570 table.insert(exuari_names,"Retordofox") 4571 table.insert(exuari_names,"Rikondogox") 4572 table.insert(exuari_names,"Rokengelex") 4573 table.insert(exuari_names,"Rutarkadax") 4574 table.insert(exuari_names,"Sakeldepex") 4575 table.insert(exuari_names,"Setiftimix") 4576 table.insert(exuari_names,"Siparkonal") 4577 table.insert(exuari_names,"Sopaldanax") 4578 table.insert(exuari_names,"Sudastulux") 4579 table.insert(exuari_names,"Takeftebex") 4580 table.insert(exuari_names,"Taliskawit") 4581 table.insert(exuari_names,"Tegundolex") 4582 table.insert(exuari_names,"Tekintipix") 4583 table.insert(exuari_names,"Tiposhomox") 4584 table.insert(exuari_names,"Tokaldapax") 4585 table.insert(exuari_names,"Tomuglupux") 4586 table.insert(exuari_names,"Tufeldepex") 4587 table.insert(exuari_names,"Unegremek") 4588 table.insert(exuari_names,"Uvendipax") 4589 table.insert(exuari_names,"Vatorgopox") 4590 table.insert(exuari_names,"Venitribix") 4591 table.insert(exuari_names,"Vobalterix") 4592 table.insert(exuari_names,"Wakintivix") 4593 table.insert(exuari_names,"Wapaltunix") 4594 table.insert(exuari_names,"Wekitrolax") 4595 table.insert(exuari_names,"Wofarbanax") 4596 table.insert(exuari_names,"Xeniplofek") 4597 table.insert(exuari_names,"Yamaglevik") 4598 table.insert(exuari_names,"Yakildivix") 4599 table.insert(exuari_names,"Yegomparik") 4600 table.insert(exuari_names,"Zapondehex") 4601 table.insert(exuari_names,"Zikandelat") 4602end 4603function setKraylorNames() 4604 kraylor_names = {} 4605 table.insert(kraylor_names,"Abroten") 4606 table.insert(kraylor_names,"Ankwar") 4607 table.insert(kraylor_names,"Bakrik") 4608 table.insert(kraylor_names,"Belgor") 4609 table.insert(kraylor_names,"Benkop") 4610 table.insert(kraylor_names,"Blargvet") 4611 table.insert(kraylor_names,"Bloktarg") 4612 table.insert(kraylor_names,"Bortok") 4613 table.insert(kraylor_names,"Bredjat") 4614 table.insert(kraylor_names,"Chankret") 4615 table.insert(kraylor_names,"Chatork") 4616 table.insert(kraylor_names,"Chokarp") 4617 table.insert(kraylor_names,"Cloprak") 4618 table.insert(kraylor_names,"Coplek") 4619 table.insert(kraylor_names,"Cortek") 4620 table.insert(kraylor_names,"Daltok") 4621 table.insert(kraylor_names,"Darpik") 4622 table.insert(kraylor_names,"Dastek") 4623 table.insert(kraylor_names,"Dotark") 4624 table.insert(kraylor_names,"Drambok") 4625 table.insert(kraylor_names,"Duntarg") 4626 table.insert(kraylor_names,"Earklat") 4627 table.insert(kraylor_names,"Ekmit") 4628 table.insert(kraylor_names,"Fakret") 4629 table.insert(kraylor_names,"Fapork") 4630 table.insert(kraylor_names,"Fawtrik") 4631 table.insert(kraylor_names,"Fenturp") 4632 table.insert(kraylor_names,"Feplik") 4633 table.insert(kraylor_names,"Figront") 4634 table.insert(kraylor_names,"Floktrag") 4635 table.insert(kraylor_names,"Fonkack") 4636 table.insert(kraylor_names,"Fontreg") 4637 table.insert(kraylor_names,"Foondrap") 4638 table.insert(kraylor_names,"Frotwak") 4639 table.insert(kraylor_names,"Gastonk") 4640 table.insert(kraylor_names,"Gentouk") 4641 table.insert(kraylor_names,"Gonpruk") 4642 table.insert(kraylor_names,"Gortak") 4643 table.insert(kraylor_names,"Gronkud") 4644 table.insert(kraylor_names,"Hewtang") 4645 table.insert(kraylor_names,"Hongtag") 4646 table.insert(kraylor_names,"Hortook") 4647 table.insert(kraylor_names,"Indrut") 4648 table.insert(kraylor_names,"Iprant") 4649 table.insert(kraylor_names,"Jakblet") 4650 table.insert(kraylor_names,"Jonket") 4651 table.insert(kraylor_names,"Jontot") 4652 table.insert(kraylor_names,"Kandarp") 4653 table.insert(kraylor_names,"Kantrok") 4654 table.insert(kraylor_names,"Kiptak") 4655 table.insert(kraylor_names,"Kortrant") 4656 table.insert(kraylor_names,"Krontgat") 4657 table.insert(kraylor_names,"Lobreck") 4658 table.insert(kraylor_names,"Lokrant") 4659 table.insert(kraylor_names,"Lomprok") 4660 table.insert(kraylor_names,"Lutrank") 4661 table.insert(kraylor_names,"Makrast") 4662 table.insert(kraylor_names,"Moklahft") 4663 table.insert(kraylor_names,"Morpug") 4664 table.insert(kraylor_names,"Nagblat") 4665 table.insert(kraylor_names,"Nokrat") 4666 table.insert(kraylor_names,"Nomek") 4667 table.insert(kraylor_names,"Notark") 4668 table.insert(kraylor_names,"Ontrok") 4669 table.insert(kraylor_names,"Orkpent") 4670 table.insert(kraylor_names,"Peechak") 4671 table.insert(kraylor_names,"Plogrent") 4672 table.insert(kraylor_names,"Pokrint") 4673 table.insert(kraylor_names,"Potarg") 4674 table.insert(kraylor_names,"Prangtil") 4675 table.insert(kraylor_names,"Quagbrok") 4676 table.insert(kraylor_names,"Quimprill") 4677 table.insert(kraylor_names,"Reekront") 4678 table.insert(kraylor_names,"Ripkort") 4679 table.insert(kraylor_names,"Rokust") 4680 table.insert(kraylor_names,"Rontrait") 4681 table.insert(kraylor_names,"Saknep") 4682 table.insert(kraylor_names,"Sengot") 4683 table.insert(kraylor_names,"Skitkard") 4684 table.insert(kraylor_names,"Skopgrek") 4685 table.insert(kraylor_names,"Sletrok") 4686 table.insert(kraylor_names,"Slorknat") 4687 table.insert(kraylor_names,"Spogrunk") 4688 table.insert(kraylor_names,"Staklurt") 4689 table.insert(kraylor_names,"Stonkbrant") 4690 table.insert(kraylor_names,"Swaktrep") 4691 table.insert(kraylor_names,"Tandrok") 4692 table.insert(kraylor_names,"Takrost") 4693 table.insert(kraylor_names,"Tonkrut") 4694 table.insert(kraylor_names,"Torkrot") 4695 table.insert(kraylor_names,"Trablok") 4696 table.insert(kraylor_names,"Trokdin") 4697 table.insert(kraylor_names,"Unkelt") 4698 table.insert(kraylor_names,"Urjop") 4699 table.insert(kraylor_names,"Vankront") 4700 table.insert(kraylor_names,"Vintrep") 4701 table.insert(kraylor_names,"Volkerd") 4702 table.insert(kraylor_names,"Vortread") 4703 table.insert(kraylor_names,"Wickurt") 4704 table.insert(kraylor_names,"Xokbrek") 4705 table.insert(kraylor_names,"Yeskret") 4706 table.insert(kraylor_names,"Zacktrope") 4707end 4708function setIndependentNames() 4709 independent_names = {} 4710 table.insert(independent_names,"Akdroft") --faux Kraylor 4711 table.insert(independent_names,"Bletnik") --faux Kraylor 4712 table.insert(independent_names,"Brogfent") --faux Kraylor 4713 table.insert(independent_names,"Cruflech") --faux Kraylor 4714 table.insert(independent_names,"Dengtoct") --faux Kraylor 4715 table.insert(independent_names,"Fiklerg") --faux Kraylor 4716 table.insert(independent_names,"Groftep") --faux Kraylor 4717 table.insert(independent_names,"Hinkflort") --faux Kraylor 4718 table.insert(independent_names,"Irklesht") --faux Kraylor 4719 table.insert(independent_names,"Jotrak") --faux Kraylor 4720 table.insert(independent_names,"Kargleth") --faux Kraylor 4721 table.insert(independent_names,"Lidroft") --faux Kraylor 4722 table.insert(independent_names,"Movrect") --faux Kraylor 4723 table.insert(independent_names,"Nitrang") --faux Kraylor 4724 table.insert(independent_names,"Poklapt") --faux Kraylor 4725 table.insert(independent_names,"Raknalg") --faux Kraylor 4726 table.insert(independent_names,"Stovtuk") --faux Kraylor 4727 table.insert(independent_names,"Trongluft") --faux Kraylor 4728 table.insert(independent_names,"Vactremp") --faux Kraylor 4729 table.insert(independent_names,"Wunklesp") --faux Kraylor 4730 table.insert(independent_names,"Yentrilg") --faux Kraylor 4731 table.insert(independent_names,"Zeltrag") --faux Kraylor 4732 table.insert(independent_names,"Avoltojop") --faux Exuari 4733 table.insert(independent_names,"Bimartarax") --faux Exuari 4734 table.insert(independent_names,"Cidalkapax") --faux Exuari 4735 table.insert(independent_names,"Darongovax") --faux Exuari 4736 table.insert(independent_names,"Felistiyik") --faux Exuari 4737 table.insert(independent_names,"Gopendewex") --faux Exuari 4738 table.insert(independent_names,"Hakortodox") --faux Exuari 4739 table.insert(independent_names,"Jemistibix") --faux Exuari 4740 table.insert(independent_names,"Kilampafax") --faux Exuari 4741 table.insert(independent_names,"Lokuftumux") --faux Exuari 4742 table.insert(independent_names,"Mabildirix") --faux Exuari 4743 table.insert(independent_names,"Notervelex") --faux Exuari 4744 table.insert(independent_names,"Pekolgonex") --faux Exuari 4745 table.insert(independent_names,"Rifaltabax") --faux Exuari 4746 table.insert(independent_names,"Sobendeyex") --faux Exuari 4747 table.insert(independent_names,"Tinaftadax") --faux Exuari 4748 table.insert(independent_names,"Vadorgomax") --faux Exuari 4749 table.insert(independent_names,"Wilerpejex") --faux Exuari 4750 table.insert(independent_names,"Yukawvalak") --faux Exuari 4751 table.insert(independent_names,"Zajiltibix") --faux Exuari 4752 table.insert(independent_names,"Alter") --faux Ghosts 4753 table.insert(independent_names,"Assign") --faux Ghosts 4754 table.insert(independent_names,"Brain") --faux Ghosts 4755 table.insert(independent_names,"Break") --faux Ghosts 4756 table.insert(independent_names,"Boundary") --faux Ghosts 4757 table.insert(independent_names,"Code") --faux Ghosts 4758 table.insert(independent_names,"Compare") --faux Ghosts 4759 table.insert(independent_names,"Continue") --faux Ghosts 4760 table.insert(independent_names,"Core") --faux Ghosts 4761 table.insert(independent_names,"CRUD") --faux Ghosts 4762 table.insert(independent_names,"Decode") --faux Ghosts 4763 table.insert(independent_names,"Decrypt") --faux Ghosts 4764 table.insert(independent_names,"Device") --faux Ghosts 4765 table.insert(independent_names,"Encode") --faux Ghosts 4766 table.insert(independent_names,"Encrypt") --faux Ghosts 4767 table.insert(independent_names,"Event") --faux Ghosts 4768 table.insert(independent_names,"Fetch") --faux Ghosts 4769 table.insert(independent_names,"Frame") --faux Ghosts 4770 table.insert(independent_names,"Go") --faux Ghosts 4771 table.insert(independent_names,"IO") --faux Ghosts 4772 table.insert(independent_names,"Interface") --faux Ghosts 4773 table.insert(independent_names,"Kilo") --faux Ghosts 4774 table.insert(independent_names,"Modify") --faux Ghosts 4775 table.insert(independent_names,"Pin") --faux Ghosts 4776 table.insert(independent_names,"Program") --faux Ghosts 4777 table.insert(independent_names,"Purge") --faux Ghosts 4778 table.insert(independent_names,"Retrieve") --faux Ghosts 4779 table.insert(independent_names,"Store") --faux Ghosts 4780 table.insert(independent_names,"Unit") --faux Ghosts 4781 table.insert(independent_names,"Wire") --faux Ghosts 4782end 4783function setHumanNames() 4784 human_names = {} 4785 table.insert(human_names,"Andromeda") 4786 table.insert(human_names,"Angelica") 4787 table.insert(human_names,"Artemis") 4788 table.insert(human_names,"Barrier") 4789 table.insert(human_names,"Beauteous") 4790 table.insert(human_names,"Bliss") 4791 table.insert(human_names,"Bonita") 4792 table.insert(human_names,"Bounty Hunter") 4793 table.insert(human_names,"Bueno") 4794 table.insert(human_names,"Capitol") 4795 table.insert(human_names,"Castigator") 4796 table.insert(human_names,"Centurion") 4797 table.insert(human_names,"Chakalaka") 4798 table.insert(human_names,"Charity") 4799 table.insert(human_names,"Christmas") 4800 table.insert(human_names,"Chutzpah") 4801 table.insert(human_names,"Constantine") 4802 table.insert(human_names,"Crystal") 4803 table.insert(human_names,"Dauntless") 4804 table.insert(human_names,"Defiant") 4805 table.insert(human_names,"Discovery") 4806 table.insert(human_names,"Dorcas") 4807 table.insert(human_names,"Elite") 4808 table.insert(human_names,"Empathy") 4809 table.insert(human_names,"Enlighten") 4810 table.insert(human_names,"Enterprise") 4811 table.insert(human_names,"Escape") 4812 table.insert(human_names,"Exclamatory") 4813 table.insert(human_names,"Faith") 4814 table.insert(human_names,"Felicity") 4815 table.insert(human_names,"Firefly") 4816 table.insert(human_names,"Foresight") 4817 table.insert(human_names,"Forthright") 4818 table.insert(human_names,"Fortitude") 4819 table.insert(human_names,"Frankenstein") 4820 table.insert(human_names,"Gallant") 4821 table.insert(human_names,"Gladiator") 4822 table.insert(human_names,"Glider") 4823 table.insert(human_names,"Godzilla") 4824 table.insert(human_names,"Grind") 4825 table.insert(human_names,"Happiness") 4826 table.insert(human_names,"Hearken") 4827 table.insert(human_names,"Helena") 4828 table.insert(human_names,"Heracles") 4829 table.insert(human_names,"Honorable Intentions") 4830 table.insert(human_names,"Hope") 4831 table.insert(human_names,"Hurricane") 4832 table.insert(human_names,"Inertia") 4833 table.insert(human_names,"Ingenius") 4834 table.insert(human_names,"Injurious") 4835 table.insert(human_names,"Insight") 4836 table.insert(human_names,"Insufferable") 4837 table.insert(human_names,"Insurmountable") 4838 table.insert(human_names,"Intractable") 4839 table.insert(human_names,"Intransigent") 4840 table.insert(human_names,"Jenny") 4841 table.insert(human_names,"Juice") 4842 table.insert(human_names,"Justice") 4843 table.insert(human_names,"Jurassic") 4844 table.insert(human_names,"Karma Cast") 4845 table.insert(human_names,"Knockout") 4846 table.insert(human_names,"Leila") 4847 table.insert(human_names,"Light Fantastic") 4848 table.insert(human_names,"Livid") 4849 table.insert(human_names,"Lolita") 4850 table.insert(human_names,"Mercury") 4851 table.insert(human_names,"Moira") 4852 table.insert(human_names,"Mona Lisa") 4853 table.insert(human_names,"Nancy") 4854 table.insert(human_names,"Olivia") 4855 table.insert(human_names,"Ominous") 4856 table.insert(human_names,"Oracle") 4857 table.insert(human_names,"Orca") 4858 table.insert(human_names,"Pandemic") 4859 table.insert(human_names,"Parsimonious") 4860 table.insert(human_names,"Personal Prejudice") 4861 table.insert(human_names,"Porpoise") 4862 table.insert(human_names,"Pristine") 4863 table.insert(human_names,"Purple Passion") 4864 table.insert(human_names,"Renegade") 4865 table.insert(human_names,"Revelation") 4866 table.insert(human_names,"Rosanna") 4867 table.insert(human_names,"Rozelle") 4868 table.insert(human_names,"Sainted Gramma") 4869 table.insert(human_names,"Shazam") 4870 table.insert(human_names,"Starbird") 4871 table.insert(human_names,"Stargazer") 4872 table.insert(human_names,"Stile") 4873 table.insert(human_names,"Streak") 4874 table.insert(human_names,"Take Flight") 4875 table.insert(human_names,"Taskmaster") 4876 table.insert(human_names,"Tempest") 4877 table.insert(human_names,"The Way") 4878 table.insert(human_names,"Tornado") 4879 table.insert(human_names,"Trailblazer") 4880 table.insert(human_names,"Trident") 4881 table.insert(human_names,"Triple Threat") 4882 table.insert(human_names,"Turnabout") 4883 table.insert(human_names,"Undulator") 4884 table.insert(human_names,"Urgent") 4885 table.insert(human_names,"Victoria") 4886 table.insert(human_names,"Wee Bit") 4887 table.insert(human_names,"Wet Willie") 4888end 4889 4890function tableRemoveRandom(array) 4891-- Remove random element from array and return it. 4892 -- Returns nil if the array is empty, 4893 -- analogous to `table.remove`. 4894 local array_item_count = #array 4895 if array_item_count == 0 then 4896 return nil 4897 end 4898 local selected_item = math.random(array_item_count) 4899 array[selected_item], array[array_item_count] = array[array_item_count], array[selected_item] 4900 return table.remove(array) 4901end 4902 4903function asteroidSize() 4904 return random(1,160)+random(1,120)+random(1,80)+random(1,40)+random(1,20)+random(1,10) 4905end 4906function createRandomListAlongArc(object_type, amount, x, y, distance, startArc, endArcClockwise, randomize) 4907-- Create amount of objects of type object_type along arc 4908-- Center defined by x and y 4909-- Radius defined by distance 4910-- Start of arc between 0 and 360 (startArc), end arc: endArcClockwise 4911-- Use randomize to vary the distance from the center point. Omit to keep distance constant 4912-- Example: 4913-- createRandomAlongArc(Asteroid, 100, 500, 3000, 65, 120, 450) 4914 local list = {} 4915 if randomize == nil then randomize = 0 end 4916 if amount == nil then amount = 1 end 4917 local arcLen = endArcClockwise - startArc 4918 if startArc > endArcClockwise then 4919 endArcClockwise = endArcClockwise + 360 4920 arcLen = arcLen + 360 4921 end 4922 if amount > arcLen then 4923 for ndex=1,arcLen do 4924 local radialPoint = startArc+ndex 4925 local pointDist = distance + random(-randomize,randomize) 4926 table.insert(list,object_type():setPosition(x + math.cos(radialPoint / 180 * math.pi) * pointDist, y + math.sin(radialPoint / 180 * math.pi) * pointDist)) 4927 end 4928 for ndex=1,amount-arcLen do 4929 radialPoint = random(startArc,endArcClockwise) 4930 pointDist = distance + random(-randomize,randomize) 4931 table.insert(list,object_type():setPosition(x + math.cos(radialPoint / 180 * math.pi) * pointDist, y + math.sin(radialPoint / 180 * math.pi) * pointDist)) 4932 end 4933 else 4934 for ndex=1,amount do 4935 radialPoint = random(startArc,endArcClockwise) 4936 pointDist = distance + random(-randomize,randomize) 4937 table.insert(list,object_type():setPosition(x + math.cos(radialPoint / 180 * math.pi) * pointDist, y + math.sin(radialPoint / 180 * math.pi) * pointDist)) 4938 end 4939 end 4940 return list 4941end 4942function createObjectsListOnLine(x1, y1, x2, y2, spacing, object_type, rows, chance, randomize) 4943-- Create objects along a line between two vectors, optionally with grid 4944-- placement and randomization. 4945-- 4946-- createObjectsOnLine(x1, y1, x2, y2, spacing, object_type, rows, chance, randomize) 4947-- x1, y1: Starting coordinates 4948-- x2, y2: Ending coordinates 4949-- spacing: The distance between each object. 4950-- object_type: The object type. Calls `object_type():setPosition()`. 4951-- rows (optional): The number of rows, minimum 1. Defaults to 1. 4952-- chance (optional): The percentile chance an object will be created, 4953-- minimum 1. Defaults to 100 (always). 4954-- randomize (optional): If present, randomize object placement by this 4955-- amount. Defaults to 0 (grid). 4956-- 4957-- Examples: To create a mine field, run: 4958-- createObjectsOnLine(0, 0, 10000, 0, 1000, Mine, 4) 4959-- This creates 4 rows of mines from 0,0 to 10000,0, with mines spaced 1U 4960-- apart. 4961-- 4962-- The `randomize` parameter adds chaos to the pattern. This works well for 4963-- asteroid fields: 4964-- createObjectsOnLine(0, 0, 10000, 0, 300, Asteroid, 4, 100, 800) 4965 local list = {} 4966 if rows == nil then rows = 1 end 4967 if chance == nil then chance = 100 end 4968 if randomize == nil then randomize = 0 end 4969 local d = distance(x1, y1, x2, y2) 4970 local xd = (x2 - x1) / d 4971 local yd = (y2 - y1) / d 4972 for cnt_x=0,d,spacing do 4973 for cnt_y=0,(rows-1)*spacing,spacing do 4974 local px = x1 + xd * cnt_x + yd * (cnt_y - (rows - 1) * spacing * 0.5) + random(-randomize, randomize) 4975 local py = y1 + yd * cnt_x - xd * (cnt_y - (rows - 1) * spacing * 0.5) + random(-randomize, randomize) 4976 if random(0, 100) < chance then 4977 table.insert(list,object_type():setPosition(px, py)) 4978 end 4979 end 4980 end 4981 return list 4982end 4983function placeRandomListAroundPoint(object_type, amount, dist_min, dist_max, x0, y0) 4984-- create amount of object_type, at a distance between dist_min and dist_max around the point (x0, y0) 4985-- save in a list that is returned to caller 4986 local object_list = {} 4987 for n=1,amount do 4988 local r = random(0, 360) 4989 local distance = random(dist_min, dist_max) 4990 x = x0 + math.cos(r / 180 * math.pi) * distance 4991 y = y0 + math.sin(r / 180 * math.pi) * distance 4992 table.insert(object_list,object_type():setPosition(x, y)) 4993 end 4994 return object_list 4995end 4996function placeRandomAsteroidsAroundPoint(amount, dist_min, dist_max, x0, y0) 4997-- create amount of asteroid, at a distance between dist_min and dist_max around the point (x0, y0) 4998 for n=1,amount do 4999 local r = random(0, 360) 5000 local distance = random(dist_min, dist_max) 5001 x = x0 + math.cos(r / 180 * math.pi) * distance 5002 y = y0 + math.sin(r / 180 * math.pi) * distance 5003 local asteroid_size = random(1,100) + random(1,75) + random(1,75) + random(1,20) + random(1,20) + random(1,20) + random(1,20) + random(1,20) + random(1,20) + random(1,20) 5004 Asteroid():setPosition(x, y):setSize(asteroid_size) 5005 end 5006end 5007function choosePlanet(index,x,y) 5008 local planet_list = { 5009 { 5010 radius = random(500,1500), distance = -2000, 5011 name = {"Gamma Piscium","Beta Lyporis","Sigma Draconis","Iota Carinae","Theta Arietis","Epsilon Indi","Beta Hydri"}, 5012 color = { 5013 red = random(0.9,1), green = random(0.85,1), blue = random(0.9,1) 5014 }, 5015 texture = { 5016 atmosphere = "planets/star-1.png" 5017 }, 5018 }, 5019 { 5020 radius = random(2500,4000), distance = -2000, rotation = random(250,350), 5021 name = {"Bespin","Aldea","Bersallis","Alpha Omicron","Farius Prime","Deneb","Mordan","Nelvana"}, 5022 texture = { 5023 surface = "planets/gas-1.png" 5024 }, 5025 }, 5026 { 5027 radius = random(2000,3500), distance = -2000, rotation = random(350,450), 5028 name = {"Alderaan","Dagobah","Dantooine","Rigel","Pahvo","Penthara","Scalos","Tanuga","Vacca","Terlina","Timor"}, 5029 color = { 5030 red = random(0.1,0.3), green = random(0.1,0.3), blue = random(0.9,1) 5031 }, 5032 texture = { 5033 surface = "planets/planet-1.png", cloud = "planets/clouds-1.png", atmosphere = "planets/atmosphere.png" 5034 }, 5035 }, 5036 { 5037 radius = random(200,400), distance = -150, rotation = random(60,100), 5038 name = {"Adrastea","Belior","Cressida","Europa","Kyrrdis","Oberon","Pallas","Telesto","Vesta"}, 5039 texture = { 5040 surface = "planets/moon-1.png" 5041 } 5042 }, 5043 } 5044 local planet = Planet():setPosition(x,y):setPlanetRadius(planet_list[index].radius):setDistanceFromMovementPlane(planet_list[index].distance):setCallSign(planet_list[index].name[math.random(1,#planet_list[index].name)]) 5045 if planet_list[index].texture.surface ~= nil then 5046 planet:setPlanetSurfaceTexture(planet_list[index].texture.surface) 5047 end 5048 if planet_list[index].texture.atmosphere ~= nil then 5049 planet:setPlanetAtmosphereTexture(planet_list[index].texture.atmosphere) 5050 end 5051 if planet_list[index].texture.cloud ~= nil then 5052 planet:setPlanetCloudTexture(planet_list[index].texture.cloud) 5053 end 5054 if planet_list[index].color ~= nil then 5055 planet:setPlanetAtmosphereColor(planet_list[index].color.red,planet_list[index].color.green,planet_list[index].color.blue) 5056 end 5057 if planet_list[index].rotation ~= nil then 5058 planet:setAxialRotationTime(planet_list[index].rotation) 5059 end 5060 return planet, planet_list[index].radius 5061end 5062function vectorFromAngleNorth(angle,distance) 5063 angle = (angle + 270) % 360 5064 local x, y = vectorFromAngle(angle,distance) 5065 return x, y 5066end 5067function angleFromVectorNorth(p1x,p1y,p2x,p2y) 5068 TWOPI = 6.2831853071795865 5069 RAD2DEG = 57.2957795130823209 5070 atan2parm1 = p2x - p1x 5071 atan2parm2 = p2y - p1y 5072 theta = math.atan2(atan2parm1, atan2parm2) 5073 if theta < 0 then 5074 theta = theta + TWOPI 5075 end 5076 return (360 - (RAD2DEG * theta)) % 360 5077end 5078function analyzeBlob(object_list) 5079--given a blob (list) of objects, find the center and the max perimeter and avg dist values 5080 local center_x = 0 5081 local center_y = 0 5082 local max_perimeter = 0 5083 local total_distance = 0 5084 local average_distance = 0 5085 if object_list ~= nil and #object_list > 0 then 5086 for i=1,#object_list do 5087 local obj_x, obj_y = object_list[i]:getPosition() 5088 center_x = center_x + obj_x 5089 center_y = center_y + obj_y 5090 end 5091 center_x = center_x/#object_list 5092 center_y = center_y/#object_list 5093 for i=1,#object_list do 5094--[[ 5095 if distance_diagnostic then 5096 print("function analyzeBlob") 5097 if object_list[i] == nil then 5098 print(" object_list[i] is nil") 5099 print(" " .. i) 5100 print(" " .. object_list) 5101 else 5102 print(" " .. i,object_list[i]) 5103 end 5104 if center_x == nil then 5105 print(" center_x is nil") 5106 else 5107 print(" center_x: " .. center_x) 5108 end 5109 end 5110--]] 5111 local current_distance = distance(object_list[i],center_x,center_y) 5112 total_distance = total_distance + current_distance 5113 if current_distance >= max_perimeter then 5114 max_perimeter = current_distance 5115 end 5116 end 5117 average_distance = total_distance/#object_list 5118 end 5119 return center_x, center_y, max_perimeter, average_distance 5120end 5121function farEnough(list,pos_x,pos_y,bubble) 5122 local far_enough = true 5123 for i=1,#list do 5124 local list_item = list[i] 5125--[[ 5126 if distance_diagnostic then 5127 print("function farEnough") 5128 if list_item == nil then 5129 print(" list_item is nil") 5130 print(" " .. i) 5131 print(" " .. list) 5132 else 5133 print(" " .. i) 5134 print(list_item) 5135 end 5136 if pos_x == nil then 5137 print(" pos_x is nil") 5138 else 5139 print(" pos_x: " .. pos_x) 5140 end 5141 end 5142--]] 5143 local distance_away = distance(list_item,pos_x,pos_y) 5144 if distance_away < bubble then 5145 far_enough = false 5146 break 5147 end 5148 if list_item.typeName == "BlackHole" or list_item.typeName == "WormHole" then 5149 if distance_away < 6000 then 5150 far_enough = false 5151 break 5152 end 5153 end 5154 if list_item.typeName == "Planet" then 5155 if distance_away < 4000 then 5156 far_enough = false 5157 break 5158 end 5159 end 5160 end 5161 return far_enough 5162end 5163-- Player ship types, placement and naming functions 5164function placeCustomPlayerShips() 5165 print("place custom player ships") 5166 player_restart = {} 5167 for pidx=1,32 do 5168 local p = getPlayerShip(pidx) 5169 if p ~= nil and p:isValid() then 5170 p:destroy() 5171 end 5172 end 5173 local angle = human_angle 5174 for _, template in ipairs(custom_player_ship_sets[custom_player_ship_type][ships_per_team]) do 5175-- print("Human ships per team template:",template) 5176 local p = nil 5177 if player_ship_stats[template].stock then 5178 p = PlayerSpaceship():setTemplate(template):setFaction("Human Navy") 5179 else 5180 p = customPlayerShip(template) 5181 p:setFaction("Human Navy") 5182 end 5183 setPlayer(p) 5184 startPlayerPosition(p,angle) 5185 local respawn_x, respawn_y = p:getPosition() 5186 p.respawn_x = respawn_x 5187 p.respawn_y = respawn_y 5188 player_restart[p:getCallSign()] = {self = p, template = p:getTypeName(), control_code = p.control_code, faction = p:getFaction(), respawn_x = respawn_x, respawn_y = respawn_y} 5189 angle = (angle + 360/ships_per_team) % 360 5190 end 5191 replicatePlayers("Kraylor") 5192 if exuari_angle ~= nil then 5193 replicatePlayers("Exuari") 5194 end 5195 if ktlitan_angle ~= nil then 5196 replicatePlayers("Ktlitans") 5197 end 5198end 5199function customPlayerShip(custom_template,p) 5200 if player_ship_stats[custom_template] == nil then 5201 print("Invalid custom player ship template") 5202 return nil 5203 end 5204 if p == nil then 5205 p = PlayerSpaceship() 5206 end 5207 if custom_template == "Striker LX" then 5208 p:setTemplate("Striker") 5209 p:setTypeName("Striker LX") 5210 p:setRepairCrewCount(3) --more (vs 2) 5211 p:setShieldsMax(100,100) --stronger shields (vs 50, 30) 5212 p:setShields(100,100) 5213 p:setHullMax(100) --weaker hull (vs 120) 5214 p:setHull(100) 5215 p:setMaxEnergy(600) --more maximum energy (vs 500) 5216 p:setEnergy(600) 5217 p:setImpulseMaxSpeed(65) --faster impulse max (vs 45) 5218 -- Arc, Dir, Range, CycleTime, Damage 5219 p:setBeamWeapon(0, 10, -15, 1100, 6.0, 6.5) --shorter (vs 1200) more damage (vs 6.0) 5220 p:setBeamWeapon(1, 10, 15, 1100, 6.0, 6.5) 5221 -- Arc, Dir, Rotate speed 5222 p:setBeamWeaponTurret(0, 100, -15, .2) --slower turret speed (vs 6) 5223 p:setBeamWeaponTurret(1, 100, 15, .2) 5224 p:setWeaponTubeCount(2) --more tubes (vs 0) 5225 p:setWeaponTubeDirection(0,180) 5226 p:setWeaponTubeDirection(1,180) 5227 p:setWeaponStorageMax("Homing",4) 5228 p:setWeaponStorage("Homing", 4) 5229 p:setWeaponStorageMax("Nuke",2) 5230 p:setWeaponStorage("Nuke", 2) 5231 p:setWeaponStorageMax("EMP",3) 5232 p:setWeaponStorage("EMP", 3) 5233 p:setWeaponStorageMax("Mine",3) 5234 p:setWeaponStorage("Mine", 3) 5235 p:setWeaponStorageMax("HVLI",6) 5236 p:setWeaponStorage("HVLI", 6) 5237 elseif custom_template == "Focus" then 5238 p:setTemplate("Crucible") 5239 p:setTypeName("Focus") 5240 p:setImpulseMaxSpeed(70) --slower (vs 80) 5241 p:setRotationMaxSpeed(20) --faster spin (vs 15) 5242 p:setWarpDrive(false) --no warp 5243 p:setHullMax(100) --weaker hull (vs 160) 5244 p:setHull(100) 5245 p:setShieldsMax(100, 100) --weaker shields (vs 160, 160) 5246 p:setShields(100, 100) 5247 -- Arc, Dir, Range, CycleTime, Damage 5248 p:setBeamWeapon(0, 60, -20, 1000.0, 6.0, 5) --narrower (vs 70) 5249 p:setBeamWeapon(1, 60, 20, 1000.0, 6.0, 5) 5250 p:setWeaponTubeCount(4) --fewer (vs 6) 5251 p:weaponTubeAllowMissle(2,"Homing") --big tube shoots more stuff (vs HVLI) 5252 p:weaponTubeAllowMissle(2,"EMP") 5253 p:weaponTubeAllowMissle(2,"Nuke") 5254 p:setWeaponTubeExclusiveFor(3,"Mine") --rear (vs left) 5255 p:setWeaponTubeDirection(3, 180) 5256 p:setWeaponStorageMax("EMP",2) --fewer (vs 6) 5257 p:setWeaponStorage("EMP", 2) 5258 p:setWeaponStorageMax("Nuke",1) --fewer (vs 4) 5259 p:setWeaponStorage("Nuke", 1) 5260 elseif custom_template == "Holmes" then 5261 p:setTemplate("Crucible") 5262 p:setTypeName("Holmes") 5263 p:setImpulseMaxSpeed(70) --slower (vs 80) 5264 -- Arc, Dir, Range, CycleTime, Dmg 5265 p:setBeamWeapon(0, 50, -85, 900.0, 6.0, 5) --broadside beams, narrower (vs 70) 5266 p:setBeamWeapon(1, 50, -95, 900.0, 6.0, 5) 5267 p:setBeamWeapon(2, 50, 85, 900.0, 6.0, 5) 5268 p:setBeamWeapon(3, 50, 95, 900.0, 6.0, 5) 5269 p:setWeaponTubeCount(4) --fewer (vs 6) 5270 p:setWeaponTubeExclusiveFor(0,"Homing") --tubes only shoot homing missiles (vs more options) 5271 p:setWeaponTubeExclusiveFor(1,"Homing") 5272 p:setWeaponTubeExclusiveFor(2,"Homing") 5273 p:setWeaponTubeExclusiveFor(3,"Mine") 5274 p:setWeaponTubeDirection(3, 180) 5275 p:setWeaponStorageMax("Homing",10) --more (vs 8) 5276 p:setWeaponStorage("Homing", 10) 5277 p:setWeaponStorageMax("HVLI",0) --fewer 5278 p:setWeaponStorage("HVLI", 0) 5279 p:setWeaponStorageMax("EMP",0) --fewer 5280 p:setWeaponStorage("EMP", 0) 5281 p:setWeaponStorageMax("Nuke",0) --fewer 5282 p:setWeaponStorage("Nuke", 0) 5283 elseif custom_template == "Maverick XP" then 5284 p:setTemplate("Maverick") 5285 p:setTypeName("Maverick XP") 5286 p:setImpulseMaxSpeed(65) --slower impulse max (vs 80) 5287 p:setWarpDrive(false) --no warp 5288 -- Arc, Dir, Range, CycleTime, Dmg 5289 p:setBeamWeapon(0, 10, 0, 1000.0, 20.0, 20) 5290 -- Arc, Dir, Rotate speed 5291 p:setBeamWeaponTurret(0, 270, 0, .4) 5292 p:setBeamWeaponEnergyPerFire(0,p:getBeamWeaponEnergyPerFire(0)*6) 5293 p:setBeamWeaponHeatPerFire(0,p:getBeamWeaponHeatPerFire(0)*5) 5294 p:setBeamWeapon(1, 0, 0, 0, 0, 0) --eliminate 5 beams 5295 p:setBeamWeapon(2, 0, 0, 0, 0, 0) 5296 p:setBeamWeapon(3, 0, 0, 0, 0, 0) 5297 p:setBeamWeapon(4, 0, 0, 0, 0, 0) 5298 p:setBeamWeapon(5, 0, 0, 0, 0, 0) 5299 elseif custom_template == "Phobos T2" then 5300 p:setTemplate("Phobos M3P") 5301 p:setTypeName("Phobos T2") 5302 p:setRepairCrewCount(4) --more repair crew (vs 3) 5303 p:setRotationMaxSpeed(20) --faster spin (vs 10) 5304 p:setShieldsMax(120,80) --stronger front, weaker rear (vs 100,100) 5305 p:setShields(120,80) 5306 p:setMaxEnergy(800) --less maximum energy (vs 1000) 5307 p:setEnergy(800) 5308 -- Arc, Dir, Range, CycleTime, Dmg 5309 p:setBeamWeapon(0, 10, -30, 1200, 4, 6) --split direction (30 vs 15) 5310 p:setBeamWeapon(1, 10, 30, 1200, 4, 6) --reduced cycle time (4 vs 8) 5311 -- Arc, Dir, Rotate speed 5312 p:setBeamWeaponTurret(0, 60, -30, .3) --slow turret beams 5313 p:setBeamWeaponTurret(1, 60, 30, .3) 5314 p:setWeaponTubeCount(2) --one fewer tube (1 forward, 1 rear vs 2 forward, 1 rear) 5315 p:setWeaponTubeDirection(0,0) --first tube points straight forward 5316 p:setWeaponTubeDirection(1,180) --second tube points straight back 5317 p:setWeaponTubeExclusiveFor(1,"Mine") 5318 p:setWeaponStorageMax("Homing",8) --reduce homing storage (vs 10) 5319 p:setWeaponStorage("Homing",8) 5320 p:setWeaponStorageMax("HVLI",16) --reduce HVLI storage (vs 20) 5321 p:setWeaponStorage("HVLI",16) 5322 end 5323 return p 5324end 5325function placeDefaultPlayerShips() 5326 player_restart = {} 5327 for pidx=1,32 do 5328 local p = getPlayerShip(pidx) 5329 if p ~= nil and p:isValid() then 5330 p:destroy() 5331 end 5332 end 5333 angle = faction_angle["Human Navy"] 5334 for _, template in ipairs(default_player_ship_sets[ships_per_team]) do 5335 local p = PlayerSpaceship():setTemplate(template):setFaction("Human Navy") 5336 setPlayer(p) 5337 startPlayerPosition(p,angle) 5338 local respawn_x, respawn_y = p:getPosition() 5339 p.respawn_x = respawn_x 5340 p.respawn_y = respawn_y 5341 player_restart[p:getCallSign()] = {self = p, template = p:getTypeName(), control_code = p.control_code, faction = p:getFaction(), respawn_x = respawn_x, respawn_y = respawn_y} 5342 angle = (angle + 360/ships_per_team) % 360 5343 end 5344 replicatePlayers("Kraylor") 5345 if exuari_angle ~= nil then 5346 replicatePlayers("Exuari") 5347 end 5348 if ktlitan_angle ~= nil then 5349 replicatePlayers("Ktlitans") 5350 end 5351end 5352function startPlayerPosition(p,angle) 5353-- print("start player position angle:",angle) 5354 vx, vy = vectorFromAngleNorth(angle,player_position_distance) 5355 p:setPosition(faction_primary_station[p:getFaction()].x + vx, faction_primary_station[p:getFaction()].y + vy):setHeading(angle):commandTargetRotation((angle + 270) % 360) 5356end 5357function replicatePlayers(faction) 5358-- Replicate the Human Navy player ships to the designated faction 5359-- print("replicate players faction:",faction) 5360 local angle = faction_angle[faction] 5361 local temp_player_restart = {} 5362 for name, details in pairs(player_restart) do 5363-- print("player restart item faction:",details.faction) 5364 if details.faction == "Human Navy" then 5365-- print("name:",name,"details:",details,"details.template:",details.template,"faction:",faction) 5366 local p = PlayerSpaceship() 5367 if p ~= nil and p:isValid() then 5368 if player_ship_stats[details.template].stock then 5369 p:setTemplate(details.template) 5370 else 5371 customPlayerShip(details.template,p) 5372 end 5373 p:setFaction(faction) 5374 setPlayer(p) 5375 startPlayerPosition(p,angle) 5376 local respawn_x, respawn_y = p:getPosition() 5377 p.respawn_x = respawn_x 5378 p.respawn_y = respawn_y 5379 temp_player_restart[p:getCallSign()] = {self = p, template = p:getTypeName(), control_code = p.control_code, faction = p:getFaction(), respawn_x = respawn_x, respawn_y = respawn_y} 5380 angle = (angle + 360/ships_per_team) % 360 5381 else 5382 addGMMessage("Player creation failed") 5383 end 5384 end 5385 end 5386 for name, details in pairs(temp_player_restart) do 5387 player_restart[name] = {self = details.self, template = details.template, control_code = details.control_code, faction = details.faction, respawn_x = details.respawn_x, respawn_y = details.respawn_y} 5388 end 5389end 5390function namePlayerShip(p) 5391 if p.name == nil then 5392 if rwc_player_ship_names[template_player_type] ~= nil and #rwc_player_ship_names[template_player_type] > 0 then 5393 local selected_name_index = math.random(1,#rwc_player_ship_names[template_player_type]) 5394 p:setCallSign(rwc_player_ship_names[template_player_type][selected_name_index]) 5395 table.remove(rwc_player_ship_names[template_player_type],selected_name_index) 5396 else 5397 if rwc_player_ship_names["Unknown"] ~= nil and #rwc_player_ship_names["Unknown"] > 0 then 5398 selected_name_index = math.random(1,#rwc_player_ship_names["Unknown"]) 5399 p:setCallSign(rwc_player_ship_names["Unknown"][selected_name_index]) 5400 table.remove(rwc_player_ship_names["Unknown"],selected_name_index) 5401 end 5402 end 5403 end 5404 p.name = "set" 5405end 5406function playerDestroyed(self,instigator) 5407 respawn_count = respawn_count + 1 5408 if respawn_count > 300 then 5409 print("Hit respawn limit") 5410 return 5411 end 5412 local name = self:getCallSign() 5413 local faction = self:getFaction() 5414 local old_template = self:getTypeName() 5415 local p = PlayerSpaceship() 5416 if p ~= nil and p:isValid() then 5417 if respawn_type == "lindworm" then 5418 p:setTemplate("ZX-Lindworm") 5419 elseif respawn_type == "self" then 5420 p:setTemplate(old_template) 5421 death_penalty[faction] = death_penalty[faction] + self.shipScore 5422 end 5423 p:setFaction(faction) 5424 p.control_code = self.control_code 5425 p:setControlCode(p.control_code) 5426 local name_15 = string.lpad(p:getCallSign(),15) 5427 local cc_15 = string.lpad(p.control_code,15) 5428-- print(p:getCallSign(),"Control code:",p.control_code,"Faction:",faction) 5429 print(name_15,"Control code:",cc_15,"Faction:",faction) 5430 if respawn_type == "lindworm" then 5431 if old_template == "ZX-Lindworm" then 5432 resetPlayer(p,name) 5433 else 5434 resetPlayer(p) 5435 end 5436 elseif respawn_type == "self" then 5437 resetPlayer(p,name) 5438 end 5439 p:setPosition(self.respawn_x, self.respawn_y) 5440 p.respawn_x = self.respawn_x 5441 p.respawn_y = self.respawn_y 5442 if respawn_type == "lindworm" then 5443 player_restart[name] = {self = p, template = "ZX-Lindworm", control_code = p.control_code, faction = faction, respawn_x = self.respawn_x, respawn_y = self.respawn_y} 5444 elseif respawn_type == "self" then 5445 player_restart[name] = {self = p, template = old_template, control_code = p.control_code, faction = faction, respawn_x = self.respawn_x, respawn_y = self.respawn_y} 5446 end 5447 else 5448 respawn_countdown = 2 5449 if restart_queue == nil then 5450 restart_queue = {} 5451 end 5452 table.insert(restart_queue,name) 5453 end 5454end 5455function string.lpad(str, len, char) 5456 if char == nil then 5457 char = " " 5458 end 5459 return str .. string.rep(char, len - string.len(str)) 5460end 5461function delayedRespawn(name) 5462 if name == nil then 5463 if restart_queue ~= nil then 5464 if #restart_queue > 0 then 5465 name = restart_queue[1] 5466 else 5467 respawn_countdown = nil 5468 return 5469 end 5470 else 5471 respawn_countdown = nil 5472 return 5473 end 5474 end 5475 if player_restart[name] ~= nil then 5476 local faction = player_restart[name].faction 5477 local old_template = player_restart[name].template 5478 local p = PlayerSpaceship() 5479 if p~= nil and p:isValid() then 5480 if respawn_type == "lindworm" then 5481 p:setTemplate("ZX-Lindworm") 5482 elseif respawn_type == "self" then 5483 p:setTemplate(old_template) 5484 death_penalty[faction] = death_penalty[faction] + self.shipScore 5485 end 5486 p:setFaction(faction) 5487 p.control_code = player_restart[name].control_code 5488 p:setControlCode(p.control_code) 5489 local name_15 = string.lpad(p:getCallSign(),15) 5490 local cc_15 = string.lpad(p.control_code,15) 5491 print(name_15,"Control code:",cc_15,"Faction:",faction) 5492-- print(p:getCallSign(),"Control code:",p.control_code,"Faction:",faction) 5493 if respawn_type == "lindworm" then 5494 if old_template == "ZX-Lindworm" then 5495 resetPlayer(p,name) 5496 else 5497 resetPlayer(p) 5498 end 5499 elseif respawn_type == "self" then 5500 resetPlayer(p,name) 5501 end 5502 p:setPosition(player_restart[name].respawn_x,player_restart[name].respawn_y) 5503 p.respawn_x = player_restart[name].respawn_x 5504 p.respawn_y = player_restart[name].respawn_y 5505 if respawn_type == "lindworm" then 5506 player_restart[name] = {self = p, template = "ZX-Lindworm", control_code = p.control_code, faction = faction, respawn_x = player_restart[name].respawn_x, respawn_y = player_restart[name].respawn_y} 5507 elseif respawn_type == "self" then 5508 player_restart[name] = {self = p, template = old_template, control_code = p.control_code, faction = faction, respawn_x = player_restart[name].respawn_x, respawn_y = player_restart[name].respawn_y} 5509 end 5510 if restart_queue ~= nil and #restart_queue > 0 then 5511 for i=1,#restart_queue do 5512 if restart_queue[i] == name then 5513 table.remove(restart_queue,i) 5514 respawn_countdown = nil 5515 break 5516 end 5517 end 5518 end 5519 else 5520 if restart_queue ~= nil and #restart_queue > 0 then 5521 respawn_countdown = 2 5522 end 5523 end 5524 else 5525 if restart_queue ~= nil then 5526 if #restart_queue > 0 then 5527 for i=1,#restart_queue do 5528 if restart_queue[i] == name then 5529 table.remove(restart_queue,i) 5530 print("problem with " .. name) 5531 break 5532 end 5533 end 5534 end 5535 end 5536 end 5537end 5538function resetPlayer(p,name) 5539 local faction = p:getFaction() 5540 if name == nil then 5541 namePlayerShip(p) 5542 else 5543 p:setCallSign(name) 5544 p.name = "set" 5545 end 5546 commonPlayerSet(p) 5547end 5548function commonPlayerSet(p) 5549 local template_player_type = p:getTypeName() 5550 if template_player_type == "Player Fighter" then 5551-- Arc, Dir, Range, CycleTime, Dmg 5552 p:setBeamWeapon(0, 40, 0, 500, 6, 4) 5553 p:setBeamWeapon(2, 40, -10, 1000, 6, 8) 5554 end 5555 p.shipScore = player_ship_stats[template_player_type].strength 5556 p.maxCargo = player_ship_stats[template_player_type].cargo 5557 p.cargo = p.maxCargo 5558 p.maxRepairCrew = p:getRepairCrewCount() 5559 p.healthyShield = 1.0 5560 p.prevShield = 1.0 5561 p.healthyReactor = 1.0 5562 p.prevReactor = 1.0 5563 p.healthyManeuver = 1.0 5564 p.prevManeuver = 1.0 5565 p.healthyImpulse = 1.0 5566 p.prevImpulse = 1.0 5567 if p:getBeamWeaponRange(0) > 0 then 5568 p.healthyBeam = 1.0 5569 p.prevBeam = 1.0 5570 end 5571 if p:getWeaponTubeCount() > 0 then 5572 p.healthyMissile = 1.0 5573 p.prevMissile = 1.0 5574 end 5575 if p:hasWarpDrive() then 5576 p.healthyWarp = 1.0 5577 p.prevWarp = 1.0 5578 end 5579 if p:hasJumpDrive() then 5580 p.healthyJump = 1.0 5581 p.prevJump = 1.0 5582 end 5583 p.initialCoolant = p:getMaxCoolant() 5584 p:setLongRangeRadarRange(player_ship_stats[template_player_type].long_range_radar) 5585 p:setShortRangeRadarRange(player_ship_stats[template_player_type].short_range_radar) 5586 p.normal_long_range_radar = p:getLongRangeRadarRange() 5587 p:setMaxScanProbeCount(player_ship_stats[template_player_type].probes) 5588 p:setScanProbeCount(p:getMaxScanProbeCount()) 5589 if (not p:hasSystem("jumpdrive") and player_ship_stats[template_player_type].long_jump > 0) or 5590 (p:hasSystem("jumpdrive") and player_ship_stats[template_player_type].long_jump ~= 50) then 5591 p:setJumpDrive(true) 5592 p.max_jump_range = player_ship_stats[template_player_type].long_jump*1000 5593 p.min_jump_range = player_ship_stats[template_player_type].short_jump*1000 5594 p:setJumpDriveRange(p.min_jump_range,p.max_jump_range) 5595 p:setJumpDriveCharge(p.max_jump_range) 5596 end 5597 if not p:hasSystem("warp") and player_ship_stats[template_player_type].warp > 0 then 5598 p:setWarpDrive(true) 5599 p:setWarpSpeed(player_ship_stats[template_player_type].warp) 5600 end 5601 p:onDestroyed(playerDestroyed) 5602end 5603function setPlayer(p) 5604 local faction = p:getFaction() 5605 namePlayerShip(p) 5606-- p:addReputationPoints(1000) --testing only 5607 p:addReputationPoints(base_reputation) 5608 local control_code_index = math.random(1,#control_code_stem) 5609 local stem = control_code_stem[control_code_index] 5610 table.remove(control_code_stem,control_code_index) 5611 local branch = math.random(100,999) 5612 p.control_code = stem .. branch 5613 local name_15 = string.lpad(p:getCallSign(),15) 5614 local cc_15 = string.lpad(p.control_code,15) 5615 print(name_15,"Control code:",cc_15,"Faction:",faction) 5616-- print(p:getCallSign(),"Control code:",p.control_code,"Faction:",faction) 5617 p:setControlCode(stem .. branch) 5618 commonPlayerSet(p) 5619end 5620-- Station placement related functions 5621function pickStation(name) 5622-- print("pick station name") 5623 if station_pool == nil then 5624 populateStationPool() 5625 end 5626 local selected_station_name = nil 5627 local station_selection_list = {} 5628 local selected_station = nil 5629 local station = nil 5630 if name == nil then 5631 --default to random in priority order 5632 for _, group in ipairs(station_priority) do 5633 if station_pool[group] ~= nil then 5634 for station, details in pairs(station_pool[group]) do 5635 table.insert(station_selection_list,station) 5636 end 5637 if #station_selection_list > 0 then 5638 if selected_station_name == nil then 5639 selected_station_name = station_selection_list[math.random(1,#station_selection_list)] 5640 station = SpaceStation():setCommsScript(""):setCommsFunction(commsStation):setCallSign(selected_station_name):setDescription(station_pool[group][selected_station_name].description) 5641 station.comms_data = station_pool[group][selected_station_name] 5642 station_pool[group][selected_station_name] = nil 5643 return group, station 5644 end 5645 end 5646 end 5647 end 5648 else 5649-- print("name parameter provided:",name) 5650 if name == "Random" then 5651 --random across all groups 5652 for group, list in pairs(station_pool) do 5653 for station_name, station_details in pairs(list) do 5654 table.insert(station_selection_list,{group = group, station_name = station_name, station_details = station_details}) 5655 end 5656 end 5657 if #station_selection_list > 0 then 5658 selected_station = station_selection_list[math.random(1,#station_selection_list)] 5659 station = SpaceStation():setCommsScript(""):setCommsFunction(commsStation):setCallSign(selected_station.station_name):setDescription(selected_station.station_details.description) 5660 station.comms_data = selected_station.station_details 5661 station_pool[selected_station.group][selected_station.station_name] = nil 5662 return selected_station.group, station 5663 end 5664 elseif name == "RandomHumanNeutral" then 5665 for group, list in pairs(station_pool) do 5666 if group ~= "Generic" and group ~= "Sinister" then 5667 for station_name, station_details in pairs(list) do 5668 table.insert(station_selection_list,{group = group, station_name = station_name, station_details = station_details}) 5669 end 5670 end 5671 end 5672 if #station_selection_list > 0 then 5673 selected_station = station_selection_list[math.random(1,#station_selection_list)] 5674 station = SpaceStation():setCommsScript(""):setCommsFunction(commsStation):setCallSign(selected_station.station_name):setDescription(selected_station.station_details.description) 5675 station.comms_data = selected_station.station_details 5676 station_pool[selected_station.group][selected_station.station_name] = nil 5677 return selected_station.group, station 5678 end 5679 elseif name == "RandomGenericSinister" then 5680 for group, list in pairs(station_pool) do 5681 if group == "Generic" or group == "Sinister" then 5682 for station_name, station_details in pairs(list) do 5683 table.insert(station_selection_list,{group = group, station_name = station_name, station_details = station_details}) 5684 end 5685 end 5686 end 5687 if #station_selection_list > 0 then 5688 selected_station = station_selection_list[math.random(1,#station_selection_list)] 5689 station = SpaceStation():setCommsScript(""):setCommsFunction(commsStation):setCallSign(selected_station.station_name):setDescription(selected_station.station_details.description) 5690 station.comms_data = selected_station.station_details 5691 station_pool[selected_station.group][selected_station.station_name] = nil 5692 return selected_station.group, station 5693 end 5694 else 5695-- print("not one of the generic random names") 5696 if station_pool[name] ~= nil then 5697-- print("name is a group name") 5698 --name is a group name 5699 for station_name, station_details in pairs(station_pool[name]) do 5700 table.insert(station_selection_list,{station_name = station_name, station_details = station_details}) 5701 end 5702 if #station_selection_list > 0 then 5703 selected_station = station_selection_list[math.random(1,#station_selection_list)] 5704 station = SpaceStation():setCommsScript(""):setCommsFunction(commsStation):setCallSign(selected_station.station_name):setDescription(selected_station.station_details.description) 5705 station.comms_data = selected_station.station_details 5706 station_pool[name][selected_station.station_name] = nil 5707 return name, station 5708 end 5709 else 5710-- print("name is not a group name") 5711 for group, list in pairs(station_pool) do 5712 if station_pool[group][name] ~= nil then 5713 station = SpaceStation():setCommsScript(""):setCommsFunction(commsStation):setCallSign(name):setDescription(station_pool[group][name].description) 5714 station.comms_data = station_pool[group][name] 5715 station_pool[group][name] = nil 5716 return group, station 5717 end 5718 end 5719 --name not found in any group 5720 print("Name provided not found in groups or stations, nor is it an accepted specialized name, like Random, RandomHumanNeutral or RandomGenericSinister") 5721 return nil 5722 end 5723 end 5724 end 5725 return nil 5726end 5727function szt() 5728--Randomly choose station size template 5729 if stationSize ~= nil then 5730 sizeTemplate = stationSize 5731 return sizeTemplate 5732 end 5733 stationSizeRandom = random(1,100) 5734 if stationSizeRandom < 8 then 5735 sizeTemplate = "Huge Station" -- 8 percent huge 5736 elseif stationSizeRandom < 24 then 5737 sizeTemplate = "Large Station" --16 percent large 5738 elseif stationSizeRandom < 50 then 5739 sizeTemplate = "Medium Station" --26 percent medium 5740 else 5741 sizeTemplate = "Small Station" --50 percent small 5742 end 5743 return sizeTemplate 5744end 5745function placeStation(x,y,name,faction,size) 5746 --x and y are the position of the station 5747 --name should be the name of the station or the name of the station group 5748 -- omit name to get random station from groups in priority order 5749 --faction is the faction of the station 5750 -- omit and stationFaction will be used 5751 --size is the name of the station template to use 5752 -- omit and station template will be chosen at random via szt function 5753 if x == nil then return nil end 5754 if y == nil then return nil end 5755 local group, station = pickStation(name) 5756 if group == nil then return nil end 5757 station:setPosition(x,y) 5758 if faction ~= nil then 5759 station:setFaction(faction) 5760 else 5761 if stationFaction ~= nil then 5762 station:setFaction(stationFaction) 5763 else 5764 station:setFaction("Independent") 5765 end 5766 end 5767 if size == nil then 5768 station:setTemplate(szt()) 5769 else 5770 local function Set(list) 5771 local set = {} 5772 for _, item in ipairs(list) do 5773 set[item] = true 5774 end 5775 return set 5776 end 5777 local station_size_templates = Set{"Small Station","Medium Station","Large Station","Huge Station"} 5778 if station_size_templates[size] then 5779 station:setTemplate(size) 5780 else 5781 station:setTemplate(szt()) 5782 end 5783 end 5784 local size_matters = 0 5785 local station_size = station:getTypeName() 5786 if station_size == "Medium Station" then 5787 size_matters = 20 5788 elseif station_size == "Large Station" then 5789 size_matters = 30 5790 elseif station_size == "Huge Station" then 5791 size_matters = 40 5792 end 5793 station.comms_data.probe_launch_repair = random(1,100) <= (20 + size_matters) 5794 station.comms_data.scan_repair = random(1,100) <= (30 + size_matters) 5795 station.comms_data.hack_repair = random(1,100) <= (10 + size_matters) 5796 station.comms_data.combat_maneuver_repair = random(1,100) <= (15 + size_matters) 5797 station.comms_data.self_destruct_repair = random(1,100) <= (25 + size_matters) 5798 station.comms_data.jump_overcharge = random(1,100) <= (5 + size_matters) 5799 station:setSharesEnergyWithDocked(random(1,100) <= (50 + size_matters)) 5800 station:setRepairDocked(random(1,100) <= (55 + size_matters)) 5801 station:setRestocksScanProbes(random(1,100) <= (45 + size_matters)) 5802 --specialized code for particular stations 5803 return station 5804end 5805function randomComponent(exclude) 5806 local good = componentGoods[math.random(1,#componentGoods)] 5807 if exclude == nil then 5808 return good 5809 else 5810 repeat 5811 good = componentGoods[math.random(1,#componentGoods)] 5812 until(good ~= exclude) 5813 return good 5814 end 5815end 5816function randomMineral(exclude) 5817 local good = mineralGoods[math.random(1,#mineralGoods)] 5818 if exclude == nil then 5819 return good 5820 else 5821 repeat 5822 good = mineralGoods[math.random(1,#mineralGoods)] 5823 until(good ~= exclude) 5824 return good 5825 end 5826end 5827function populateStationPool() 5828 station_pool = { 5829 ["Science"] = { 5830 ["Asimov"] = { 5831 weapon_available = { 5832 Homing = true, 5833 HVLI = random(1,13)<=(9-difficulty), 5834 Mine = true, 5835 Nuke = random(1,13)<=(5-difficulty), 5836 EMP = random(1,13)<=(6-difficulty), 5837 }, 5838 services = { 5839 supplydrop = "friend", 5840 reinforcements = "friend", 5841 jumpsupplydrop = "friend", 5842 }, 5843 service_cost = { 5844 supplydrop = math.random(80,120), 5845 reinforcements = math.random(125,175), 5846 jumpsupplydrop = math.random(110,140), 5847 }, 5848 reputation_cost_multipliers = { 5849 friend = 1.0, 5850 neutral = 3.0, 5851 }, 5852 goods = { 5853 tractor = { 5854 quantity = 5, 5855 cost = 48, 5856 }, 5857 repulsor = { 5858 quantity = 5, 5859 cost = 48, 5860 }, 5861 }, 5862 trade = { 5863 food = false, 5864 medicine = false, 5865 luxury = false, 5866 }, 5867 description = "Training and Coordination", 5868 general = "We train naval cadets in routine and specialized functions aboard space vessels and coordinate naval activity throughout the sector", 5869 history = "The original station builders were fans of the late 20th century scientist and author Isaac Asimov. The station was initially named Foundation, but was later changed simply to Asimov. It started off as a stellar observatory, then became a supply stop and as it has grown has become an educational and coordination hub for the region", 5870 }, 5871 ["Armstrong"] = { 5872 weapon_available = { 5873 Homing = random(1,13)<=(8-difficulty), 5874 HVLI = true, 5875 Mine = random(1,13)<=(7-difficulty), 5876 Nuke = random(1,13)<=(5-difficulty), 5877 EMP = true 5878 }, 5879 services = { 5880 supplydrop = "friend", 5881 reinforcements = "friend", 5882 jumpsupplydrop = "friend", 5883 }, 5884 service_cost = { 5885 supplydrop = math.random(80,120), 5886 reinforcements = math.random(125,175), 5887 jumpsupplydrop = math.random(110,140), 5888 }, 5889 goods = { 5890 warp = { 5891 quantity = 5, 5892 cost = 77, 5893 }, 5894 repulsor = { 5895 quantity = 5, 5896 cost = 62, 5897 }, 5898 }, 5899 trade = { 5900 food = random(1,100) <= 45, 5901 medicine = false, 5902 luxury = false, 5903 }, 5904 buy = { 5905 [randomMineral()] = math.random(40,200), 5906 }, 5907 description = "Warp and Impulse engine manufacturing", 5908 general = "We manufacture warp, impulse and jump engines for the human navy fleet as well as other independent clients on a contract basis", 5909 history = "The station is named after the late 19th century astronaut as well as the fictionlized stations that followed. The station initially constructed entire space worthy vessels. In time, it transitioned into specializeing in propulsion systems.", 5910 }, 5911 ["Broeck"] = { 5912 weapon_available = { 5913 Homing = random(1,13)<=(8-difficulty), 5914 HVLI = random(1,13)<=(9-difficulty), 5915 Mine = random(1,13)<=(7-difficulty), 5916 Nuke = random(1,13)<=(5-difficulty), 5917 EMP = random(1,13)<=(6-difficulty), 5918 }, 5919 services = { 5920 supplydrop = "friend", 5921 reinforcements = "friend", 5922 jumpsupplydrop = "friend", 5923 }, 5924 service_cost = { 5925 supplydrop = math.random(80,120), 5926 reinforcements = math.random(125,175), 5927 jumpsupplydrop = math.random(110,140), 5928 }, 5929 goods = { 5930 warp = { 5931 quantity = 5, 5932 cost = 36, 5933 }, 5934 }, 5935 trade = { 5936 food = random(1,100) <= 14, 5937 medicine = false, 5938 luxury = random(1,100) < 62, 5939 }, 5940 buy = { 5941 [randomMineral()] = math.random(40,200), 5942 }, 5943 description = "Warp drive components", 5944 general = "We provide warp drive engines and components", 5945 history = "This station is named after Chris Van Den Broeck who did some initial research into the possibility of warp drive in the late 20th century on Earth", 5946 }, 5947 ["Coulomb"] = { 5948 weapon_available = { 5949 Homing = random(1,13)<=(8-difficulty), 5950 HVLI = random(1,13)<=(9-difficulty), 5951 Mine = random(1,13)<=(7-difficulty), 5952 Nuke = random(1,13)<=(5-difficulty), 5953 EMP = random(1,13)<=(6-difficulty), 5954 }, 5955 services = { 5956 supplydrop = "friend", 5957 reinforcements = "friend", 5958 jumpsupplydrop = "friend", 5959 }, 5960 service_cost = { 5961 supplydrop = math.random(80,120), 5962 reinforcements = math.random(125,175), 5963 jumpsupplydrop = math.random(110,140), 5964 }, 5965 reputation_cost_multipliers = { 5966 friend = 1.0, 5967 neutral = 3.0, 5968 }, 5969 goods = { 5970 circuit = { 5971 quantity = 5, 5972 cost = 50, 5973 }, 5974 }, 5975 trade = { 5976 food = random(1,100) <= 35, 5977 medicine = false, 5978 luxury = random(1,100) < 82, 5979 }, 5980 buy = { 5981 [randomMineral()] = math.random(40,200), 5982 }, 5983 description = "Shielded circuitry fabrication", 5984 general = "We make a large variety of circuits for numerous ship systems shielded from sensor detection and external control interference", 5985 history = "Our station is named after the law which quantifies the amount of force with which stationary electrically charged particals repel or attact each other - a fundamental principle in the design of our circuits", 5986 }, 5987 ["Heyes"] = { 5988 weapon_available = { 5989 Homing = random(1,13)<=(8-difficulty), 5990 HVLI = true, 5991 Mine = random(1,13)<=(7-difficulty), 5992 Nuke = random(1,13)<=(5-difficulty), 5993 EMP = random(1,13)<=(6-difficulty), 5994 }, 5995 services = { 5996 supplydrop = "friend", 5997 reinforcements = "friend", 5998 jumpsupplydrop = "friend", 5999 }, 6000 service_cost = { 6001 supplydrop = math.random(80,120), 6002 reinforcements = math.random(125,175), 6003 jumpsupplydrop = math.random(110,140), 6004 }, 6005 reputation_cost_multipliers = { 6006 friend = 1.0, 6007 neutral = 3.0, 6008 }, 6009 goods = { 6010 sensor = { 6011 quantity = 5, 6012 cost = 72, 6013 }, 6014 }, 6015 trade = { 6016 food = random(1,100) <= 32, 6017 medicine = false, 6018 luxury = true, 6019 }, 6020 buy = { 6021 [randomMineral()] = math.random(40,200), 6022 }, 6023 description = "Sensor components", 6024 general = "We research and manufacture sensor components and systems", 6025 history = "The station is named after Tony Heyes the inventor of some of the earliest electromagnetic sensors in the mid 20th century on Earth in the United Kingdom to assist blind human mobility", 6026 }, 6027 ["Hossam"] = { 6028 weapon_available = { 6029 Homing = random(1,13)<=(8-difficulty), 6030 HVLI = random(1,13)<=(9-difficulty), 6031 Mine = random(1,13)<=(7-difficulty), 6032 Nuke = random(1,13)<=(5-difficulty), 6033 EMP = random(1,13)<=(6-difficulty), 6034 }, 6035 services = { 6036 supplydrop = "friend", 6037 reinforcements = "friend", 6038 jumpsupplydrop = "friend", 6039 }, 6040 service_cost = { 6041 supplydrop = math.random(80,120), 6042 reinforcements = math.random(125,175), 6043 jumpsupplydrop = math.random(110,140), 6044 }, 6045 reputation_cost_multipliers = { 6046 friend = 1.0, 6047 neutral = 3.0, 6048 }, 6049 goods = { 6050 nanites = { 6051 quantity = 5, 6052 cost = 90, 6053 }, 6054 }, 6055 trade = { 6056 food = random(1,100) < 24, 6057 medicine = random(1,100) < 44, 6058 luxury = random(1,100) < 63, 6059 }, 6060 description = "Nanite supplier", 6061 general = "We provide nanites for various organic and non-organic systems", 6062 history = "This station is named after the nanotechnologist Hossam Haick from the early 21st century on Earth in Israel", 6063 }, 6064 ["Maiman"] = { 6065 weapon_available = { 6066 Homing = random(1,13)<=(8-difficulty), 6067 HVLI = false, 6068 Mine = random(1,13)<=(7-difficulty), 6069 Nuke = random(1,13)<=(5-difficulty), 6070 EMP = random(1,13)<=(6-difficulty), 6071 }, 6072 services = { 6073 supplydrop = "friend", 6074 reinforcements = "friend", 6075 jumpsupplydrop = "friend", 6076 }, 6077 service_cost = { 6078 supplydrop = math.random(80,120), 6079 reinforcements = math.random(125,175), 6080 jumpsupplydrop = math.random(110,140), 6081 }, 6082 reputation_cost_multipliers = { 6083 friend = 1.0, 6084 neutral = 3.0, 6085 }, 6086 goods = { 6087 beam = { 6088 quantity = 5, 6089 cost = 70, 6090 }, 6091 }, 6092 trade = { 6093 food = random(1,100) <= 75, 6094 medicine = true, 6095 luxury = false, 6096 }, 6097 buy = { 6098 [randomMineral()] = math.random(40,200), 6099 }, 6100 description = "Energy beam components", 6101 general = "We research and manufacture energy beam components and systems", 6102 history = "The station is named after Theodore Maiman who researched and built the first laser in the mid 20th century on Earth", 6103 }, 6104 ["Malthus"] = { 6105 weapon_available = { 6106 Homing = random(1,13)<=(8-difficulty), 6107 HVLI = random(1,13)<=(9-difficulty), 6108 Mine = random(1,13)<=(7-difficulty), 6109 Nuke = random(1,13)<=(5-difficulty), 6110 EMP = random(1,13)<=(6-difficulty), 6111 }, 6112 services = { 6113 supplydrop = "friend", 6114 reinforcements = "friend", 6115 jumpsupplydrop = "friend", 6116 }, 6117 service_cost = { 6118 supplydrop = math.random(80,120), 6119 reinforcements = math.random(125,175), 6120 jumpsupplydrop = math.random(110,140), 6121 }, 6122 reputation_cost_multipliers = { 6123 friend = 1.0, 6124 neutral = 3.0, 6125 }, 6126 goods = {}, 6127 trade = { 6128 food = random(1,100) <= 65, 6129 medicine = false, 6130 luxury = false, 6131 }, 6132 description = "Gambling and resupply", 6133 general = "The oldest station in the quadrant", 6134 history = "", 6135 }, 6136 ["Marconi"] = { 6137 weapon_available = { 6138 Homing = random(1,13)<=(8-difficulty), 6139 HVLI = random(1,13)<=(9-difficulty), 6140 Mine = random(1,13)<=(7-difficulty), 6141 Nuke = random(1,13)<=(5-difficulty), 6142 EMP = random(1,13)<=(6-difficulty), 6143 }, 6144 services = { 6145 supplydrop = "friend", 6146 reinforcements = "friend", 6147 jumpsupplydrop = "friend", 6148 }, 6149 service_cost = { 6150 supplydrop = math.random(80,120), 6151 reinforcements = math.random(125,175), 6152 jumpsupplydrop = math.random(110,140), 6153 }, 6154 reputation_cost_multipliers = { 6155 friend = 1.0, 6156 neutral = 3.0, 6157 }, 6158 goods = { 6159 beam = { 6160 quantity = 5, 6161 cost = 80, 6162 }, 6163 }, 6164 trade = { 6165 food = random(1,100) <= 53, 6166 medicine = false, 6167 luxury = true, 6168 }, 6169 description = "Energy Beam Components", 6170 general = "We manufacture energy beam components", 6171 history = "Station named after Guglielmo Marconi an Italian inventor from early 20th century Earth who, along with Nicolo Tesla, claimed to have invented a death ray or particle beam weapon", 6172 }, 6173 ["Miller"] = { 6174 weapon_available = { 6175 Homing = random(1,13)<=(8-difficulty), 6176 HVLI = random(1,13)<=(9-difficulty), 6177 Mine = random(1,13)<=(7-difficulty), 6178 Nuke = random(1,13)<=(5-difficulty), 6179 EMP = random(1,13)<=(6-difficulty), 6180 }, 6181 services = { 6182 supplydrop = "friend", 6183 reinforcements = "friend", 6184 jumpsupplydrop = "friend", 6185 }, 6186 service_cost = { 6187 supplydrop = math.random(80,120), 6188 reinforcements = math.random(125,175), 6189 jumpsupplydrop = math.random(110,140), 6190 }, 6191 reputation_cost_multipliers = { 6192 friend = 1.0, 6193 neutral = 3.0, 6194 }, 6195 goods = { 6196 optic = { 6197 quantity = 5, 6198 cost = 60, 6199 }, 6200 }, 6201 trade = { 6202 food = random(1,100) <= 68, 6203 medicine = false, 6204 luxury = false, 6205 }, 6206 description = "Exobiology research", 6207 general = "We study recently discovered life forms not native to Earth", 6208 history = "This station was named after one of the early exobiologists from mid 20th century Earth, Dr. Stanley Miller", 6209 }, 6210 ["Shawyer"] = { 6211 weapon_available = { 6212 Homing = random(1,13)<=(8-difficulty), 6213 HVLI = random(1,13)<=(9-difficulty), 6214 Mine = random(1,13)<=(7-difficulty), 6215 Nuke = random(1,13)<=(5-difficulty), 6216 EMP = random(1,13)<=(6-difficulty), 6217 }, 6218 services = { 6219 supplydrop = "friend", 6220 reinforcements = "friend", 6221 jumpsupplydrop = "friend", 6222 }, 6223 service_cost = { 6224 supplydrop = math.random(80,120), 6225 reinforcements = math.random(125,175), 6226 jumpsupplydrop = math.random(110,140), 6227 }, 6228 reputation_cost_multipliers = { 6229 friend = 1.0, 6230 neutral = 2.0, 6231 }, 6232 goods = { 6233 impulse = { 6234 quantity = 5, 6235 cost = 100, 6236 }, 6237 }, 6238 trade = { 6239 food = random(1,100) <= 42, 6240 medicine = false, 6241 luxury = true, 6242 }, 6243 description = "Impulse engine components", 6244 general = "We research and manufacture impulse engine components and systems", 6245 history = "The station is named after Roger Shawyer who built the first prototype impulse engine in the early 21st century", 6246 }, 6247 }, 6248 ["History"] = { 6249 ["Archimedes"] = { 6250 weapon_available = { 6251 Homing = random(1,13)<=(8-difficulty), 6252 HVLI = random(1,13)<=(9-difficulty), 6253 Mine = random(1,13)<=(7-difficulty), 6254 Nuke = random(1,13)<=(5-difficulty), 6255 EMP = random(1,13)<=(6-difficulty), 6256 }, 6257 services = { 6258 supplydrop = "friend", 6259 reinforcements = "friend", 6260 jumpsupplydrop = "friend", 6261 }, 6262 service_cost = { 6263 supplydrop = math.random(80,120), 6264 reinforcements = math.random(125,175), 6265 jumpsupplydrop = math.random(110,140), 6266 }, 6267 reputation_cost_multipliers = { 6268 friend = 1.0, 6269 neutral = 3.0, 6270 }, 6271 goods = { 6272 beam = { 6273 quantity = 5, 6274 cost = 80, 6275 }, 6276 }, 6277 trade = { 6278 food = true, 6279 medicine = false, 6280 luxury = true, 6281 }, 6282 description = "Energy and particle beam components", 6283 general = "We fabricate general and specialized components for ship beam systems", 6284 history = "This station was named after Archimedes who, according to legend, used a series of adjustable focal length mirrors to focus sunlight on a Roman naval fleet invading Syracuse, setting fire to it", 6285 }, 6286 ["Chatuchak"] = { 6287 weapon_available = { 6288 Homing = random(1,10)<=(8-difficulty), 6289 HVLI = random(1,10)<=(9-difficulty), 6290 Mine = false, 6291 Nuke = random(1,10)<=(5-difficulty), 6292 EMP = random(1,10)<=(6-difficulty), 6293 }, 6294 services = { 6295 supplydrop = "friend", 6296 reinforcements = "friend", 6297 jumpsupplydrop = "friend", 6298 }, 6299 service_cost = { 6300 supplydrop = math.random(80,120), 6301 reinforcements = math.random(125,175), 6302 jumpsupplydrop = math.random(110,140), 6303 }, 6304 reputation_cost_multipliers = { 6305 friend = 1.0, 6306 neutral = 2.0, 6307 }, 6308 goods = { 6309 luxury = { 6310 quantity = 5, 6311 cost = 60, 6312 }, 6313 }, 6314 trade = { 6315 food = false, 6316 medicine = false, 6317 luxury = false, 6318 }, 6319 description = "Trading station", 6320 general = "Only the largest market and trading location in twenty sectors. You can find your heart's desire here", 6321 history = "Modeled after the early 21st century bazaar on Earth in Bangkok, Thailand. Designed and built with trade and commerce in mind", 6322 }, 6323 ["Grasberg"] = { 6324 weapon_available = { 6325 Homing = random(1,13)<=(8-difficulty), 6326 HVLI = random(1,13)<=(9-difficulty), 6327 Mine = random(1,13)<=(7-difficulty), 6328 Nuke = random(1,13)<=(5-difficulty), 6329 EMP = random(1,13)<=(6-difficulty), 6330 }, 6331 services = { 6332 supplydrop = "friend", 6333 reinforcements = "friend", 6334 jumpsupplydrop = "friend", 6335 }, 6336 service_cost = { 6337 supplydrop = math.random(80,120), 6338 reinforcements = math.random(125,175), 6339 jumpsupplydrop = math.random(110,140), 6340 }, 6341 reputation_cost_multipliers = { 6342 friend = 1.0, 6343 neutral = 2.0, 6344 }, 6345 goods = { 6346 luxury = { 6347 quantity = 5, 6348 cost = 70, 6349 }, 6350 }, 6351 trade = { 6352 food = true, 6353 medicine = false, 6354 luxury = false, 6355 }, 6356 buy = { 6357 [randomComponent()] = math.random(40,200), 6358 }, 6359 description = "Mining", 6360 general ="We mine nearby asteroids for precious minerals and process them for sale", 6361 history = "This station's name is inspired by a large gold mine on Earth in Indonesia. The station builders hoped to have a similar amount of minerals found amongst these asteroids", 6362 }, 6363 ["Hayden"] = { 6364 weapon_available = { 6365 Homing = random(1,13)<=(8-difficulty), 6366 HVLI = random(1,13)<=(9-difficulty), 6367 Mine = random(1,13)<=(7-difficulty), 6368 Nuke = random(1,13)<=(5-difficulty), 6369 EMP = random(1,13)<=(6-difficulty), 6370 }, 6371 services = { 6372 supplydrop = "friend", 6373 reinforcements = "friend", 6374 jumpsupplydrop = "friend", 6375 }, 6376 service_cost = { 6377 supplydrop = math.random(80,120), 6378 reinforcements = math.random(125,175), 6379 jumpsupplydrop = math.random(110,140), 6380 }, 6381 reputation_cost_multipliers = { 6382 friend = 1.0, 6383 neutral = 2.0, 6384 }, 6385 goods = { 6386 nanites = { 6387 quantity = 5, 6388 cost = 65, 6389 }, 6390 }, 6391 trade = { 6392 food = random(1,100) <= 85, 6393 medicine = false, 6394 luxury = false, 6395 }, 6396 description = "Observatory and stellar mapping", 6397 general = "We study the cosmos and map stellar phenomena. We also track moving asteroids. Look out! Just kidding", 6398 history = "Station named in honor of Charles Hayden whose philanthropy continued astrophysical research and education on Earth in the early 20th century", 6399 }, 6400 ["Lipkin"] = { 6401 weapon_available = { 6402 Homing = random(1,13)<=(8-difficulty), 6403 HVLI = random(1,13)<=(9-difficulty), 6404 Mine = false, 6405 Nuke = random(1,13)<=(5-difficulty), 6406 EMP = random(1,13)<=(6-difficulty), 6407 }, 6408 services = { 6409 supplydrop = "friend", 6410 reinforcements = "friend", 6411 jumpsupplydrop = "friend", 6412 }, 6413 service_cost = { 6414 supplydrop = math.random(80,120), 6415 reinforcements = math.random(125,175), 6416 jumpsupplydrop = math.random(110,140), 6417 }, 6418 reputation_cost_multipliers = { 6419 friend = 1.0, 6420 neutral = 2.0, 6421 }, 6422 goods = { 6423 autodoc = { 6424 quantity = 5, 6425 cost = 76, 6426 }, 6427 }, 6428 trade = { 6429 food = false, 6430 medicine = false, 6431 luxury = true, 6432 }, 6433 description = "Autodoc components", 6434 general = "", 6435 history = "The station is named after Dr. Lipkin who pioneered some of the research and application around robot assisted surgery in the area of partial nephrectomy for renal tumors in the early 21st century on Earth", 6436 }, 6437 ["Madison"] = { 6438 weapon_available = { 6439 Homing = false, 6440 HVLI = random(1,13)<=(9-difficulty), 6441 Mine = random(1,13)<=(7-difficulty), 6442 Nuke = random(1,13)<=(5-difficulty), 6443 EMP = random(1,13)<=(6-difficulty), 6444 }, 6445 services = { 6446 supplydrop = "friend", 6447 reinforcements = "friend", 6448 jumpsupplydrop = "friend", 6449 }, 6450 service_cost = { 6451 supplydrop = math.random(80,120), 6452 reinforcements = math.random(125,175), 6453 jumpsupplydrop = math.random(110,140), 6454 }, 6455 reputation_cost_multipliers = { 6456 friend = 1.0, 6457 neutral = 2.0, 6458 }, 6459 goods = { 6460 luxury = { 6461 quantity = 5, 6462 cost = math.random(60,70), 6463 }, 6464 }, 6465 trade = { 6466 food = false, 6467 medicine = true, 6468 luxury = false, 6469 }, 6470 description = "Zero gravity sports and entertainment", 6471 general = "Come take in a game or two or perhaps see a show", 6472 history = "Named after Madison Square Gardens from 21st century Earth, this station was designed to serve similar purposes in space - a venue for sports and entertainment", 6473 }, 6474 ["Rutherford"] = { 6475 weapon_available = { 6476 Homing = random(1,13)<=(8-difficulty), 6477 HVLI = random(1,13)<=(9-difficulty), 6478 Mine = random(1,13)<=(7-difficulty), 6479 Nuke = random(1,13)<=(5-difficulty), 6480 EMP = random(1,13)<=(6-difficulty), 6481 }, 6482 services = { 6483 supplydrop = "friend", 6484 reinforcements = "friend", 6485 jumpsupplydrop = "friend", 6486 }, 6487 service_cost = { 6488 supplydrop = math.random(80,120), 6489 reinforcements = math.random(125,175), 6490 jumpsupplydrop = math.random(110,140), 6491 }, 6492 reputation_cost_multipliers = { 6493 friend = 1.0, 6494 neutral = 2.0, 6495 }, 6496 goods = { 6497 shield = { 6498 quantity = 5, 6499 cost = 90, 6500 }, 6501 }, 6502 trade = { 6503 food = false, 6504 medicine = false, 6505 luxury = random(1,100) < 43, 6506 }, 6507 description = "Shield components and research", 6508 general = "We research and fabricate components for ship shield systems", 6509 history = "This station was named after the national research institution Rutherford Appleton Laboratory in the United Kingdom which conducted some preliminary research into the feasability of generating an energy shield in the late 20th century", 6510 }, 6511 ["Toohie"] = { 6512 weapon_available = { 6513 Homing = random(1,13)<=(8-difficulty), 6514 HVLI = random(1,13)<=(9-difficulty), 6515 Mine = random(1,13)<=(7-difficulty), 6516 Nuke = random(1,13)<=(5-difficulty), 6517 EMP = random(1,13)<=(6-difficulty), 6518 }, 6519 services = { 6520 supplydrop = "friend", 6521 reinforcements = "friend", 6522 jumpsupplydrop = "friend", 6523 }, 6524 service_cost = { 6525 supplydrop = math.random(80,120), 6526 reinforcements = math.random(125,175), 6527 jumpsupplydrop = math.random(110,140), 6528 }, 6529 reputation_cost_multipliers = { 6530 friend = 1.0, 6531 neutral = 3.0, 6532 }, 6533 goods = { 6534 shield = { 6535 quantity = 5, 6536 cost = 90, 6537 }, 6538 }, 6539 trade = { 6540 food = random(1,100) <= 21, 6541 medicine = false, 6542 luxury = true, 6543 }, 6544 description = "Shield and armor components and research", 6545 general = "We research and make general and specialized components for ship shield and ship armor systems", 6546 history = "This station was named after one of the earliest researchers in shield technology, Alexander Toohie back when it was considered impractical to construct shields due to the physics involved."}, 6547 }, 6548 ["Pop Sci Fi"] = { 6549 ["Anderson"] = { 6550 weapon_available = { 6551 Homing = false, 6552 HVLI = random(1,13)<=(9-difficulty), 6553 Mine = random(1,13)<=(7-difficulty), 6554 Nuke = random(1,13)<=(5-difficulty), 6555 EMP = random(1,13)<=(6-difficulty), 6556 }, 6557 services = { 6558 supplydrop = "friend", 6559 reinforcements = "friend", 6560 jumpsupplydrop = "friend", 6561 }, 6562 service_cost = { 6563 supplydrop = math.random(80,120), 6564 reinforcements = math.random(125,175), 6565 jumpsupplydrop = math.random(110,140), 6566 }, 6567 reputation_cost_multipliers = { 6568 friend = 1.0, 6569 neutral = 2.0, 6570 }, 6571 goods = { 6572 battery = { 6573 quantity = 5, 6574 cost = 66, 6575 }, 6576 software = { 6577 quantity = 5, 6578 cost = 115, 6579 }, 6580 }, 6581 trade = { 6582 food = false, 6583 medicine = false, 6584 luxury = true, 6585 }, 6586 description = "Battery and software engineering", 6587 general = "We provide high quality high capacity batteries and specialized software for all shipboard systems", 6588 history = "The station is named after a fictional software engineer in a late 20th century movie depicting humanity unknowingly conquered by aliens and kept docile by software generated illusion", 6589 }, 6590 ["Archer"] = { 6591 weapon_available = { 6592 Homing = random(1,13)<=(8-difficulty), 6593 HVLI = true, 6594 Mine = random(1,13)<=(7-difficulty), 6595 Nuke = random(1,13)<=(5-difficulty), 6596 EMP = true 6597 }, 6598 services = { 6599 supplydrop = "friend", 6600 reinforcements = "friend", 6601 jumpsupplydrop = "friend", 6602 }, 6603 service_cost = { 6604 supplydrop = math.random(80,120), 6605 reinforcements = math.random(125,175), 6606 jumpsupplydrop = math.random(110,140), 6607 }, 6608 goods = { 6609 shield = { 6610 quantity = 5, 6611 cost = 90, 6612 }, 6613 }, 6614 trade = { 6615 food = false, 6616 medicine = false, 6617 luxury = true, 6618 }, 6619 buy = { 6620 [randomMineral()] = math.random(40,200), 6621 }, 6622 description = "Shield and Armor Research", 6623 general = "The finest shield and armor manufacturer in the quadrant", 6624 history = "We named this station for the pioneering spirit of the 22nd century Starfleet explorer, Captain Jonathan Archer", 6625 }, 6626 ["Barclay"] = { 6627 weapon_available = { 6628 Homing = random(1,13)<=(8-difficulty), 6629 HVLI = random(1,13)<=(9-difficulty), 6630 Mine = false, 6631 Nuke = random(1,13)<=(5-difficulty), 6632 EMP = random(1,13)<=(6-difficulty), 6633 }, 6634 services = { 6635 supplydrop = "friend", 6636 reinforcements = "friend", 6637 jumpsupplydrop = "friend", 6638 }, 6639 service_cost = { 6640 supplydrop = math.random(80,120), 6641 reinforcements = math.random(125,175), 6642 jumpsupplydrop = math.random(110,140), 6643 }, 6644 goods = { 6645 communication = { 6646 quantity = 5, 6647 cost = 58, 6648 }, 6649 }, 6650 trade = { 6651 food = false, 6652 medicine = false, 6653 luxury = false, 6654 }, 6655 buy = { 6656 [randomMineral()] = math.random(40,200), 6657 }, 6658 description = "Communication components", 6659 general = "We provide a range of communication equipment and software for use aboard ships", 6660 history = "The station is named after Reginald Barclay who established the first transgalactic com link through the creative application of a quantum singularity. Station personnel often refer to the station as the Broccoli station", 6661 }, 6662 ["Calvin"] = { 6663 weapon_available = { 6664 Homing = false, 6665 HVLI = random(1,13)<=(9-difficulty), 6666 Mine = random(1,13)<=(7-difficulty), 6667 Nuke = random(1,13)<=(5-difficulty), 6668 EMP = random(1,13)<=(6-difficulty), 6669 }, 6670 services = { 6671 supplydrop = "friend", 6672 reinforcements = "friend", 6673 jumpsupplydrop = "friend", 6674 }, 6675 service_cost = { 6676 supplydrop = math.random(80,120), 6677 reinforcements = math.random(125,175), 6678 jumpsupplydrop = math.random(110,140), 6679 }, 6680 goods = { 6681 robotic = { 6682 quantity = 5, 6683 cost = 90, 6684 }, 6685 }, 6686 trade = { 6687 food = random(1,100) <= 35, 6688 medicine = false, 6689 luxury = true, 6690 }, 6691 buy = { 6692 [randomComponent("robotic")] = math.random(40,200) 6693 }, 6694 description = "Robotic research", 6695 general = "We research and provide robotic systems and components", 6696 history = "This station is named after Dr. Susan Calvin who pioneered robotic behavioral research and programming", 6697 }, 6698 ["Cavor"] = { 6699 weapon_available = { 6700 Homing = random(1,13)<=(8-difficulty), 6701 HVLI = random(1,13)<=(9-difficulty), 6702 Mine = random(1,13)<=(7-difficulty), 6703 Nuke = random(1,13)<=(5-difficulty), 6704 EMP = random(1,13)<=(6-difficulty), 6705 }, 6706 services = { 6707 supplydrop = "friend", 6708 reinforcements = "friend", 6709 jumpsupplydrop = "friend", 6710 }, 6711 service_cost = { 6712 supplydrop = math.random(80,120), 6713 reinforcements = math.random(125,175), 6714 jumpsupplydrop = math.random(110,140), 6715 }, 6716 reputation_cost_multipliers = { 6717 friend = 1.0, 6718 neutral = 2.0, 6719 }, 6720 goods = { 6721 filament = { 6722 quantity = 5, 6723 cost = 42, 6724 }, 6725 }, 6726 trade = { 6727 food = false, 6728 medicine = false, 6729 luxury = false, 6730 }, 6731 description = "Advanced Material components", 6732 general = "We fabricate several different kinds of materials critical to various space industries like ship building, station construction and mineral extraction", 6733 history = "We named our station after Dr. Cavor, the physicist that invented a barrier material for gravity waves - Cavorite", 6734 }, 6735 ["Cyrus"] = { 6736 weapon_available = { 6737 Homing = random(1,13)<=(8-difficulty), 6738 HVLI = random(1,13)<=(9-difficulty), 6739 Mine = random(1,13)<=(7-difficulty), 6740 Nuke = random(1,13)<=(5-difficulty), 6741 EMP = random(1,13)<=(6-difficulty), 6742 }, 6743 services = { 6744 supplydrop = "friend", 6745 reinforcements = "friend", 6746 jumpsupplydrop = "friend", 6747 }, 6748 service_cost = { 6749 supplydrop = math.random(80,120), 6750 reinforcements = math.random(125,175), 6751 jumpsupplydrop = math.random(110,140), 6752 }, 6753 reputation_cost_multipliers = { 6754 friend = 1.0, 6755 neutral = 3.0, 6756 }, 6757 goods = { 6758 impulse = { 6759 quantity = 5, 6760 cost = 124, 6761 }, 6762 }, 6763 trade = { 6764 food = false, 6765 medicine = false, 6766 luxury = random(1,100) < 78, 6767 }, 6768 description = "Impulse engine components", 6769 general = "We supply high quality impulse engines and parts for use aboard ships", 6770 history = "This station was named after the fictional engineer, Cyrus Smith created by 19th century author Jules Verne", 6771 }, 6772 ["Deckard"] = { 6773 weapon_available = { 6774 Homing = random(1,13)<=(8-difficulty), 6775 HVLI = random(1,13)<=(9-difficulty), 6776 Mine = random(1,13)<=(7-difficulty), 6777 Nuke = random(1,13)<=(5-difficulty), 6778 EMP = random(1,13)<=(6-difficulty), 6779 }, 6780 services = { 6781 supplydrop = "friend", 6782 reinforcements = "friend", 6783 jumpsupplydrop = "friend", 6784 }, 6785 service_cost = { 6786 supplydrop = math.random(80,120), 6787 reinforcements = math.random(125,175), 6788 jumpsupplydrop = math.random(110,140), 6789 }, 6790 reputation_cost_multipliers = { 6791 friend = 1.0, 6792 neutral = 2.0, 6793 }, 6794 goods = { 6795 android = { 6796 quantity = 5, 6797 cost = 73, 6798 }, 6799 }, 6800 trade = { 6801 food = false, 6802 medicine = false, 6803 luxury = true, 6804 }, 6805 description = "Android components", 6806 general = "Supplier of android components, programming and service", 6807 history = "Named for Richard Deckard who inspired many of the sophisticated safety security algorithms now required for all androids", 6808 }, 6809 ["Erickson"] = { 6810 weapon_available = { 6811 Homing = random(1,13)<=(8-difficulty), 6812 HVLI = random(1,13)<=(9-difficulty), 6813 Mine = random(1,13)<=(7-difficulty), 6814 Nuke = random(1,13)<=(5-difficulty), 6815 EMP = random(1,13)<=(6-difficulty), 6816 }, 6817 services = { 6818 supplydrop = "friend", 6819 reinforcements = "friend", 6820 jumpsupplydrop = "friend", 6821 }, 6822 service_cost = { 6823 supplydrop = math.random(80,120), 6824 reinforcements = math.random(125,175), 6825 jumpsupplydrop = math.random(110,140), 6826 }, 6827 goods = { 6828 transporter = { 6829 quantity = 5, 6830 cost = 63, 6831 }, 6832 }, 6833 trade = { 6834 food = false, 6835 medicine = false, 6836 luxury = true, 6837 }, 6838 description = "Transporter components", 6839 general = "We provide transporters used aboard ships as well as the components for repair and maintenance", 6840 history = "The station is named after the early 22nd century inventor of the transporter, Dr. Emory Erickson. This station is proud to have received the endorsement of Admiral Leonard McCoy", 6841 }, 6842 ["Jabba"] = { 6843 weapon_available = { 6844 Homing = random(1,13)<=(8-difficulty), 6845 HVLI = random(1,13)<=(9-difficulty), 6846 Mine = random(1,13)<=(7-difficulty), 6847 Nuke = random(1,13)<=(5-difficulty), 6848 EMP = random(1,13)<=(6-difficulty), 6849 }, 6850 services = { 6851 supplydrop = "friend", 6852 reinforcements = "friend", 6853 jumpsupplydrop = "friend", 6854 }, 6855 service_cost = { 6856 supplydrop = math.random(80,120), 6857 reinforcements = math.random(125,175), 6858 jumpsupplydrop = math.random(110,140), 6859 }, 6860 reputation_cost_multipliers = { 6861 friend = 1.0, 6862 neutral = 2.0, 6863 }, 6864 goods = { 6865 luxury = { 6866 quantity = 5, 6867 cost = math.random(30,80), 6868 }, 6869 }, 6870 trade = { 6871 food = false, 6872 medicine = false, 6873 luxury = false, 6874 }, 6875 description = "Commerce and gambling", 6876 general = "Come play some games and shop. House take does not exceed 4 percent", 6877 history = "", 6878 }, 6879 ["Komov"] = { 6880 weapon_available = { 6881 Homing = random(1,13)<=(8-difficulty), 6882 HVLI = random(1,13)<=(9-difficulty), 6883 Mine = true, 6884 Nuke = false, 6885 EMP = random(1,13)<=(6-difficulty), 6886 }, 6887 services = { 6888 supplydrop = "friend", 6889 reinforcements = "friend", 6890 jumpsupplydrop = "friend", 6891 }, 6892 service_cost = { 6893 supplydrop = math.random(80,120), 6894 reinforcements = math.random(125,175), 6895 jumpsupplydrop = math.random(110,140), 6896 }, 6897 reputation_cost_multipliers = { 6898 friend = 1.0, 6899 neutral = 2.0, 6900 }, 6901 goods = { 6902 filament = { 6903 quantity = 5, 6904 cost = 46, 6905 }, 6906 }, 6907 trade = { 6908 food = false, 6909 medicine = false, 6910 luxury = false, 6911 }, 6912 description = "Xenopsychology training", 6913 general = "We provide classes and simulation to help train diverse species in how to relate to each other", 6914 history = "A continuation of the research initially conducted by Dr. Gennady Komov in the early 22nd century on Venus, supported by the application of these principles", 6915 }, 6916 ["Lando"] = { 6917 weapon_available = { 6918 Homing = true, 6919 HVLI = true, 6920 Mine = true, 6921 Nuke = false, 6922 EMP = false, 6923 }, 6924 weapon_cost = { 6925 Homing = math.random(2,5), 6926 HVLI = 2, 6927 Mine = math.random(2,5), 6928 }, 6929 services = { 6930 supplydrop = "friend", 6931 reinforcements = "friend", 6932 jumpsupplydrop = "friend", 6933 }, 6934 service_cost = { 6935 supplydrop = math.random(80,120), 6936 reinforcements = math.random(125,175), 6937 jumpsupplydrop = math.random(110,140), 6938 }, 6939 goods = { 6940 shield = { 6941 quantity = 5, 6942 cost = 90, 6943 }, 6944 }, 6945 trade = { 6946 food = false, 6947 medicine = false, 6948 luxury = false, 6949 }, 6950 description = "Casino and Gambling", 6951 general = "", 6952 history = "", 6953 }, 6954 ["Muddville"] = { 6955 weapon_available = { 6956 Homing = random(1,13)<=(8-difficulty), 6957 HVLI = random(1,13)<=(9-difficulty), 6958 Mine = random(1,13)<=(7-difficulty), 6959 Nuke = random(1,13)<=(5-difficulty), 6960 EMP = random(1,13)<=(6-difficulty), 6961 }, 6962 services = { 6963 supplydrop = "friend", 6964 reinforcements = "friend", 6965 jumpsupplydrop = "friend", 6966 }, 6967 service_cost = { 6968 supplydrop = math.random(80,120), 6969 reinforcements = math.random(125,175), 6970 jumpsupplydrop = math.random(110,140), 6971 }, 6972 goods = { 6973 luxury = { 6974 quantity = 5, 6975 cost = 60, 6976 }, 6977 }, 6978 trade = { 6979 food = true, 6980 medicine = true, 6981 luxury = false, 6982 }, 6983 description = "Trading station", 6984 general = "Come to Muddvile for all your trade and commerce needs and desires", 6985 history = "Upon retirement, Harry Mudd started this commercial venture using his leftover inventory and extensive connections obtained while he traveled the stars as a salesman", 6986 }, 6987 ["Nexus-6"] = { 6988 weapon_available = { 6989 Homing = random(1,13)<=(8-difficulty), 6990 HVLI = false, 6991 Mine = random(1,13)<=(7-difficulty), 6992 Nuke = random(1,13)<=(5-difficulty), 6993 EMP = random(1,13)<=(6-difficulty), 6994 }, 6995 services = { 6996 supplydrop = "friend", 6997 reinforcements = "friend", 6998 jumpsupplydrop = "friend", 6999 }, 7000 service_cost = { 7001 supplydrop = math.random(80,120), 7002 reinforcements = math.random(125,175), 7003 jumpsupplydrop = math.random(110,140), 7004 }, 7005 reputation_cost_multipliers = { 7006 friend = 1.0, 7007 neutral = 3.0, 7008 }, 7009 goods = { 7010 android = { 7011 quantity = 5, 7012 cost = 93, 7013 }, 7014 }, 7015 trade = { 7016 food = false, 7017 medicine = true, 7018 luxury = false, 7019 }, 7020 buy = { 7021 [randomMineral()] = math.random(40,200), 7022 [randomComponent("android")] = math.random(40,200), 7023 }, 7024 description = "Android components", 7025 general = "Androids, their parts, maintenance and recylcling", 7026 history = "We named the station after the ground breaking android model produced by the Tyrell corporation", 7027 }, 7028 ["O'Brien"] = { 7029 weapon_available = { 7030 Homing = random(1,13)<=(8-difficulty), 7031 HVLI = random(1,13)<=(9-difficulty), 7032 Mine = random(1,13)<=(7-difficulty), 7033 Nuke = random(1,13)<=(5-difficulty), 7034 EMP = random(1,13)<=(6-difficulty), 7035 }, 7036 services = { 7037 supplydrop = "friend", 7038 reinforcements = "friend", 7039 jumpsupplydrop = "friend", 7040 }, 7041 service_cost = { 7042 supplydrop = math.random(80,120), 7043 reinforcements = math.random(125,175), 7044 jumpsupplydrop = math.random(110,140), 7045 }, 7046 reputation_cost_multipliers = { 7047 friend = 1.0, 7048 neutral = 3.0, 7049 }, 7050 goods = { 7051 transporter = { 7052 quantity = 5, 7053 cost = 76, 7054 }, 7055 }, 7056 trade = { 7057 food = random(1,100) < 13, 7058 medicine = true, 7059 luxury = random(1,100) < 43, 7060 }, 7061 description = "Transporter components", 7062 general = "We research and fabricate high quality transporters and transporter components for use aboard ships", 7063 history = "Miles O'Brien started this business after his experience as a transporter chief", 7064 }, 7065 ["Organa"] = { 7066 weapon_available = { 7067 Homing = random(1,13)<=(8-difficulty), 7068 HVLI = random(1,13)<=(9-difficulty), 7069 Mine = random(1,13)<=(7-difficulty), 7070 Nuke = random(1,13)<=(5-difficulty), 7071 EMP = random(1,13)<=(6-difficulty), 7072 }, 7073 services = { 7074 supplydrop = "friend", 7075 reinforcements = "friend", 7076 jumpsupplydrop = "friend", 7077 }, 7078 service_cost = { 7079 supplydrop = math.random(80,120), 7080 reinforcements = math.random(125,175), 7081 jumpsupplydrop = math.random(110,140), 7082 }, 7083 reputation_cost_multipliers = { 7084 friend = 1.0, 7085 neutral = 2.0, 7086 }, 7087 goods = { 7088 luxury = { 7089 quantity = 5, 7090 cost = 95, 7091 }, 7092 }, 7093 trade = { 7094 food = false, 7095 medicine = false, 7096 luxury = false, 7097 }, 7098 description = "Diplomatic training", 7099 general = "The premeire academy for leadership and diplomacy training in the region", 7100 history = "Established by the royal family so critical during the political upheaval era", 7101 }, 7102 ["Owen"] = { 7103 weapon_available = { 7104 Homing = true, 7105 HVLI = false, 7106 Mine = random(1,13)<=(7-difficulty), 7107 Nuke = random(1,13)<=(5-difficulty), 7108 EMP = random(1,13)<=(6-difficulty), 7109 }, 7110 services = { 7111 supplydrop = "friend", 7112 reinforcements = "friend", 7113 jumpsupplydrop = "friend", 7114 }, 7115 service_cost = { 7116 supplydrop = math.random(80,120), 7117 reinforcements = math.random(125,175), 7118 jumpsupplydrop = math.random(110,140), 7119 }, 7120 reputation_cost_multipliers = { 7121 friend = 1.0, 7122 neutral = 3.0, 7123 }, 7124 goods = { 7125 lifter = { 7126 quantity = 5, 7127 cost = 61, 7128 }, 7129 }, 7130 trade = { 7131 food = false, 7132 medicine = false, 7133 luxury = true, 7134 }, 7135 description = "Load lifters and components", 7136 general = "We provide load lifters and components for various ship systems", 7137 history = "Owens started off in the moisture vaporator business on Tattooine then branched out into load lifters based on acquisition of proprietary software and protocols. The station name recognizes the tragic loss of our founder to Imperial violence", 7138 }, 7139 ["Ripley"] = { 7140 weapon_available = { 7141 Homing = false, 7142 HVLI = true, 7143 Mine = random(1,13)<=(7-difficulty), 7144 Nuke = random(1,13)<=(5-difficulty), 7145 EMP = random(1,13)<=(6-difficulty), 7146 }, 7147 services = { 7148 supplydrop = "friend", 7149 reinforcements = "friend", 7150 jumpsupplydrop = "friend", 7151 }, 7152 service_cost = { 7153 supplydrop = math.random(80,120), 7154 reinforcements = math.random(125,175), 7155 jumpsupplydrop = math.random(110,140), 7156 }, 7157 reputation_cost_multipliers = { 7158 friend = 1.0, 7159 neutral = 3.0, 7160 }, 7161 goods = { 7162 lifter = { 7163 quantity = 5, 7164 cost = 82, 7165 }, 7166 }, 7167 trade = { 7168 food = false, 7169 medicine = false, 7170 luxury = random(1,100) < 47, 7171 }, 7172 description = "Load lifters and components", 7173 general = "We provide load lifters and components", 7174 history = "The station is named after Ellen Ripley who made creative and effective use of one of our load lifters when defending her ship", 7175 }, 7176 ["Skandar"] = { 7177 weapon_available = { 7178 Homing = random(1,13)<=(8-difficulty), 7179 HVLI = random(1,13)<=(9-difficulty), 7180 Mine = random(1,13)<=(7-difficulty), 7181 Nuke = random(1,13)<=(5-difficulty), 7182 EMP = random(1,13)<=(6-difficulty), 7183 }, 7184 services = { 7185 supplydrop = "friend", 7186 reinforcements = "friend", 7187 jumpsupplydrop = "friend", 7188 }, 7189 service_cost = { 7190 supplydrop = math.random(80,120), 7191 reinforcements = math.random(125,175), 7192 jumpsupplydrop = math.random(110,140), 7193 }, 7194 reputation_cost_multipliers = { 7195 friend = 1.0, 7196 neutral = 2.0, 7197 }, 7198 goods = { 7199 luxury = { 7200 quantity = 5, 7201 cost = math.random(30,80), 7202 }, 7203 }, 7204 trade = { 7205 food = false, 7206 medicine = false, 7207 luxury = false, 7208 }, 7209 description = "Routine maintenance and entertainment", 7210 general = "Stop by for repairs. Take in one of our juggling shows featuring the four-armed Skandars", 7211 history = "The nomadic Skandars have set up at this station to practice their entertainment and maintenance skills as well as build a community where Skandars can relax", 7212 }, 7213 ["Soong"] = { 7214 weapon_available = { 7215 Homing = random(1,13)<=(8-difficulty), 7216 HVLI = random(1,13)<=(9-difficulty), 7217 Mine = random(1,13)<=(7-difficulty), 7218 Nuke = random(1,13)<=(5-difficulty), 7219 EMP = random(1,13)<=(6-difficulty), 7220 }, 7221 services = { 7222 supplydrop = "friend", 7223 reinforcements = "friend", 7224 jumpsupplydrop = "friend", 7225 }, 7226 service_cost = { 7227 supplydrop = math.random(80,120), 7228 reinforcements = math.random(125,175), 7229 jumpsupplydrop = math.random(110,140), 7230 }, 7231 reputation_cost_multipliers = { 7232 friend = 1.0, 7233 neutral = 3.0, 7234 }, 7235 goods = { 7236 android = { 7237 quantity = 5, 7238 cost = 73, 7239 }, 7240 }, 7241 trade = { 7242 food = false, 7243 medicine = false, 7244 luxury = true, 7245 }, 7246 description = "Android components", 7247 general = "We create androids and android components", 7248 history = "The station is named after Dr. Noonian Soong, the famous android researcher and builder", 7249 }, 7250 ["Starnet"] = { 7251 weapon_available = { 7252 Homing = random(1,13)<=(8-difficulty), 7253 HVLI = random(1,13)<=(9-difficulty), 7254 Mine = random(1,13)<=(7-difficulty), 7255 Nuke = random(1,13)<=(5-difficulty), 7256 EMP = random(1,13)<=(6-difficulty), 7257 }, 7258 services = { 7259 supplydrop = "friend", 7260 reinforcements = "friend", 7261 jumpsupplydrop = "friend", 7262 }, 7263 service_cost = { 7264 supplydrop = math.random(80,120), 7265 reinforcements = math.random(125,175), 7266 jumpsupplydrop = math.random(110,140), 7267 }, 7268 reputation_cost_multipliers = { 7269 friend = 1.0, 7270 neutral = 3.0, 7271 }, 7272 goods = { 7273 software = { 7274 quantity = 5, 7275 cost = 140, 7276 }, 7277 }, 7278 trade = { 7279 food = false, 7280 medicine = false, 7281 luxury = false, 7282 }, 7283 description = "Automated weapons systems", 7284 general = "We research and create automated weapons systems to improve ship combat capability", 7285 history = "Lost the history memory bank. Recovery efforts only brought back the phrase, 'I'll be back'", 7286 }, 7287 ["Tiberius"] = { 7288 weapon_available = { 7289 Homing = random(1,13)<=(8-difficulty), 7290 HVLI = random(1,13)<=(9-difficulty), 7291 Mine = random(1,13)<=(7-difficulty), 7292 Nuke = random(1,13)<=(5-difficulty), 7293 EMP = random(1,13)<=(6-difficulty), 7294 }, 7295 services = { 7296 supplydrop = "friend", 7297 reinforcements = "friend", 7298 jumpsupplydrop = "friend", 7299 }, 7300 service_cost = { 7301 supplydrop = math.random(80,120), 7302 reinforcements = math.random(125,175), 7303 jumpsupplydrop = math.random(110,140), 7304 }, 7305 goods = { 7306 food = { 7307 quantity = 5, 7308 cost = 1, 7309 }, 7310 }, 7311 trade = { 7312 food = false, 7313 medicine = false, 7314 luxury = false, 7315 }, 7316 description = "Logistics coordination", 7317 general = "We support the stations and ships in the area with planning and communication services", 7318 history = "We recognize the influence of Starfleet Captain James Tiberius Kirk in the 23rd century in our station name", 7319 }, 7320 ["Tokra"] = { 7321 weapon_available = { 7322 Homing = random(1,13)<=(8-difficulty), 7323 HVLI = random(1,13)<=(9-difficulty), 7324 Mine = random(1,13)<=(7-difficulty), 7325 Nuke = random(1,13)<=(5-difficulty), 7326 EMP = random(1,13)<=(6-difficulty), 7327 }, 7328 services = { 7329 supplydrop = "friend", 7330 reinforcements = "friend", 7331 jumpsupplydrop = "friend", 7332 }, 7333 service_cost = { 7334 supplydrop = math.random(80,120), 7335 reinforcements = math.random(125,175), 7336 jumpsupplydrop = math.random(110,140), 7337 }, 7338 reputation_cost_multipliers = { 7339 friend = 1.0, 7340 neutral = 3.0, 7341 }, 7342 goods = { 7343 filament = { 7344 quantity = 5, 7345 cost = 42, 7346 }, 7347 }, 7348 trade = { 7349 food = false, 7350 medicine = false, 7351 luxury = false, 7352 }, 7353 description = "Advanced material components", 7354 general = "We create multiple types of advanced material components. Our most popular products are our filaments", 7355 history = "We learned several of our critical industrial processes from the Tokra race, so we honor our fortune by naming the station after them", 7356 }, 7357 ["Utopia Planitia"] = { 7358 weapon_available = { 7359 Homing = random(1,13)<=(8-difficulty), 7360 HVLI = random(1,13)<=(9-difficulty), 7361 Mine = random(1,13)<=(7-difficulty), 7362 Nuke = true, 7363 EMP = random(1,13)<=(6-difficulty), 7364 }, 7365 services = { 7366 supplydrop = "friend", 7367 reinforcements = "friend", 7368 jumpsupplydrop = "friend", 7369 }, 7370 service_cost = { 7371 supplydrop = math.random(80,120), 7372 reinforcements = math.random(125,175), 7373 jumpsupplydrop = math.random(110,140), 7374 }, 7375 goods = { 7376 warp = { 7377 quantity = 5, 7378 cost = 167, 7379 }, 7380 }, 7381 trade = { 7382 food = false, 7383 medicine = false, 7384 luxury = false 7385 }, 7386 description = "Ship building and maintenance facility", 7387 general = "We work on all aspects of naval ship building and maintenance. Many of the naval models are researched, designed and built right here on this station. Our design goals seek to make the space faring experience as simple as possible given the tremendous capabilities of the modern naval vessel", 7388 history = "" 7389 }, 7390 ["Vaiken"] = { 7391 weapon_available = { 7392 Homing = random(1,13)<=(8-difficulty), 7393 HVLI = random(1,13)<=(9-difficulty), 7394 Mine = random(1,13)<=(7-difficulty), 7395 Nuke = random(1,13)<=(5-difficulty), 7396 EMP = random(1,13)<=(6-difficulty), 7397 }, 7398 services = { 7399 supplydrop = "friend", 7400 reinforcements = "friend", 7401 jumpsupplydrop = "friend", 7402 }, 7403 service_cost = { 7404 supplydrop = math.random(80,120), 7405 reinforcements = math.random(125,175), 7406 jumpsupplydrop = math.random(110,140), 7407 }, 7408 goods = { 7409 food = { 7410 quantity = 10, 7411 cost = 1, 7412 }, 7413 medicine = { 7414 quantity = 5, 7415 cost = 5, 7416 }, 7417 impulse = { 7418 quantity = 5, 7419 cost = math.random(65,97), 7420 }, 7421 }, 7422 trade = { 7423 food = false, 7424 medicine = false, 7425 luxury = false, 7426 }, 7427 description = "Ship building and maintenance facility", 7428 general = "", 7429 history = "", 7430 }, 7431 ["Zefram"] = { 7432 weapon_available = { 7433 Homing = random(1,13)<=(8-difficulty), 7434 HVLI = random(1,13)<=(9-difficulty), 7435 Mine = random(1,13)<=(7-difficulty), 7436 Nuke = random(1,13)<=(5-difficulty), 7437 EMP = random(1,13)<=(6-difficulty), 7438 }, 7439 services = { 7440 supplydrop = "friend", 7441 reinforcements = "friend", 7442 jumpsupplydrop = "friend", 7443 }, 7444 service_cost = { 7445 supplydrop = math.random(80,120), 7446 reinforcements = math.random(125,175), 7447 jumpsupplydrop = math.random(110,140), 7448 }, 7449 reputation_cost_multipliers = { 7450 friend = 1.0, 7451 neutral = 3.0, 7452 }, 7453 goods = { 7454 warp = { 7455 quantity = 5, 7456 cost = 140, 7457 }, 7458 }, 7459 trade = { 7460 food = false, 7461 medicine = false, 7462 luxury = true, 7463 }, 7464 description = "Warp engine components", 7465 general = "We specialize in the esoteric components necessary to make warp drives function properly", 7466 history = "Zefram Cochrane constructed the first warp drive in human history. We named our station after him because of the specialized warp systems work we do", 7467 }, 7468 }, 7469 ["Spec Sci Fi"] = { 7470 ["Alcaleica"] = { 7471 weapon_available = { 7472 Homing = random(1,13)<=(8-difficulty), 7473 HVLI = random(1,13)<=(9-difficulty), 7474 Mine = random(1,13)<=(7-difficulty), 7475 Nuke = random(1,13)<=(5-difficulty), 7476 EMP = random(1,13)<=(6-difficulty), 7477 }, 7478 services = { 7479 supplydrop = "friend", 7480 reinforcements = "friend", 7481 jumpsupplydrop = "friend", 7482 }, 7483 service_cost = { 7484 supplydrop = math.random(80,120), 7485 reinforcements = math.random(125,175), 7486 jumpsupplydrop = math.random(110,140), 7487 }, 7488 goods = { 7489 optic = { 7490 quantity = 5, 7491 cost = 66, 7492 }, 7493 }, 7494 trade = { 7495 food = false, 7496 medicine = false, 7497 luxury = false, 7498 }, 7499 buy = { 7500 [randomMineral()] = math.random(40,200), 7501 }, 7502 description = "Optical Components", 7503 general = "We make and supply optic components for various station and ship systems", 7504 history = "This station continues the businesses from Earth based on the merging of several companies including Leica from Switzerland, the lens manufacturer and the Japanese advanced low carbon (ALCA) electronic and optic research and development company", 7505 }, 7506 ["Bethesda"] = { 7507 weapon_available = { 7508 Homing = random(1,13)<=(8-difficulty), 7509 HVLI = random(1,13)<=(9-difficulty), 7510 Mine = random(1,13)<=(7-difficulty), 7511 Nuke = random(1,13)<=(5-difficulty), 7512 EMP = random(1,13)<=(6-difficulty), 7513 }, 7514 services = { 7515 supplydrop = "friend", 7516 reinforcements = "friend", 7517 jumpsupplydrop = "friend", 7518 }, 7519 service_cost = { 7520 supplydrop = math.random(80,120), 7521 reinforcements = math.random(125,175), 7522 jumpsupplydrop = math.random(110,140), 7523 }, 7524 reputation_cost_multipliers = { 7525 friend = 1.0, 7526 neutral = 3.0, 7527 }, 7528 goods = { 7529 autodoc = { 7530 quantity = 5, 7531 cost = 36, 7532 }, 7533 medicine = { 7534 quantity = 5, 7535 cost = 5, 7536 }, 7537 food = { 7538 quantity = math.random(5,10), 7539 cost = 1, 7540 }, 7541 }, 7542 trade = { 7543 food = false, 7544 medicine = false, 7545 luxury = false, 7546 }, 7547 description = "Medical research", 7548 general = "We research and treat exotic medical conditions", 7549 history = "The station is named after the United States national medical research center based in Bethesda, Maryland on earth which was established in the mid 20th century", 7550 }, 7551 ["Deer"] = { 7552 weapon_available = { 7553 Homing = random(1,13)<=(8-difficulty), 7554 HVLI = random(1,13)<=(9-difficulty), 7555 Mine = random(1,13)<=(7-difficulty), 7556 Nuke = random(1,13)<=(5-difficulty), 7557 EMP = random(1,13)<=(6-difficulty), 7558 }, 7559 services = { 7560 supplydrop = "friend", 7561 reinforcements = "friend", 7562 jumpsupplydrop = "friend", 7563 }, 7564 service_cost = { 7565 supplydrop = math.random(80,120), 7566 reinforcements = math.random(125,175), 7567 jumpsupplydrop = math.random(110,140), 7568 }, 7569 goods = { 7570 tractor = { 7571 quantity = 5, 7572 cost = 90, 7573 }, 7574 repulsor = { 7575 quantity = 5, 7576 cost = math.random(85,95), 7577 }, 7578 }, 7579 trade = { 7580 food = false, 7581 medicine = false, 7582 luxury = true, 7583 }, 7584 description = "Repulsor and Tractor Beam Components", 7585 general = "We can meet all your pushing and pulling needs with specialized equipment custom made", 7586 history = "The station name comes from a short story by the 20th century author Clifford D. Simak as well as from the 19th century developer John Deere who inspired a company that makes the Earth bound equivalents of our products", 7587 }, 7588 ["Evondos"] = { 7589 weapon_available = { 7590 Homing = random(1,13)<=(8-difficulty), 7591 HVLI = true, 7592 Mine = random(1,13)<=(7-difficulty), 7593 Nuke = random(1,13)<=(5-difficulty), 7594 EMP = random(1,13)<=(6-difficulty), 7595 }, 7596 services = { 7597 supplydrop = "friend", 7598 reinforcements = "friend", 7599 jumpsupplydrop = "friend", 7600 }, 7601 service_cost = { 7602 supplydrop = math.random(80,120), 7603 reinforcements = math.random(125,175), 7604 jumpsupplydrop = math.random(110,140), 7605 }, 7606 reputation_cost_multipliers = { 7607 friend = 1.0, 7608 neutral = 3.0, 7609 }, 7610 goods = { 7611 autodoc = { 7612 quantity = 5, 7613 cost = 56, 7614 }, 7615 }, 7616 trade = { 7617 food = false, 7618 medicine = false, 7619 luxury = random(1,100) < 41, 7620 }, 7621 description = "Autodoc components", 7622 general = "We provide components for automated medical machinery", 7623 history = "The station is the evolution of the company that started automated pharmaceutical dispensing in the early 21st century on Earth in Finland", 7624 }, 7625 ["Feynman"] = { 7626 weapon_available = { 7627 Homing = random(1,13)<=(8-difficulty), 7628 HVLI = random(1,13)<=(9-difficulty), 7629 Mine = true, 7630 Nuke = random(1,13)<=(5-difficulty), 7631 EMP = random(1,13)<=(6-difficulty), 7632 }, 7633 services = { 7634 supplydrop = "friend", 7635 reinforcements = "friend", 7636 jumpsupplydrop = "friend", 7637 }, 7638 service_cost = { 7639 supplydrop = math.random(80,120), 7640 reinforcements = math.random(125,175), 7641 jumpsupplydrop = math.random(110,140), 7642 }, 7643 reputation_cost_multipliers = { 7644 friend = 1.0, 7645 neutral = 3.0, 7646 }, 7647 goods = { 7648 software = { 7649 quantity = 5, 7650 cost = 115, 7651 }, 7652 nanites = { 7653 quantity = 5, 7654 cost = 79, 7655 }, 7656 }, 7657 trade = { 7658 food = false, 7659 medicine = false, 7660 luxury = true, 7661 }, 7662 description = "Nanotechnology research", 7663 general = "We provide nanites and software for a variety of ship-board systems", 7664 history = "This station's name recognizes one of the first scientific researchers into nanotechnology, physicist Richard Feynman", 7665 }, 7666 ["Mayo"] = { 7667 weapon_available = { 7668 Homing = random(1,13)<=(8-difficulty), 7669 HVLI = random(1,13)<=(9-difficulty), 7670 Mine = random(1,13)<=(7-difficulty), 7671 Nuke = random(1,13)<=(5-difficulty), 7672 EMP = random(1,13)<=(6-difficulty), 7673 }, 7674 services = { 7675 supplydrop = "friend", 7676 reinforcements = "friend", 7677 jumpsupplydrop = "friend", 7678 }, 7679 service_cost = { 7680 supplydrop = math.random(80,120), 7681 reinforcements = math.random(125,175), 7682 jumpsupplydrop = math.random(110,140), 7683 }, 7684 goods = { 7685 autodoc = { 7686 quantity = 5, 7687 cost = 128, 7688 }, 7689 food = { 7690 quantity = 5, 7691 cost = 1, 7692 }, 7693 medicine = { 7694 quantity = 5, 7695 cost = 5, 7696 }, 7697 }, 7698 trade = { 7699 food = false, 7700 medicine = false, 7701 luxury = false, 7702 }, 7703 description = "Medical Research", 7704 general = "We research exotic diseases and other human medical conditions", 7705 history = "We continue the medical work started by William Worrall Mayo in the late 19th century on Earth", 7706 }, 7707 ["Olympus"] = { 7708 weapon_available = { 7709 Homing = random(1,13)<=(8-difficulty), 7710 HVLI = random(1,13)<=(9-difficulty), 7711 Mine = random(1,13)<=(7-difficulty), 7712 Nuke = random(1,13)<=(5-difficulty), 7713 EMP = random(1,13)<=(6-difficulty), 7714 }, 7715 services = { 7716 supplydrop = "friend", 7717 reinforcements = "friend", 7718 jumpsupplydrop = "friend", 7719 }, 7720 service_cost = { 7721 supplydrop = math.random(80,120), 7722 reinforcements = math.random(125,175), 7723 jumpsupplydrop = math.random(110,140), 7724 }, 7725 reputation_cost_multipliers = { 7726 friend = 1.0, 7727 neutral = 3.0, 7728 }, 7729 goods = { 7730 optic = { 7731 quantity = 5, 7732 cost = 66, 7733 }, 7734 }, 7735 trade = { 7736 food = false, 7737 medicine = false, 7738 luxury = false, 7739 }, 7740 description = "Optical components", 7741 general = "We fabricate optical lenses and related equipment as well as fiber optic cabling and components", 7742 history = "This station grew out of the Olympus company based on earth in the early 21st century. It merged with Infinera, then bought several software comapnies before branching out into space based industry", 7743 }, 7744 ["Panduit"] = { 7745 weapon_available = { 7746 Homing = random(1,13)<=(8-difficulty), 7747 HVLI = random(1,13)<=(9-difficulty), 7748 Mine = random(1,13)<=(7-difficulty), 7749 Nuke = random(1,13)<=(5-difficulty), 7750 EMP = random(1,13)<=(6-difficulty), 7751 }, 7752 services = { 7753 supplydrop = "friend", 7754 reinforcements = "friend", 7755 jumpsupplydrop = "friend", 7756 }, 7757 service_cost = { 7758 supplydrop = math.random(80,120), 7759 reinforcements = math.random(125,175), 7760 jumpsupplydrop = math.random(110,140), 7761 }, 7762 reputation_cost_multipliers = { 7763 friend = 1.0, 7764 neutral = 3.0, 7765 }, 7766 goods = { 7767 optic = { 7768 quantity = 5, 7769 cost = 79, 7770 }, 7771 }, 7772 trade = { 7773 food = false, 7774 medicine = false, 7775 luxury = true, 7776 }, 7777 description = "Optic components", 7778 general = "We provide optic components for various ship systems", 7779 history = "This station is an outgrowth of the Panduit corporation started in the mid 20th century on Earth in the United States", 7780 }, 7781 ["Shree"] = { 7782 weapon_available = { 7783 Homing = random(1,13)<=(8-difficulty), 7784 HVLI = random(1,13)<=(9-difficulty), 7785 Mine = random(1,13)<=(7-difficulty), 7786 Nuke = random(1,13)<=(5-difficulty), 7787 EMP = random(1,13)<=(6-difficulty), 7788 }, 7789 services = { 7790 supplydrop = "friend", 7791 reinforcements = "friend", 7792 jumpsupplydrop = "friend", 7793 }, 7794 service_cost = { 7795 supplydrop = math.random(80,120), 7796 reinforcements = math.random(125,175), 7797 jumpsupplydrop = math.random(110,140), 7798 }, 7799 reputation_cost_multipliers = { 7800 friend = 1.0, 7801 neutral = 3.0, 7802 }, 7803 goods = { 7804 tractor = { 7805 quantity = 5, 7806 cost = 90, 7807 }, 7808 repulsor = { 7809 quantity = 5, 7810 cost = math.random(85,95), 7811 }, 7812 }, 7813 trade = { 7814 food = false, 7815 medicine = false, 7816 luxury = true, 7817 }, 7818 description = "Repulsor and tractor beam components", 7819 general = "We make ship systems designed to push or pull other objects around in space", 7820 history = "Our station is named Shree after one of many tugboat manufacturers in the early 21st century on Earth in India. Tugboats serve a similar purpose for ocean-going vessels on earth as tractor and repulsor beams serve for space-going vessels today", 7821 }, 7822 ["Vactel"] = { 7823 weapon_available = { 7824 Homing = random(1,13)<=(8-difficulty), 7825 HVLI = random(1,13)<=(9-difficulty), 7826 Mine = random(1,13)<=(7-difficulty), 7827 Nuke = random(1,13)<=(5-difficulty), 7828 EMP = random(1,13)<=(6-difficulty), 7829 }, 7830 services = { 7831 supplydrop = "friend", 7832 reinforcements = "friend", 7833 jumpsupplydrop = "friend", 7834 }, 7835 service_cost = { 7836 supplydrop = math.random(80,120), 7837 reinforcements = math.random(125,175), 7838 jumpsupplydrop = math.random(110,140), 7839 }, 7840 goods = { 7841 circuit = { 7842 quantity = 5, 7843 cost = 50, 7844 }, 7845 }, 7846 trade = { 7847 food = false, 7848 medicine = false, 7849 luxury = false, 7850 }, 7851 description = "Shielded Circuitry Fabrication", 7852 general = "We specialize in circuitry shielded from external hacking suitable for ship systems", 7853 history = "We started as an expansion from the lunar based chip manufacturer of Earth legacy Intel electronic chips", 7854 }, 7855 ["Veloquan"] = { 7856 weapon_available = { 7857 Homing = random(1,13)<=(8-difficulty), 7858 HVLI = random(1,13)<=(9-difficulty), 7859 Mine = random(1,13)<=(7-difficulty), 7860 Nuke = random(1,13)<=(5-difficulty), 7861 EMP = random(1,13)<=(6-difficulty), 7862 }, 7863 services = { 7864 supplydrop = "friend", 7865 reinforcements = "friend", 7866 jumpsupplydrop = "friend", 7867 }, 7868 service_cost = { 7869 supplydrop = math.random(80,120), 7870 reinforcements = math.random(125,175), 7871 jumpsupplydrop = math.random(110,140), 7872 }, 7873 reputation_cost_multipliers = { 7874 friend = 1.0, 7875 neutral = 3.0, 7876 }, 7877 goods = { 7878 sensor = { 7879 quantity = 5, 7880 cost = 68, 7881 }, 7882 }, 7883 trade = { 7884 food = false, 7885 medicine = false, 7886 luxury = false, 7887 }, 7888 description = "Sensor components", 7889 general = "We research and construct components for the most powerful and accurate sensors used aboard ships along with the software to make them easy to use", 7890 history = "The Veloquan company has its roots in the manufacturing of LIDAR sensors in the early 21st century on Earth in the United States for autonomous ground-based vehicles. They expanded research and manufacturing operations to include various sensors for space vehicles. Veloquan was the result of numerous mergers and acquisitions of several companies including Velodyne and Quanergy", 7891 }, 7892 ["Tandon"] = { 7893 weapon_available = { 7894 Homing = random(1,13)<=(8-difficulty), 7895 HVLI = random(1,13)<=(9-difficulty), 7896 Mine = random(1,13)<=(7-difficulty), 7897 Nuke = random(1,13)<=(5-difficulty), 7898 EMP = random(1,13)<=(6-difficulty), 7899 }, 7900 services = { 7901 supplydrop = "friend", 7902 reinforcements = "friend", 7903 jumpsupplydrop = "friend", 7904 }, 7905 service_cost = { 7906 supplydrop = math.random(80,120), 7907 reinforcements = math.random(125,175), 7908 jumpsupplydrop = math.random(110,140), 7909 }, 7910 reputation_cost_multipliers = { 7911 friend = 1.0, 7912 neutral = 3.0, 7913 }, 7914 goods = {}, 7915 trade = { 7916 food = false, 7917 medicine = false, 7918 luxury = false, 7919 }, 7920 description = "Biotechnology research", 7921 general = "Merging the organic and inorganic through research", 7922 history = "Continued from the Tandon school of engineering started on Earth in the early 21st century", 7923 }, 7924 }, 7925 ["Generic"] = { 7926 ["California"] = { 7927 weapon_available = { 7928 Homing = random(1,13)<=(8-difficulty), 7929 HVLI = random(1,13)<=(9-difficulty), 7930 Mine = random(1,13)<=(7-difficulty), 7931 Nuke = random(1,13)<=(5-difficulty), 7932 EMP = random(1,13)<=(6-difficulty), 7933 }, 7934 services = { 7935 supplydrop = "friend", 7936 reinforcements = "friend", 7937 jumpsupplydrop = "friend", 7938 }, 7939 service_cost = { 7940 supplydrop = math.random(80,120), 7941 reinforcements = math.random(125,175), 7942 jumpsupplydrop = math.random(110,140), 7943 }, 7944 goods = { 7945 gold = { 7946 quantity = 5, 7947 cost = 90, 7948 }, 7949 dilithium = { 7950 quantity = 2, 7951 cost = 25, 7952 }, 7953 }, 7954 trade = { 7955 food = false, 7956 medicine = false, 7957 luxury = false, 7958 }, 7959 description = "Mining station", 7960 general = "", 7961 history = "", 7962 }, 7963 ["Impala"] = { 7964 weapon_available = { 7965 Homing = random(1,13)<=(8-difficulty), 7966 HVLI = random(1,13)<=(9-difficulty), 7967 Mine = random(1,13)<=(7-difficulty), 7968 Nuke = random(1,13)<=(5-difficulty), 7969 EMP = random(1,13)<=(6-difficulty), 7970 }, 7971 services = { 7972 supplydrop = "friend", 7973 reinforcements = "friend", 7974 jumpsupplydrop = "friend", 7975 }, 7976 service_cost = { 7977 supplydrop = math.random(80,120), 7978 reinforcements = math.random(125,175), 7979 jumpsupplydrop = math.random(110,140), 7980 }, 7981 reputation_cost_multipliers = { 7982 friend = 1.0, 7983 neutral = 3.0, 7984 }, 7985 goods = { 7986 luxury = { 7987 quantity = 5, 7988 cost = 70, 7989 }, 7990 }, 7991 trade = { 7992 food = true, 7993 medicine = false, 7994 luxury = true, 7995 }, 7996 buy = { 7997 [randomComponent()] = math.random(40,200), 7998 }, 7999 description = "Mining", 8000 general = "We mine nearby asteroids for precious minerals", 8001 history = "", 8002 }, 8003 ["Krak"] = { 8004 weapon_available = { 8005 Homing = random(1,13)<=(8-difficulty), 8006 HVLI = true, 8007 Mine = random(1,13)<=(7-difficulty), 8008 Nuke = random(1,13)<=(5-difficulty), 8009 EMP = random(1,13)<=(6-difficulty), 8010 }, 8011 services = { 8012 supplydrop = "friend", 8013 reinforcements = "friend", 8014 jumpsupplydrop = "friend", 8015 }, 8016 service_cost = { 8017 supplydrop = math.random(80,120), 8018 reinforcements = math.random(125,175), 8019 jumpsupplydrop = math.random(110,140), 8020 }, 8021 reputation_cost_multipliers = { 8022 friend = 1.0, 8023 neutral = 3.0, 8024 }, 8025 goods = { 8026 nickel = { 8027 quantity = 5, 8028 cost = 20, 8029 }, 8030 }, 8031 trade = { 8032 food = random(1,100) < 50, 8033 medicine = true, 8034 luxury = random(1,100) < 50, 8035 }, 8036 buy = { 8037 [randomComponent()] = math.random(40,200), 8038 }, 8039 description = "Mining station", 8040 general = "", 8041 history = "", 8042 }, 8043 ["Krik"] = { 8044 weapon_available = { 8045 Homing = random(1,13)<=(8-difficulty), 8046 HVLI = random(1,13)<=(9-difficulty), 8047 Mine = random(1,13)<=(7-difficulty), 8048 Nuke = random(1,13)<=(5-difficulty), 8049 EMP = random(1,13)<=(6-difficulty), 8050 }, 8051 services = { 8052 supplydrop = "friend", 8053 reinforcements = "friend", 8054 jumpsupplydrop = "friend", 8055 }, 8056 service_cost = { 8057 supplydrop = math.random(80,120), 8058 reinforcements = math.random(125,175), 8059 jumpsupplydrop = math.random(110,140), 8060 }, 8061 reputation_cost_multipliers = { 8062 friend = 1.0, 8063 neutral = 3.0, 8064 }, 8065 goods = { 8066 nickel = { 8067 quantity = 5, 8068 cost = 20, 8069 }, 8070 }, 8071 trade = { 8072 food = true, 8073 medicine = true, 8074 luxury = random(1,100) < 50, 8075 }, 8076 description = "Mining station", 8077 general = "", 8078 history = "", 8079 }, 8080 ["Kruk"] = { 8081 weapon_available = { 8082 Homing = random(1,13)<=(8-difficulty), 8083 HVLI = random(1,13)<=(9-difficulty), 8084 Mine = random(1,13)<=(7-difficulty), 8085 Nuke = random(1,13)<=(5-difficulty), 8086 EMP = random(1,13)<=(6-difficulty), 8087 }, 8088 services = { 8089 supplydrop = "friend", 8090 reinforcements = "friend", 8091 jumpsupplydrop = "friend", 8092 }, 8093 service_cost = { 8094 supplydrop = math.random(80,120), 8095 reinforcements = math.random(125,175), 8096 jumpsupplydrop = math.random(110,140), 8097 }, 8098 reputation_cost_multipliers = { 8099 friend = 1.0, 8100 neutral = 3.0, 8101 }, 8102 goods = { 8103 nickel = { 8104 quantity = 5, 8105 cost = 20, 8106 }, 8107 }, 8108 trade = { 8109 food = random(1,100) < 50, 8110 medicine = random(1,100) < 50, 8111 luxury = true }, 8112 buy = { 8113 [randomComponent()] = math.random(40,200), 8114 }, 8115 description = "Mining station", 8116 general = "", 8117 history = "", 8118 }, 8119 ["Maverick"] = { 8120 weapon_available = { 8121 Homing = random(1,13)<=(8-difficulty), 8122 HVLI = random(1,13)<=(9-difficulty), 8123 Mine = random(1,13)<=(7-difficulty), 8124 Nuke = random(1,13)<=(5-difficulty), 8125 EMP = random(1,13)<=(6-difficulty), 8126 }, 8127 services = { 8128 supplydrop = "friend", 8129 reinforcements = "friend", 8130 jumpsupplydrop = "friend", 8131 }, 8132 service_cost = { 8133 supplydrop = math.random(80,120), 8134 reinforcements = math.random(125,175), 8135 jumpsupplydrop = math.random(110,140), 8136 }, 8137 goods = { 8138 luxury = { 8139 quantity = 5, 8140 cost = math.random(30,80), 8141 }, 8142 }, 8143 trade = { 8144 food = false, 8145 medicine = false, 8146 luxury = false, 8147 }, 8148 description = "Gambling and resupply", 8149 general = "Relax and meet some interesting players", 8150 history = "", 8151 }, 8152 ["Nefatha"] = { 8153 weapon_available = { 8154 Homing = random(1,13)<=(8-difficulty), 8155 HVLI = random(1,13)<=(9-difficulty), 8156 Mine = random(1,13)<=(7-difficulty), 8157 Nuke = random(1,13)<=(5-difficulty), 8158 EMP = random(1,13)<=(6-difficulty), 8159 }, 8160 services = { 8161 supplydrop = "friend", 8162 reinforcements = "friend", 8163 jumpsupplydrop = "friend", 8164 }, 8165 service_cost = { 8166 supplydrop = math.random(80,120), 8167 reinforcements = math.random(125,175), 8168 jumpsupplydrop = math.random(110,140), 8169 }, 8170 reputation_cost_multipliers = { 8171 friend = 1.0, 8172 neutral = 2.0, 8173 }, 8174 goods = { 8175 luxury = { 8176 quantity = 5, 8177 cost = math.random(30,80), 8178 }, 8179 }, 8180 trade = { 8181 food = false, 8182 medicine = false, 8183 luxury = false, 8184 }, 8185 description = "Commerce and recreation", 8186 general = "", 8187 history = "", 8188 }, 8189 ["Okun"] = { 8190 weapon_available = { 8191 Homing = random(1,13)<=(8-difficulty), 8192 HVLI = random(1,13)<=(9-difficulty), 8193 Mine = false, 8194 Nuke = random(1,13)<=(5-difficulty), 8195 EMP = random(1,13)<=(6-difficulty), 8196 }, 8197 services = { 8198 supplydrop = "friend", 8199 reinforcements = "friend", 8200 jumpsupplydrop = "friend", 8201 }, 8202 service_cost = { 8203 supplydrop = math.random(80,120), 8204 reinforcements = math.random(125,175), 8205 jumpsupplydrop = math.random(110,140), 8206 }, 8207 reputation_cost_multipliers = { 8208 friend = 1.0, 8209 neutral = 3.0, 8210 }, 8211 goods = {}, 8212 trade = { 8213 food = false, 8214 medicine = false, 8215 luxury = false, 8216 }, 8217 description = "Xenopsychology research", 8218 general = "", 8219 history = "", 8220 }, 8221 ["Outpost-15"] = { 8222 weapon_available = { 8223 Homing = random(1,13)<=(8-difficulty), 8224 HVLI = random(1,13)<=(9-difficulty), 8225 Mine = random(1,13)<=(7-difficulty), 8226 Nuke = random(1,13)<=(5-difficulty), 8227 EMP = random(1,13)<=(6-difficulty), 8228 }, 8229 services = { 8230 supplydrop = "friend", 8231 reinforcements = "friend", 8232 jumpsupplydrop = "friend", 8233 }, 8234 service_cost = { 8235 supplydrop = math.random(80,120), 8236 reinforcements = math.random(125,175), 8237 jumpsupplydrop = math.random(110,140), 8238 }, 8239 reputation_cost_multipliers = { 8240 friend = 1.0, 8241 neutral = 2.0, 8242 }, 8243 goods = { 8244 luxury = { 8245 quantity = 5, 8246 cost = math.random(30,80), 8247 }, 8248 }, 8249 trade = { 8250 food = false, 8251 medicine = false, 8252 luxury = false, 8253 }, 8254 description = "Mining and trade", 8255 general = "", 8256 history = "", 8257 }, 8258 ["Outpost-21"] = { 8259 weapon_available = { 8260 Homing = random(1,13)<=(8-difficulty), 8261 HVLI = random(1,13)<=(9-difficulty), 8262 Mine = random(1,13)<=(7-difficulty), 8263 Nuke = random(1,13)<=(5-difficulty), 8264 EMP = random(1,13)<=(6-difficulty), 8265 }, 8266 services = { 8267 supplydrop = "friend", 8268 reinforcements = "friend", 8269 jumpsupplydrop = "friend", 8270 }, 8271 service_cost = { 8272 supplydrop = math.random(80,120), 8273 reinforcements = math.random(125,175), 8274 jumpsupplydrop = math.random(110,140), 8275 }, 8276 reputation_cost_multipliers = { 8277 friend = 1.0, 8278 neutral = 2.0, 8279 }, 8280 goods = { 8281 luxury = { 8282 quantity = 5, 8283 cost = math.random(30,80), 8284 }, 8285 }, 8286 trade = { 8287 food = false, 8288 medicine = false, 8289 luxury = false, 8290 }, 8291 description = "Mining and gambling", 8292 general = "", 8293 history = "", 8294 }, 8295 ["Outpost-7"] = { 8296 weapon_available = { 8297 Homing = random(1,13)<=(8-difficulty), 8298 HVLI = random(1,13)<=(9-difficulty), 8299 Mine = random(1,13)<=(7-difficulty), 8300 Nuke = random(1,13)<=(5-difficulty), 8301 EMP = random(1,13)<=(6-difficulty), 8302 }, 8303 services = { 8304 supplydrop = "friend", 8305 reinforcements = "friend", 8306 jumpsupplydrop = "friend", 8307 }, 8308 service_cost = { 8309 supplydrop = math.random(80,120), 8310 reinforcements = math.random(125,175), 8311 jumpsupplydrop = math.random(110,140), 8312 }, 8313 reputation_cost_multipliers = { 8314 friend = 1.0, 8315 neutral = 2.0, 8316 }, 8317 goods = { 8318 luxury = { 8319 quantity = 5, 8320 cost = math.random(30,80), 8321 }, 8322 }, 8323 trade = { 8324 food = false, 8325 medicine = false, 8326 luxury = false, 8327 }, 8328 description = "Resupply", 8329 general = "", 8330 history = "", 8331 }, 8332 ["Outpost-8"] = { 8333 weapon_available = { 8334 Homing = random(1,13)<=(8-difficulty), 8335 HVLI = random(1,13)<=(9-difficulty), 8336 Mine = random(1,13)<=(7-difficulty), 8337 Nuke = random(1,13)<=(5-difficulty), 8338 EMP = random(1,13)<=(6-difficulty), 8339 }, 8340 services = { 8341 supplydrop = "friend", 8342 reinforcements = "friend", 8343 jumpsupplydrop = "friend", 8344 }, 8345 service_cost = { 8346 supplydrop = math.random(80,120), 8347 reinforcements = math.random(125,175), 8348 jumpsupplydrop = math.random(110,140), 8349 }, 8350 reputation_cost_multipliers = { 8351 friend = 1.0, 8352 neutral = 2.0, 8353 }, 8354 goods = { 8355 luxury = { 8356 quantity = 5, 8357 cost = math.random(30,80), 8358 }, 8359 }, 8360 trade = { 8361 food = false, 8362 medicine = false, 8363 luxury = false, 8364 }, 8365 description = "", 8366 general = "", 8367 history = "", 8368 }, 8369 ["Outpost-33"] = { 8370 weapon_available = { 8371 Homing = random(1,13)<=(8-difficulty), 8372 HVLI = random(1,13)<=(9-difficulty), 8373 Mine = random(1,13)<=(7-difficulty), 8374 Nuke = random(1,13)<=(5-difficulty), 8375 EMP = random(1,13)<=(6-difficulty), 8376 }, 8377 services = { 8378 supplydrop = "friend", 8379 reinforcements = "friend", 8380 jumpsupplydrop = "friend", 8381 }, 8382 service_cost = { 8383 supplydrop = math.random(80,120), 8384 reinforcements = math.random(125,175), 8385 jumpsupplydrop = math.random(110,140), 8386 }, 8387 reputation_cost_multipliers = { 8388 friend = 1.0, 8389 neutral = 2.0, 8390 }, 8391 goods = { 8392 luxury = { 8393 quantity = 5, 8394 cost = math.random(30,80), 8395 }, 8396 }, 8397 trade = { 8398 food = false, 8399 medicine = false, 8400 luxury = false, 8401 }, 8402 description = "Resupply", 8403 general = "", 8404 history = "", 8405 }, 8406 ["Prada"] = { 8407 weapon_available = { 8408 Homing = random(1,13)<=(8-difficulty), 8409 HVLI = random(1,13)<=(9-difficulty), 8410 Mine = false, 8411 Nuke = random(1,13)<=(5-difficulty), 8412 EMP = random(1,13)<=(6-difficulty), 8413 }, 8414 services = { 8415 supplydrop = "friend", 8416 reinforcements = "friend", 8417 jumpsupplydrop = "friend", 8418 }, 8419 service_cost = { 8420 supplydrop = math.random(80,120), 8421 reinforcements = math.random(125,175), 8422 jumpsupplydrop = math.random(110,140), 8423 }, 8424 reputation_cost_multipliers = { 8425 friend = 1.0, 8426 neutral = 2.0, 8427 }, 8428 goods = {}, 8429 trade = { 8430 food = false, 8431 medicine = false, 8432 luxury = false, 8433 }, 8434 description = "Textiles and fashion", 8435 general = "", 8436 history = "", 8437 }, 8438 ["Research-11"] = { 8439 weapon_available = { 8440 Homing = random(1,13)<=(8-difficulty), 8441 HVLI = random(1,13)<=(9-difficulty), 8442 Mine = random(1,13)<=(7-difficulty), 8443 Nuke = random(1,13)<=(5-difficulty), 8444 EMP = random(1,13)<=(6-difficulty), 8445 }, 8446 services = { 8447 supplydrop = "friend", 8448 reinforcements = "friend", 8449 jumpsupplydrop = "friend", 8450 }, 8451 service_cost = { 8452 supplydrop = math.random(80,120), 8453 reinforcements = math.random(125,175), 8454 jumpsupplydrop = math.random(110,140), 8455 }, 8456 reputation_cost_multipliers = { 8457 friend = 1.0, 8458 neutral = 2.0, 8459 }, 8460 goods = { 8461 medicine = { 8462 quantity = 5, 8463 cost = math.random(30,80), 8464 }, 8465 }, 8466 trade = { 8467 food = false, 8468 medicine = false, 8469 luxury = false, 8470 }, 8471 description = "Stress Psychology Research", 8472 general = "", 8473 history = "", 8474 }, 8475 ["Research-19"] = { 8476 weapon_available ={ 8477 Homing = random(1,13)<=(8-difficulty), 8478 HVLI = random(1,13)<=(9-difficulty), 8479 Mine = random(1,13)<=(7-difficulty), 8480 Nuke = random(1,13)<=(5-difficulty), 8481 EMP = random(1,13)<=(6-difficulty), 8482 }, 8483 services = { 8484 supplydrop = "friend", 8485 reinforcements = "friend", 8486 jumpsupplydrop = "friend", 8487 }, 8488 service_cost = { 8489 supplydrop = math.random(80,120), 8490 reinforcements = math.random(125,175), 8491 jumpsupplydrop = math.random(110,140), 8492 }, 8493 reputation_cost_multipliers = { 8494 friend = 1.0, 8495 neutral = 2.0, 8496 }, 8497 goods = {}, 8498 trade = { 8499 food = false, 8500 medicine = false, 8501 luxury = false, 8502 }, 8503 description = "Low gravity research", 8504 general = "", 8505 history = "", 8506 }, 8507 ["Rubis"] = { 8508 weapon_available = { 8509 Homing = random(1,13)<=(8-difficulty), 8510 HVLI = random(1,13)<=(9-difficulty), 8511 Mine = random(1,13)<=(7-difficulty), 8512 Nuke = random(1,13)<=(5-difficulty), 8513 EMP = random(1,13)<=(6-difficulty), 8514 }, 8515 services = { 8516 supplydrop = "friend", 8517 reinforcements = "friend", 8518 jumpsupplydrop = "friend", 8519 }, 8520 service_cost = { 8521 supplydrop = math.random(80,120), 8522 reinforcements = math.random(125,175), 8523 jumpsupplydrop = math.random(110,140), 8524 }, 8525 reputation_cost_multipliers = { 8526 friend = 1.0, 8527 neutral = 3.0, 8528 }, 8529 goods = { 8530 luxury = { 8531 quantity = 5, 8532 cost = math.random(30,80), 8533 }, 8534 }, 8535 trade = { 8536 food = false, 8537 medicine = false, 8538 luxury = false, 8539 }, 8540 description = "Resupply", 8541 general = "Get your energy here! Grab a drink before you go!", 8542 history = "", 8543 }, 8544 ["Science-2"] = { 8545 weapon_available = { 8546 Homing = random(1,13)<=(8-difficulty), 8547 HVLI = random(1,13)<=(9-difficulty), 8548 Mine = random(1,13)<=(7-difficulty), 8549 Nuke = random(1,13)<=(5-difficulty), 8550 EMP = random(1,13)<=(6-difficulty), 8551 }, 8552 services = { 8553 supplydrop = "friend", 8554 reinforcements = "friend", 8555 jumpsupplydrop = "friend", 8556 }, 8557 service_cost = { 8558 supplydrop = math.random(80,120), 8559 reinforcements = math.random(125,175), 8560 jumpsupplydrop = math.random(110,140), 8561 }, 8562 goods = { 8563 circuit = { 8564 quantity = 5, 8565 cost = math.random(30,80), 8566 }, 8567 }, 8568 trade = { 8569 food = false, 8570 medicine = false, 8571 luxury = false, 8572 }, 8573 description = "Research Lab and Observatory", 8574 general = "", 8575 history = "", 8576 }, 8577 ["Science-4"] = { 8578 weapon_available = { 8579 Homing = random(1,13)<=(8-difficulty), 8580 HVLI = random(1,13)<=(9-difficulty), 8581 Mine = random(1,13)<=(7-difficulty), 8582 Nuke = random(1,13)<=(5-difficulty), 8583 EMP = random(1,13)<=(6-difficulty), 8584 }, 8585 services = { 8586 supplydrop = "friend", 8587 reinforcements = "friend", 8588 jumpsupplydrop = "friend", 8589 }, 8590 service_cost = { 8591 supplydrop = math.random(80,120), 8592 reinforcements = math.random(125,175), 8593 jumpsupplydrop = math.random(110,140), 8594 }, 8595 reputation_cost_multipliers = { 8596 friend = 1.0, 8597 neutral = 2.0, 8598 }, 8599 goods = { 8600 medicine = { 8601 quantity = 5, 8602 cost = math.random(30,80), 8603 }, 8604 autodoc = { 8605 quantity = 5, 8606 cost = math.random(30,80), 8607 }, 8608 }, 8609 trade = { 8610 food = false, 8611 medicine = false, 8612 luxury = false, 8613 }, 8614 description = "Biotech research", 8615 general = "", 8616 history = "", 8617 }, 8618 ["Science-7"] = { 8619 weapon_available = { 8620 Homing = random(1,13)<=(8-difficulty), 8621 HVLI = random(1,13)<=(9-difficulty), 8622 Mine = random(1,13)<=(7-difficulty), 8623 Nuke = random(1,13)<=(5-difficulty), 8624 EMP = random(1,13)<=(6-difficulty), 8625 }, 8626 services = { 8627 supplydrop = "friend", 8628 reinforcements = "friend", 8629 jumpsupplydrop = "friend", 8630 }, 8631 service_cost = { 8632 supplydrop = math.random(80,120), 8633 reinforcements = math.random(125,175), 8634 jumpsupplydrop = math.random(110,140), 8635 }, 8636 goods = { 8637 food = { 8638 quantity = 2, 8639 cost = 1, 8640 }, 8641 }, 8642 trade = { 8643 food = false, 8644 medicine = false, 8645 luxury = false, 8646 }, 8647 description = "Observatory", 8648 general = "", 8649 history = "", 8650 }, 8651 ["Spot"] = { 8652 weapon_available = { 8653 Homing = random(1,13)<=(8-difficulty), 8654 HVLI = random(1,13)<=(9-difficulty), 8655 Mine = random(1,13)<=(7-difficulty), 8656 Nuke = random(1,13)<=(5-difficulty), 8657 EMP = random(1,13)<=(6-difficulty), 8658 }, 8659 services = { 8660 supplydrop = "friend", 8661 reinforcements = "friend", 8662 jumpsupplydrop = "friend", 8663 }, 8664 service_cost = { 8665 supplydrop = math.random(80,120), 8666 reinforcements = math.random(125,175), 8667 jumpsupplydrop = math.random(110,140), 8668 }, 8669 reputation_cost_multipliers = { 8670 friend = 1.0, 8671 neutral = 3.0, 8672 }, 8673 goods = {}, 8674 trade = { 8675 food = false, 8676 medicine = false, 8677 luxury = false, 8678 }, 8679 description = "Observatory", 8680 general = "", 8681 history = "", 8682 }, 8683 ["Valero"] = { 8684 weapon_available = { 8685 Homing = random(1,13)<=(8-difficulty), 8686 HVLI = random(1,13)<=(9-difficulty), 8687 Mine = random(1,13)<=(7-difficulty), 8688 Nuke = random(1,13)<=(5-difficulty), 8689 EMP = random(1,13)<=(6-difficulty), 8690 }, 8691 services = { 8692 supplydrop = "friend", 8693 reinforcements = "friend", 8694 jumpsupplydrop = "friend", 8695 }, 8696 service_cost = { 8697 supplydrop = math.random(80,120), 8698 reinforcements = math.random(125,175), 8699 jumpsupplydrop = math.random(110,140), 8700 }, 8701 reputation_cost_multipliers = { 8702 friend = 1.0, 8703 neutral = 2.0, 8704 }, 8705 goods = { 8706 luxury = { 8707 quantity = 5, 8708 cost = math.random(30,80), 8709 }, 8710 }, 8711 trade = { 8712 food = false, 8713 medicine = false, 8714 luxury = false, 8715 }, 8716 description = "Resupply", 8717 general = "", 8718 history = "", 8719 }, 8720 }, 8721 ["Sinister"] = { 8722 ["Aramanth"] = {goods = {}, description = "", general = "", history = ""}, 8723 ["Empok Nor"] = {goods = {}, description = "", general = "", history = ""}, 8724 ["Gandala"] = {goods = {}, description = "", general = "", history = ""}, 8725 ["Hassenstadt"] = {goods = {}, description = "", general = "", history = ""}, 8726 ["Kaldor"] = {goods = {}, description = "", general = "", history = ""}, 8727 ["Magenta Mesra"] = {goods = {}, description = "", general = "", history = ""}, 8728 ["Mos Eisley"] = {goods = {}, description = "", general = "", history = ""}, 8729 ["Questa Verde"] = {goods = {}, description = "", general = "", history = ""}, 8730 ["R'lyeh"] = {goods = {}, description = "", general = "", history = ""}, 8731 ["Scarlet Citadel"] = {goods = {}, description = "", general = "", history = ""}, 8732 ["Stahlstadt"] = {goods = {}, description = "", general = "", history = ""}, 8733 ["Ticonderoga"] = {goods = {}, description = "", general = "", history = ""}, 8734 }, 8735 } 8736 station_priority = {} 8737 table.insert(station_priority,"Science") 8738 table.insert(station_priority,"Pop Sci Fi") 8739 table.insert(station_priority,"Spec Sci Fi") 8740 table.insert(station_priority,"History") 8741 table.insert(station_priority,"Generic") 8742 for group, list in pairs(station_pool) do 8743 local already_inserted = false 8744 for _, previous_group in ipairs(station_priority) do 8745 if group == previous_group then 8746 already_inserted = true 8747 break 8748 end 8749 end 8750 if not already_inserted and group ~= "Sinister" then 8751 table.insert(station_priority,group) 8752 end 8753 end 8754end 8755------------------------------ 8756-- Station communications -- 8757------------------------------ 8758function commsStation() 8759 if comms_target.comms_data == nil then 8760 comms_target.comms_data = {} 8761 end 8762 mergeTables(comms_target.comms_data, { 8763 friendlyness = random(0.0, 100.0), 8764 weapons = { 8765 Homing = "neutral", 8766 HVLI = "neutral", 8767 Mine = "neutral", 8768 Nuke = "friend", 8769 EMP = "friend", 8770 }, 8771 weapon_cost = { 8772 Homing = math.random(1,4), 8773 HVLI = math.random(1,3), 8774 Mine = math.random(2,5), 8775 Nuke = math.random(12,18), 8776 EMP = math.random(7,13), 8777 }, 8778 services = { 8779 supplydrop = "friend", 8780 reinforcements = "friend", 8781 sensor_boost = "neutral", 8782 preorder = "friend", 8783 activatedefensefleet = "neutral", 8784 }, 8785 service_cost = { 8786 supplydrop = math.random(80,120), 8787 reinforcements = math.random(125,175), 8788 phobosReinforcements = math.random(200,250), 8789 stalkerReinforcements = math.random(275,325), 8790 activatedefensefleet = 20, 8791 }, 8792 reputation_cost_multipliers = { 8793 friend = 1.0, 8794 neutral = 3.0, 8795 }, 8796 max_weapon_refill_amount = { 8797 friend = 1.0, 8798 neutral = 0.5, 8799 } 8800 }) 8801 comms_data = comms_target.comms_data 8802 if comms_source:isEnemy(comms_target) then 8803 return false 8804 end 8805-- if comms_target:areEnemiesInRange(5000) then 8806-- setCommsMessage("We are under attack! No time for chatting!"); 8807-- return true 8808-- end 8809 if not comms_source:isDocked(comms_target) then 8810 handleUndockedState() 8811 else 8812 handleDockedState() 8813 end 8814 return true 8815end 8816function commsDefensePlatform() 8817 if comms_target.comms_data == nil then 8818 comms_target.comms_data = {} 8819 end 8820 mergeTables(comms_target.comms_data, { 8821 friendlyness = random(0.0, 100.0), 8822 weapons = { 8823 Homing = "neutral", 8824 HVLI = "neutral", 8825 Mine = "neutral", 8826 Nuke = "friend", 8827 EMP = "friend" 8828 }, 8829 weapon_cost = { 8830 Homing = math.random(1,4), 8831 HVLI = math.random(1,3), 8832 Mine = math.random(2,5), 8833 Nuke = math.random(12,18), 8834 EMP = math.random(7,13) 8835 }, 8836 services = { 8837 supplydrop = "friend", 8838 reinforcements = "friend", 8839 }, 8840 service_cost = { 8841 supplydrop = math.random(80,120), 8842 reinforcements = math.random(125,175), 8843 phobosReinforcements = math.random(200,250), 8844 stalkerReinforcements = math.random(275,325) 8845 }, 8846 reputation_cost_multipliers = { 8847 friend = 1.0, 8848 neutral = 3.0 8849 }, 8850 max_weapon_refill_amount = { 8851 friend = 1.0, 8852 neutral = 0.5 8853 } 8854 }) 8855 comms_data = comms_target.comms_data 8856 if comms_source:isEnemy(comms_target) then 8857 return false 8858 end 8859 if comms_source:isDocked(comms_target) then 8860 -- handleDockedState() 8861 setCommsMessage(string.format("Hi %s",comms_source:getCallSign())) 8862 restockOrdnance(commsDefensePlatform) 8863 completionConditions(commsDefensePlatform) 8864 dockingServicesStatus(commsDefensePlatform) 8865 repairSubsystems(commsDefensePlatform) 8866 stationDefenseReport(commsDefensePlatform) 8867 if primary_jammers then 8868 if comms_source:isFriendly(comms_target) then 8869 addCommsReply(string.format("Transfer to %s",comms_target.primary_station:getCallSign()),function() 8870 comms_source:commandUndock() 8871 local psx, psy = comms_target.primary_station:getPosition() 8872 local angle = comms_source:getHeading() 8873 local station_dock_radius = { 8874 ["Small Station"] = 300, 8875 ["Medium Station"] = 1000, 8876 ["Large Station"] = 1300, 8877 ["Huge Station"] = 1500, 8878 } 8879 local dock_distance = station_dock_radius[comms_target.primary_station:getTypeName()] 8880 local vx, vy = vectorFromAngleNorth(angle,dock_distance) 8881 comms_source:setPosition(psx + vx, psy + vy) 8882 comms_source:commandDock(comms_target.primary_station) 8883 setCommsMessage(string.format("Don't let %s forget their friends on duty at %s",comms_target.primary_station:getCallSign(),comms_target:getCallSign())) 8884 end) 8885 end 8886 end 8887 else --undocked 8888 local dock_messages = { 8889 "Dock if you want anything", 8890 "You must dock before we can do anything", 8891 "Gotta dock first", 8892 "Can't do anything for you unless you dock", 8893 "Docking crew is standing by", 8894 "Dock first, then talk", 8895 } 8896 setCommsMessage(dock_messages[math.random(1,#dock_messages)]) 8897 ordnanceAvailability(commsDefensePlatform) 8898 completionConditions(commsDefensePlatform) 8899 dockingServicesStatus(commsDefensePlatform) 8900 stationDefenseReport(commsDefensePlatform) 8901 end 8902 return true 8903end 8904function handleDockedState() 8905 if comms_source:isFriendly(comms_target) then 8906 oMsg = "Good day, officer!\nWhat can we do for you today?" 8907 else 8908 oMsg = "Welcome to our lovely station." 8909 end 8910 if comms_target:areEnemiesInRange(20000) then 8911 oMsg = oMsg .. "\nForgive us if we seem a little distracted. We are carefully monitoring the enemies nearby." 8912 end 8913 setCommsMessage(oMsg) 8914 restockOrdnance(commsStation) 8915 completionConditions(commsStation) 8916 dockingServicesStatus(commsStation) 8917 repairSubsystems(commsStation) 8918 boostSensorsWhileDocked(commsStation) 8919 overchargeJump(commsStation) 8920 activateDefenseFleet(commsStation) 8921 for _, scientist in ipairs(scientist_list[comms_target:getFaction()]) do 8922 if scientist.location == comms_target then 8923 addCommsReply(string.format("Speak with scientist %s",scientist.name),function() 8924 setCommsMessage(string.format("Greetings, %s\nI've got great ideas for the war effort.\nWhat can I do for you?",comms_source:getCallSign())) 8925 addCommsReply("Please come aboard our ship",function() 8926 setCommsMessage(string.format("Certainly, %s\n\n%s boards your ship",comms_source:getCallSign(),scientist.name)) 8927 scientist.location = comms_source 8928 scientist.location_name = comms_source:getCallSign() 8929 addCommsReply("Back", commsStation) 8930 end) 8931 addCommsReply("Can you tell me some more about your ideas?",function() 8932 local rc = false 8933 local msg = "" 8934 local completed_message = "" 8935 local npc_message = "" 8936 setCommsMessage(string.format("I'd need to visit %s to proceed further",faction_primary_station[comms_target:getFaction()].station:getCallSign())) 8937 if string.find(scientist.upgrade_requirement,"talk") or string.find(scientist.upgrade_requirement,"meet") then 8938 if string.find(scientist.upgrade_requirement,"primary") then 8939 if faction_primary_station[comms_target:getFaction()].station ~= nil and faction_primary_station[comms_target:getFaction()].station:isValid() then 8940 if faction_primary_station[comms_target:getFaction()].station.available_upgrades == nil then 8941 faction_primary_station[comms_target:getFaction()].station.available_upgrades = {} 8942 end 8943 faction_primary_station[comms_target:getFaction()].station.available_upgrades[scientist.upgrade.name] = scientist.upgrade.action 8944 setCommsMessage(string.format("I just sent details on a %s to %s. With their facilities, you should be able to apply the upgrade the next time you dock there.",scientist.upgrade.name,faction_primary_station[comms_target:getFaction()].station:getCallSign())) 8945 else 8946 setCommsMessage("Without your primary station to apply my research, I'm afraid my information is useless") 8947 end 8948 else 8949 rc, msg = scientist.upgrade.action(comms_source) 8950 if rc then 8951 completed_message = string.format("After an extended conversation with %s and the exchange of technical information with various crew members, you apply the insight into %s gained by %s.\n\n%s",scientist.name,scientist.topic,scientist.name,msg) 8952 if scientist.upgrade_automated_application == "single" then 8953 setCommsMessage(completed_message) 8954 elseif scientist.upgrade_automated_application == "players" then 8955 for pidx=1,32 do 8956 local p = getPlayerShip(pidx) 8957 if p ~= nil and p:isValid() and p ~= comms_source and p:getFaction() == comms_source:getFaction() then 8958 rc, msg = scientist.upgrade.action(p) 8959 if rc then 8960 p:addToShipLog(string.format("%s provided details from %s for an upgrade. %s",comms_source:getCallSign(),scientist.name,msg),"Magenta") 8961 end 8962 end 8963 end 8964 setCommsMessage(completed_message .. "\nThe upgrade details were also provided to the other players in your faction.") 8965 elseif scientist.upgrade_automated_application == "all" then 8966 if scientist.upgrade.action ~= longerSensorsUpgrade and scientist.upgrade.action ~= batteryEfficiencyUpgrade then 8967 if npc_fleet ~= nil and npc_fleet[comms_source:getFaction()] ~= nil and #npc_fleet[comms_source:getFaction()] > 0 then 8968 for i=1,#npc_fleet[comms_source:getFaction()] do 8969 local npc = npc_fleet[comms_source:getFaction()][i] 8970 if npc ~= nil and npc:isValid() then 8971 rc, msg = scientist.upgrade.action(npc) 8972 end 8973 end 8974 npc_message = "and npc ships " 8975 end 8976 end 8977 for pidx=1,32 do 8978 local p = getPlayerShip(pidx) 8979 if p ~= nil and p:isValid() and p ~= comms_source and p:getFaction() == comms_source:getFaction() then 8980 rc, msg = scientist.upgrade.action(p) 8981 if rc then 8982 p:addToShipLog(string.format("%s provided details from %s for an upgrade. %s",comms_source:getCallSign(),scientist.name,msg),"Magenta") 8983 end 8984 end 8985 end 8986 setCommsMessage(string.format("%s\nThe upgrade details were also provided to the other players %sin your faction.",completed_message,npc_message)) 8987 end 8988 else 8989 setCommsMessage(string.format("Your conversation with %s about %s was interesting, but not directly applicable.\n\n%s",scientist.name,scientist.topic,msg)) 8990 end 8991 end 8992 elseif scientist.upgrade_requirement == "transport" then 8993 if comms_target == faction_primary_station[comms_target:getFaction()].station then 8994 rc, msg = scientist.upgrade.action(comms_source) 8995 if rc then 8996 completed_message = string.format("After an extended conversation with %s, various crew members and %s facilities managers, you apply the insight into %s gained by %s.\n\n%s",scientist.name,comms_target:getCallSign(),scientist.topic,scientist.name,msg) 8997 if faction_primary_station[comms_target:getFaction()].station.available_upgrades == nil then 8998 faction_primary_station[comms_target:getFaction()].station.available_upgrades = {} 8999 end 9000 faction_primary_station[comms_target:getFaction()].station.available_upgrades[scientist.upgrade.name] = scientist.upgrade.action 9001 setCommsMessage(completed_message) 9002 if scientist.upgrade_automated_application == "all" then 9003 if scientist.upgrade.action ~= longerSensorsUpgrade and scientist.upgrade.action ~= batteryEfficiencyUpgrade then 9004 if npc_fleet ~= nil and npc_fleet[comms_source:getFaction()] ~= nil and #npc_fleet[comms_source:getFaction()] > 0 then 9005 for i=1,#npc_fleet[comms_source:getFaction()] do 9006 local npc = npc_fleet[comms_source:getFaction()][i] 9007 if npc ~= nil and npc:isValid() then 9008 rc, msg = scientist.upgrade.action(npc) 9009 end 9010 end 9011 npc_message = "and npc ships " 9012 end 9013 end 9014 setCommsMessage(string.format("%s\nNPC ships received the upgrade as well",completed_message)) 9015 end 9016 else 9017 setCommsMessage(string.format("Your conversation with %s about %s was interesting, but not directly applicable.\n\n%s",scientist.name,scientist.topic,msg)) 9018 if faction_primary_station[comms_target:getFaction()].station.available_upgrades == nil then 9019 faction_primary_station[comms_target:getFaction()].station.available_upgrades = {} 9020 end 9021 faction_primary_station[comms_target:getFaction()].station.available_upgrades[scientist.upgrade.name] = scientist.upgrade.action 9022 end 9023 end 9024 elseif scientist.upgrade_requirement == "confer" then 9025 if comms_target == faction_primary_station[comms_target:getFaction()].station then 9026 local colleage_count = 0 9027 local conferee = nil 9028 for _, colleague in ipairs(scientist_list[comms_target:getFaction()]) do 9029 if colleague.location == comms_target and colleague ~= scientist then 9030 colleage_count = colleage_count + 1 9031 conferee = colleague 9032 end 9033 end 9034 if colleage_count > 0 then 9035 rc, msg = scientist.upgrade.action(comms_source) 9036 if rc then 9037 completed_message = string.format("After an extended conversation with %s, %s, various crew members and %s facilities managers, you apply the insight into %s and %s gained by %s.\n\n%s",scientist.name,conferee.name,comms_target:getCallSign(),scientist.topic,conferee.topic,scientist.name,msg) 9038 if faction_primary_station[comms_target:getFaction()].station.available_upgrades == nil then 9039 faction_primary_station[comms_target:getFaction()].station.available_upgrades = {} 9040 end 9041 faction_primary_station[comms_target:getFaction()].station.available_upgrades[scientist.upgrade.name] = scientist.upgrade.action 9042 if scientist.upgrade_automated_application == "single" then 9043 setCommsMessage(completed_message) 9044 elseif scientist.upgrade_automated_application == "players" then 9045 for pidx=1,32 do 9046 local p = getPlayerShip(pidx) 9047 if p ~= nil and p:isValid() and p ~= comms_source and p:getFaction() == comms_source:getFaction() then 9048 rc, msg = scientist.upgrade.action(p) 9049 if rc then 9050 p:addToShipLog(string.format("%s provided details from %s for an upgrade. %s",comms_source:getCallSign(),scientist.name,msg),"Magenta") 9051 end 9052 end 9053 end 9054 setCommsMessage(completed_message .. "\nThe upgrade details were also provided to the other players in your faction.") 9055 elseif scientist.upgrade_automated_application == "all" then 9056 if scientist.upgrade.action ~= longerSensorsUpgrade and scientist.upgrade.action ~= batteryEfficiencyUpgrade then 9057 if npc_fleet ~= nil and npc_fleet[comms_source:getFaction()] ~= nil and #npc_fleet[comms_source:getFaction()] > 0 then 9058 for i=1,#npc_fleet[comms_source:getFaction()] do 9059 local npc = npc_fleet[comms_source:getFaction()][i] 9060 if npc ~= nil and npc:isValid() then 9061 rc, msg = scientist.upgrade.action(npc) 9062 end 9063 end 9064 npc_message = "and npc ships " 9065 end 9066 end 9067 for pidx=1,32 do 9068 local p = getPlayerShip(pidx) 9069 if p ~= nil and p:isValid() and p ~= comms_source and p:getFaction() == comms_source:getFaction() then 9070 rc, msg = scientist.upgrade.action(p) 9071 if rc then 9072 p:addToShipLog(string.format("%s provided details from %s for an upgrade. %s",comms_source:getCallSign(),scientist.name,msg),"Magenta") 9073 end 9074 end 9075 end 9076 setCommsMessage(string.format("%s\nThe upgrade details were also provided to the other players %sin your faction.",completed_message,npc_message)) 9077 end 9078 else 9079 setCommsMessage(string.format("Your conversation with %s and %s about %s and %s was interesting, but not directly applicable.\n\n%s",scientist.name,conferee.name,scientist.topic,conferee.topic,msg)) 9080 if faction_primary_station[comms_target:getFaction()].station.available_upgrades == nil then 9081 faction_primary_station[comms_target:getFaction()].station.available_upgrades = {} 9082 end 9083 faction_primary_station[comms_target:getFaction()].station.available_upgrades[scientist.upgrade.name] = scientist.upgrade.action 9084 end 9085 else 9086 setCommsMessage(string.format("I've got this idea for a %s, but I just can't quite get it to crystalize. If I had another scientist here to collaborate with, I might get further along",scientist.upgrade.name)) 9087 end 9088 end 9089 end 9090 end) 9091 addCommsReply("Back", commsStation) 9092 end) 9093 end 9094 if scientist.location == comms_source then 9095 addCommsReply(string.format("Escort %s on to %s",scientist.name,comms_target:getCallSign()),function() 9096 setCommsMessage(string.format("%s thanks you for your hospitality and disembarks to %s",scientist.name,comms_target:getCallSign())) 9097 scientist.location = comms_target 9098 scientist.location_name = comms_target:getCallSign() 9099 addCommsReply("Back", commsStation) 9100 end) 9101 end 9102 end 9103 if comms_target.available_upgrades ~= nil then 9104 for name, action in pairs(comms_target.available_upgrades) do 9105 addCommsReply(name,function() 9106 string.format("") --Serious Proton needs global reference/context 9107 local rc, msg = action(comms_source) 9108 if rc then 9109 setCommsMessage(string.format("Congratulations!\n%s",msg)) 9110 else 9111 setCommsMessage(string.format("Sorry.\n%s",msg)) 9112 end 9113 end) 9114 end 9115 end 9116 stationFlavorInformation(commsStation) 9117 if comms_source:isFriendly(comms_target) then 9118 if random(1,100) <= (20 - difficulty*2) then 9119 if comms_source:getRepairCrewCount() < comms_source.maxRepairCrew then 9120 hireCost = math.random(30,60) 9121 else 9122 hireCost = math.random(45,90) 9123 end 9124 addCommsReply(string.format("Recruit repair crew member for %i reputation",hireCost), function() 9125 if not comms_source:takeReputationPoints(hireCost) then 9126 setCommsMessage("Insufficient reputation") 9127 else 9128 comms_source:setRepairCrewCount(comms_source:getRepairCrewCount() + 1) 9129 resetPreviousSystemHealth(comms_source) 9130 setCommsMessage("Repair crew member hired") 9131 end 9132 addCommsReply("Back", commsStation) 9133 end) 9134 end 9135 if comms_source.initialCoolant ~= nil then 9136 if math.random(1,100) <= (20 - difficulty*2) then 9137 local coolantCost = math.random(45,90) 9138 if comms_source:getMaxCoolant() < comms_source.initialCoolant then 9139 coolantCost = math.random(30,60) 9140 end 9141 addCommsReply(string.format("Purchase coolant for %i reputation",coolantCost), function() 9142 if not comms_source:takeReputationPoints(coolantCost) then 9143 setCommsMessage("Insufficient reputation") 9144 else 9145 comms_source:setMaxCoolant(comms_source:getMaxCoolant() + 2) 9146 setCommsMessage("Additional coolant purchased") 9147 end 9148 addCommsReply("Back", commsStation) 9149 end) 9150 end 9151 end 9152 end 9153 if primary_jammers then 9154 if comms_source:isFriendly(comms_target) then 9155 if defense_platform_count > 0 and comms_target == faction_primary_station[comms_source:getFaction()].station then 9156 addCommsReply("Exit Jammer",function() 9157 comms_source:commandUndock() 9158 local psx, psy = comms_target:getPosition() 9159 local angle = (faction_angle[comms_source:getFaction()] + 180) % 360 9160 local vx, vy = vectorFromAngleNorth(angle,defense_platform_distance + 4000) 9161 comms_source:setPosition(psx + vx, psy + vy):setHeading(angle):commandTargetRotation((angle + 270) % 360) 9162 setCommsMessage("Have fun storming the castle") 9163 end) 9164 end 9165 end 9166 end 9167 buySellTrade(commsStation) 9168end --end of handleDockedState function 9169function handleUndockedState() 9170 --Handle communications when we are not docked with the station. 9171 if comms_source:isFriendly(comms_target) then 9172 oMsg = "Good day, officer.\nIf you need supplies, please dock with us first." 9173 else 9174 oMsg = "Greetings.\nIf you want to do business, please dock with us first." 9175 end 9176 if comms_target:areEnemiesInRange(20000) then 9177 oMsg = oMsg .. "\nBe aware that if enemies in the area get much closer, we will be too busy to conduct business with you." 9178 end 9179 setCommsMessage(oMsg) 9180-- expediteDock(commsStation) --may reinstate if time permits. Needs code in update function, player loop 9181 addCommsReply("I need information", function() 9182 setCommsMessage("What kind of information do you need?") 9183 ordnanceAvailability(commsStation) 9184 goodsAvailabilityOnStation(commsStation) 9185 completionConditions(commsStation) 9186 dockingServicesStatus(commsStation) 9187 stationFlavorInformation(commsStation) 9188 stationDefenseReport(commsStation) 9189 end) 9190 requestSupplyDrop(commsStation) 9191 requestJumpSupplyDrop(commsStation) 9192 requestReinforcements(commsStation) 9193 for _, scientist in ipairs(scientist_list[comms_target:getFaction()]) do 9194 if scientist.location == comms_target then 9195 addCommsReply(string.format("Speak with scientist %s",scientist.name),function() 9196 setCommsMessage(string.format("Greetings, %s\nI've got great ideas for the war effort.\nWhat can I do for you?",comms_source:getCallSign())) 9197 addCommsReply("Can you tell me some more about your ideas?",function() 9198 local rc = false 9199 local msg = "" 9200 local completed_message = "" 9201 local npc_message = "" 9202 if string.find(scientist.upgrade_requirement,"talk") then 9203 if string.find(scientist.upgrade_requirement,"primary") then 9204 if faction_primary_station[comms_target:getFaction()].station ~= nil and faction_primary_station[comms_target:getFaction()].station:isValid() then 9205 if faction_primary_station[comms_target:getFaction()].station.available_upgrades == nil then 9206 faction_primary_station[comms_target:getFaction()].station.available_upgrades = {} 9207 end 9208 faction_primary_station[comms_target:getFaction()].station.available_upgrades[scientist.upgrade.name] = scientist.upgrade.action 9209 setCommsMessage(string.format("I just sent details on a %s to %s. With their facilities, you should be able to apply the upgrade the next time you dock there.",scientist.upgrade.name,faction_primary_station[comms_target:getFaction()].station:getCallSign())) 9210 else 9211 setCommsMessage("Without your primary station to apply my research, I'm afraid my information is useless") 9212 end 9213 else 9214 local rc, msg = scientist.upgrade.action(comms_source) 9215 if rc then 9216 completed_message = string.format("After an extended conversation with %s and the exchange of technical information with various crew members, you apply the insight into %s gained by %s.\n\n%s",scientist.name,scientist.topic,scientist.name,msg) 9217 if scientist.upgrade_automated_application == "single" then 9218 setCommsMessage(completed_message) 9219 elseif scientist.upgrade_automated_application == "players" then 9220 for pidx=1,32 do 9221 local p = getPlayerShip(pidx) 9222 if p ~= nil and p:isValid() and p ~= comms_source and p:getFaction() == comms_source:getFaction() then 9223 rc, msg = scientist.upgrade.action(p) 9224 if rc then 9225 p:addToShipLog(string.format("%s provided details from %s for an upgrade. %s",comms_source:getCallSign(),scientist.name,msg),"Magenta") 9226 end 9227 end 9228 end 9229 setCommsMessage(completed_message .. "\nThe upgrade details were also provided to the other players in your faction.") 9230 elseif scientist.upgrade_automated_application == "all" then 9231 if scientist.upgrade.action ~= longerSensorsUpgrade and scientist.upgrade.action ~= batteryEfficiencyUpgrade then 9232 if npc_fleet ~= nil and npc_fleet[comms_source:getFaction()] ~= nil and #npc_fleet[comms_source:getFaction()] > 0 then 9233 for i=1,#npc_fleet[comms_source:getFaction()] do 9234 local npc = npc_fleet[comms_source:getFaction()][i] 9235 if npc ~= nil and npc:isValid() then 9236 rc, msg = scientist.upgrade.action(npc) 9237 end 9238 end 9239 npc_message = "and npc ships " 9240 end 9241 end 9242 for pidx=1,32 do 9243 local p = getPlayerShip(pidx) 9244 if p ~= nil and p:isValid() and p ~= comms_source and p:getFaction() == comms_source:getFaction() then 9245 rc, msg = scientist.upgrade.action(p) 9246 if rc then 9247 p:addToShipLog(string.format("%s provided details from %s for an upgrade. %s",comms_source:getCallSign(),scientist.name,msg),"Magenta") 9248 end 9249 end 9250 end 9251 setCommsMessage(string.format("%s\nThe upgrade details were also provided to the other players %sin your faction.",completed_message,npc_message)) 9252 end 9253 else 9254 setCommsMessage(string.format("Your conversation with %s about %s was interesting, but not directly applicable.\n\n%s",scientist.name,scientist.topic,msg)) 9255 end 9256 local overhear_chance = 16 9257 if scientist.upgrade_automated_application == "players" then 9258 overhear_chance = 28 9259 end 9260 if scientist.upgrade_automated_application == "all" then 9261 overhear_chance = 39 9262 end 9263 if random(1,100) <= overhear_chance then 9264 for pidx=1,32 do 9265 local p = getPlayerShip(pidx) 9266 if p ~= nil and p:isValid() then 9267 if p:getFaction() == comms_source:getFaction() then 9268 p:addToShipLog(string.format("Communication between %s and %s intercepted by enemy faction",comms_source:getCallSign(),comms_target:getCallSign()),"Magenta") 9269 else 9270 p:addToShipLog(string.format("%s conversation intercepted regarding %s. Probable military application. Suggest you contact our own scientist in the same field",comms_source:getFaction(),scientist.topic),"Magenta") 9271 end 9272 end 9273 end 9274 end 9275 end 9276 else 9277 setCommsMessage("I should not discuss it over an open communication line. Perhaps you should visit and we can talk") 9278 end 9279 end) 9280 addCommsReply("Back", commsStation) 9281 end) 9282 end 9283 end 9284 if isAllowedTo(comms_target.comms_data.services.activatedefensefleet) and 9285 comms_target.comms_data.idle_defense_fleet ~= nil then 9286 local defense_fleet_count = 0 9287 for name, template in pairs(comms_target.comms_data.idle_defense_fleet) do 9288 defense_fleet_count = defense_fleet_count + 1 9289 end 9290 if defense_fleet_count > 0 then 9291 addCommsReply("Activate station defense fleet (" .. getServiceCost("activatedefensefleet") .. " rep)",function() 9292 if comms_source:takeReputationPoints(getServiceCost("activatedefensefleet")) then 9293 local out = string.format("%s defense fleet\n",comms_target:getCallSign()) 9294 for name, template in pairs(comms_target.comms_data.idle_defense_fleet) do 9295 local script = Script() 9296 local position_x, position_y = comms_target:getPosition() 9297 local station_name = comms_target:getCallSign() 9298 script:setVariable("position_x", position_x):setVariable("position_y", position_y) 9299 script:setVariable("station_name",station_name) 9300 script:setVariable("name",name) 9301 script:setVariable("template",template) 9302 script:setVariable("faction_id",comms_target:getFactionId()) 9303 script:run("border_defend_station.lua") 9304 out = out .. " " .. name 9305 comms_target.comms_data.idle_defense_fleet[name] = nil 9306 end 9307 out = out .. "\nactivated" 9308 setCommsMessage(out) 9309 else 9310 setCommsMessage("Insufficient reputation") 9311 end 9312 addCommsReply("Back", mainMenu) 9313 end) 9314 end 9315 end 9316end 9317function isAllowedTo(state) 9318 if state == "friend" and comms_source:isFriendly(comms_target) then 9319 return true 9320 end 9321 if state == "neutral" and not comms_source:isEnemy(comms_target) then 9322 return true 9323 end 9324 return false 9325end 9326function getWeaponCost(weapon) 9327 return math.ceil(comms_data.weapon_cost[weapon] * comms_data.reputation_cost_multipliers[getFriendStatus()]) 9328end 9329function getFriendStatus() 9330 if comms_source:isFriendly(comms_target) then 9331 return "friend" 9332 else 9333 return "neutral" 9334 end 9335end 9336function dockingServicesStatus(return_function) 9337 addCommsReply("Docking services status", function() 9338 local service_status = string.format("Station %s docking services status:",comms_target:getCallSign()) 9339 if comms_target:getRestocksScanProbes() then 9340 service_status = string.format("%s\nReplenish scan probes.",service_status) 9341 else 9342 if comms_target.probe_fail_reason == nil then 9343 local reason_list = { 9344 "Cannot replenish scan probes due to fabrication unit failure.", 9345 "Parts shortage prevents scan probe replenishment.", 9346 "Management has curtailed scan probe replenishment for cost cutting reasons.", 9347 } 9348 comms_target.probe_fail_reason = reason_list[math.random(1,#reason_list)] 9349 end 9350 service_status = string.format("%s\n%s",service_status,comms_target.probe_fail_reason) 9351 end 9352 if comms_target:getRepairDocked() then 9353 service_status = string.format("%s\nShip hull repair.",service_status) 9354 else 9355 if comms_target.repair_fail_reason == nil then 9356 reason_list = { 9357 "We're out of the necessary materials and supplies for hull repair.", 9358 "Hull repair automation unavailable while it is undergoing maintenance.", 9359 "All hull repair technicians quarantined to quarters due to illness.", 9360 } 9361 comms_target.repair_fail_reason = reason_list[math.random(1,#reason_list)] 9362 end 9363 service_status = string.format("%s\n%s",service_status,comms_target.repair_fail_reason) 9364 end 9365 if comms_target:getSharesEnergyWithDocked() then 9366 service_status = string.format("%s\nRecharge ship energy stores.",service_status) 9367 else 9368 if comms_target.energy_fail_reason == nil then 9369 reason_list = { 9370 "A recent reactor failure has put us on auxiliary power, so we cannot recharge ships.", 9371 "A damaged power coupling makes it too dangerous to recharge ships.", 9372 "An asteroid strike damaged our solar cells and we are short on power, so we can't recharge ships right now.", 9373 } 9374 comms_target.energy_fail_reason = reason_list[math.random(1,#reason_list)] 9375 end 9376 service_status = string.format("%s\n%s",service_status,comms_target.energy_fail_reason) 9377 end 9378 if comms_target.comms_data.jump_overcharge then 9379 service_status = string.format("%s\nMay overcharge jump drive",service_status) 9380 end 9381 if comms_target.comms_data.probe_launch_repair then 9382 service_status = string.format("%s\nMay repair probe launch system",service_status) 9383 end 9384 if comms_target.comms_data.hack_repair then 9385 service_status = string.format("%s\nMay repair hacking system",service_status) 9386 end 9387 if comms_target.comms_data.scan_repair then 9388 service_status = string.format("%s\nMay repair scanners",service_status) 9389 end 9390 if comms_target.comms_data.combat_maneuver_repair then 9391 service_status = string.format("%s\nMay repair combat maneuver",service_status) 9392 end 9393 if comms_target.comms_data.self_destruct_repair then 9394 service_status = string.format("%s\nMay repair self destruct system",service_status) 9395 end 9396 if comms_target.comms_data.tube_slow_down_repair then 9397 service_status = string.format("%s\nMay repair slow loading tubes",service_status) 9398 end 9399 setCommsMessage(service_status) 9400 addCommsReply("Back", return_function) 9401 end) 9402end 9403function stationFlavorInformation(return_function) 9404 if (comms_target.comms_data.general ~= nil and comms_target.comms_data.general ~= "") or (comms_target.comms_data.history ~= nil and comms_target.comms_data.history ~= "") then 9405 addCommsReply("Tell me more about your station", function() 9406 setCommsMessage("What would you like to know?") 9407 if comms_target.comms_data.general ~= nil and comms_target.comms_data.general ~= "" then 9408 addCommsReply("General information", function() 9409 setCommsMessage(comms_target.comms_data.general) 9410 addCommsReply("Back", return_function) 9411 end) 9412 end 9413 if comms_target.comms_data.history ~= nil and comms_target.comms_data.history ~= "" then 9414 addCommsReply("Station history", function() 9415 setCommsMessage(comms_target.comms_data.history) 9416 addCommsReply("Back", return_function) 9417 end) 9418 end 9419 end) 9420 end 9421end 9422function stationDefenseReport(return_function) 9423 addCommsReply("Report status", function() 9424 msg = "Hull: " .. math.floor(comms_target:getHull() / comms_target:getHullMax() * 100) .. "%\n" 9425 local shields = comms_target:getShieldCount() 9426 if shields == 1 then 9427 msg = msg .. "Shield: " .. math.floor(comms_target:getShieldLevel(0) / comms_target:getShieldMax(0) * 100) .. "%\n" 9428 else 9429 for n=0,shields-1 do 9430 msg = msg .. "Shield " .. n .. ": " .. math.floor(comms_target:getShieldLevel(n) / comms_target:getShieldMax(n) * 100) .. "%\n" 9431 end 9432 end 9433 setCommsMessage(msg); 9434 addCommsReply("Back", return_function) 9435 end) 9436end 9437function completionConditions(return_function) 9438 addCommsReply("What ends the war?",function() 9439 local out = string.format("The war ends in one of three ways:\n1) Time runs out\n2) A faction drops below half of original score\n3) A faction either leads or trails the other factions by %i%%\n",thresh*100) 9440 local stat_list = gatherStats() 9441 out = out .. string.format("\nHuman Navy Current:%.1f Original:%.1f (%.2f%%)",stat_list.human.weighted_score,original_score["Human Navy"],(stat_list.human.weighted_score/original_score["Human Navy"])*100) 9442 out = out .. string.format("\nKraylor Current:%.1f Original:%.1f (%.2f%%)",stat_list.kraylor.weighted_score,original_score["Kraylor"],(stat_list.kraylor.weighted_score/original_score["Kraylor"])*100) 9443 if exuari_angle ~= nil then 9444 out = out .. string.format("\nExuari Current:%.1f Original:%.1f (%.2f%%)",stat_list.exuari.weighted_score,original_score["Exuari"],(stat_list.exuari.weighted_score/original_score["Exuari"])*100) 9445 end 9446 if ktlitan_angle ~= nil then 9447 out = out .. string.format("\nKtlitan Current:%.1f Original:%.1f (%.2f%%)",stat_list.ktlitan.weighted_score,original_score["Ktlitans"],(stat_list.ktlitan.weighted_score/original_score["Ktlitans"])*100) 9448 end 9449 out = out .. string.format("\n\nStation weight:%i%% Player ship weight:%i%% NPC weight:%i%%",stat_list.weight.station*100,stat_list.weight.ship*100,stat_list.weight.npc*100) 9450 setCommsMessage(out) 9451 addCommsReply(string.format("Station values (Total:%i)",stat_list[f2s[comms_source:getFaction()]].station_score_total),function() 9452 local out = "Stations: (value, type, name)" 9453 for name, details in pairs(stat_list[f2s[comms_source:getFaction()]].station) do 9454 out = out .. string.format("\n %i, %s, %s",details.score_value,details.template_type,name) 9455 end 9456 out = out .. string.format("\nTotal:%i multiplied by weight (%i%%) = weighted total:%.1f",stat_list[f2s[comms_source:getFaction()]].station_score_total,stat_list.weight.station*100,stat_list[f2s[comms_source:getFaction()]].station_score_total*stat_list.weight.station) 9457 setCommsMessage(out) 9458 addCommsReply("Back", return_function) 9459 end) 9460 addCommsReply(string.format("Player ship values (Total:%i)",stat_list[f2s[comms_source:getFaction()]].ship_score_total),function() 9461 local out = "Player ships: (value, type, name)" 9462 for name, details in pairs(stat_list[f2s[comms_source:getFaction()]].ship) do 9463 out = out .. string.format("\n %i, %s, %s",details.score_value,details.template_type,name) 9464 end 9465 out = out .. string.format("\nTotal:%i multiplied by weight (%i%%) = weighted total:%.1f",stat_list[f2s[comms_source:getFaction()]].ship_score_total,stat_list.weight.ship*100,stat_list[f2s[comms_source:getFaction()]].ship_score_total*stat_list.weight.ship) 9466 setCommsMessage(out) 9467 addCommsReply("Back", return_function) 9468 end) 9469 addCommsReply(string.format("NPC ship values (Total:%i)",stat_list[f2s[comms_source:getFaction()]].npc_score_total),function() 9470 local out = "NPC assets: value, type, name (location)" 9471 for name, details in pairs(stat_list[f2s[comms_source:getFaction()]].npc) do 9472 if details.template_type ~= nil then 9473 out = out .. string.format("\n %i, %s, %s",details.score_value,details.template_type,name) 9474 elseif details.topic ~= nil then 9475 out = out .. string.format("\n %i, %s, %s (%s)",details.score_value,details.topic,name,details.location_name) 9476 end 9477 end 9478 out = out .. string.format("\nTotal:%i multiplied by weight (%i%%) = weighted total:%.1f",stat_list[f2s[comms_source:getFaction()]].npc_score_total,stat_list.weight.npc*100,stat_list[f2s[comms_source:getFaction()]].npc_score_total*stat_list.weight.npc) 9479 setCommsMessage(out) 9480 addCommsReply("Back", return_function) 9481 end) 9482 addCommsReply("Back", return_function) 9483 end) 9484end 9485-- Undocked actions 9486function getServiceCost(service) 9487 return math.ceil(comms_data.service_cost[service]) 9488end 9489function requestSupplyDrop(return_function) 9490 if isAllowedTo(comms_target.comms_data.services.supplydrop) then 9491 addCommsReply("Can you send a supply drop? ("..getServiceCost("supplydrop").."rep)", function() 9492 if comms_source:getWaypointCount() < 1 then 9493 setCommsMessage("You need to set a waypoint before you can request backup."); 9494 else 9495 setCommsMessage("To which waypoint should we deliver your supplies?"); 9496 for n=1,comms_source:getWaypointCount() do 9497 addCommsReply("WP" .. n, function() 9498 if comms_source:takeReputationPoints(getServiceCost("supplydrop")) then 9499 local position_x, position_y = comms_target:getPosition() 9500 local target_x, target_y = comms_source:getWaypoint(n) 9501 local script = Script() 9502 script:setVariable("position_x", position_x):setVariable("position_y", position_y) 9503 script:setVariable("target_x", target_x):setVariable("target_y", target_y) 9504 script:setVariable("faction_id", comms_target:getFactionId()):run("supply_drop.lua") 9505 setCommsMessage("We have dispatched a supply ship toward WP" .. n); 9506 else 9507 setCommsMessage("Not enough reputation!"); 9508 end 9509 addCommsReply("Back", return_function) 9510 end) 9511 end 9512 end 9513 addCommsReply("Back", return_function) 9514 end) 9515 end 9516end 9517function requestJumpSupplyDrop(return_function) 9518 if isAllowedTo(comms_target.comms_data.services.jumpsupplydrop) then 9519 addCommsReply("Can you send a supply drop via jump ship? ("..getServiceCost("jumpsupplydrop").."rep)", function() 9520 if comms_source:getWaypointCount() < 1 then 9521 setCommsMessage("You need to set a waypoint before you can request backup."); 9522 else 9523 setCommsMessage("To which waypoint should we deliver your supplies?"); 9524 for n=1,comms_source:getWaypointCount() do 9525 addCommsReply("WP" .. n, function() 9526 if comms_source:takeReputationPoints(getServiceCost("jumpsupplydrop")) then 9527 local position_x, position_y = comms_target:getPosition() 9528 local target_x, target_y = comms_source:getWaypoint(n) 9529 local script = Script() 9530 script:setVariable("position_x", position_x):setVariable("position_y", position_y) 9531 script:setVariable("target_x", target_x):setVariable("target_y", target_y) 9532 script:setVariable("jump_freighter","Yes") 9533 script:setVariable("faction_id", comms_target:getFactionId()):run("supply_drop.lua") 9534 setCommsMessage("We have dispatched a supply ship with a jump drive toward WP" .. n); 9535 else 9536 setCommsMessage("Not enough reputation!"); 9537 end 9538 addCommsReply("Back", return_function) 9539 end) 9540 end 9541 end 9542 addCommsReply("Back", return_function) 9543 end) 9544 end 9545end 9546function requestReinforcements(return_function) 9547 if isAllowedTo(comms_target.comms_data.services.reinforcements) then 9548 addCommsReply("Please send reinforcements",function() 9549 if comms_source:getWaypointCount() < 1 then 9550 setCommsMessage("You need to set a waypoint before you can request reinforcements") 9551 else 9552 setCommsMessage("What kind of reinforcements would you like?") 9553 addCommsReply(string.format("Standard Adder MK5 (%i Rep)",getServiceCost("reinforcements")),function() 9554 if comms_source:getWaypointCount() < 1 then 9555 setCommsMessage("You need to set a waypoint before you can request reinforcements") 9556 else 9557 setCommsMessage("To which waypoint should we dispatch the Adder MK5?"); 9558 for n=1,comms_source:getWaypointCount() do 9559 addCommsReply("Waypoint " .. n, function() 9560 if comms_source:takeReputationPoints(getServiceCost("reinforcements")) then 9561 ship = CpuShip():setFactionId(comms_target:getFactionId()):setPosition(comms_target:getPosition()):setTemplate("Adder MK5"):setScanned(true):orderDefendLocation(comms_source:getWaypoint(n)) 9562 ship:setCommsScript(""):setCommsFunction(commsShip) 9563 ship.score_value = ship_template["Adder MK5"].strength 9564 table.insert(npc_fleet[comms_target:getFaction()],ship) 9565 setCommsMessage("We have dispatched " .. ship:getCallSign() .. " to assist at waypoint " .. n); 9566 else 9567 setCommsMessage("Not enough reputation!"); 9568 end 9569 addCommsReply("Back", return_function) 9570 end) 9571 end 9572 end 9573 addCommsReply("Back", return_function) 9574 end) 9575 if comms_data.service_cost.hornetreinforcements ~= nil then 9576 addCommsReply(string.format("MU52 Hornet (%i Rep)",getServiceCost("hornetreinforcements")),function() 9577 if comms_source:getWaypointCount() < 1 then 9578 setCommsMessage("You need to set a waypoint before you can request reinforcements") 9579 else 9580 setCommsMessage("To which waypoint should we dispatch the MU52 Hornet?"); 9581 for n=1,comms_source:getWaypointCount() do 9582 addCommsReply("Waypoint " .. n, function() 9583 if comms_source:takeReputationPoints(getServiceCost("hornetreinforcements")) then 9584 ship = CpuShip():setFactionId(comms_target:getFactionId()):setPosition(comms_target:getPosition()):setTemplate("MU52 Hornet"):setScanned(true):orderDefendLocation(comms_source:getWaypoint(n)) 9585 ship:setCommsScript(""):setCommsFunction(commsShip) 9586 ship.score_value = ship_template["MU52 Hornet"].strength 9587 table.insert(npc_fleet[comms_target:getFaction()],ship) 9588 setCommsMessage("We have dispatched " .. ship:getCallSign() .. " to assist at waypoint " .. n); 9589 else 9590 setCommsMessage("Not enough reputation!"); 9591 end 9592 addCommsReply("Back", return_function) 9593 end) 9594 end 9595 end 9596 addCommsReply("Back", return_function) 9597 end) 9598 end 9599 if comms_data.service_cost.phobosreinforcements ~= nil then 9600 addCommsReply(string.format("Phobos T3 (%i Rep)",getServiceCost("phobosreinforcements")),function() 9601 if comms_source:getWaypointCount() < 1 then 9602 setCommsMessage("You need to set a waypoint before you can request reinforcements") 9603 else 9604 setCommsMessage("To which waypoint should we dispatch the Phobos T3?"); 9605 for n=1,comms_source:getWaypointCount() do 9606 addCommsReply("Waypoint " .. n, function() 9607 if comms_source:takeReputationPoints(getServiceCost("phobosreinforcements")) then 9608 ship = CpuShip():setFactionId(comms_target:getFactionId()):setPosition(comms_target:getPosition()):setTemplate("Phobos T3"):setScanned(true):orderDefendLocation(comms_source:getWaypoint(n)) 9609 ship:setCommsScript(""):setCommsFunction(commsShip) 9610 ship.score_value = ship_template["Phobos T3"].strength 9611 table.insert(npc_fleet[comms_target:getFaction()],ship) 9612 setCommsMessage("We have dispatched " .. ship:getCallSign() .. " to assist at waypoint " .. n); 9613 else 9614 setCommsMessage("Not enough reputation!"); 9615 end 9616 addCommsReply("Back", return_function) 9617 end) 9618 end 9619 end 9620 addCommsReply("Back", return_function) 9621 end) 9622 end 9623 end 9624 addCommsReply("Back", return_function) 9625 end) 9626 end 9627end 9628function ordnanceAvailability(return_function) 9629 addCommsReply("What ordnance do you have available for restock?", function() 9630 local missileTypeAvailableCount = 0 9631 local ordnanceListMsg = "" 9632 if comms_target.comms_data.weapon_available.Homing and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.Homing > 0) then 9633 missileTypeAvailableCount = missileTypeAvailableCount + 1 9634 ordnanceListMsg = ordnanceListMsg .. "\n Homing" 9635 if not comms_target.comms_data.weapon_inventory.Unlimited then 9636 ordnanceListMsg = ordnanceListMsg .. string.format("(%i)",math.floor(comms_target.comms_data.weapon_inventory.Homing)) 9637 end 9638 end 9639 if comms_target.comms_data.weapon_available.Nuke and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.Nuke > 0) then 9640 missileTypeAvailableCount = missileTypeAvailableCount + 1 9641 ordnanceListMsg = ordnanceListMsg .. "\n Nuke" 9642 if not comms_target.comms_data.weapon_inventory.Unlimited then 9643 ordnanceListMsg = ordnanceListMsg .. string.format("(%i)",math.floor(comms_target.comms_data.weapon_inventory.Nuke)) 9644 end 9645 end 9646 if comms_target.comms_data.weapon_available.Mine and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.Mine > 0) then 9647 missileTypeAvailableCount = missileTypeAvailableCount + 1 9648 ordnanceListMsg = ordnanceListMsg .. "\n Mine" 9649 if not comms_target.comms_data.weapon_inventory.Unlimited then 9650 ordnanceListMsg = ordnanceListMsg .. string.format("(%i)",math.floor(comms_target.comms_data.weapon_inventory.Mine)) 9651 end 9652 end 9653 if comms_target.comms_data.weapon_available.EMP and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.EMP > 0) then 9654 missileTypeAvailableCount = missileTypeAvailableCount + 1 9655 ordnanceListMsg = ordnanceListMsg .. "\n EMP" 9656 if not comms_target.comms_data.weapon_inventory.Unlimited then 9657 ordnanceListMsg = ordnanceListMsg .. string.format("(%i)",math.floor(comms_target.comms_data.weapon_inventory.EMP)) 9658 end 9659 end 9660 if comms_target.comms_data.weapon_available.HVLI and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.HVLI > 0) then 9661 missileTypeAvailableCount = missileTypeAvailableCount + 1 9662 ordnanceListMsg = ordnanceListMsg .. "\n HVLI" 9663 if not comms_target.comms_data.weapon_inventory.Unlimited then 9664 ordnanceListMsg = ordnanceListMsg .. string.format("(%i)",math.floor(comms_target.comms_data.weapon_inventory.HVLI)) 9665 end 9666 end 9667 if missileTypeAvailableCount == 0 then 9668 ordnanceListMsg = "We have no ordnance available for restock" 9669 elseif missileTypeAvailableCount == 1 then 9670 ordnanceListMsg = "We have the following type of ordnance available for restock:" .. ordnanceListMsg 9671 else 9672 ordnanceListMsg = "We have the following types of ordnance available for restock:" .. ordnanceListMsg 9673 end 9674 setCommsMessage(ordnanceListMsg) 9675 addCommsReply("Back", return_function) 9676 end) 9677end 9678function goodsAvailabilityOnStation(return_function) 9679 local goodsAvailable = false 9680 if comms_target.comms_data.goods ~= nil then 9681 for good, goodData in pairs(comms_target.comms_data.goods) do 9682 if goodData["quantity"] > 0 then 9683 goodsAvailable = true 9684 end 9685 end 9686 end 9687 if goodsAvailable then 9688 addCommsReply("What goods do you have available for sale or trade?", function() 9689 local goodsAvailableMsg = string.format("Station %s:\nGoods or components available: quantity, cost in reputation",comms_target:getCallSign()) 9690 for good, goodData in pairs(comms_target.comms_data.goods) do 9691 goodsAvailableMsg = goodsAvailableMsg .. string.format("\n %14s: %2i, %3i",good,goodData["quantity"],goodData["cost"]) 9692 end 9693 setCommsMessage(goodsAvailableMsg) 9694 addCommsReply("Back", return_function) 9695 end) 9696 end 9697end 9698function expediteDock(return_function) 9699 if isAllowedTo(comms_target.comms_data.services.preorder) then 9700 addCommsReply("Expedite Dock",function() 9701 if comms_source.expedite_dock == nil then 9702 comms_source.expedite_dock = false 9703 end 9704 if comms_source.expedite_dock then 9705 --handle expedite request already present 9706 local existing_expedite = "Docking crew is standing by" 9707 if comms_target == comms_source.expedite_dock_station then 9708 existing_expedite = existing_expedite .. ". Current preorders:" 9709 local preorders_identified = false 9710 if comms_source.preorder_hvli ~= nil then 9711 preorders_identified = true 9712 existing_expedite = existing_expedite .. string.format("\n HVLIs: %i",comms_source.preorder_hvli) 9713 end 9714 if comms_source.preorder_homing ~= nil then 9715 preorders_identified = true 9716 existing_expedite = existing_expedite .. string.format("\n Homings: %i",comms_source.preorder_homing) 9717 end 9718 if comms_source.preorder_mine ~= nil then 9719 preorders_identified = true 9720 existing_expedite = existing_expedite .. string.format("\n Mines: %i",comms_source.preorder_mine) 9721 end 9722 if comms_source.preorder_emp ~= nil then 9723 preorders_identified = true 9724 existing_expedite = existing_expedite .. string.format("\n EMPs: %i",comms_source.preorder_emp) 9725 end 9726 if comms_source.preorder_nuke ~= nil then 9727 preorders_identified = true 9728 existing_expedite = existing_expedite .. string.format("\n Nukes: %i",comms_source.preorder_nuke) 9729 end 9730 if comms_source.preorder_repair_crew ~= nil then 9731 preorders_identified = true 9732 existing_expedite = existing_expedite .. "\n One repair crew" 9733 end 9734 if comms_source.preorder_coolant ~= nil then 9735 preorders_identified = true 9736 existing_expedite = existing_expedite .. "\n Coolant" 9737 end 9738 if preorders_identified then 9739 existing_expedite = existing_expedite .. "\nWould you like to preorder anything else?" 9740 else 9741 existing_expedite = existing_expedite .. " none.\nWould you like to preorder anything?" 9742 end 9743 preorder_message = existing_expedite 9744 preOrderOrdnance(return_function) 9745 else 9746 existing_expedite = existing_expedite .. string.format(" on station %s (not this station, %s).",comms_source.expedite_dock_station:getCallSign(),comms_target:getCallSign()) 9747 setCommsMessage(existing_expedite) 9748 end 9749 addCommsReply("Back",return_function) 9750 else 9751 setCommsMessage("If you would like to speed up the addition of resources such as energy, ordnance, etc., please provide a time frame for your arrival. A docking crew will stand by until that time, after which they will return to their normal duties") 9752 preorder_message = "Docking crew is standing by. Would you like to pre-order anything?" 9753 addCommsReply("One minute (5 rep)", function() 9754 if comms_source:takeReputationPoints(5) then 9755 comms_source.expedite_dock = true 9756 comms_source.expedite_dock_station = comms_target 9757 comms_source.expedite_dock_timer_max = 60 9758 preOrderOrdnance(return_function) 9759 else 9760 setCommsMessage("Insufficient reputation") 9761 end 9762 addCommsReply("Back", return_function) 9763 end) 9764 addCommsReply("Two minutes (10 Rep)", function() 9765 if comms_source:takeReputationPoints(10) then 9766 comms_source.expedite_dock = true 9767 comms_source.expedite_dock_station = comms_target 9768 comms_source.expedite_dock_timer_max = 120 9769 preOrderOrdnance(return_function) 9770 else 9771 setCommsMessage("Insufficient reputation") 9772 end 9773 addCommsReply("Back", return_function) 9774 end) 9775 addCommsReply("Three minutes (15 Rep)", function() 9776 if comms_source:takeReputationPoints(15) then 9777 comms_source.expedite_dock = true 9778 comms_source.expedite_dock_station = comms_target 9779 comms_source.expedite_dock_timer_max = 180 9780 preOrderOrdnance(return_function) 9781 else 9782 setCommsMessage("Insufficient reputation") 9783 end 9784 addCommsReply("Back", return_function) 9785 end) 9786 end 9787 addCommsReply("Back", return_function) 9788 end) 9789 end 9790end 9791function preOrderOrdnance(return_function) 9792 setCommsMessage(preorder_message) 9793 local hvli_count = math.floor(comms_source:getWeaponStorageMax("HVLI") * comms_target.comms_data.max_weapon_refill_amount[getFriendStatus()]) - comms_source:getWeaponStorage("HVLI") 9794 if comms_target.comms_data.weapon_available.HVLI and isAllowedTo(comms_target.comms_data.weapons["HVLI"]) and hvli_count > 0 then 9795 local hvli_prompt = "" 9796 local hvli_cost = getWeaponCost("HVLI") 9797 if hvli_count > 1 then 9798 hvli_prompt = string.format("%i HVLIs * %i Rep = %i Rep",hvli_count,hvli_cost,hvli_count*hvli_cost) 9799 else 9800 hvli_prompt = string.format("%i HVLI * %i Rep = %i Rep",hvli_count,hvli_cost,hvli_count*hvli_cost) 9801 end 9802 addCommsReply(hvli_prompt,function() 9803 if comms_source:takeReputationPoints(hvli_count*hvli_cost) then 9804 comms_source.preorder_hvli = hvli_count 9805 if hvli_count > 1 then 9806 setCommsMessage(string.format("%i HVLIs preordered",hvli_count)) 9807 else 9808 setCommsMessage(string.format("%i HVLI preordered",hvli_count)) 9809 end 9810 else 9811 setCommsMessage("Insufficient reputation") 9812 end 9813 preorder_message = "Docking crew is standing by. Would you like to pre-order anything?" 9814 addCommsReply("Back",return_function) 9815 end) 9816 end 9817 local homing_count = math.floor(comms_source:getWeaponStorageMax("Homing") * comms_target.comms_data.max_weapon_refill_amount[getFriendStatus()]) - comms_source:getWeaponStorage("Homing") 9818 if comms_target.comms_data.weapon_available.Homing and isAllowedTo(comms_target.comms_data.weapons["Homing"]) and homing_count > 0 then 9819 local homing_prompt = "" 9820 local homing_cost = getWeaponCost("Homing") 9821 if homing_count > 1 then 9822 homing_prompt = string.format("%i Homings * %i Rep = %i Rep",homing_count,homing_cost,homing_count*homing_cost) 9823 else 9824 homing_prompt = string.format("%i Homing * %i Rep = %i Rep",homing_count,homing_cost,homing_count*homing_cost) 9825 end 9826 addCommsReply(homing_prompt,function() 9827 if comms_source:takeReputationPoints(homing_count*homing_cost) then 9828 comms_source.preorder_homing = homing_count 9829 if homing_count > 1 then 9830 setCommsMessage(string.format("%i Homings preordered",homing_count)) 9831 else 9832 setCommsMessage(string.format("%i Homing preordered",homing_count)) 9833 end 9834 else 9835 setCommsMessage("Insufficient reputation") 9836 end 9837 preorder_message = "Docking crew is standing by. Would you like to pre-order anything?" 9838 addCommsReply("Back",return_function) 9839 end) 9840 end 9841 local mine_count = math.floor(comms_source:getWeaponStorageMax("Mine") * comms_target.comms_data.max_weapon_refill_amount[getFriendStatus()]) - comms_source:getWeaponStorage("Mine") 9842 if comms_target.comms_data.weapon_available.Mine and isAllowedTo(comms_target.comms_data.weapons["Mine"]) and mine_count > 0 then 9843 local mine_prompt = "" 9844 local mine_cost = getWeaponCost("Mine") 9845 if mine_count > 1 then 9846 mine_prompt = string.format("%i Mines * %i Rep = %i Rep",mine_count,mine_cost,mine_count*mine_cost) 9847 else 9848 mine_prompt = string.format("%i Mine * %i Rep = %i Rep",mine_count,mine_cost,mine_count*mine_cost) 9849 end 9850 addCommsReply(mine_prompt,function() 9851 if comms_source:takeReputationPoints(mine_count*mine_cost) then 9852 comms_source.preorder_mine = mine_count 9853 if mine_count > 1 then 9854 setCommsMessage(string.format("%i Mines preordered",mine_count)) 9855 else 9856 setCommsMessage(string.format("%i Mine preordered",mine_count)) 9857 end 9858 else 9859 setCommsMessage("Insufficient reputation") 9860 end 9861 preorder_message = "Docking crew is standing by. Would you like to pre-order anything?" 9862 addCommsReply("Back",return_function) 9863 end) 9864 end 9865 local emp_count = math.floor(comms_source:getWeaponStorageMax("EMP") * comms_target.comms_data.max_weapon_refill_amount[getFriendStatus()]) - comms_source:getWeaponStorage("EMP") 9866 if comms_target.comms_data.weapon_available.EMP and isAllowedTo(comms_target.comms_data.weapons["EMP"]) and emp_count > 0 then 9867 local emp_prompt = "" 9868 local emp_cost = getWeaponCost("EMP") 9869 if emp_count > 1 then 9870 emp_prompt = string.format("%i EMPs * %i Rep = %i Rep",emp_count,emp_cost,emp_count*emp_cost) 9871 else 9872 emp_prompt = string.format("%i EMP * %i Rep = %i Rep",emp_count,emp_cost,emp_count*emp_cost) 9873 end 9874 addCommsReply(emp_prompt,function() 9875 if comms_source:takeReputationPoints(emp_count*emp_cost) then 9876 comms_source.preorder_emp = emp_count 9877 if emp_count > 1 then 9878 setCommsMessage(string.format("%i EMPs preordered",emp_count)) 9879 else 9880 setCommsMessage(string.format("%i EMP preordered",emp_count)) 9881 end 9882 else 9883 setCommsMessage("Insufficient reputation") 9884 end 9885 preorder_message = "Docking crew is standing by. Would you like to pre-order anything?" 9886 addCommsReply("Back",return_function) 9887 end) 9888 end 9889 local nuke_count = math.floor(comms_source:getWeaponStorageMax("Nuke") * comms_target.comms_data.max_weapon_refill_amount[getFriendStatus()]) - comms_source:getWeaponStorage("Nuke") 9890 if comms_target.comms_data.weapon_available.Nuke and isAllowedTo(comms_target.comms_data.weapons["Nuke"]) and nuke_count > 0 then 9891 local nuke_prompt = "" 9892 local nuke_cost = getWeaponCost("Nuke") 9893 if nuke_count > 1 then 9894 nuke_prompt = string.format("%i Nukes * %i Rep = %i Rep",nuke_count,nuke_cost,nuke_count*nuke_cost) 9895 else 9896 nuke_prompt = string.format("%i Nuke * %i Rep = %i Rep",nuke_count,nuke_cost,nuke_count*nuke_cost) 9897 end 9898 addCommsReply(nuke_prompt,function() 9899 if comms_source:takeReputationPoints(nuke_count*nuke_cost) then 9900 comms_source.preorder_nuke = nuke_count 9901 if nuke_count > 1 then 9902 setCommsMessage(string.format("%i Nukes preordered",nuke_count)) 9903 else 9904 setCommsMessage(string.format("%i Nuke preordered",nuke_count)) 9905 end 9906 else 9907 setCommsMessage("Insufficient reputation") 9908 end 9909 preorder_message = "Docking crew is standing by. Would you like to pre-order anything?" 9910 addCommsReply("Back",return_function) 9911 end) 9912 end 9913 if comms_source.preorder_repair_crew == nil then 9914 if random(1,100) <= 20 then 9915 if comms_source:isFriendly(comms_target) then 9916 if comms_source:getRepairCrewCount() < comms_source.maxRepairCrew then 9917 hireCost = math.random(30,60) 9918 else 9919 hireCost = math.random(45,90) 9920 end 9921 addCommsReply(string.format("Recruit repair crew member for %i reputation",hireCost), function() 9922 if not comms_source:takeReputationPoints(hireCost) then 9923 setCommsMessage("Insufficient reputation") 9924 else 9925 comms_source.preorder_repair_crew = 1 9926 setCommsMessage("Repair crew hired on your behalf. They will board when you dock") 9927 end 9928 preorder_message = "Docking crew is standing by. Would you like to pre-order anything?" 9929 addCommsReply("Back",return_function) 9930 end) 9931 end 9932 end 9933 end 9934 if comms_source.preorder_coolant == nil then 9935 if random(1,100) <= 20 then 9936 if comms_source:isFriendly(comms_target) then 9937 if comms_source.initialCoolant ~= nil then 9938 local coolant_cost = math.random(45,90) 9939 if comms_source:getMaxCoolant() < comms_source.initialCoolant then 9940 coolant_cost = math.random(30,60) 9941 end 9942 addCommsReply(string.format("Set aside coolant for %i reputation",coolant_cost), function() 9943 if comms_source:takeReputationPoints(coolant_cost) then 9944 comms_source.preorder_coolant = 2 9945 setCommsMessage("Coolant set aside for you. It will be loaded when you dock") 9946 else 9947 setCommsMessage("Insufficient reputation") 9948 end 9949 preorder_message = "Docking crew is standing by. Would you like to pre-order anything?" 9950 addCommsReply("Back",return_function) 9951 end) 9952 end 9953 end 9954 end 9955 end 9956end 9957function activateDefenseFleet(return_function) 9958 if isAllowedTo(comms_target.comms_data.services.activatedefensefleet) and 9959 comms_target.comms_data.idle_defense_fleet ~= nil then 9960 local defense_fleet_count = 0 9961 for name, template in pairs(comms_target.comms_data.idle_defense_fleet) do 9962 defense_fleet_count = defense_fleet_count + 1 9963 end 9964 if defense_fleet_count > 0 then 9965 addCommsReply("Activate station defense fleet (" .. getServiceCost("activatedefensefleet") .. " rep)",function() 9966 if comms_source:takeReputationPoints(getServiceCost("activatedefensefleet")) then 9967 local out = string.format("%s defense fleet\n",comms_target:getCallSign()) 9968 for name, template in pairs(comms_target.comms_data.idle_defense_fleet) do 9969 local script = Script() 9970 local position_x, position_y = comms_target:getPosition() 9971 local station_name = comms_target:getCallSign() 9972 script:setVariable("position_x", position_x):setVariable("position_y", position_y) 9973 script:setVariable("station_name",station_name) 9974 script:setVariable("name",name) 9975 script:setVariable("template",template) 9976 script:setVariable("faction_id",comms_target:getFactionId()) 9977 script:run("border_defend_station.lua") 9978 out = out .. " " .. name 9979 comms_target.comms_data.idle_defense_fleet[name] = nil 9980 end 9981 out = out .. "\nactivated" 9982 setCommsMessage(out) 9983 else 9984 setCommsMessage("Insufficient reputation") 9985 end 9986 addCommsReply("Back", return_function) 9987 end) 9988 end 9989 end 9990end 9991-- Docked actions 9992function restockOrdnance(return_function) 9993 local missilePresence = 0 9994 local missile_types = {'Homing', 'Nuke', 'Mine', 'EMP', 'HVLI'} 9995 for _, missile_type in ipairs(missile_types) do 9996 missilePresence = missilePresence + comms_source:getWeaponStorageMax(missile_type) 9997 end 9998 if missilePresence > 0 then 9999 if (comms_target.comms_data.weapon_available.Nuke and comms_source:getWeaponStorageMax("Nuke") > 0) and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.Nuke > 0) or 10000 (comms_target.comms_data.weapon_available.EMP and comms_source:getWeaponStorageMax("EMP") > 0) and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.EMP > 0) or 10001 (comms_target.comms_data.weapon_available.Homing and comms_source:getWeaponStorageMax("Homing") > 0) and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.Homing > 0) or 10002 (comms_target.comms_data.weapon_available.Mine and comms_source:getWeaponStorageMax("Mine") > 0) and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.Mine > 0) or 10003 (comms_target.comms_data.weapon_available.HVLI and comms_source:getWeaponStorageMax("HVLI") > 0) and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.HVLI > 0) then 10004 addCommsReply("I need ordnance restocked", function() 10005 setCommsMessage("What type of ordnance?") 10006 if comms_source:getWeaponStorageMax("Nuke") > 0 and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.Nuke > 0) then 10007 if comms_target.comms_data.weapon_available.Nuke then 10008 local ask = {"Can you supply us with some nukes?","We really need some nukes."} 10009 local avail = "" 10010 if not comms_target.comms_data.weapon_inventory.Unlimited then 10011 avail = string.format(", %i avail",math.floor(comms_target.comms_data.weapon_inventory.Nuke)) 10012 end 10013 local nuke_prompt = string.format("%s (%i rep each%s)",ask[math.random(1,#ask)],getWeaponCost("Nuke"),avail) 10014 addCommsReply(nuke_prompt, function() 10015 handleWeaponRestock("Nuke",return_function) 10016 end) 10017 end --end station has nuke available if branch 10018 end --end player can accept nuke if branch 10019 if comms_source:getWeaponStorageMax("EMP") > 0 and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.EMP > 0) then 10020 if comms_target.comms_data.weapon_available.EMP then 10021 local ask = {"Please re-stock our EMP missiles.","Got any EMPs?"} 10022 local avail = "" 10023 if not comms_target.comms_data.weapon_inventory.Unlimited then 10024 avail = string.format(", %i avail",math.floor(comms_target.comms_data.weapon_inventory.EMP)) 10025 end 10026 local emp_prompt = string.format("%s (%i rep each%s)",ask[math.random(1,#ask)],getWeaponCost("EMP"),avail) 10027 addCommsReply(emp_prompt, function() 10028 handleWeaponRestock("EMP",return_function) 10029 end) 10030 end --end station has EMP available if branch 10031 end --end player can accept EMP if branch 10032 if comms_source:getWeaponStorageMax("Homing") > 0 and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.Homing > 0) then 10033 if comms_target.comms_data.weapon_available.Homing then 10034 local ask = {"Do you have spare homing missiles for us?","Do you have extra homing missiles?"} 10035 local avail = "" 10036 if not comms_target.comms_data.weapon_inventory.Unlimited then 10037 avail = string.format(", %i avail",math.floor(comms_target.comms_data.weapon_inventory.Homing)) 10038 end 10039 local homing_prompt = string.format("%s (%i rep each%s)",ask[math.random(1,#ask)],getWeaponCost("Homing"),avail) 10040 addCommsReply(homing_prompt, function() 10041 handleWeaponRestock("Homing",return_function) 10042 end) 10043 end --end station has homing for player if branch 10044 end --end player can accept homing if branch 10045 if comms_source:getWeaponStorageMax("Mine") > 0 and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.Mine > 0) then 10046 if comms_target.comms_data.weapon_available.Mine then 10047 local ask = {"We could use some mines.","How about mines?"} 10048 local avail = "" 10049 if not comms_target.comms_data.weapon_inventory.Unlimited then 10050 avail = string.format(", %i avail",math.floor(comms_target.comms_data.weapon_inventory.Mine)) 10051 end 10052 local mine_prompt = string.format("%s (%i rep each%s)",ask[math.random(1,#ask)],getWeaponCost("Mine"),avail) 10053 addCommsReply(mine_prompt, function() 10054 handleWeaponRestock("Mine",return_function) 10055 end) 10056 end --end station has mine for player if branch 10057 end --end player can accept mine if branch 10058 if comms_source:getWeaponStorageMax("HVLI") > 0 and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory.HVLI > 0) then 10059 if comms_target.comms_data.weapon_available.HVLI then 10060 local ask = {"What about HVLI?","Could you provide HVLI?"} 10061 local avail = "" 10062 if not comms_target.comms_data.weapon_inventory.Unlimited then 10063 avail = string.format(", %i avail",math.floor(comms_target.comms_data.weapon_inventory.HVLI)) 10064 end 10065 local hvli_prompt = string.format("%s (%i rep each%s)",ask[math.random(1,#ask)],getWeaponCost("HVLI"),avail) 10066 addCommsReply(hvli_prompt, function() 10067 handleWeaponRestock("HVLI",return_function) 10068 end) 10069 end --end station has HVLI for player if branch 10070 end --end player can accept HVLI if branch 10071 end) --end player requests secondary ordnance comms reply branch 10072 end --end secondary ordnance available from station if branch 10073 end --end missles used on player ship if branch 10074end 10075function repairSubsystems(return_function) 10076 local offer_repair = false 10077 if comms_target.comms_data.probe_launch_repair and not comms_source:getCanLaunchProbe() then 10078 offer_repair = true 10079 end 10080 if not offer_repair and comms_target.comms_data.hack_repair and not comms_source:getCanHack() then 10081 offer_repair = true 10082 end 10083 if not offer_repair and comms_target.comms_data.scan_repair and not comms_source:getCanScan() then 10084 offer_repair = true 10085 end 10086 if not offer_repair and comms_target.comms_data.combat_maneuver_repair and not comms_source:getCanCombatManeuver() then 10087 offer_repair = true 10088 end 10089 if not offer_repair and comms_target.comms_data.self_destruct_repair and not comms_source:getCanSelfDestruct() then 10090 offer_repair = true 10091 end 10092 if not offer_repair and comms_target.comms_data.tube_slow_down_repair then 10093 local tube_load_time_slowed = false 10094 if comms_source.normal_tube_load_time ~= nil then 10095 local tube_count = comms_source:getWeaponTubeCount() 10096 if tube_count > 0 then 10097 local tube_index = 0 10098 repeat 10099 if comms_source.normal_tube_load_time[tube_index] ~= comms_source:getTubeLoadTime(tube_index) then 10100 tube_load_time_slowed = true 10101 break 10102 end 10103 tube_index = tube_index + 1 10104 until(tube_index >= tube_count) 10105 end 10106 end 10107 if tube_load_time_slowed then 10108 offer_repair = true 10109 end 10110 end 10111 if offer_repair then 10112 addCommsReply("Repair ship system",function() 10113 setCommsMessage("What system would you like repaired?") 10114 if comms_target.comms_data.probe_launch_repair then 10115 if not comms_source:getCanLaunchProbe() then 10116 addCommsReply("Repair probe launch system (5 Rep)",function() 10117 if comms_source:takeReputationPoints(5) then 10118 comms_source:setCanLaunchProbe(true) 10119 setCommsMessage("Your probe launch system has been repaired") 10120 else 10121 setCommsMessage("Insufficient reputation") 10122 end 10123 addCommsReply("Back", return_function) 10124 end) 10125 end 10126 end 10127 if comms_target.comms_data.hack_repair then 10128 if not comms_source:getCanHack() then 10129 addCommsReply("Repair hacking system (5 Rep)",function() 10130 if comms_source:takeReputationPoints(5) then 10131 comms_source:setCanHack(true) 10132 setCommsMessage("Your hack system has been repaired") 10133 else 10134 setCommsMessage("Insufficient reputation") 10135 end 10136 addCommsReply("Back", return_function) 10137 end) 10138 end 10139 end 10140 if comms_target.comms_data.scan_repair then 10141 if not comms_source:getCanScan() then 10142 addCommsReply("Repair scanners (5 Rep)",function() 10143 if comms_source:takeReputationPoints(5) then 10144 comms_source:setCanScan(true) 10145 setCommsMessage("Your scanners have been repaired") 10146 else 10147 setCommsMessage("Insufficient reputation") 10148 end 10149 addCommsReply("Back", return_function) 10150 end) 10151 end 10152 end 10153 if comms_target.comms_data.combat_maneuver_repair then 10154 if not comms_source:getCanCombatManeuver() then 10155 addCommsReply("Repair combat maneuver (5 Rep)",function() 10156 if comms_source:takeReputationPoints(5) then 10157 comms_source:setCanCombatManeuver(true) 10158 setCommsMessage("Your combat maneuver has been repaired") 10159 else 10160 setCommsMessage("Insufficient reputation") 10161 end 10162 addCommsReply("Back", return_function) 10163 end) 10164 end 10165 end 10166 if comms_target.comms_data.self_destruct_repair then 10167 if not comms_source:getCanSelfDestruct() then 10168 addCommsReply("Repair self destruct system (5 Rep)",function() 10169 if comms_source:takeReputationPoints(5) then 10170 comms_source:setCanSelfDestruct(true) 10171 setCommsMessage("Your self destruct system has been repaired") 10172 else 10173 setCommsMessage("Insufficient reputation") 10174 end 10175 addCommsReply("Back", return_function) 10176 end) 10177 end 10178 end 10179 if comms_target.comms_data.tube_slow_down_repair then 10180 local tube_load_time_slowed = false 10181 if comms_source.normal_tube_load_time ~= nil then 10182 local tube_count = comms_source:getWeaponTubeCount() 10183 if tube_count > 0 then 10184 local tube_index = 0 10185 repeat 10186 if comms_source.normal_tube_load_time[tube_index] ~= comms_source:getTubeLoadTime(tube_index) then 10187 tube_load_time_slowed = true 10188 break 10189 end 10190 tube_index = tube_index + 1 10191 until(tube_index >= tube_count) 10192 end 10193 end 10194 if tube_load_time_slowed then 10195 addCommsReply("Repair slow tube loading (5 Rep)",function() 10196 if comms_source:takeReputationPoints(5) then 10197 local tube_count = comms_source:getWeaponTubeCount() 10198 local tube_index = 0 10199 repeat 10200 comms_source:setTubeLoadTime(tube_index,comms_source.normal_tube_load_time[tube_index]) 10201 tube_index = tube_index + 1 10202 until(tube_index >= tube_count) 10203 setCommsMessage("Your tube load times have been returned to normal") 10204 else 10205 setCommsMessage("Insufficient reputation") 10206 end 10207 addCommsReply("Back", return_function) 10208 end) 10209 end 10210 end 10211 addCommsReply("Back", return_function) 10212 end) 10213 end 10214end 10215function handleWeaponRestock(weapon, return_function) 10216 if not comms_source:isDocked(comms_target) then 10217 setCommsMessage("You need to stay docked for that action.") 10218 return 10219 end 10220 if not isAllowedTo(comms_data.weapons[weapon]) then 10221 if weapon == "Nuke" then setCommsMessage("We do not deal in weapons of mass destruction.") 10222 elseif weapon == "EMP" then setCommsMessage("We do not deal in weapons of mass disruption.") 10223 else setCommsMessage("We do not deal in those weapons.") end 10224 return 10225 end 10226 local points_per_item = getWeaponCost(weapon) 10227 local item_amount = math.floor(comms_source:getWeaponStorageMax(weapon) * comms_data.max_weapon_refill_amount[getFriendStatus()]) - comms_source:getWeaponStorage(weapon) 10228 if item_amount <= 0 then 10229 if weapon == "Nuke" then 10230 setCommsMessage("All nukes are charged and primed for destruction."); 10231 else 10232 setCommsMessage("Sorry, sir, but you are as fully stocked as I can allow."); 10233 end 10234 addCommsReply("Back", return_function) 10235 else 10236 local inventory_status = "" 10237 if comms_source:getReputationPoints() > points_per_item * item_amount and (comms_target.comms_data.weapon_inventory.Unlimited or comms_target.comms_data.weapon_inventory[weapon] >= item_amount) then 10238 if comms_source:takeReputationPoints(points_per_item * item_amount) then 10239 comms_source:setWeaponStorage(weapon, comms_source:getWeaponStorage(weapon) + item_amount) 10240 if not comms_target.comms_data.weapon_inventory.Unlimited then 10241 comms_target.comms_data.weapon_inventory[weapon] = comms_target.comms_data.weapon_inventory[weapon] - item_amount 10242 inventory_status = string.format("\nStation inventory of %s type weapons reduced to %i",weapon,math.floor(comms_target.comms_data.weapon_inventory[weapon])) 10243 end 10244 if comms_source:getWeaponStorage(weapon) == comms_source:getWeaponStorageMax(weapon) then 10245 setCommsMessage("You are fully loaded and ready to explode things." .. inventory_status) 10246 else 10247 setCommsMessage("We generously resupplied you with some weapon charges.\nPut them to good use." .. inventory_status) 10248 end 10249 else 10250 setCommsMessage("Not enough reputation.") 10251 return 10252 end 10253 else 10254 if comms_source:getReputationPoints() > points_per_item then 10255 setCommsMessage("Either you can't afford as much as I'd like to give you, or I don't have enough to fully restock you.") 10256 addCommsReply("Get just one", function() 10257 if comms_source:takeReputationPoints(points_per_item) then 10258 comms_source:setWeaponStorage(weapon, comms_source:getWeaponStorage(weapon) + 1) 10259 if not comms_target.comms_data.weapon_inventory.Unlimited then 10260 comms_target.comms_data.weapon_inventory[weapon] = comms_target.comms_data.weapon_inventory[weapon] - 1 10261 inventory_status = string.format("\nStation inventory of %s type weapons reduced to %i",weapon,math.floor(comms_target.comms_data.weapon_inventory[weapon])) 10262 end 10263 if comms_source:getWeaponStorage(weapon) == comms_source:getWeaponStorageMax(weapon) then 10264 setCommsMessage("You are fully loaded and ready to explode things." .. inventory_status) 10265 else 10266 setCommsMessage("We generously resupplied you with one weapon charge.\nPut it to good use." .. inventory_status) 10267 end 10268 else 10269 setCommsMessage("Not enough reputation.") 10270 end 10271 return 10272 end) 10273 else 10274 setCommsMessage("Not enough reputation.") 10275 return 10276 end 10277 end 10278 addCommsReply("Back", return_function) 10279 end 10280end 10281function buySellTrade(return_function) 10282 local goodCount = 0 10283 if comms_target.comms_data.goods == nil then 10284 return 10285 end 10286 for good, goodData in pairs(comms_target.comms_data.goods) do 10287 goodCount = goodCount + 1 10288 end 10289 if goodCount > 0 then 10290 addCommsReply("Buy, sell, trade", function() 10291 local goodsReport = string.format("Station %s:\nGoods or components available for sale: quantity, cost in reputation\n",comms_target:getCallSign()) 10292 for good, goodData in pairs(comms_target.comms_data.goods) do 10293 goodsReport = goodsReport .. string.format(" %s: %i, %i\n",good,goodData["quantity"],goodData["cost"]) 10294 end 10295 if comms_target.comms_data.buy ~= nil then 10296 goodsReport = goodsReport .. "Goods or components station will buy: price in reputation\n" 10297 for good, price in pairs(comms_target.comms_data.buy) do 10298 goodsReport = goodsReport .. string.format(" %s: %i\n",good,price) 10299 end 10300 end 10301 goodsReport = goodsReport .. string.format("Current cargo aboard %s:\n",comms_source:getCallSign()) 10302 local cargoHoldEmpty = true 10303 local goodCount = 0 10304 if comms_source.goods ~= nil then 10305 for good, goodQuantity in pairs(comms_source.goods) do 10306 goodCount = goodCount + 1 10307 goodsReport = goodsReport .. string.format(" %s: %i\n",good,goodQuantity) 10308 end 10309 end 10310 if goodCount < 1 then 10311 goodsReport = goodsReport .. " Empty\n" 10312 end 10313 goodsReport = goodsReport .. string.format("Available Space: %i, Available Reputation: %i\n",comms_source.cargo,math.floor(comms_source:getReputationPoints())) 10314 setCommsMessage(goodsReport) 10315 for good, goodData in pairs(comms_target.comms_data.goods) do 10316 addCommsReply(string.format("Buy one %s for %i reputation",good,goodData["cost"]), function() 10317 local goodTransactionMessage = string.format("Type: %s, Quantity: %i, Rep: %i",good,goodData["quantity"],goodData["cost"]) 10318 if comms_source.cargo < 1 then 10319 goodTransactionMessage = goodTransactionMessage .. "\nInsufficient cargo space for purchase" 10320 elseif goodData["cost"] > math.floor(comms_source:getReputationPoints()) then 10321 goodTransactionMessage = goodTransactionMessage .. "\nInsufficient reputation for purchase" 10322 elseif goodData["quantity"] < 1 then 10323 goodTransactionMessage = goodTransactionMessage .. "\nInsufficient station inventory" 10324 else 10325 if comms_source:takeReputationPoints(goodData["cost"]) then 10326 comms_source.cargo = comms_source.cargo - 1 10327 goodData["quantity"] = goodData["quantity"] - 1 10328 if comms_source.goods == nil then 10329 comms_source.goods = {} 10330 end 10331 if comms_source.goods[good] == nil then 10332 comms_source.goods[good] = 0 10333 end 10334 comms_source.goods[good] = comms_source.goods[good] + 1 10335 goodTransactionMessage = goodTransactionMessage .. "\npurchased" 10336 else 10337 goodTransactionMessage = goodTransactionMessage .. "\nInsufficient reputation for purchase" 10338 end 10339 end 10340 setCommsMessage(goodTransactionMessage) 10341 addCommsReply("Back", return_function) 10342 end) 10343 end 10344 if comms_target.comms_data.buy ~= nil then 10345 for good, price in pairs(comms_target.comms_data.buy) do 10346 if comms_source.goods ~= nil then 10347 if comms_source.goods[good] ~= nil and comms_source.goods[good] > 0 then 10348 addCommsReply(string.format("Sell one %s for %i reputation",good,price), function() 10349 local goodTransactionMessage = string.format("Type: %s, Reputation price: %i",good,price) 10350 comms_source.goods[good] = comms_source.goods[good] - 1 10351 comms_source:addReputationPoints(price) 10352 goodTransactionMessage = goodTransactionMessage .. "\nOne sold" 10353 comms_source.cargo = comms_source.cargo + 1 10354 setCommsMessage(goodTransactionMessage) 10355 addCommsReply("Back", return_function) 10356 end) 10357 end 10358 end 10359 end 10360 end 10361 if comms_target.comms_data.trade.food and comms_source.goods["food"] > 0 then 10362 for good, goodData in pairs(comms_target.comms_data.goods) do 10363 addCommsReply(string.format("Trade food for %s",good), function() 10364 local goodTransactionMessage = string.format("Type: %s, Quantity: %i",good,goodData["quantity"]) 10365 if goodData["quantity"] < 1 then 10366 goodTransactionMessage = goodTransactionMessage .. "\nInsufficient station inventory" 10367 else 10368 goodData["quantity"] = goodData["quantity"] - 1 10369 if comms_source.goods == nil then 10370 comms_source.goods = {} 10371 end 10372 if comms_source.goods[good] == nil then 10373 comms_source.goods[good] = 0 10374 end 10375 comms_source.goods[good] = comms_source.goods[good] + 1 10376 comms_source.goods["food"] = comms_source.goods["food"] - 1 10377 goodTransactionMessage = goodTransactionMessage .. "\nTraded" 10378 end 10379 setCommsMessage(goodTransactionMessage) 10380 addCommsReply("Back", return_function) 10381 end) 10382 end 10383 end 10384 if comms_target.comms_data.trade.medicine and comms_source.goods["medicine"] > 0 then 10385 for good, goodData in pairs(comms_target.comms_data.goods) do 10386 addCommsReply(string.format("Trade medicine for %s",good), function() 10387 local goodTransactionMessage = string.format("Type: %s, Quantity: %i",good,goodData["quantity"]) 10388 if goodData["quantity"] < 1 then 10389 goodTransactionMessage = goodTransactionMessage .. "\nInsufficient station inventory" 10390 else 10391 goodData["quantity"] = goodData["quantity"] - 1 10392 if comms_source.goods == nil then 10393 comms_source.goods = {} 10394 end 10395 if comms_source.goods[good] == nil then 10396 comms_source.goods[good] = 0 10397 end 10398 comms_source.goods[good] = comms_source.goods[good] + 1 10399 comms_source.goods["medicine"] = comms_source.goods["medicine"] - 1 10400 goodTransactionMessage = goodTransactionMessage .. "\nTraded" 10401 end 10402 setCommsMessage(goodTransactionMessage) 10403 addCommsReply("Back", return_function) 10404 end) 10405 end 10406 end 10407 if comms_target.comms_data.trade.luxury and comms_source.goods["luxury"] > 0 then 10408 for good, goodData in pairs(comms_target.comms_data.goods) do 10409 addCommsReply(string.format("Trade luxury for %s",good), function() 10410 local goodTransactionMessage = string.format("Type: %s, Quantity: %i",good,goodData["quantity"]) 10411 if goodData[quantity] < 1 then 10412 goodTransactionMessage = goodTransactionMessage .. "\nInsufficient station inventory" 10413 else 10414 goodData["quantity"] = goodData["quantity"] - 1 10415 if comms_source.goods == nil then 10416 comms_source.goods = {} 10417 end 10418 if comms_source.goods[good] == nil then 10419 comms_source.goods[good] = 0 10420 end 10421 comms_source.goods[good] = comms_source.goods[good] + 1 10422 comms_source.goods["luxury"] = comms_source.goods["luxury"] - 1 10423 goodTransactionMessage = goodTransactionMessage .. "\nTraded" 10424 end 10425 setCommsMessage(goodTransactionMessage) 10426 addCommsReply("Back", return_function) 10427 end) 10428 end 10429 end 10430 addCommsReply("Back", return_function) 10431 end) 10432 end 10433end 10434function boostSensorsWhileDocked(return_function) 10435 if comms_target.comms_data.sensor_boost ~= nil then 10436 if comms_target.comms_data.sensor_boost.cost > 0 then 10437 addCommsReply(string.format("Augment scan range with station sensors while docked (%i rep)",comms_target.comms_data.sensor_boost.cost),function() 10438 if comms_source:takeReputationPoints(comms_target.comms_data.sensor_boost.cost) then 10439 if comms_source.normal_long_range_radar == nil then 10440 comms_source.normal_long_range_radar = comms_source:getLongRangeRadarRange() 10441 end 10442 comms_source:setLongRangeRadarRange(comms_source.normal_long_range_radar + comms_target.comms_data.sensor_boost.value) 10443 setCommsMessage(string.format("sensors increased by %i units",comms_target.comms_data.sensor_boost.value/1000)) 10444 else 10445 setCommsMessage("Insufficient reputation") 10446 end 10447 addCommsReply("Back", return_function) 10448 end) 10449 end 10450 end 10451end 10452function overchargeJump(return_function) 10453 if comms_target.comms_data.jump_overcharge and isAllowedTo(comms_target.comms_data.services.jumpovercharge) then 10454 if comms_source:hasJumpDrive() then 10455 local max_charge = comms_source.max_jump_range 10456 if max_charge == nil then 10457 max_charge = 50000 10458 end 10459 if comms_source:getJumpDriveCharge() >= max_charge then 10460 addCommsReply("Overcharge Jump Drive (" .. getServiceCost("jumpovercharge") .. " rep)",function() 10461 if comms_source:takeReputationPoints(getServiceCost("jumpovercharge")) then 10462 comms_source:setJumpDriveCharge(comms_source:getJumpDriveCharge() + max_charge) 10463 setCommsMessage(string.format("Your jump drive has been overcharged to %ik",math.floor(comms_source:getJumpDriveCharge()/1000))) 10464 else 10465 setCommsMessage("Insufficient reputation") 10466 end 10467 addCommsReply("Back", return_function) 10468 end) 10469 end 10470 end 10471 end 10472end 10473-- Upgrades 10474function hullStrengthUpgrade(p) 10475 if p.hull_strength_upgrade == nil then 10476 p.hull_strength_upgrade = "done" 10477 p:setHullMax(p:getHullMax()*1.2) 10478 p:setHull(p:getHullMax()) 10479 p:setImpulseMaxSpeed(p:getImpulseMaxSpeed()*.9) 10480 return true, "Your hull strength has been increased by 20%" 10481 else 10482 return false, "You already have the hull strength upgrade" 10483 end 10484end 10485function missileLoadSpeedUpgrade(p) 10486 if p.missile_load_speed_upgrade == nil then 10487 local tube_count = p:getWeaponTubeCount() 10488 if tube_count > 0 then 10489 local tube_index = 0 10490 if p.normal_tube_load_time == nil then 10491 p.normal_tube_load_time = {} 10492 repeat 10493 p.normal_tube_load_time[tube_index] = p:getTubeLoadTime(tube_index) 10494 tube_index = tube_index + 1 10495 until(tube_index >= tube_count) 10496 tube_index = 0 10497 end 10498 repeat 10499 p:setTubeLoadTime(tube_index,p.normal_tube_load_time[tube_index]*.8) 10500 p.normal_tube_load_time[tube_index] = p.normal_tube_load_time[tube_index]*.8 10501 tube_index = tube_index + 1 10502 until(tube_index >= tube_count) 10503 return true, "Your missile tube load time has been reduced by 20%" 10504 else 10505 return false, "Your ship has no missile systems and thus cannot be upgraded" 10506 end 10507 else 10508 return false, "You already have the missile load speed upgrade" 10509 end 10510end 10511function shieldStrengthUpgrade(p) 10512 if p.shield_strength_upgrade == nil then 10513 if p:getShieldCount() > 0 then 10514 p.shield_strength_upgrade = "done" 10515 if p:getShieldCount() == 1 then 10516 p:setShieldsMax(p:getShieldMax(0)*1.2) 10517 else 10518 p:setShieldsMax(p:getShieldMax(0)*1.2,p:getShieldMax(1)*1.2) 10519 end 10520 return true, "Your ship shields are now 20% stronger. They'll need to charge to their new higher capacity" 10521 else 10522 return false, "Your ship has no shields and thus cannot be upgraded" 10523 end 10524 else 10525 return false, "You already have the shield upgrade" 10526 end 10527end 10528function beamDamageUpgrade(p) 10529 if p.beam_damage_upgrade == nil then 10530 if p:getBeamWeaponRange(0) > 0 then 10531 p.beam_damage_upgrade = "done" 10532 local bi = 0 10533 repeat 10534 local tempArc = p:getBeamWeaponArc(bi) 10535 local tempDir = p:getBeamWeaponDirection(bi) 10536 local tempRng = p:getBeamWeaponRange(bi) 10537 local tempCyc = p:getBeamWeaponCycleTime(bi) 10538 local tempDmg = p:getBeamWeaponDamage(bi) 10539 p:setBeamWeapon(bi,tempArc,tempDir,tempRng,tempCyc,tempDmg*1.2) 10540 p:setBeamWeaponHeatPerFire(bi,p:getBeamWeaponHeatPerFire(bi)*1.2) 10541 p:setBeamWeaponEnergyPerFire(bi,p:getBeamWeaponEnergyPerFire(bi)*1.2) 10542 bi = bi + 1 10543 until(p:getBeamWeaponRange(bi) < 1) 10544 return true, "Your ship beam weapons damage has been increased by 20%" 10545 else 10546 return false, "Your ship has no beam weapons and thus cannot be upgraded" 10547 end 10548 else 10549 return false, "You already have the beam damage upgrade" 10550 end 10551end 10552function beamRangeUpgrade(p) 10553 if p.beam_range_upgrade == nil then 10554 if p:getBeamWeaponRange(0) > 0 then 10555 p.beam_range_upgrade = "done" 10556 local bi = 0 10557 repeat 10558 local tempArc = p:getBeamWeaponArc(bi) 10559 local tempDir = p:getBeamWeaponDirection(bi) 10560 local tempRng = p:getBeamWeaponRange(bi) 10561 local tempCyc = p:getBeamWeaponCycleTime(bi) 10562 local tempDmg = p:getBeamWeaponDamage(bi) 10563 p:setBeamWeapon(bi,tempArc,tempDir,tempRng*1.2,tempCyc,tempDmg) 10564 p:setBeamWeaponHeatPerFire(bi,p:getBeamWeaponHeatPerFire(bi)*1.2) 10565 p:setBeamWeaponEnergyPerFire(bi,p:getBeamWeaponEnergyPerFire(bi)*1.2) 10566 bi = bi + 1 10567 until(p:getBeamWeaponRange(bi) < 1) 10568 return true, "Your ship beam weapons range has been increased by 20%" 10569 else 10570 return false, "Your ship has no beam weapons and thus cannot be upgraded" 10571 end 10572 else 10573 return false, "You already have the beam range upgrade" 10574 end 10575end 10576function batteryEfficiencyUpgrade(p) 10577 if p.battery_efficiency_upgrade == nil then 10578 p.battery_efficiency_upgrade = "done" 10579 p:setMaxEnergy(p:getMaxEnergy()*1.2) 10580 p:setImpulseMaxSpeed(p:getImpulseMaxSpeed()*.95) 10581 return true, "Your ship batteries can now store 20% more energy. You'll need to charge them longer to use their full capacity" 10582 else 10583 return false, "You already have the battery efficiency upgrade" 10584 end 10585end 10586function fasterImpulseUpgrade(p) 10587 if p.faster_impulse_upgrade == nil then 10588 p.faster_impulse_upgrade = "done" 10589 p:setImpulseMaxSpeed(p:getImpulseMaxSpeed()*1.2) 10590 p:setRotationMaxSpeed(p:getRotationMaxSpeed()*.95) 10591 return true, "Your maximum impulse top speed has been increased by 20%" 10592 else 10593 return false, "You already have an upgraded impulse engine" 10594 end 10595end 10596function longerSensorsUpgrade(p) 10597 if p.longer_sensors_upgrade == nil then 10598 p.longer_sensors_upgrade = "done" 10599 if p.normal_long_range_radar == nil then 10600 p.normal_long_range_radar = p:getLongRangeRadarRange() 10601 end 10602 p:setLongRangeRadarRange(p:getLongRangeRadarRange() + 10000) 10603 p.normal_long_range_radar = p.normal_long_range_radar + 10000 10604 return true, "Your ship's long range sensors have had their reach increased by 10 units" 10605 else 10606 return false, "You already have upgraded long range sensors" 10607 end 10608end 10609function fasterSpinUpgrade(p) 10610 if p.faster_spin_upgrade == nil then 10611 p.faster_spin_upgrade = "done" 10612 p:setRotationMaxSpeed(p:getRotationMaxSpeed()*1.2) 10613 return true, "Your maneuvering speed has been increased by 20%" 10614 else 10615 return false, "You already have upgraded maneuvering speed" 10616 end 10617end 10618--------------------------- 10619-- Ship Communications -- 10620--------------------------- 10621function commsShip() 10622 if comms_target.comms_data == nil then 10623 comms_target.comms_data = {friendlyness = random(0.0, 100.0)} 10624 end 10625 comms_data = comms_target.comms_data 10626 if comms_data.goods == nil then 10627 comms_data.goods = {} 10628 comms_data.goods[commonGoods[math.random(1,#commonGoods)]] = {quantity = 1, cost = random(20,80)} 10629 local shipType = comms_target:getTypeName() 10630 if shipType:find("Freighter") ~= nil then 10631 if shipType:find("Goods") ~= nil or shipType:find("Equipment") ~= nil then 10632 repeat 10633 comms_data.goods[commonGoods[math.random(1,#commonGoods)]] = {quantity = 1, cost = random(20,80)} 10634 local goodCount = 0 10635 for good, goodData in pairs(comms_data.goods) do 10636 goodCount = goodCount + 1 10637 end 10638 until(goodCount >= 3) 10639 end 10640 end 10641 end 10642 if comms_source:isFriendly(comms_target) then 10643 return friendlyComms(comms_data) 10644 end 10645 if comms_source:isEnemy(comms_target) and comms_target:isFriendOrFoeIdentifiedBy(comms_source) then 10646 return enemyComms(comms_data) 10647 end 10648 return neutralComms(comms_data) 10649end 10650function friendlyComms(comms_data) 10651 if comms_data.friendlyness < 20 then 10652 setCommsMessage("What do you want?"); 10653 else 10654 setCommsMessage("Sir, how can we assist?"); 10655 end 10656 shipDefendWaypoint(commsShip) 10657 shipFlyBlind(commsShip) 10658 shipAssistPlayer(comms_data,commsShip) 10659 shipStatusReport(commsShip) 10660 shipDockNearby(commsShip) 10661 shipRoaming(commsShip) 10662 shipStandGround(commsShip) 10663 shipIdle(commsShip) 10664 fleetCommunication(commsShip) 10665 friendlyFreighterCommunication(comms_data,commsShip) 10666 return true 10667end 10668function enemyComms(comms_data) 10669 local faction = comms_target:getFaction() 10670 local tauntable = false 10671 local amenable = false 10672 if comms_data.friendlyness >= 33 then --final: 33 10673 --taunt logic 10674 local taunt_option = "We will see to your destruction!" 10675 local taunt_success_reply = "Your bloodline will end here!" 10676 local taunt_failed_reply = "Your feeble threats are meaningless." 10677 local taunt_threshold = 30 --base chance of being taunted 10678 if faction == "Kraylor" then 10679 taunt_threshold = 35 10680 setCommsMessage("Ktzzzsss.\nYou will DIEEee weaklingsss!"); 10681 local kraylorTauntChoice = math.random(1,3) 10682 if kraylorTauntChoice == 1 then 10683 taunt_option = "We will destroy you" 10684 taunt_success_reply = "We think not. It is you who will experience destruction!" 10685 elseif kraylorTauntChoice == 2 then 10686 taunt_option = "You have no honor" 10687 taunt_success_reply = "Your insult has brought our wrath upon you. Prepare to die." 10688 taunt_failed_reply = "Your comments about honor have no meaning to us" 10689 else 10690 taunt_option = "We pity your pathetic race" 10691 taunt_success_reply = "Pathetic? You will regret your disparagement!" 10692 taunt_failed_reply = "We don't care what you think of us" 10693 end 10694 elseif faction == "Arlenians" then 10695 taunt_threshold = 25 10696 setCommsMessage("We wish you no harm, but will harm you if we must.\nEnd of transmission."); 10697 elseif faction == "Exuari" then 10698 taunt_threshold = 40 10699 setCommsMessage("Stay out of our way, or your death will amuse us extremely!"); 10700 elseif faction == "Ghosts" then 10701 taunt_threshold = 20 10702 setCommsMessage("One zero one.\nNo binary communication detected.\nSwitching to universal speech.\nGenerating appropriate response for target from human language archives.\n:Do not cross us:\nCommunication halted."); 10703 taunt_option = "EXECUTE: SELFDESTRUCT" 10704 taunt_success_reply = "Rogue command received. Targeting source." 10705 taunt_failed_reply = "External command ignored." 10706 elseif faction == "Ktlitans" then 10707 setCommsMessage("The hive suffers no threats. Opposition to any of us is opposition to us all.\nStand down or prepare to donate your corpses toward our nutrition."); 10708 taunt_option = "<Transmit 'The Itsy-Bitsy Spider' on all wavelengths>" 10709 taunt_success_reply = "We do not need permission to pluck apart such an insignificant threat." 10710 taunt_failed_reply = "The hive has greater priorities than exterminating pests." 10711 elseif faction == "TSN" then 10712 taunt_threshold = 15 10713 setCommsMessage("State your business") 10714 elseif faction == "USN" then 10715 taunt_threshold = 15 10716 setCommsMessage("What do you want? (not that we care)") 10717 elseif faction == "CUF" then 10718 taunt_threshold = 15 10719 setCommsMessage("Don't waste our time") 10720 else 10721 setCommsMessage("Mind your own business!"); 10722 end 10723 comms_data.friendlyness = comms_data.friendlyness - random(0, 10) --reduce friendlyness after each interaction 10724 addCommsReply(taunt_option, function() 10725 if random(0, 100) <= taunt_threshold then --final: 30 10726 local current_order = comms_target:getOrder() 10727 print("order: " .. current_order) 10728 --Possible order strings returned: 10729 --Roaming 10730 --Fly towards 10731 --Attack 10732 --Stand Ground 10733 --Idle 10734 --Defend Location 10735 --Defend Target 10736 --Fly Formation (?) 10737 --Fly towards (ignore all) 10738 --Dock 10739 if comms_target.original_order == nil then 10740 comms_target.original_faction = faction 10741 comms_target.original_order = current_order 10742 if current_order == "Fly towards" or current_order == "Defend Location" or current_order == "Fly towards (ignore all)" then 10743 comms_target.original_target_x, comms_target.original_target_y = comms_target:getOrderTargetLocation() 10744 --print(string.format("Target_x: %f, Target_y: %f",comms_target.original_target_x,comms_target.original_target_y)) 10745 end 10746 if current_order == "Attack" or current_order == "Dock" or current_order == "Defend Target" then 10747 local original_target = comms_target:getOrderTarget() 10748 --print("target:") 10749 --print(original_target) 10750 --print(original_target:getCallSign()) 10751 comms_target.original_target = original_target 10752 end 10753 comms_target.taunt_may_expire = true --change to conditional in future refactoring 10754 table.insert(enemy_reverts,comms_target) 10755 end 10756 comms_target:orderAttack(comms_source) --consider alternative options besides attack in future refactoring 10757 setCommsMessage(taunt_success_reply); 10758 else 10759 setCommsMessage(taunt_failed_reply); 10760 end 10761 end) 10762 tauntable = true 10763 end 10764 local enemy_health = getEnemyHealth(comms_target) 10765 if change_enemy_order_diagnostic then print(string.format(" enemy health: %.2f",enemy_health)) end 10766 if change_enemy_order_diagnostic then print(string.format(" friendliness: %.1f",comms_data.friendlyness)) end 10767 if comms_data.friendlyness >= 66 or enemy_health < .5 then --final: 66, .5 10768 --amenable logic 10769 local amenable_chance = comms_data.friendlyness/3 + (1 - enemy_health)*30 10770 if change_enemy_order_diagnostic then print(string.format(" amenability: %.1f",amenable_chance)) end 10771 addCommsReply("Stop your actions",function() 10772 local amenable_roll = random(0,100) 10773 if change_enemy_order_diagnostic then print(string.format(" amenable roll: %.1f",amenable_roll)) end 10774 if amenable_roll < amenable_chance then 10775 local current_order = comms_target:getOrder() 10776 if comms_target.original_order == nil then 10777 comms_target.original_order = current_order 10778 comms_target.original_faction = faction 10779 if current_order == "Fly towards" or current_order == "Defend Location" or current_order == "Fly towards (ignore all)" then 10780 comms_target.original_target_x, comms_target.original_target_y = comms_target:getOrderTargetLocation() 10781 --print(string.format("Target_x: %f, Target_y: %f",comms_target.original_target_x,comms_target.original_target_y)) 10782 end 10783 if current_order == "Attack" or current_order == "Dock" or current_order == "Defend Target" then 10784 local original_target = comms_target:getOrderTarget() 10785 --print("target:") 10786 --print(original_target) 10787 --print(original_target:getCallSign()) 10788 comms_target.original_target = original_target 10789 end 10790 table.insert(enemy_reverts,comms_target) 10791 end 10792 comms_target.amenability_may_expire = true 10793 comms_target:orderIdle() 10794 comms_target:setFaction("Independent") 10795 setCommsMessage("Just this once, we'll take your advice") 10796 else 10797 setCommsMessage("No") 10798 end 10799 end) 10800 comms_data.friendlyness = comms_data.friendlyness - random(0, 10) --reduce friendlyness after each interaction 10801 amenable = true 10802 end 10803 if tauntable or amenable then 10804 return true 10805 else 10806 return false 10807 end 10808end 10809function neutralComms(comms_data) 10810 local shipType = comms_target:getTypeName() 10811 if shipType:find("Freighter") ~= nil or shipType:find("Transport") ~= nil or shipType:find("Cargo") ~= nil then 10812 setCommsMessage("Yes?") 10813 shipCargoSellReport(commsShip) 10814 if distance(comms_source,comms_target) < 5000 then 10815 if comms_source.cargo > 0 then 10816 if comms_data.friendlyness > 66 then 10817 if shipType:find("Goods") ~= nil or shipType:find("Equipment") ~= nil then 10818 shipBuyGoods(commsShip,1) 10819 else 10820 shipBuyGoods(commsShip,2) 10821 end 10822 elseif comms_data.friendlyness > 33 then 10823 if shipType:find("Goods") ~= nil or shipType:find("Equipment") ~= nil then 10824 shipBuyGoods(commsShip,2) 10825 else 10826 shipBuyGoods(commsShip,3) 10827 end 10828 else --least friendly 10829 if shipType:find("Goods") ~= nil or shipType:find("Equipment") ~= nil then 10830 shipBuyGoods(commsShip,3) 10831 end 10832 end --end friendly branches 10833 end --player has room for cargo 10834 end --close enough to sell 10835 else --not a freighter 10836 if comms_data.friendlyness > 50 then 10837 setCommsMessage("Sorry, we have no time to chat with you.\nWe are on an important mission."); 10838 else 10839 setCommsMessage("We have nothing for you.\nGood day."); 10840 end 10841 end --end non-freighter communications else branch 10842 return true 10843end --end neutral communications function 10844function shipStatusReport(return_function) 10845 addCommsReply("Report status", function() 10846 msg = "Hull: " .. math.floor(comms_target:getHull() / comms_target:getHullMax() * 100) .. "%\n" 10847 local shields = comms_target:getShieldCount() 10848 if shields == 1 then 10849 msg = msg .. "Shield: " .. math.floor(comms_target:getShieldLevel(0) / comms_target:getShieldMax(0) * 100) .. "%\n" 10850 elseif shields == 2 then 10851 msg = msg .. "Front Shield: " .. math.floor(comms_target:getShieldLevel(0) / comms_target:getShieldMax(0) * 100) .. "%\n" 10852 msg = msg .. "Rear Shield: " .. math.floor(comms_target:getShieldLevel(1) / comms_target:getShieldMax(1) * 100) .. "%\n" 10853 else 10854 for n=0,shields-1 do 10855 msg = msg .. "Shield " .. n .. ": " .. math.floor(comms_target:getShieldLevel(n) / comms_target:getShieldMax(n) * 100) .. "%\n" 10856 end 10857 end 10858 local missile_types = {'Homing', 'Nuke', 'Mine', 'EMP', 'HVLI'} 10859 for i, missile_type in ipairs(missile_types) do 10860 if comms_target:getWeaponStorageMax(missile_type) > 0 then 10861 msg = msg .. missile_type .. " Missiles: " .. math.floor(comms_target:getWeaponStorage(missile_type)) .. "/" .. math.floor(comms_target:getWeaponStorageMax(missile_type)) .. "\n" 10862 end 10863 end 10864 if comms_target:hasJumpDrive() then 10865 msg = msg .. "Jump drive charge: " .. comms_target:getJumpDriveCharge() 10866 end 10867 setCommsMessage(msg); 10868 addCommsReply("Back", return_function) 10869 end) 10870end 10871function shipIdle(return_function) 10872 addCommsReply("Stop. Do nothing.", function() 10873 comms_target:orderIdle() 10874 local idle_comment = { 10875 "routine system maintenance", 10876 "for idle ship gossip", 10877 "exterior paint touch-up", 10878 "exercise for continued fitness", 10879 "meditation therapy", 10880 "internal simulated flight routines", 10881 "digital dreamscape construction", 10882 "catching up on reading the latest war drama novel", 10883 "writing up results of bifurcated personality research", 10884 "categorizing nearby miniscule space particles", 10885 "continuing the count of visible stars from this region", 10886 "internal systems diagnostics", 10887 } 10888 setCommsMessage(string.format("Stopping. Doing nothing except %s",idle_comment[math.random(1,#idle_comment)])) 10889 addCommsReply("Back", return_function) 10890 end) 10891end 10892function shipRoaming(return_function) 10893 addCommsReply("Attack all enemies. Start with the nearest.", function() 10894 comms_target:orderRoaming() 10895 setCommsMessage("Searching and destroying") 10896 addCommsReply("Back", return_function) 10897 end) 10898end 10899function shipStandGround(return_function) 10900 addCommsReply("Stop and defned your current location", function() 10901 comms_target:orderStandGround() 10902 setCommsMessage("Stopping. Shooting any enemy that approaches") 10903 addCommsReply("Back", return_function) 10904 end) 10905end 10906function shipDefendWaypoint(return_function) 10907 addCommsReply("Defend a waypoint", function() 10908 if comms_source:getWaypointCount() == 0 then 10909 setCommsMessage("No waypoints set. Please set a waypoint first."); 10910 addCommsReply("Back", return_function) 10911 else 10912 setCommsMessage("Which waypoint should we defend?"); 10913 for n=1,comms_source:getWaypointCount() do 10914 addCommsReply("Defend WP" .. n, function() 10915 comms_target:orderDefendLocation(comms_source:getWaypoint(n)) 10916 setCommsMessage("We are heading to assist at WP" .. n .."."); 10917 addCommsReply("Back", return_function) 10918 end) 10919 end 10920 end 10921 end) 10922end 10923function shipFlyBlind(return_function) 10924 addCommsReply("Go to waypoint, ignore enemies", function() 10925 if comms_source:getWaypointCount() == 0 then 10926 setCommsMessage("No waypoints set. Please set a waypoint first."); 10927 addCommsReply("Back", return_function) 10928 else 10929 setCommsMessage("Which waypoint should we approach?"); 10930 for n=1,comms_source:getWaypointCount() do 10931 addCommsReply("Defend WP" .. n, function() 10932 comms_target:orderFlyTowardsBlind(comms_source:getWaypoint(n)) 10933 setCommsMessage("We are heading to WP" .. n ..", ignoring enemies."); 10934 addCommsReply("Back", return_function) 10935 end) 10936 end 10937 end 10938 end) 10939end 10940function shipAssistPlayer(comms_data,return_function) 10941 if comms_data.friendlyness > 0.2 then 10942 addCommsReply("Assist me", function() 10943 setCommsMessage("Heading toward you to assist."); 10944 comms_target:orderDefendTarget(comms_source) 10945 addCommsReply("Back", return_function) 10946 end) 10947 end 10948end 10949function shipDockNearby(return_function) 10950 for _, obj in ipairs(comms_target:getObjectsInRange(5000)) do 10951 local player_carrier = false 10952 local template_name = "" 10953 if obj.typeName == "PlayerSpaceship" then 10954 template_name = obj:getTypeName() 10955 if template_name == "Benedict" or template_name == "Kiriya" then 10956 player_carrier = true 10957 end 10958 end 10959 local defense_platform = false 10960 if obj.typeName == "CpuShip" then 10961 template_name = obj:getTypeName() 10962 if template_name == "Defense platform" then 10963 defense_platform = true 10964 end 10965 end 10966 if (obj.typeName == "SpaceStation" and not comms_target:isEnemy(obj)) or player_carrier or defense_platform then 10967 addCommsReply("Dock at " .. obj:getCallSign(), function() 10968 setCommsMessage("Docking at " .. obj:getCallSign() .. "."); 10969 comms_target:orderDock(obj) 10970 addCommsReply("Back", return_function) 10971 end) 10972 end 10973 end 10974end 10975function fleetCommunication(return_function) 10976 if comms_target.fleetIndex ~= nil then 10977 addCommsReply(string.format("Direct fleet %i",comms_target.fleetIndex), function() 10978 local fleet_state = string.format("Fleet %i consists of:\n",comms_target.fleetIndex) 10979 for _, ship in ipairs(npc_fleet[comms_target:getFaction()]) do 10980 if ship.fleetIndex == comms_target.fleetIndex then 10981 fleet_state = fleet_state .. ship:getCallSign() .. " " 10982 end 10983 end 10984 setCommsMessage(string.format("%s\n\nWhat command should be given to fleet %i?",fleet_state,comms_target.fleetIndex)) 10985 addCommsReply("Report hull and shield status", function() 10986 msg = string.format("Fleet %i status:",comms_target.fleetIndex) 10987 for _, fleetShip in ipairs(npc_fleet[comms_target:getFaction()]) do 10988 if fleetShip.fleetIndex == comms_target.fleetIndex then 10989 if fleetShip ~= nil and fleetShip:isValid() then 10990 msg = msg .. "\n " .. fleetShip:getCallSign() .. ":" 10991 msg = msg .. "\n Hull: " .. math.floor(fleetShip:getHull() / fleetShip:getHullMax() * 100) .. "%" 10992 local shields = fleetShip:getShieldCount() 10993 if shields == 1 then 10994 msg = msg .. "\n Shield: " .. math.floor(fleetShip:getShieldLevel(0) / fleetShip:getShieldMax(0) * 100) .. "%" 10995 else 10996 msg = msg .. "\n Shields: " 10997 if shields == 2 then 10998 msg = msg .. "Front:" .. math.floor(fleetShip:getShieldLevel(0) / fleetShip:getShieldMax(0) * 100) .. "% Rear:" .. math.floor(fleetShip:getShieldLevel(1) / fleetShip:getShieldMax(1) * 100) .. "%" 10999 else 11000 for n=0,shields-1 do 11001 msg = msg .. " " .. n .. ":" .. math.floor(fleetShip:getShieldLevel(n) / fleetShip:getShieldMax(n) * 100) .. "%" 11002 end 11003 end 11004 end 11005 end 11006 end 11007 end 11008 setCommsMessage(msg) 11009 addCommsReply("Back", return_function) 11010 end) 11011 addCommsReply("Report missile status", function() 11012 msg = string.format("Fleet %i missile status:",comms_target.fleetIndex) 11013 for _, fleetShip in ipairs(npc_fleet[comms_target:getFaction()]) do 11014 if fleetShip.fleetIndex == comms_target.fleetIndex then 11015 if fleetShip ~= nil and fleetShip:isValid() then 11016 msg = msg .. "\n " .. fleetShip:getCallSign() .. ":" 11017 local missile_types = {'Homing', 'Nuke', 'Mine', 'EMP', 'HVLI'} 11018 missileMsg = "" 11019 for _, missile_type in ipairs(missile_types) do 11020 if fleetShip:getWeaponStorageMax(missile_type) > 0 then 11021 missileMsg = missileMsg .. "\n " .. missile_type .. ": " .. math.floor(fleetShip:getWeaponStorage(missile_type)) .. "/" .. math.floor(fleetShip:getWeaponStorageMax(missile_type)) 11022 end 11023 end 11024 if missileMsg ~= "" then 11025 msg = msg .. "\n Missiles: " .. missileMsg 11026 end 11027 end 11028 end 11029 end 11030 setCommsMessage(msg) 11031 addCommsReply("Back", return_function) 11032 end) 11033 addCommsReply("Assist me", function() 11034 for _, fleetShip in ipairs(npc_fleet[comms_target:getFaction()]) do 11035 if fleetShip.fleetIndex == comms_target.fleetIndex then 11036 if fleetShip ~= nil and fleetShip:isValid() then 11037 fleetShip:orderDefendTarget(comms_source) 11038 end 11039 end 11040 end 11041 setCommsMessage(string.format("Fleet %s heading toward you to assist",comms_target.fleetIndex)) 11042 addCommsReply("Back", return_function) 11043 end) 11044 addCommsReply("Defend a waypoint", function() 11045 if comms_source:getWaypointCount() == 0 then 11046 setCommsMessage("No waypoints set. Please set a waypoint first."); 11047 addCommsReply("Back", return_function) 11048 else 11049 setCommsMessage("Which waypoint should we defend?"); 11050 for n=1,comms_source:getWaypointCount() do 11051 addCommsReply("Defend WP" .. n, function() 11052 for _, fleetShip in ipairs(npc_fleet[comms_target:getFaction()]) do 11053 if fleetShip.fleetIndex == comms_target.fleetIndex then 11054 if fleetShip ~= nil and fleetShip:isValid() then 11055 fleetShip:orderDefendLocation(comms_source:getWaypoint(n)) 11056 end 11057 end 11058 end 11059 setCommsMessage("We are heading to assist at WP" .. n .."."); 11060 addCommsReply("Back", return_function) 11061 end) 11062 end 11063 end 11064 end) 11065 addCommsReply("Go to waypoint. Attack enemies en route", function() 11066 if comms_source:getWaypointCount() == 0 then 11067 setCommsMessage("No waypoints set. Please set a waypoint first."); 11068 addCommsReply("Back", return_function) 11069 else 11070 setCommsMessage("Which waypoint?"); 11071 for n=1,comms_source:getWaypointCount() do 11072 addCommsReply("Go to WP" .. n, function() 11073 for _, fleetShip in ipairs(npc_fleet[comms_target:getFaction()]) do 11074 if fleetShip.fleetIndex == comms_target.fleetIndex then 11075 if fleetShip ~= nil and fleetShip:isValid() then 11076 fleetShip:orderFlyTowards(comms_source:getWaypoint(n)) 11077 end 11078 end 11079 end 11080 setCommsMessage("Going to WP" .. n ..", watching for enemies en route"); 11081 addCommsReply("Back", return_function) 11082 end) 11083 end 11084 end 11085 end) 11086 addCommsReply("Go to waypoint. Ignore enemies", function() 11087 if comms_source:getWaypointCount() == 0 then 11088 setCommsMessage("No waypoints set. Please set a waypoint first."); 11089 addCommsReply("Back", return_function) 11090 else 11091 setCommsMessage("Which waypoint?"); 11092 for n=1,comms_source:getWaypointCount() do 11093 addCommsReply("Go to WP" .. n, function() 11094 for _, fleetShip in ipairs(npc_fleet[comms_target:getFaction()]) do 11095 if fleetShip.fleetIndex == comms_target.fleetIndex then 11096 if fleetShip ~= nil and fleetShip:isValid() then 11097 fleetShip:orderFlyTowardsBlind(comms_source:getWaypoint(n)) 11098 end 11099 end 11100 end 11101 setCommsMessage("Going to WP" .. n ..", ignoring enemies"); 11102 addCommsReply("Back", return_function) 11103 end) 11104 end 11105 end 11106 end) 11107 addCommsReply("Go offensive, attack all enemy targets", function() 11108 for _, fleetShip in ipairs(npc_fleet[comms_target:getFaction()]) do 11109 if fleetShip.fleetIndex == comms_target.fleetIndex then 11110 if fleetShip ~= nil and fleetShip:isValid() then 11111 fleetShip:orderRoaming() 11112 end 11113 end 11114 end 11115 setCommsMessage(string.format("Fleet %s is on an offensive rampage",comms_target.fleetIndex)) 11116 addCommsReply("Back", return_function) 11117 end) 11118 addCommsReply("Stop and defend your current position", function() 11119 for _, fleetShip in ipairs(npc_fleet[comms_target:getFaction()]) do 11120 if fleetShip.fleetIndex == comms_target.fleetIndex then 11121 fleetShip:orderStandGround() 11122 end 11123 end 11124 setCommsMessage("Stopping and defending") 11125 addCommsReply("Back", return_function) 11126 end) 11127 addCommsReply("Stop and do nothing", function() 11128 for _, fleetShip in ipairs(npc_fleet[comms_target:getFaction()]) do 11129 if fleetShip.fleetIndex == comms_target.fleetIndex then 11130 fleetShip:orderIdle() 11131 end 11132 end 11133 setCommsMessage("Stopping and doing nothing") 11134 addCommsReply("Back", return_function) 11135 end) 11136 end) 11137 end 11138end 11139function friendlyFreighterCommunication(comms_data,return_function) 11140 local shipType = comms_target:getTypeName() 11141 if shipType:find("Freighter") ~= nil then 11142 if distance(comms_source, comms_target) < 5000 then 11143 if comms_data.friendlyness > 66 then 11144 if shipType:find("Goods") ~= nil or shipType:find("Equipment") ~= nil then 11145 shipTradeGoods(comms_data,return_function) 11146 end --goods or equipment freighter 11147 if comms_source.cargo > 0 then 11148 shipBuyGoods(comms_data,return_function,1) 11149 end --player has cargo space branch 11150 elseif comms_data.friendlyness > 33 then 11151 if comms_source.cargo > 0 then 11152 if shipType:find("Goods") ~= nil or shipType:find("Equipment") ~= nil then 11153 shipBuyGoods(comms_data,return_function,1) 11154 else --not goods or equipment freighter 11155 shipBuyGoods(comms_data,return_function,2) 11156 end 11157 end --player has room for cargo branch 11158 else --least friendly 11159 if comms_source.cargo > 0 then 11160 if shipType:find("Goods") ~= nil or shipType:find("Equipment") ~= nil then 11161 shipBuyGoods(comms_data,return_function,2) 11162 end --goods or equipment freighter 11163 end --player has room to get goods 11164 end --various friendliness choices 11165 else --not close enough to sell 11166 shipCargoSellReport(comms_data,return_function) 11167 end 11168 end 11169end 11170function shipCargoSellReport(comms_data,return_function) 11171 addCommsReply("Do you have cargo you might sell?", function() 11172 local goodCount = 0 11173 local cargoMsg = "We've got " 11174 for good, goodData in pairs(comms_data.goods) do 11175 if goodData.quantity > 0 then 11176 if goodCount > 0 then 11177 cargoMsg = cargoMsg .. ", " .. good 11178 else 11179 cargoMsg = cargoMsg .. good 11180 end 11181 end 11182 goodCount = goodCount + goodData.quantity 11183 end 11184 if goodCount == 0 then 11185 cargoMsg = cargoMsg .. "nothing" 11186 end 11187 setCommsMessage(cargoMsg) 11188 addCommsReply("Back", return_function) 11189 end) 11190end 11191function shipTradeGoods(comms_data,return_function) 11192 if comms_source.goods ~= nil and comms_source.goods.luxury ~= nil and comms_source.goods.luxury > 0 then 11193 for good, goodData in pairs(comms_data.goods) do 11194 if goodData.quantity > 0 and good ~= "luxury" then 11195 addCommsReply(string.format("Trade luxury for %s",good), function() 11196 goodData.quantity = goodData.quantity - 1 11197 if comms_source.goods == nil then 11198 comms_source.goods = {} 11199 end 11200 if comms_source.goods[good] == nil then 11201 comms_source.goods[good] = 0 11202 end 11203 comms_source.goods[good] = comms_source.goods[good] + 1 11204 comms_source.goods.luxury = comms_source.goods.luxury - 1 11205 setCommsMessage(string.format("Traded your luxury for %s from %s",good,comms_target:getCallSign())) 11206 addCommsReply("Back", return_function) 11207 end) 11208 end 11209 end --freighter goods loop 11210 end --player has luxury branch 11211end 11212function shipBuyGoods(comms_data,return_function,price_multiplier) 11213 for good, goodData in pairs(comms_data.goods) do 11214 if goodData.quantity > 0 then 11215 addCommsReply(string.format("Buy one %s for %i reputation",good,math.floor(goodData.cost*price_multiplier)), function() 11216 if comms_source:takeReputationPoints(goodData.cost*price_multiplier) then 11217 goodData.quantity = goodData.quantity - 1 11218 if comms_source.goods == nil then 11219 comms_source.goods = {} 11220 end 11221 if comms_source.goods[good] == nil then 11222 comms_source.goods[good] = 0 11223 end 11224 comms_source.goods[good] = comms_source.goods[good] + 1 11225 comms_source.cargo = comms_source.cargo - 1 11226 setCommsMessage(string.format("Purchased %s from %s",good,comms_target:getCallSign())) 11227 else 11228 setCommsMessage("Insufficient reputation for purchase") 11229 end 11230 addCommsReply("Back", return_function) 11231 end) 11232 end 11233 end --freighter goods loop 11234end 11235------------------------------- 11236-- Defend ship communication -- 11237------------------------------- 11238function commsDefendShip() 11239 if comms_target.comms_data == nil then 11240 comms_target.comms_data = {friendlyness = random(0.0, 100.0)} 11241 end 11242 comms_data = comms_target.comms_data 11243 if comms_source:isFriendly(comms_target) then 11244 return friendlyDefendComms(comms_data) 11245 end 11246 if comms_source:isEnemy(comms_target) and comms_target:isFriendOrFoeIdentifiedBy(comms_source) then 11247 return enemyDefendComms(comms_data) 11248 end 11249 return neutralDefendComms(comms_data) 11250end 11251function friendlyDefendComms(comms_data) 11252 if comms_data.friendlyness < 20 then 11253 setCommsMessage("What do you want?"); 11254 else 11255 setCommsMessage("Sir, how can we assist?"); 11256 end 11257 shipStatusReport(commsDefendShip) 11258 return true 11259end 11260function enemyDefendComms(comms_data) 11261 if comms_data.friendlyness > 50 then 11262 local faction = comms_target:getFaction() 11263 local taunt_option = "We will see to your destruction!" 11264 local taunt_success_reply = "Your bloodline will end here!" 11265 local taunt_failed_reply = "Your feeble threats are meaningless." 11266 if faction == "Kraylor" then 11267 setCommsMessage("Ktzzzsss.\nYou will DIEEee weaklingsss!"); 11268 elseif faction == "Arlenians" then 11269 setCommsMessage("We wish you no harm, but will harm you if we must.\nEnd of transmission."); 11270 elseif faction == "Exuari" then 11271 setCommsMessage("Stay out of our way, or your death will amuse us extremely!"); 11272 elseif faction == "Ghosts" then 11273 setCommsMessage("One zero one.\nNo binary communication detected.\nSwitching to universal speech.\nGenerating appropriate response for target from human language archives.\n:Do not cross us:\nCommunication halted."); 11274 taunt_option = "EXECUTE: SELFDESTRUCT" 11275 taunt_success_reply = "Rogue command received. Targeting source." 11276 taunt_failed_reply = "External command ignored." 11277 elseif faction == "Ktlitans" then 11278 setCommsMessage("The hive suffers no threats. Opposition to any of us is opposition to us all.\nStand down or prepare to donate your corpses toward our nutrition."); 11279 taunt_option = "<Transmit 'The Itsy-Bitsy Spider' on all wavelengths>" 11280 taunt_success_reply = "We do not need permission to pluck apart such an insignificant threat." 11281 taunt_failed_reply = "The hive has greater priorities than exterminating pests." 11282 else 11283 setCommsMessage("Mind your own business!"); 11284 end 11285 comms_data.friendlyness = comms_data.friendlyness - random(0, 10) 11286 addCommsReply(taunt_option, function() 11287 if random(0, 100) < 30 then 11288 comms_target:orderAttack(player) 11289 setCommsMessage(taunt_success_reply); 11290 else 11291 setCommsMessage(taunt_failed_reply); 11292 end 11293 end) 11294 return true 11295 end 11296 return false 11297end 11298function neutralDefendComms(comms_data) 11299 if comms_data.friendlyness > 50 then 11300 setCommsMessage("Sorry, we have no time to chat with you.\nWe are on an important mission."); 11301 else 11302 setCommsMessage("We have nothing for you.\nGood day."); 11303 end 11304 return true 11305end 11306 11307function playerShipCargoInventory(p) 11308 p:addToShipLog(string.format("%s Current cargo:",p:getCallSign()),"Yellow") 11309 local goodCount = 0 11310 if p.goods ~= nil then 11311 for good, goodQuantity in pairs(p.goods) do 11312 goodCount = goodCount + 1 11313 p:addToShipLog(string.format(" %s: %i",good,goodQuantity),"Yellow") 11314 end 11315 end 11316 if goodCount < 1 then 11317 p:addToShipLog(" Empty","Yellow") 11318 end 11319 p:addToShipLog(string.format("Available space: %i",p.cargo),"Yellow") 11320end 11321function resetPreviousSystemHealth(p) 11322 string.format("") --may need global context 11323 if p == nil then 11324 p = comms_source 11325 end 11326 local currentShield = 0 11327 if p:getShieldCount() > 1 then 11328 currentShield = (p:getSystemHealth("frontshield") + p:getSystemHealth("rearshield"))/2 11329 else 11330 currentShield = p:getSystemHealth("frontshield") 11331 end 11332 p.prevShield = currentShield 11333 p.prevReactor = p:getSystemHealth("reactor") 11334 p.prevManeuver = p:getSystemHealth("maneuver") 11335 p.prevImpulse = p:getSystemHealth("impulse") 11336 if p:getBeamWeaponRange(0) > 0 then 11337 if p.healthyBeam == nil then 11338 p.healthyBeam = 1.0 11339 p.prevBeam = 1.0 11340 end 11341 p.prevBeam = p:getSystemHealth("beamweapons") 11342 end 11343 if p:getWeaponTubeCount() > 0 then 11344 if p.healthyMissile == nil then 11345 p.healthyMissile = 1.0 11346 p.prevMissile = 1.0 11347 end 11348 p.prevMissile = p:getSystemHealth("missilesystem") 11349 end 11350 if p:hasWarpDrive() then 11351 if p.healthyWarp == nil then 11352 p.healthyWarp = 1.0 11353 p.prevWarp = 1.0 11354 end 11355 p.prevWarp = p:getSystemHealth("warp") 11356 end 11357 if p:hasJumpDrive() then 11358 if p.healthyJump == nil then 11359 p.healthyJump = 1.0 11360 p.prevJump = 1.0 11361 end 11362 p.prevJump = p:getSystemHealth("jumpdrive") 11363 end 11364end 11365function gatherStats() 11366 local stat_list = {} 11367 stat_list.scenario = {name = "Chaos of War", version = scenario_version} 11368 stat_list.times = {} 11369 stat_list.times.game = {} 11370 stat_list.times.stage = game_state 11371 stat_list.times.game.max = max_game_time 11372 stat_list.times.game.total_seconds_left = game_time_limit 11373 stat_list.times.game.minutes_left = math.floor(game_time_limit / 60) 11374 stat_list.times.game.seconds_left = math.floor(game_time_limit % 60) 11375 stat_list.human = {} 11376 stat_list.human.ship = {} 11377 stat_list.human.ship_score_total = 0 11378 stat_list.human.npc = {} 11379 stat_list.human.npc_score_total = 0 11380 stat_list.human.station_score_total = 0 11381 stat_list.human.station = {} 11382 stat_list.kraylor = {} 11383 stat_list.kraylor.ship = {} 11384 stat_list.kraylor.ship_score_total = 0 11385 stat_list.kraylor.npc = {} 11386 stat_list.kraylor.npc_score_total = 0 11387 stat_list.kraylor.station_score_total = 0 11388 stat_list.kraylor.station = {} 11389 if exuari_angle ~= nil then 11390 stat_list.exuari = {} 11391 stat_list.exuari.ship = {} 11392 stat_list.exuari.ship_score_total = 0 11393 stat_list.exuari.npc = {} 11394 stat_list.exuari.npc_score_total = 0 11395 stat_list.exuari.station_score_total = 0 11396 stat_list.exuari.station = {} 11397 end 11398 if ktlitan_angle ~= nil then 11399 stat_list.ktlitan = {} 11400 stat_list.ktlitan.ship = {} 11401 stat_list.ktlitan.ship_score_total = 0 11402 stat_list.ktlitan.npc = {} 11403 stat_list.ktlitan.npc_score_total = 0 11404 stat_list.ktlitan.station_score_total = 0 11405 stat_list.ktlitan.station = {} 11406 end 11407 for pidx=1,32 do 11408 p = getPlayerShip(pidx) 11409 if p ~= nil then 11410 if p:isValid() then 11411 local faction = p:getFaction() 11412 if p.shipScore ~= nil then 11413 stat_list[f2s[faction]].ship_score_total = stat_list[f2s[faction]].ship_score_total + p.shipScore 11414 stat_list[f2s[faction]].ship[p:getCallSign()] = {template_type = p:getTypeName(), is_alive = true, score_value = p.shipScore} 11415 else 11416 print("ship score for " .. p:getCallSign() .. " has not been set") 11417 end 11418 end 11419 end 11420 end 11421 if npc_fleet ~= nil then 11422 for faction, list in pairs(npc_fleet) do 11423 for _, ship in ipairs(list) do 11424 if ship:isValid() then 11425 stat_list[f2s[faction]].npc_score_total = stat_list[f2s[faction]].npc_score_total + ship.score_value 11426 stat_list[f2s[faction]].npc[ship:getCallSign()] = {template_type = ship:getTypeName(), is_alive = true, score_value = ship.score_value} 11427 end 11428 end 11429 end 11430 end 11431 if scientist_list ~= nil then 11432 for faction, list in pairs(scientist_list) do 11433 for _, scientist in ipairs(list) do 11434 if scientist.location:isValid() then 11435 stat_list[f2s[faction]].npc_score_total = stat_list[f2s[faction]].npc_score_total + scientist.score_value 11436 stat_list[f2s[faction]].npc[scientist.name] = {topic = scientist.topic, is_alive = true, score_value = scientist.score_value, location_name = scientist.location_name} 11437 end 11438 end 11439 end 11440 end 11441 for faction, list in pairs(station_list) do 11442 for _, station in ipairs(list) do 11443 if station:isValid() then 11444 stat_list[f2s[faction]].station_score_total = stat_list[f2s[faction]].station_score_total + station.score_value 11445 stat_list[f2s[faction]].station[station:getCallSign()] = {template_type = station:getTypeName(), is_alive = true, score_value = station.score_value} 11446 end 11447 end 11448 end 11449 local station_weight = .6 11450 local player_ship_weight = .3 11451 local npc_ship_weight = .1 11452 stat_list.weight = {} 11453 stat_list.weight.station = station_weight 11454 stat_list.weight.ship = player_ship_weight 11455 stat_list.weight.npc = npc_ship_weight 11456 local human_death_penalty = 0 11457 local kraylor_death_penalty = 0 11458 local exuari_death_penalty = 0 11459 local ktlitan_death_penalty = 0 11460 if respawn_type == "self" then 11461 human_death_penalty = death_penalty["Human Navy"] 11462 kraylor_death_penalty = death_penalty["Kraylor"] 11463 if exuari_angle ~= nil then 11464 exuari_death_penalty = death_penalty["Exuari"] 11465 end 11466 if ktlitan_angle ~= nil then 11467 ktlitan_death_penalty = death_penalty["Ktlitans"] 11468 end 11469 end 11470 stat_list.human.weighted_score = 11471 stat_list.human.station_score_total*station_weight + 11472 stat_list.human.ship_score_total*player_ship_weight + 11473 stat_list.human.npc_score_total*npc_ship_weight - 11474 human_death_penalty 11475 stat_list.kraylor.weighted_score = 11476 stat_list.kraylor.station_score_total*station_weight + 11477 stat_list.kraylor.ship_score_total*player_ship_weight + 11478 stat_list.kraylor.npc_score_total*npc_ship_weight - 11479 kraylor_death_penalty 11480 if exuari_angle ~= nil then 11481 stat_list.exuari.weighted_score = 11482 stat_list.exuari.station_score_total*station_weight + 11483 stat_list.exuari.ship_score_total*player_ship_weight + 11484 stat_list.exuari.npc_score_total*npc_ship_weight - 11485 exuari_death_penalty 11486 end 11487 if ktlitan_angle ~= nil then 11488 stat_list.ktlitan.weighted_score = 11489 stat_list.ktlitan.station_score_total*station_weight + 11490 stat_list.ktlitan.ship_score_total*player_ship_weight + 11491 stat_list.ktlitan.npc_score_total*npc_ship_weight - 11492 ktlitan_death_penalty 11493 end 11494 if original_score ~= nil then 11495 stat_list.human.original_weighted_score = original_score["Human Navy"] 11496 stat_list.kraylor.original_weighted_score = original_score["Kraylor"] 11497 if exuari_angle ~= nil then 11498 stat_list.exuari.original_weighted_score = original_score["Exuari"] 11499 end 11500 if ktlitan_angle ~= nil then 11501 stat_list.ktlitan.original_weighted_score = original_score["Ktlitans"] 11502 end 11503 end 11504 return stat_list 11505end 11506function pickWinner(reason) 11507 local stat_list = gatherStats() 11508 local sorted_faction = {} 11509 local tie_breaker = {} 11510 for pidx=1,32 do 11511 local p = getPlayerShip(pidx) 11512 if p ~= nil and p:isValid() then 11513 tie_breaker[p:getFaction()] = p:getReputationPoints()/10000 11514 end 11515 end 11516 stat_list.human.weighted_score = stat_list.human.weighted_score + tie_breaker["Human Navy"] 11517 table.insert(sorted_faction,{name="Human Navy",score=stat_list.human.weighted_score}) 11518 stat_list.kraylor.weighted_score = stat_list.kraylor.weighted_score + tie_breaker["Kraylor"] 11519 table.insert(sorted_faction,{name="Kraylor",score=stat_list.kraylor.weighted_score}) 11520 if exuari_angle ~= nil then 11521 stat_list.exuari.weighted_score = stat_list.exuari.weighted_score + tie_breaker["Exuari"] 11522 table.insert(sorted_faction,{name="Exuari",score=stat_list.exuari.weighted_score}) 11523 end 11524 if ktlitan_angle ~= nil then 11525 stat_list.ktlitan.weighted_score = stat_list.ktlitan.weighted_score + tie_breaker["Ktlitans"] 11526 table.insert(sorted_faction,{name="Ktlitans",score=stat_list.ktlitan.weighted_score}) 11527 end 11528 table.sort(sorted_faction,function(a,b) 11529 return a.score > b.score 11530 end) 11531 local out = string.format("%s wins with a score of %.1f!\n",sorted_faction[1].name,sorted_faction[1].score) 11532 for i=2,#sorted_faction do 11533 out = out .. string.format("%s:%.1f ",sorted_faction[i].name,sorted_faction[i].score) 11534 end 11535 out = out .. "\n" .. reason 11536 print(out) 11537 print("Humans:",stat_list.human.weighted_score) 11538 print("Kraylor:",stat_list.kraylor.weighted_score) 11539 if exuari_angle then 11540 print("Exuari:",stat_list.exuari.weighted_score) 11541 end 11542 if ktlitan_angle then 11543 print("Ktlitans:",stat_list.ktlitan.weighted_score) 11544 end 11545 addGMMessage(out) 11546 globalMessage(out) 11547 game_state = string.format("victory-%s",f2s[sorted_faction[1].name]) 11548 victory(sorted_faction[1].name) 11549end 11550function update(delta) 11551 if delta == 0 then 11552 --game paused 11553 return 11554 end 11555 if respawn_countdown ~= nil then 11556 respawn_countdown = respawn_countdown - delta 11557 if respawn_countdown < 0 then 11558 delayedRespawn() 11559 end 11560 end 11561 if mainGMButtons == mainGMButtonsDuringPause then 11562 mainGMButtons = mainGMButtonsAfterPause 11563 mainGMButtons() 11564 end 11565 if not terrain_generated then 11566 generateTerrain() 11567 end 11568 game_state = "running" 11569 local stat_list = gatherStats() 11570 if stat_list.human.weighted_score < original_score["Human Navy"]/2 then 11571 pickWinner("End cause: Human Navy fell below 50% of original strength") 11572 end 11573 if stat_list.kraylor.weighted_score < original_score["Kraylor"]/2 then 11574 pickWinner("End cause: Kraylor fell below 50% of original strength") 11575 end 11576 if exuari_angle ~= nil then 11577 if stat_list.exuari.weighted_score < original_score["Exuari"]/2 then 11578 pickWinner("End cause: Exuari fell below 50% of original strength") 11579 end 11580 end 11581 if ktlitan_angle ~= nil then 11582 if stat_list.ktlitan.weighted_score < original_score["Ktlitans"]/2 then 11583 pickWinner("End cause: Ktlitans fell below 50% of original strength") 11584 end 11585 end 11586 game_time_limit = game_time_limit - delta 11587 if game_time_limit < 0 then 11588 pickWinner("End cause: Time ran out") 11589 end 11590 local hrs = stat_list.human.weighted_score/original_score["Human Navy"] 11591 local krs = stat_list.kraylor.weighted_score/original_score["Kraylor"] 11592 local rel_dif = math.abs(hrs-krs) 11593 if rel_dif > thresh then 11594 if exuari_angle ~= nil then 11595 ers = stat_list.exuari.weighted_score/original_score["Exuari"] 11596 rel_dif = math.abs(hrs-ers) 11597 local ref_dif_2 = math.abs(ers-krs) 11598 if rel_dif > thresh or ref_dif_2 > thresh then 11599 if ktlitan_angle ~= nil then 11600 brs = stat_list.ktlitan.weighted_score/original_score["Ktlitans"] 11601 rel_dif = math.abs(brs-ers) 11602 ref_dif_2 = math.abs(brs-krs) 11603 local rel_dif_3 = math.abs(hrs-brs) 11604 if rel_dif > thresh or ref_dif_2 > thresh or rel_dif_3 > thresh then 11605 pickWinner(string.format("End cause: score difference exceeded %i%%",thresh*100)) 11606 end 11607 else 11608 pickWinner(string.format("End cause: score difference exceeded %i%%",thresh*100)) 11609 end 11610 end 11611 else 11612 pickWinner(string.format("End cause: score difference exceeded %i%%",thresh*100)) 11613 end 11614 end 11615 local score_banner = string.format("H:%i K:%i",math.floor(stat_list.human.weighted_score),math.floor(stat_list.kraylor.weighted_score)) 11616 if exuari_angle ~= nil then 11617 score_banner = string.format("%s E:%i",score_banner,math.floor(stat_list.exuari.weighted_score)) 11618 end 11619 if ktlitan_angle ~= nil then 11620 score_banner = string.format("%s B:%i",score_banner,math.floor(stat_list.ktlitan.weighted_score)) 11621 end 11622 if game_time_limit > 60 then 11623 score_banner = string.format("%s %i:%.2i",score_banner,stat_list.times.game.minutes_left,stat_list.times.game.seconds_left) 11624 else 11625 score_banner = string.format("%s %i",score_banner,stat_list.times.game.seconds_left) 11626 end 11627 if scientist_asset_message == nil then 11628 scientist_asset_message = "sent" 11629 if scientist_list ~= nil then 11630 for pidx=1,32 do 11631 local p = getPlayerShip(pidx) 11632 if p ~= nil and p:isValid() then 11633 if scientist_list[p:getFaction()] ~= nil then 11634 if #scientist_list[p:getFaction()] > 1 then 11635 p:addToShipLog("In addition to the stations and fleet assets, Command has deemed certain scientists as critical to the war effort. Loss of these scientists will count against you like the loss of stations and fleet assets will. Scientist list:","Magenta") 11636 else 11637 p:addToShipLog("In addition to the stations and fleet assets, Command has deemed this scientist as critical to the war effort. Loss of this scientist will count against you like the loss of stations and fleet assets will. Scientist:","Magenta") 11638 end 11639 for _, scientist in ipairs(scientist_list[p:getFaction()]) do 11640 p:addToShipLog(string.format("Value: %i, Name: %s, Specialization: %s, Location: %s",scientist.score_value,scientist.name,scientist.topic,scientist.location_name),"Magenta") 11641 end 11642 if #scientist_list[p:getFaction()] > 1 then 11643 p:addToShipLog("These scientists will be weighted with the other NPC assets","Magenta") 11644 else 11645 p:addToShipLog("This scientist will be weighted with the other NPC assets","Magenta") 11646 end 11647 end 11648 end 11649 end 11650 end 11651 end 11652 healthCheckTimer = healthCheckTimer - delta 11653 local warning_message = nil 11654 local warning_station = nil 11655 local warning_message = {} 11656 local warning_station = {} 11657 for stn_faction, stn_list in pairs(station_list) do 11658 for station_index=1,#stn_list do 11659 local current_station = stn_list[station_index] 11660 if current_station ~= nil and current_station:isValid() then 11661 if current_station.proximity_warning == nil then 11662 for _, obj in ipairs(current_station:getObjectsInRange(station_sensor_range)) do 11663 if obj ~= nil and obj:isValid() then 11664 if obj:isEnemy(current_station) then 11665 local obj_type_name = obj.typeName 11666 if obj_type_name ~= nil and string.find(obj_type_name,"PlayerSpaceship") then 11667 warning_station[stn_faction] = current_station 11668 warning_message[stn_faction] = string.format("[%s in %s] We detect one or more enemies nearby. At least one is of type %s",current_station:getCallSign(),current_station:getSectorName(),obj:getTypeName()) 11669 current_station.proximity_warning = warning_message[stn_faction] 11670 current_station.proximity_warning_timer = delta + 300 11671 break 11672 end 11673 end 11674 end 11675 end 11676 if warning_station[stn_faction] ~= nil then --was originally warning message 11677 break 11678 end 11679 else 11680 current_station.proximity_warning_timer = current_station.proximity_warning_timer - delta 11681 if current_station.proximity_warning_timer < 0 then 11682 current_station.proximity_warning = nil 11683 end 11684 end 11685 if warning_station[stn_faction] == nil then 11686 --shield damage warning 11687 if current_station.shield_damage_warning == nil then 11688 for i=1,current_station:getShieldCount() do 11689 if current_station:getShieldLevel(i-1) < current_station:getShieldMax(i-1) then 11690 warning_station[stn_faction] = current_station 11691 warning_message[stn_faction] = string.format("[%s in %s] Our shields have taken damage",current_station:getCallSign(),current_station:getSectorName()) 11692 current_station.shield_damage_warning = warning_message[stn_faction] 11693 current_station.shield_damage_warning_timer = delta + 300 11694 break 11695 end 11696 end 11697 if warning_station[stn_faction] ~= nil then 11698 break 11699 end 11700 else 11701 current_station.shield_damage_warning_timer = current_station.shield_damage_warning_timer - delta 11702 if current_station.shield_damage_warning_timer < 0 then 11703 current_station.shield_damage_warning = nil 11704 end 11705 end 11706 end 11707 if warning_station[stn_faction] == nil then 11708 --severe shield damage warning 11709 if current_station.severe_shield_warning == nil then 11710 local current_station_shield_count = current_station:getShieldCount() 11711 for i=1,current_station_shield_count do 11712 if current_station:getShieldLevel(i-1) < current_station:getShieldMax(i-1)*.1 then 11713 warning_station[stn_faction] = current_station 11714 if current_station_shield_count == 1 then 11715 warning_message[stn_faction] = string.format("[%s in %s] Our shields are nearly gone",current_station:getCallSign(),current_station:getSectorName()) 11716 else 11717 warning_message[stn_faction] = string.format("[%s in %s] One or more of our shields are nearly gone",current_station:getCallSign(),current_station:getSectorName()) 11718 end 11719 current_station.severe_shield_warning = warning_message[stn_faction] 11720 current_station.severe_shield_warning_timer = delta + 300 11721 break 11722 end 11723 end 11724 if warning_station[stn_faction] ~= nil then 11725 break 11726 end 11727 else 11728 current_station.severe_shield_warning_timer = current_station.severe_shield_warning_timer - delta 11729 if current_station.severe_shield_warning_timer < 0 then 11730 current_station.severe_shield_warning = nil 11731 end 11732 end 11733 end 11734 if warning_station[stn_faction] == nil then 11735 --hull damage warning 11736 if current_station.hull_warning == nil then 11737 if current_station:getHull() < current_station:getHullMax() then 11738 warning_station[stn_faction] = current_station 11739 warning_message[stn_faction] = string.format("[%s in %s] Our hull has been damaged",current_station:getCallSign(),current_station:getSectorName()) 11740 current_station.hull_warning = warning_message[stn_faction] 11741 break 11742 end 11743 end 11744 end 11745 if warning_station[stn_faction] == nil then 11746 --severe hull damage warning 11747 if current_station.severe_hull_warning == nil then 11748 if current_station:getHull() < current_station:getHullMax()*.1 then 11749 warning_station[stn_faction] = current_station 11750 warning_message[stn_faction] = string.format("[%s in %s] We are on the brink of destruction",current_station:getCallSign(),current_station:getSectorName()) 11751 current_station.severe_hull_warning = warning_message[stn_faction] 11752 end 11753 end 11754 end 11755 end -- current station not nil and is valid 11756 end 11757 end 11758 for pidx=1,32 do 11759 local p = getPlayerShip(pidx) 11760 if p ~= nil and p:isValid() then 11761 local player_name = p:getCallSign() 11762 if warning_station["Human Navy"] ~= nil and p:getFaction() == "Human Navy" then 11763 p:addToShipLog(warning_message["Human Navy"],"Red") 11764 end 11765 if warning_station["Kraylor"] ~= nil and p:getFaction() == "Kraylor" then 11766 p:addToShipLog(warning_message["Kraylor"],"Red") 11767 end 11768 if exuari_angle ~= nil then 11769 if warning_station["Exuari"] ~= nil and p:getFaction() == "Exuari" then 11770 p:addToShipLog(warning_message["Exuari"],"Red") 11771 end 11772 end 11773 if ktlitan_angle ~= nil then 11774 if warning_station["Ktlitans"] ~= nil and p:getFaction() == "Ktlitans" then 11775 p:addToShipLog(warning_message["Ktlitans"],"Red") 11776 end 11777 end 11778 local name_tag_text = string.format("%s in %s",player_name,p:getSectorName()) 11779 if p:hasPlayerAtPosition("Relay") then 11780 p.name_tag = "name_tag" 11781 p:addCustomInfo("Relay",p.name_tag,name_tag_text) 11782 p.score_banner = "score_banner" 11783 p:addCustomInfo("Relay",p.score_banner,score_banner) 11784 end 11785 if p:hasPlayerAtPosition("Operations") then 11786 p.name_tag_ops = "name_tag_ops" 11787 p:addCustomInfo("Operations",p.name_tag_ops,name_tag_text) 11788 p.score_banner_ops = "score_banner_ops" 11789 p:addCustomInfo("Operations",p.score_banner_ops,score_banner) 11790 end 11791 if p:hasPlayerAtPosition("ShipLog") then 11792 p.name_tag_log = "name_tag_log" 11793 p:addCustomInfo("ShipLog",p.name_tag_log,name_tag_text) 11794 p.score_banner_log = "score_banner_log" 11795 p:addCustomInfo("ShipLog",p.score_banner_log,score_banner) 11796 end 11797 if p:hasPlayerAtPosition("Helms") then 11798 p.name_tag_helm = "name_tag_helm" 11799 p:addCustomInfo("Helms",p.name_tag_helm,name_tag_text) 11800 end 11801 if p:hasPlayerAtPosition("Tactical") then 11802 p.name_tag_tac = "name_tag_tac" 11803 p:addCustomInfo("Tactical",p.name_tag_tac,name_tag_text) 11804 end 11805 if p.inventoryButton == nil then 11806 local goodCount = 0 11807 if p.goods ~= nil then 11808 for good, goodQuantity in pairs(p.goods) do 11809 goodCount = goodCount + 1 11810 end 11811 end 11812 if goodCount > 0 then --add inventory button when cargo acquired 11813 if p:hasPlayerAtPosition("Relay") then 11814 if p.inventoryButton == nil then 11815 local tbi = "inventory" .. player_name 11816 p:addCustomButton("Relay",tbi,"Inventory",function () playerShipCargoInventory(p) end) 11817 p.inventoryButton = true 11818 end 11819 end 11820 if p:hasPlayerAtPosition("Operations") then 11821 if p.inventoryButton == nil then 11822 local tbi = "inventoryOp" .. player_name 11823 p:addCustomButton("Operations",tbi,"Inventory", function () playerShipCargoInventory(p) end) 11824 p.inventoryButton = true 11825 end 11826 end 11827 end 11828 end 11829 if healthCheckTimer < 0 then --check to see if any crew perish (or other consequences) due to excessive damage 11830 if p:getRepairCrewCount() > 0 then 11831 local fatalityChance = 0 11832 local currentShield = 0 11833 if p:getShieldCount() > 1 then 11834 currentShield = (p:getSystemHealth("frontshield") + p:getSystemHealth("rearshield"))/2 11835 else 11836 currentShield = p:getSystemHealth("frontshield") 11837 end 11838 fatalityChance = fatalityChance + (p.prevShield - currentShield) 11839 p.prevShield = currentShield 11840 local currentReactor = p:getSystemHealth("reactor") 11841 fatalityChance = fatalityChance + (p.prevReactor - currentReactor) 11842 p.prevReactor = currentReactor 11843 local currentManeuver = p:getSystemHealth("maneuver") 11844 fatalityChance = fatalityChance + (p.prevManeuver - currentManeuver) 11845 p.prevManeuver = currentManeuver 11846 local currentImpulse = p:getSystemHealth("impulse") 11847 fatalityChance = fatalityChance + (p.prevImpulse - currentImpulse) 11848 p.prevImpulse = currentImpulse 11849 if p:getBeamWeaponRange(0) > 0 then 11850 if p.healthyBeam == nil then 11851 p.healthyBeam = 1.0 11852 p.prevBeam = 1.0 11853 end 11854 local currentBeam = p:getSystemHealth("beamweapons") 11855 fatalityChance = fatalityChance + (p.prevBeam - currentBeam) 11856 p.prevBeam = currentBeam 11857 end 11858 if p:getWeaponTubeCount() > 0 then 11859 if p.healthyMissile == nil then 11860 p.healthyMissile = 1.0 11861 p.prevMissile = 1.0 11862 end 11863 local currentMissile = p:getSystemHealth("missilesystem") 11864 fatalityChance = fatalityChance + (p.prevMissile - currentMissile) 11865 p.prevMissile = currentMissile 11866 end 11867 if p:hasWarpDrive() then 11868 if p.healthyWarp == nil then 11869 p.healthyWarp = 1.0 11870 p.prevWarp = 1.0 11871 end 11872 local currentWarp = p:getSystemHealth("warp") 11873 fatalityChance = fatalityChance + (p.prevWarp - currentWarp) 11874 p.prevWarp = currentWarp 11875 end 11876 if p:hasJumpDrive() then 11877 if p.healthyJump == nil then 11878 p.healthyJump = 1.0 11879 p.prevJump = 1.0 11880 end 11881 local currentJump = p:getSystemHealth("jumpdrive") 11882 fatalityChance = fatalityChance + (p.prevJump - currentJump) 11883 p.prevJump = currentJump 11884 end 11885 if p:getRepairCrewCount() == 1 then 11886 fatalityChance = fatalityChance/2 -- increase survival chances of last repair crew standing 11887 end 11888 if fatalityChance > 0 then 11889 if math.random() < (fatalityChance) then 11890 if p.initialCoolant == nil then 11891 p:setRepairCrewCount(p:getRepairCrewCount() - 1) 11892 if p:hasPlayerAtPosition("Engineering") then 11893 local repairCrewFatality = "repairCrewFatality" 11894 p:addCustomMessage("Engineering",repairCrewFatality,"One of your repair crew has perished") 11895 end 11896 if p:hasPlayerAtPosition("Engineering+") then 11897 local repairCrewFatalityPlus = "repairCrewFatalityPlus" 11898 p:addCustomMessage("Engineering+",repairCrewFatalityPlus,"One of your repair crew has perished") 11899 end 11900 else 11901 local consequence = 0 11902 local upper_consequence = 2 11903 local consequence_list = {} 11904 if p:getCanLaunchProbe() then 11905 upper_consequence = upper_consequence + 1 11906 table.insert(consequence_list,"probe") 11907 end 11908 if p:getCanHack() then 11909 upper_consequence = upper_consequence + 1 11910 table.insert(consequence_list,"hack") 11911 end 11912 if p:getCanScan() then 11913 upper_consequence = upper_consequence + 1 11914 table.insert(consequence_list,"scan") 11915 end 11916 if p:getCanCombatManeuver() then 11917 upper_consequence = upper_consequence + 1 11918 table.insert(consequence_list,"combat_maneuver") 11919 end 11920 if p:getCanSelfDestruct() then 11921 upper_consequence = upper_consequence + 1 11922 table.insert(consequence_list,"self_destruct") 11923 end 11924 if p:getWeaponTubeCount() > 0 then 11925 upper_consequence = upper_consequence + 1 11926 table.insert(consequence_list,"tube_time") 11927 end 11928 consequence = math.random(1,upper_consequence) 11929 if consequence == 1 then 11930 p:setRepairCrewCount(p:getRepairCrewCount() - 1) 11931 if p:hasPlayerAtPosition("Engineering") then 11932 local repairCrewFatality = "repairCrewFatality" 11933 p:addCustomMessage("Engineering",repairCrewFatality,"One of your repair crew has perished") 11934 end 11935 if p:hasPlayerAtPosition("Engineering+") then 11936 local repairCrewFatalityPlus = "repairCrewFatalityPlus" 11937 p:addCustomMessage("Engineering+",repairCrewFatalityPlus,"One of your repair crew has perished") 11938 end 11939 elseif consequence == 2 then 11940 local current_coolant = p:getMaxCoolant() 11941 local lost_coolant = 0 11942 if current_coolant >= 10 then 11943 lost_coolant = current_coolant*random(.25,.5) --lose between 25 and 50 percent 11944 else 11945 lost_coolant = current_coolant*random(.15,.35) --lose between 15 and 35 percent 11946 end 11947 p:setMaxCoolant(current_coolant - lost_coolant) 11948 if p.reclaimable_coolant == nil then 11949 p.reclaimable_coolant = 0 11950 end 11951 p.reclaimable_coolant = math.min(20,p.reclaimable_coolant + lost_coolant*random(.8,1)) 11952 if p:hasPlayerAtPosition("Engineering") then 11953 local coolantLoss = "coolantLoss" 11954 p:addCustomMessage("Engineering",coolantLoss,"Damage has caused a loss of coolant") 11955 end 11956 if p:hasPlayerAtPosition("Engineering+") then 11957 local coolantLossPlus = "coolantLossPlus" 11958 p:addCustomMessage("Engineering+",coolantLossPlus,"Damage has caused a loss of coolant") 11959 end 11960 else 11961 local named_consequence = consequence_list[consequence-2] 11962 if named_consequence == "probe" then 11963 p:setCanLaunchProbe(false) 11964 if p:hasPlayerAtPosition("Engineering") then 11965 p:addCustomMessage("Engineering","probe_launch_damage_message","The probe launch system has been damaged") 11966 end 11967 if p:hasPlayerAtPosition("Engineering+") then 11968 p:addCustomMessage("Engineering+","probe_launch_damage_message_plus","The probe launch system has been damaged") 11969 end 11970 elseif named_consequence == "hack" then 11971 p:setCanHack(false) 11972 if p:hasPlayerAtPosition("Engineering") then 11973 p:addCustomMessage("Engineering","hack_damage_message","The hacking system has been damaged") 11974 end 11975 if p:hasPlayerAtPosition("Engineering+") then 11976 p:addCustomMessage("Engineering+","hack_damage_message_plus","The hacking system has been damaged") 11977 end 11978 elseif named_consequence == "scan" then 11979 p:setCanScan(false) 11980 if p:hasPlayerAtPosition("Engineering") then 11981 p:addCustomMessage("Engineering","scan_damage_message","The scanners have been damaged") 11982 end 11983 if p:hasPlayerAtPosition("Engineering+") then 11984 p:addCustomMessage("Engineering+","scan_damage_message_plus","The scanners have been damaged") 11985 end 11986 elseif named_consequence == "combat_maneuver" then 11987 p:setCanCombatManeuver(false) 11988 if p:hasPlayerAtPosition("Engineering") then 11989 p:addCustomMessage("Engineering","combat_maneuver_damage_message","Combat maneuver has been damaged") 11990 end 11991 if p:hasPlayerAtPosition("Engineering+") then 11992 p:addCustomMessage("Engineering+","combat_maneuver_damage_message_plus","Combat maneuver has been damaged") 11993 end 11994 elseif named_consequence == "self_destruct" then 11995 p:setCanSelfDestruct(false) 11996 if p:hasPlayerAtPosition("Engineering") then 11997 p:addCustomMessage("Engineering","self_destruct_damage_message","Self destruct system has been damaged") 11998 end 11999 if p:hasPlayerAtPosition("Engineering+") then 12000 p:addCustomMessage("Engineering+","self_destruct_damage_message_plus","Self destruct system has been damaged") 12001 end 12002 elseif named_consequence == "tube_time" then 12003 local tube_count = p:getWeaponTubeCount() 12004 local tube_index = 0 12005 if p.normal_tube_load_time == nil then 12006 p.normal_tube_load_time = {} 12007 repeat 12008 p.normal_tube_load_time[tube_index] = p:getTubeLoadTime(tube_index) 12009 tube_index = tube_index + 1 12010 until(tube_index >= tube_count) 12011 tube_index = 0 12012 end 12013 repeat 12014 p:setTubeLoadTime(tube_index,p:getTubeLoadTime(tube_index) + 2) 12015 tube_index = tube_index + 1 12016 until(tube_index >= tube_count) 12017 if p:hasPlayerAtPosition("Engineering") then 12018 p:addCustomMessage("Engineering","tube_slow_down_message","Tube damage has caused tube load time to increase") 12019 end 12020 if p:hasPlayerAtPosition("Engineering+") then 12021 p:addCustomMessage("Engineering+","tube_slow_down_message_plus","Tube damage has caused tube load time to increase") 12022 end 12023 end 12024 end --coolant loss branch 12025 end --could lose coolant branch 12026 end --bad consequences of damage branch 12027 end --possible chance of bad consequences branch 12028 else --no repair crew left 12029 if random(1,100) <= 4 then 12030 p:setRepairCrewCount(1) 12031 if p:hasPlayerAtPosition("Engineering") then 12032 local repairCrewRecovery = "repairCrewRecovery" 12033 p:addCustomMessage("Engineering",repairCrewRecovery,"Medical team has revived one of your repair crew") 12034 end 12035 if p:hasPlayerAtPosition("Engineering+") then 12036 local repairCrewRecoveryPlus = "repairCrewRecoveryPlus" 12037 p:addCustomMessage("Engineering+",repairCrewRecoveryPlus,"Medical team has revived one of your repair crew") 12038 end 12039 resetPreviousSystemHealth(p) 12040 end --medical science triumph branch 12041 end --no repair crew left 12042 if p.initialCoolant ~= nil then 12043 current_coolant = p:getMaxCoolant() 12044 if current_coolant < 20 then 12045 if random(1,100) <= 4 then 12046 local reclaimed_coolant = 0 12047 if p.reclaimable_coolant ~= nil and p.reclaimable_coolant > 0 then 12048 reclaimed_coolant = p.reclaimable_coolant*random(.1,.5) --get back 10 to 50 percent of reclaimable coolant 12049 p:setMaxCoolant(math.min(20,current_coolant + reclaimed_coolant)) 12050 p.reclaimable_coolant = p.reclaimable_coolant - reclaimed_coolant 12051 end 12052 local noticable_reclaimed_coolant = math.floor(reclaimed_coolant) 12053 if noticable_reclaimed_coolant > 0 then 12054 if p:hasPlayerAtPosition("Engineering") then 12055 local coolant_recovery = "coolant_recovery" 12056 p:addCustomMessage("Engineering",coolant_recovery,"Automated systems have recovered some coolant") 12057 end 12058 if p:hasPlayerAtPosition("Engineering+") then 12059 local coolant_recovery_plus = "coolant_recovery_plus" 12060 p:addCustomMessage("Engineering+",coolant_recovery_plus,"Automated systems have recovered some coolant") 12061 end 12062 end 12063 resetPreviousSystemHealth(p) 12064 end 12065 end 12066 end 12067 end --health check branch 12068 local secondary_systems_optimal = true 12069 if not p:getCanLaunchProbe() then 12070 secondary_systems_optimal = false 12071 end 12072 if secondary_systems_optimal and not p:getCanHack() then 12073 secondary_systems_optimal = false 12074 end 12075 if secondary_systems_optimal and not p:getCanScan() then 12076 secondary_systems_optimal = false 12077 end 12078 if secondary_systems_optimal and not p:getCanCombatManeuver() then 12079 secondary_systems_optimal = false 12080 end 12081 if secondary_systems_optimal and not p:getCanSelfDestruct() then 12082 secondary_systems_optimal = false 12083 end 12084 if secondary_systems_optimal then 12085 local tube_count = p:getWeaponTubeCount() 12086 if tube_count > 0 and p.normal_tube_load_time ~= nil then 12087 local tube_index = 0 12088 repeat 12089 if p.normal_tube_load_time[tube_index] ~= p:getTubeLoadTime(tube_index) then 12090 secondary_systems_optimal = false 12091 break 12092 end 12093 tube_index = tube_index + 1 12094 until(tube_index >= tube_count) 12095 end 12096 end 12097 if secondary_systems_optimal then --remove damage report button 12098 if p.damage_report ~= nil then 12099 p:removeCustom(p.damage_report) 12100 p.damage_report = nil 12101 end 12102 if p.damage_report_plus ~= nil then 12103 p:removeCustom(p.damage_report_plus) 12104 p.damage_report_plus = nil 12105 end 12106 else --add damage report button 12107 if p:hasPlayerAtPosition("Engineering") then 12108 p.damage_report = "damage_report" 12109 p:addCustomButton("Engineering",p.damage_report,"Damage Report",function() 12110 local dmg_msg = "In addition to the primary systems constantly monitored in engineering, the following secondary systems have also been damaged requiring docking repair facilities:" 12111 if not p:getCanLaunchProbe() then 12112 dmg_msg = dmg_msg .. "\nProbe launch system" 12113 end 12114 if not p:getCanHack() then 12115 dmg_msg = dmg_msg .. "\nHacking system" 12116 end 12117 if not p:getCanScan() then 12118 dmg_msg = dmg_msg .. "\nScanning system" 12119 end 12120 if not p:getCanCombatManeuver() then 12121 dmg_msg = dmg_msg .. "\nCombat maneuvering system" 12122 end 12123 if not p:getCanSelfDestruct() then 12124 dmg_msg = dmg_msg .. "\nSelf destruct system" 12125 end 12126 local tube_count = p:getWeaponTubeCount() 12127 if tube_count > 0 then 12128 if tube_count > 0 and p.normal_tube_load_time ~= nil then 12129 local tube_index = 0 12130 repeat 12131 if p.normal_tube_load_time[tube_index] ~= p:getTubeLoadTime(tube_index) then 12132 dmg_msg = dmg_msg .. "\nWeapon tube load time degraded" 12133 break 12134 end 12135 tube_index = tube_index + 1 12136 until(tube_index >= tube_count) 12137 end 12138 end 12139 p.dmg_msg = "dmg_msg" 12140 p:addCustomMessage("Engineering",p.dmg_msg,dmg_msg) 12141 end) 12142 end --engineering damage report button 12143 if p:hasPlayerAtPosition("Engineering+") then 12144 p.damage_report_plus = "damage_report_plus" 12145 p:addCustomButton("Engineering",p.damage_report_plus,"Damage Report",function() 12146 local dmg_msg = "In addition to the primary systems constantly monitored in engineering, the following secondary systems have also been damaged requiring docking repair facilities:" 12147 if not p:getCanLaunchProbe() then 12148 dmg_msg = dmg_msg .. "\nProbe launch system" 12149 end 12150 if not p:getCanHack() then 12151 dmg_msg = dmg_msg .. "\nHacking system" 12152 end 12153 if not p:getCanScan() then 12154 dmg_msg = dmg_msg .. "\nScanning system" 12155 end 12156 if not p:getCanCombatManeuver() then 12157 dmg_msg = dmg_msg .. "\nCombat maneuvering system" 12158 end 12159 if not p:getCanSelfDestruct() then 12160 dmg_msg = dmg_msg .. "\nSelf destruct system" 12161 end 12162 local tube_count = p:getWeaponTubeCount() 12163 if tube_count > 0 then 12164 if tube_count > 0 and p.normal_tube_load_time ~= nil then 12165 local tube_index = 0 12166 repeat 12167 if p.normal_tube_load_time[tube_index] ~= p:getTubeLoadTime(tube_index) then 12168 dmg_msg = dmg_msg .. "\nWeapon tube load time degraded" 12169 break 12170 end 12171 tube_index = tube_index + 1 12172 until(tube_index >= tube_count) 12173 end 12174 end 12175 p.dmg_msg = "dmg_msg" 12176 p:addCustomMessage("Engineering+",p.dmg_msg,dmg_msg) 12177 end) 12178 end --engineering plus damage report button 12179 end --damage report button necessary 12180 if p.normal_long_range_radar == nil then 12181 p.normal_long_range_radar = p:getLongRangeRadarRange() 12182 end 12183 local sensor_boost_amount = 0 12184 local sensor_boost_present = false 12185 if station_primary_human:isValid() then 12186 if p:isDocked(station_primary_human) then 12187 sensor_boost_present = true 12188 sensor_boost_amount = station_primary_human.comms_data.sensor_boost.value 12189 end 12190 end 12191 if station_primary_kraylor:isValid() then 12192 if p:isDocked(station_primary_kraylor) then 12193 sensor_boost_present = true 12194 sensor_boost_amount = station_primary_kraylor.comms_data.sensor_boost.value 12195 end 12196 end 12197 if exuari_angle ~= nil then 12198 if station_primary_exuari:isValid() then 12199 if p:isDocked(station_primary_exuari) then 12200 sensor_boost_present = true 12201 sensor_boost_amount = station_primary_exuari.comms_data.sensor_boost.value 12202 end 12203 end 12204 end 12205 if ktlitan_angle ~= nil then 12206 if station_primary_ktlitan:isValid() then 12207 if p:isDocked(station_primary_ktlitan) then 12208 sensor_boost_present = true 12209 sensor_boost_amount = station_primary_ktlitan.comms_data.sensor_boost.value 12210 end 12211 end 12212 end 12213 local boosted_range = p.normal_long_range_radar + sensor_boost_amount 12214 if sensor_boost_present then 12215 if p:getLongRangeRadarRange() < boosted_range then 12216 p:setLongRangeRadarRange(boosted_range) 12217 end 12218 else 12219 if p:getLongRangeRadarRange() > p.normal_long_range_radar then 12220 p:setLongRangeRadarRange(p.normal_long_range_radar) 12221 end 12222 end 12223 end --p is not nil and is valid 12224 end --loop through players 12225end 12226