action_nitro: general gameplay tweaks
[nit.git] / contrib / action_nitro / src / game / planegen.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Enemy generation
16 module planegen
17
18 import core
19
20 redef class World
21
22 # Max planes within view
23 var max_planes = 12
24
25 # Max human enemies within view
26 var max_enemies = 2
27
28 redef fun update(dt) do
29 super
30 spawn_enemy spawn_plane
31 end
32
33 # Randomly spawn a plane if needed
34 fun spawn_plane: Bool do
35 var p = player
36 if p == null then return false
37 if p.altitude >= boss_altitude then
38 return false
39 end
40 for i in planes.reverse_iterator do
41 if i.out_of_screen(p, self) then
42 #print "Despawning plane"
43 i.destroy self
44 end
45 end
46
47 if p.dead then return false
48 if planes.length >= max_planes then return false
49 if 100.rand < 95 then return false
50
51 var pos
52 var xspawn = 50.0.rand
53 var direction: Int
54 if xspawn >= 25.0 then
55 xspawn = camera_view.right - 1.0
56 direction = 1
57 else
58 xspawn = camera_view.left - 8.0
59 direction = 0
60 end
61 var yspawn
62 if planes.length == 0 then
63 #print "First plane spawn"
64 yspawn = p.center.y & 25.0
65 else
66 var py = p.center.y
67 var planes_below = 0
68 var planes_above = 0
69 var above_y = new Array[Float]
70 var below_y = new Array[Float]
71 for i in planes do
72 #print "Plane coordinates = {i.center}"
73 var iy = i.center.y
74 if iy > py then
75 planes_above += 1
76 above_y.add iy
77 else
78 planes_below += 1
79 below_y.add iy
80 end
81 end
82 if planes_below < planes_above then
83 if planes_below == 0 then
84 yspawn = py - 15.0.rand
85 else
86 yspawn = below_y.rand - 25.0.rand
87 end
88 else
89 if planes_above == 0 then
90 yspawn = py + 15.0.rand
91 else
92 yspawn = above_y.rand + 25.0.rand
93 end
94 end
95 if yspawn < 0.0 then
96 yspawn = py + 15.0.rand
97 end
98 end
99 pos = new Point3d[Float](xspawn, yspawn, 0.0 & 0.2)
100 #print("Spawning plane at position {pos}")
101 var platform_type = 100.rand
102 var plane: Platform
103 if platform_type < 90 then
104 plane = new Airplane(pos, 16.0, 4.0)
105 else
106 plane = new Helicopter(pos, 16.0, 4.0)
107 end
108 var xspeed = 50.0
109 if direction == 1 then xspeed = -xspeed
110 plane.inertia = new Point3d[Float](xspeed, -0.1, 0.0)
111 planes.add(plane)
112 return true
113 end
114
115 # Randomly spawn an enemy if needed
116 fun spawn_enemy(spawned_plane: Bool) do
117 var p = player
118 if p == null then return
119 if p.altitude >= boss_altitude then
120 for e in enemies.reverse_iterator do if e isa JetpackEnemy then
121 e.destroy self
122 end
123 return
124 end
125 for i in enemies.reverse_iterator do
126 if i.out_of_screen(p, self) then
127 #print "Despawning enemy"
128 i.destroy self
129 end
130 end
131
132 if enemies.length >= max_enemies then return
133 if 100.rand < 95 then return
134
135 if spawned_plane then
136 var pl = planes.last
137 var pos = new Point3d[Float](pl.center.x, pl.center.y + pl.top / 2.0, 0.0)
138 #print "Spawning walking enemy at positon {pos}"
139 var enemy = new WalkingEnemy(pos, 3.0, 3.0, new Pistol)
140 enemy.inertia = pl.inertia
141 pl.enemy = enemy
142 enemies.add enemy
143 return
144 end
145 # 0: Up
146 # 1: Right
147 # 2: Down
148 # 3: Left
149 var dirspawn = 4.rand
150 var xspawn
151 var yspawn
152 var xinertia
153 var yinertia
154 var cam = camera_view
155 if dirspawn == 0 then
156 xspawn = (cam.right - cam.left).rand
157 yspawn = cam.top + 10.0
158 yinertia = -(10.0.rand)
159 xinertia = 0.0
160 else if dirspawn == 1 then
161 yspawn = (cam.top - cam.bottom).rand
162 xspawn = cam.right + 10.0
163 xinertia = -(10.0.rand)
164 yinertia = 0.0
165 else if dirspawn == 2 then
166 xspawn = (cam.right - cam.left).rand
167 yspawn = cam.bottom - 10.0
168 yinertia = 10.0.rand
169 xinertia = 0.0
170 else if dirspawn == 3 then
171 yspawn = (cam.top - cam.bottom).rand
172 xspawn = cam.left - 10.0
173 xinertia = 10.0.rand
174 yinertia = 0.0
175 else
176 #print "Rand failed, should not happen"
177 abort
178 end
179 var pos = new Point3d[Float](xspawn, yspawn, 0.0)
180 #print "Spawning jetpack enemy at positon {pos}"
181 var enemy = new JetpackEnemy(pos, 3.0, 3.0, new Pistol)
182 enemy.inertia = new Point3d[Float](xinertia, yinertia, 0.0)
183 enemies.add enemy
184 end
185 end