source: Lua/scripts/universe.lua @ 76

Revision 76, 6.1 KB checked in by knowknowledge, 4 years ago (diff)

Tag In Space

AI Scripts for Space Tag where one ship hunts while the rest try to run.
The player is included.
When the AI run, they don't run directly away because that would be
boring. Instead they randomly decide to follow one of a few directions.

Unfortunately, the only way to tell what's going on is to turn on the
in-game console, which cut my FPS to a third of normal.

Line 
1
2-- Use this script for a solar system
3
4-- Lua Global variables
5shipList = {}  -- The ships that Lua has access to.  TODO: This list should probably be generated at each tick from a c++ call.
6frozen=0 -- Setting this to 1 causes all AI to stop 'thinking' and just drift.
7ticks=0
8player  = Epiar.player()
9shipList[0] = player
10it_countdown=100
11
12function 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")
26end
27
28function 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
52end
53
54function 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)
58end
59
60function 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
79end
80
81
82-- The C++ engine calls this function once per tick.
83-- This function is responsible for directing all of the game AI.
84function 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
142end
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.
146function stop()
147        frozen=1
148end
149
150function go()
151        frozen=0
152end
153
154function open(x,y,w,h,someString) -- Create an Arbitrary Window
155        EpiarLua.UI:newWindow(x,y,w,h,someString)
156end
157
158function close() -- Close all the windows
159        EpiarLua.UI:close()
160end
161
162-- Tag Functions
163function 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
173end
174function whosit()
175        if it==0 then
176                Epiar.echo("You are it")
177        else
178                Epiar.echo("Player "..it.." is it.")
179        end
180end
181function 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)
185end
186
187function 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                )
193end
194
195function 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                )
205end
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
209if 1 >0 then
210        CreateShips(3,345,215)
211        CreateShips(6,-40,-135)
212        CreateShips(6,4640,-735)
213end
214it=math.random(#shipList)
215it=0
216
217
Note: See TracBrowser for help on using the repository browser.