| 1 | |
|---|
| 2 | -- Use this script for a solar system |
|---|
| 3 | |
|---|
| 4 | -- Lua Global variables |
|---|
| 5 | shipList = {} -- The ships that Lua has access to. TODO: This list should probably be generated at each tick from a c++ call. |
|---|
| 6 | frozen=0 -- Setting this to 1 causes all AI to stop 'thinking' and just drift. |
|---|
| 7 | ticks=0 |
|---|
| 8 | player = Epiar.player() |
|---|
| 9 | shipList[0] = player |
|---|
| 10 | it_countdown=100 |
|---|
| 11 | |
|---|
| 12 | function CreateShips(number_of_ships, X, Y) |
|---|
| 13 | -- Generate Ships |
|---|
| 14 | for s =1,number_of_ships do |
|---|
| 15 | io.write("Creating Ship ",s) |
|---|
| 16 | cur_ship = EpiarLua.Ship:new( |
|---|
| 17 | math.random(1000)-500+X, -- X |
|---|
| 18 | math.random(1000)-500+Y, -- Y |
|---|
| 19 | "Terran FV-5 Frigate", -- Ship Model |
|---|
| 20 | "chase" -- Ship Script |
|---|
| 21 | ) |
|---|
| 22 | table.insert(shipList, cur_ship ) |
|---|
| 23 | end |
|---|
| 24 | |
|---|
| 25 | io.write("Ships Total: ", #shipList ,"\n") |
|---|
| 26 | end |
|---|
| 27 | |
|---|
| 28 | function SwarmAverage() |
|---|
| 29 | -- Find the swarm center |
|---|
| 30 | avg_x,avg_y = 0,0 |
|---|
| 31 | avg_angle = 0 |
|---|
| 32 | avg_vector= 0 |
|---|
| 33 | avg_speed = 0 |
|---|
| 34 | for s =1,#shipList do |
|---|
| 35 | cur_ship = shipList[s] |
|---|
| 36 | x,y = EpiarLua.Ship.GetPosition(cur_ship) |
|---|
| 37 | avg_x = avg_x + x |
|---|
| 38 | avg_y = avg_y + y |
|---|
| 39 | angle = EpiarLua.Ship.GetAngle(cur_ship) |
|---|
| 40 | vec = EpiarLua.Ship.GetMomentumAngle(cur_ship) |
|---|
| 41 | speed = EpiarLua.Ship.GetMomentumSpeed(cur_ship) |
|---|
| 42 | avg_angle = avg_angle + angle |
|---|
| 43 | avg_vector= avg_vector+ vec |
|---|
| 44 | avg_speed = avg_speed + speed |
|---|
| 45 | end |
|---|
| 46 | avg_x = avg_x / #shipList |
|---|
| 47 | avg_y = avg_y / #shipList |
|---|
| 48 | avg_angle = avg_angle / #shipList |
|---|
| 49 | avg_vector = avg_vector / #shipList |
|---|
| 50 | avg_speed = avg_speed / #shipList |
|---|
| 51 | return avg_x,avg_y,avg_angle,avg_vector,avg_speed |
|---|
| 52 | end |
|---|
| 53 | |
|---|
| 54 | function distfrom( pt1_x,pt1_y, pt2_x,pt2_y) |
|---|
| 55 | x_diff = (pt1_x - pt2_x) |
|---|
| 56 | y_diff = pt1_y - pt2_y |
|---|
| 57 | return math.sqrt(x_diff*x_diff + y_diff*y_diff) |
|---|
| 58 | end |
|---|
| 59 | |
|---|
| 60 | function closestToIT() |
|---|
| 61 | target=-1 |
|---|
| 62 | mindist = 100000 |
|---|
| 63 | min_x,min_y = 10000,10000 |
|---|
| 64 | it_x,it_y = EpiarLua.Ship.GetPosition(shipList[it]) |
|---|
| 65 | |
|---|
| 66 | -- Find the closest ship to whomever is IT |
|---|
| 67 | for other=0, #shipList do |
|---|
| 68 | if not(other == it) then |
|---|
| 69 | other_x,other_y = EpiarLua.Ship.GetPosition(shipList[other]) |
|---|
| 70 | dist = distfrom(other_x,other_y,it_x,it_y) |
|---|
| 71 | if dist < mindist then |
|---|
| 72 | target = other |
|---|
| 73 | mindist = dist |
|---|
| 74 | min_x,min_y = other_x,other_y |
|---|
| 75 | end |
|---|
| 76 | end |
|---|
| 77 | end |
|---|
| 78 | return target, min_x, min_y, mindist |
|---|
| 79 | end |
|---|
| 80 | |
|---|
| 81 | |
|---|
| 82 | -- The C++ engine calls this function once per tick. |
|---|
| 83 | -- This function is responsible for directing all of the game AI. |
|---|
| 84 | function Update () |
|---|
| 85 | if frozen>0 then |
|---|
| 86 | return 1 |
|---|
| 87 | end |
|---|
| 88 | |
|---|
| 89 | |
|---|
| 90 | avg_x,avg_y,avg_angle,avg_vector,avg_speed = SwarmAverage() |
|---|
| 91 | |
|---|
| 92 | player_x,player_y = EpiarLua.Ship.GetPosition(player) |
|---|
| 93 | it_x,it_y = EpiarLua.Ship.GetPosition(shipList[it]) |
|---|
| 94 | |
|---|
| 95 | -- Move |
|---|
| 96 | for s =1, # shipList do |
|---|
| 97 | cur_ship = shipList[s] |
|---|
| 98 | x,y = EpiarLua.Ship.GetPosition(cur_ship) |
|---|
| 99 | |
|---|
| 100 | if s == it then -- IT |
|---|
| 101 | dir_closest = EpiarLua.Ship.directionTowards(cur_ship, min_x,min_y) -- direction towards the closest target |
|---|
| 102 | EpiarLua.Ship.Rotate(cur_ship, dir_closest) |
|---|
| 103 | else -- Not IT |
|---|
| 104 | if math.sqrt(x*x + y*y) >3000 then |
|---|
| 105 | dir_center = EpiarLua.Ship.directionTowards(cur_ship, 0,0) -- direction towards the center of the universe |
|---|
| 106 | EpiarLua.Ship.Rotate(cur_ship, dir_center) |
|---|
| 107 | else |
|---|
| 108 | if math.random(100) <10 then |
|---|
| 109 | dir_it = EpiarLua.Ship.directionTowards(cur_ship, it_x, it_y) -- direction towards the ship that is IT |
|---|
| 110 | EpiarLua.Ship.Rotate(cur_ship, dir_it) |
|---|
| 111 | elseif math.random(100) <40 then |
|---|
| 112 | dir_it = EpiarLua.Ship.directionTowards(cur_ship, it_x, it_y) -- direction away from the ship that is IT |
|---|
| 113 | EpiarLua.Ship.Rotate(cur_ship, -dir_it) |
|---|
| 114 | elseif math.random(100) <70 then |
|---|
| 115 | dir_swarm_center = EpiarLua.Ship.directionTowards(cur_ship, avg_x, avg_y) -- direction towards the center of the swarm |
|---|
| 116 | EpiarLua.Ship.Rotate(cur_ship, dir_swarm_center) |
|---|
| 117 | else |
|---|
| 118 | dir_swarm_aim = EpiarLua.Ship.directionTowards(cur_ship, avg_angle ) -- direction towards the swarm direction |
|---|
| 119 | EpiarLua.Ship.Rotate(cur_ship, dir_swarm_aim) |
|---|
| 120 | end |
|---|
| 121 | end |
|---|
| 122 | |
|---|
| 123 | end |
|---|
| 124 | EpiarLua.Ship.Accelerate(cur_ship ) |
|---|
| 125 | end |
|---|
| 126 | |
|---|
| 127 | if it_countdown==0 then |
|---|
| 128 | -- Is someone else it now? |
|---|
| 129 | target, min_x, min_y, mindist = closestToIT() |
|---|
| 130 | if mindist < 200 then |
|---|
| 131 | setIt(target) |
|---|
| 132 | end |
|---|
| 133 | else |
|---|
| 134 | it_countdown= it_countdown-1 |
|---|
| 135 | if it_countdown==0 then |
|---|
| 136 | Epiar.echo("Let the games begin") |
|---|
| 137 | elseif it_countdown%10==0 then |
|---|
| 138 | Epiar.echo("Player "..it.." is counting down: "..it_countdown/10) |
|---|
| 139 | end |
|---|
| 140 | end |
|---|
| 141 | |
|---|
| 142 | end |
|---|
| 143 | |
|---|
| 144 | -- Functions to use from the console. ( Enter the console by hitting backtick. ) |
|---|
| 145 | -- TODO: Remove these functions, they are only interesting for debugging and even very useful then. |
|---|
| 146 | function stop() |
|---|
| 147 | frozen=1 |
|---|
| 148 | end |
|---|
| 149 | |
|---|
| 150 | function go() |
|---|
| 151 | frozen=0 |
|---|
| 152 | end |
|---|
| 153 | |
|---|
| 154 | function open(x,y,w,h,someString) -- Create an Arbitrary Window |
|---|
| 155 | EpiarLua.UI:newWindow(x,y,w,h,someString) |
|---|
| 156 | end |
|---|
| 157 | |
|---|
| 158 | function close() -- Close all the windows |
|---|
| 159 | EpiarLua.UI:close() |
|---|
| 160 | end |
|---|
| 161 | |
|---|
| 162 | -- Tag Functions |
|---|
| 163 | function setIt(target) |
|---|
| 164 | it=target |
|---|
| 165 | it_countdown = 100 |
|---|
| 166 | if it==0 then |
|---|
| 167 | Epiar.echo("TAG! You're now it!") |
|---|
| 168 | --pauseMessage("TAG! You're now it!") |
|---|
| 169 | else |
|---|
| 170 | Epiar.echo("Ship "..target.." is now IT.") |
|---|
| 171 | --pauseMessage("Ship "..target.." is now IT.") |
|---|
| 172 | end |
|---|
| 173 | end |
|---|
| 174 | function whosit() |
|---|
| 175 | if it==0 then |
|---|
| 176 | Epiar.echo("You are it") |
|---|
| 177 | else |
|---|
| 178 | Epiar.echo("Player "..it.." is it.") |
|---|
| 179 | end |
|---|
| 180 | end |
|---|
| 181 | function whosClosest() |
|---|
| 182 | it_x,it_y = EpiarLua.Ship.GetPosition(shipList[it]) |
|---|
| 183 | target, min_x, min_y, mindist = closestToIT() |
|---|
| 184 | Epiar.echo("Closest ship to IT "..it.." at ("..it_x..","..it_y..") is ".. target.." at ("..min_x..","..min_y..") "..mindist) |
|---|
| 185 | end |
|---|
| 186 | |
|---|
| 187 | function pauseMessage(message) |
|---|
| 188 | Epiar.pause() |
|---|
| 189 | menuWin = EpiarLua.UI:newWindow( 900,200,120,250,"Paused", |
|---|
| 190 | EpiarLua.UI:newLabel(10,40,message), |
|---|
| 191 | EpiarLua.UI:newButton(10,90,100,30,"Unpause","Epiar.unpause()") |
|---|
| 192 | ) |
|---|
| 193 | end |
|---|
| 194 | |
|---|
| 195 | function menu() -- Generate a test window |
|---|
| 196 | -- Create windows |
|---|
| 197 | menuWin = EpiarLua.UI:newWindow( 900,200,120,450,"Menu", |
|---|
| 198 | EpiarLua.UI:newButton(10,40,100,30,"Pause","Epiar.pause()"), |
|---|
| 199 | EpiarLua.UI:newButton(10,90,100,30,"Unpause","Epiar.unpause()"), |
|---|
| 200 | EpiarLua.UI:newButton(10,140,100,30,"AI Drift","stop()"), |
|---|
| 201 | EpiarLua.UI:newButton(10,190,100,30,"AI Think","go()"), |
|---|
| 202 | EpiarLua.UI:newButton(10,240,100,30,"IT","setIt(0)"), |
|---|
| 203 | EpiarLua.UI:newButton(10,290,100,30,"NOT IT","setIt(math.random(#shipList))") |
|---|
| 204 | ) |
|---|
| 205 | end |
|---|
| 206 | |
|---|
| 207 | -- Create Some ships around the planets |
|---|
| 208 | -- TODO, Lua should create these ships based off of information found in the planets-default.xml |
|---|
| 209 | if 1 >0 then |
|---|
| 210 | CreateShips(3,345,215) |
|---|
| 211 | CreateShips(6,-40,-135) |
|---|
| 212 | CreateShips(6,4640,-735) |
|---|
| 213 | end |
|---|
| 214 | it=math.random(#shipList) |
|---|
| 215 | it=0 |
|---|
| 216 | |
|---|
| 217 | |
|---|