-
Notifications
You must be signed in to change notification settings - Fork 3
/
clsBunker.cls
371 lines (303 loc) · 10.4 KB
/
clsBunker.cls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "clsBunker"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
Rem *** Bunker Class
Rem *** Purpose: Inits, draws handles bunkers actions
Enum enumBunkerTarget
BTARGET_SHIP = 0
BTARGET_METEOR
BTARGET_MISSILE
End Enum
Enum enumBunkerPosition
BP_CLOSE = 0
BP_FAR
BP_VERYFAR
End Enum
Enum enumBunkerType
BT_WEAK = 1
BT_STRONG
BT_STONE 'COLD
End Enum
Dim m_x As Integer
Dim m_y As Integer
Dim m_cx As Integer
Dim m_cy As Integer
Dim m_BP As enumBunkerPosition ' distance
Dim m_BT As enumBunkerType
Dim m_hitpoints As Byte ' hitpoints left
Dim m_Rotation As enumDirection ' set rotation animation
Dim m_bFiring As Boolean ' enable firing animation
Dim m_Frame As Byte ' animation frame
Dim m_Visible As Boolean ' Deceased or not
' enemy containers
Dim m_Target As enumBunkerTarget ' what will the bunker fire at?
Dim m_TR As Integer ' maximum target range
'Dim w
Dim m_EnemyIndex As Byte
Dim m_bEnemyEngaged As Boolean
Public Sub CreateBunker(x As Integer, y As Integer, _
eBP As enumBunkerPosition, _
eBT As enumBunkerType)
m_x = x
m_y = y
m_BP = eBP
m_BT = eBT
m_Frame = 0
m_hitpoints = eBT * 10
' set target range
If m_BP = BP_CLOSE Then
m_cx = 180
m_cy = 140
m_TR = 350
ElseIf m_BP = BP_FAR Then
m_cx = 100
m_cy = 60
m_TR = 350
ElseIf m_BP = BP_VERYFAR Then
m_cx = 60
m_cy = 40
m_TR = 350
End If
m_Visible = True
End Sub
Public Sub GetTarget() ' choose a random target in it's sight range
' Desc: Get an enemy target for the bunker
If m_bEnemyEngaged Or m_Visible = False Then Exit Sub ' exit if an enemy's been already engaged
Dim cn As Long ' local counter
' Check for a meteor in the sight-range
If (Not m_bEnemyEngaged) Then
For cn = 0 To MAX_METEORS
If g_Meteor(cn).Visible And _
(nGetDist2D(CInt(g_Meteor(cn).x), CInt(g_Meteor(cn).y), _
GetX, GetY) < m_TR) Then
m_bEnemyEngaged = True
m_Target = BTARGET_METEOR
m_EnemyIndex = CByte(cn)
SetFire = True
End If
Next
End If
' check for an enemy spaceship
For cn = 0 To MAX_ENEMIES
If CShip(cn).GetVisible Then
If fGetDist2D(CShip(cn).GetX, CShip(cn).GetY, _
CSng(GetX), CSng(GetY)) < m_TR Then
m_bEnemyEngaged = True ' set "busy attacking" flag
m_Target = BTARGET_SHIP
m_EnemyIndex = CByte(cn)
SetFire = True
End If
End If
Next
' Check for an enemy missiles
If (Not m_bEnemyEngaged) Then
For cn = 0 To MAX_MISSILES
If g_Missile(cn).Visible And _
(nGetDist2D(CInt(g_Missile(cn).x), CInt(g_Missile(cn).y), _
GetX, GetY) < m_TR) Then
m_bEnemyEngaged = True
m_Target = BTARGET_MISSILE
m_EnemyIndex = CByte(cn)
SetFire = True
End If
Next
End If
' rotate bunker at the enemy's face
'If cShip(cn).GetX > GetX Then
' SetRotation = SO_RIGHT
'Else
' SetRotation = SO_LEFT
'End If
'm_bEnemyEngaged = True ' set "busy attacking" flag
'm_EnemyIndex = CByte(cn)
'm_Target = BTARGET_SHIP ' identify taget ( Sounds familiar a? ;)
'Debug.Print "Targeted ship n:" & cn
End Sub
Public Sub FireWeapon()
' Desc: Update bunker fire, do range checkings and position tracking
If (Not m_Visible) Then Exit Sub
Dim fEnemyX As Single
Dim fEnemyY As Single
Dim bytEnemyZ As Byte
Dim benemyVisible As Boolean
Dim eExplosion As enumExplosionType
' fill target info
If m_bEnemyEngaged Then ' if an enemy's been engaged
Select Case m_Target
Case BTARGET_SHIP
fEnemyX = CShip(m_EnemyIndex).GetX
fEnemyY = CShip(m_EnemyIndex).GetY
bytEnemyZ = CShip(m_EnemyIndex).GetZ
benemyVisible = CShip(m_EnemyIndex).GetVisible
eExplosion = (ET_SMALLBLUE + 3 * (bytEnemyZ - 1))
Case BTARGET_METEOR
fEnemyX = g_Meteor(m_EnemyIndex).x
fEnemyY = g_Meteor(m_EnemyIndex).y
bytEnemyZ = g_Meteor(m_EnemyIndex).z
benemyVisible = g_Meteor(m_EnemyIndex).Visible
eExplosion = (ET_SMALLBLUE + 3 * (bytEnemyZ - 1))
Case BTARGET_MISSILE
fEnemyX = g_Missile(m_EnemyIndex).x
fEnemyY = g_Missile(m_EnemyIndex).y
bytEnemyZ = g_Missile(m_EnemyIndex).z
benemyVisible = g_Missile(m_EnemyIndex).Visible
eExplosion = (ET_SMALLBLUE + 3 * (bytEnemyZ - 1))
Case Else: '...
End Select
' if target's already been destroyed or got out of range then release bunker and exit procedure
If (Not benemyVisible Or _
nGetDist2D(CInt(fEnemyX), CInt(fEnemyY), GetX, GetY) > m_TR) Then
m_bEnemyEngaged = False
Exit Sub
End If
If (nGetRnd(0, 2000) < 100) Then ' determine if it should fire
If (fEnemyX > GetX) Then ' set appropriate rotation relevant to ship x-position
SetRotation = SO_RIGHT
Else
SetRotation = SO_LEFT
End If
' take damage from encounterd target
If (m_Target = BTARGET_SHIP) Then
CShip(m_EnemyIndex).DoDamage = 1
ElseIf (m_Target = BTARGET_MISSILE) Then
'g_Missile(m_EnemyIndex).HP = g_Missile(m_EnemyIndex).HP - 1
g_Missile(m_EnemyIndex).Visible = False
ElseIf (m_Target = BTARGET_METEOR) Then
g_Meteor(m_EnemyIndex).HP = g_Meteor(m_EnemyIndex).HP - 2 '{!}
End If
Call CreateExplosion(CInt(fEnemyX + nGetRnd(-20, 20)), _
CInt(fEnemyY + nGetRnd(-2, 2)), _
bytEnemyZ, eExplosion)
SetFire = True ' enable fire animation
Else
SetFire = False
End If
End If
End Sub
Public Sub Render()
Dim rBunker As RECT
Static lRTime As Long ' rotation time
If (m_Visible) Then
' update rotation animation frame
Call Rotate(m_Rotation)
Call SetRect(rBunker, 0, 0, m_cx, m_cy)
Call BltFastGFX_HBM(m_x - wx, m_y - wy, g_Objects.Bunker1(m_BP, m_Frame))
Else
' update destroyed anim.
Call SetRect(rBunker, 0, 0, m_cx, m_cy)
Call BltFastGFX_HBM(m_x - wx, m_y - wy, g_Objects.Bunker1Dead(m_BP))
End If
End Sub
Private Sub Rotate(eDir As enumDirection)
Static lFPSTime As Long
Dim bUpdateFrame As Boolean
If lFPSTime < GetTicks Then
lFPSTime = GetTicks + FPS_ANIMS
bUpdateFrame = True
End If
If bUpdateFrame Then
' reset fire
If m_Frame = 5 And m_bFiring = True Then
m_Frame = 2
m_bFiring = False
End If
If m_Frame = 3 And m_bFiring = True Then
m_Frame = 0
m_bFiring = False
End If
' do rotating
Select Case eDir ' determine rotation
Case SO_LEFT ' 3-5 ' firing
If m_bFiring Then ' check for fire flag
If m_Frame > 3 Then m_Frame = m_Frame - 1
Else
If m_Frame > 0 Then m_Frame = m_Frame - 1
End If
Case SO_RIGHT
If m_bFiring Then
If m_Frame < 5 Then m_Frame = m_Frame + 1
Else
If m_Frame < 2 Then m_Frame = m_Frame + 1
End If
Case Else
End Select
End If
End Sub
' Info setting procs.
'-------------------------------------------------------------------
Public Property Let DoDamage(nDamage As Integer)
' Desc: Take hitpoints
If Not m_Visible Then Exit Property ' if bunker's already dead then exit
Dim nHP As Integer
nHP = CInt(m_hitpoints)
nHP = nHP - nDamage
' bunker's about to die -> do app. settings
If nHP <= 0 Then
SetVisible = False
m_hitpoints = 0
Call CreateExplosion(GetX, GetY, 1, ET_BIG)
' play destruction sound
If (m_BP = BP_CLOSE) Then Call DSPlaySound(g_dsSfx(SFX_BUNKEREXPLODE), False, (GetX() - wx), SFX_VOLUMENORMAL)
If (m_BP = BP_FAR) Then Call DSPlaySound(g_dsSfx(SFX_BUNKEREXPLODE), False, (GetX() - wx), SFX_VOLUMECLOSE)
If (m_BP = BP_VERYFAR) Then Call DSPlaySound(g_dsSfx(SFX_BUNKEREXPLODE), False, (GetX() - wx), SFX_VOLUMEFAR)
Else
m_hitpoints = nHP
End If
End Property
Public Property Let SetRotation(eDir As enumDirection)
m_Rotation = eDir
End Property
Public Property Let SetFire(bSF As Boolean)
If (m_bFiring = True And bSF = True) Or _
(m_bFiring = False And bSF = False) Then Exit Property
m_bFiring = bSF
' adjust animation frame
If m_bFiring = True Then
m_Frame = (m_Frame + 3) ' Mod 5) + 3 ' ' move right 3 frames
If m_Frame > 5 Then m_Frame = 5
Else
If m_Frame >= 3 Then
m_Frame = (m_Frame - 3) ' move left 3 frames to disable weapons fire
End If
End If
' play fire sound
'getx = 2080 ' right
'wx = 0
'fl = (GetX - wx) '/ 2100
'Call DSPlaySound(g_dsCannon(m_BP + 2), False, (GetX - wx))
If (m_BP = BP_CLOSE) Then Call DSPlaySound(g_dsCannon(SFX_CLOSEBUNKER), False, (GetX - wx), SFX_VOLUMECLOSE)
If (m_BP = BP_FAR) Then Call DSPlaySound(g_dsCannon(SFX_FARBUNKER), False, (GetX - wx), SFX_VOLUMEFAR)
If (m_BP = BP_VERYFAR) Then Call DSPlaySound(g_dsCannon(SFX_VERYFARBUNKER), False, (GetX - wx), SFX_VOLUMEVERYFAR)
End Property
Public Property Let SetVisible(bVisible As Boolean)
m_hitpoints = m_BT * 10 '{!}
m_Visible = bVisible
End Property
' Info retrieving procs.
'-------------------------------------------------------------------
Public Property Get GetPos() As enumBunkerPosition
GetPos = m_BP
End Property
Public Property Get GetX() As Integer
GetX = m_x + m_cx / 2
End Property
Public Property Get GetY() As Integer
GetY = m_y + m_cy / 2
End Property
Public Property Get GetZ() As enumBunkerPosition
GetZ = m_BP
End Property
Public Property Get GetVisible() As Boolean
GetVisible = m_Visible
End Property