16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
17 *) |
17 *) |
18 |
18 |
19 unit uGears; |
19 unit uGears; |
20 interface |
20 interface |
21 uses SDLh, uConsts; |
21 uses SDLh, uConsts, uFloat; |
22 {$INCLUDE options.inc} |
22 {$INCLUDE options.inc} |
23 const AllInactive: boolean = false; |
23 const AllInactive: boolean = false; |
24 |
24 |
25 type PGear = ^TGear; |
25 type PGear = ^TGear; |
26 TGearStepProcedure = procedure (Gear: PGear); |
26 TGearStepProcedure = procedure (Gear: PGear); |
27 TGear = record |
27 TGear = record |
28 NextGear, PrevGear: PGear; |
28 NextGear, PrevGear: PGear; |
29 Active: Boolean; |
29 Active: Boolean; |
30 State : Longword; |
30 State : Longword; |
31 X : Double; |
31 X : hwFloat; |
32 Y : Double; |
32 Y : hwFloat; |
33 dX: Double; |
33 dX: hwFloat; |
34 dY: Double; |
34 dY: hwFloat; |
35 Kind: TGearType; |
35 Kind: TGearType; |
36 Pos: Longword; |
36 Pos: Longword; |
37 doStep: TGearStepProcedure; |
37 doStep: TGearStepProcedure; |
38 Radius: integer; |
38 Radius: integer; |
39 Angle, Power : Longword; |
39 Angle, Power : Longword; |
40 DirAngle: Double; |
40 DirAngle: hwFloat; |
41 Timer : LongWord; |
41 Timer : LongWord; |
42 Elasticity: Double; |
42 Elasticity: hwFloat; |
43 Friction : Double; |
43 Friction : hwFloat; |
44 Message : Longword; |
44 Message : Longword; |
45 Hedgehog: pointer; |
45 Hedgehog: pointer; |
46 Health, Damage: integer; |
46 Health, Damage: integer; |
47 CollIndex: Longword; |
47 CollIndex: Longword; |
48 Tag: integer; |
48 Tag: integer; |
49 Surf: PSDL_Surface; |
49 Surf: PSDL_Surface; |
50 Z: Longword; |
50 Z: Longword; |
51 end; |
51 end; |
52 |
52 |
53 function AddGear(X, Y: integer; Kind: TGearType; State: Longword; const dX: Double=0.0; dY: Double=0.0; Timer: LongWord=0): PGear; |
53 function AddGear(X, Y: integer; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear; |
54 procedure ProcessGears; |
54 procedure ProcessGears; |
55 procedure SetAllToActive; |
55 procedure SetAllToActive; |
56 procedure SetAllHHToActive; |
56 procedure SetAllHHToActive; |
57 procedure DrawGears(Surface: PSDL_Surface); |
57 procedure DrawGears(Surface: PSDL_Surface); |
58 procedure FreeGearsList; |
58 procedure FreeGearsList; |
93 |
93 |
94 {$INCLUDE GSHandlers.inc} |
94 {$INCLUDE GSHandlers.inc} |
95 {$INCLUDE HHHandlers.inc} |
95 {$INCLUDE HHHandlers.inc} |
96 |
96 |
97 const doStepHandlers: array[TGearType] of TGearStepProcedure = ( |
97 const doStepHandlers: array[TGearType] of TGearStepProcedure = ( |
98 doStepCloud, |
98 @doStepCloud, |
99 doStepBomb, |
99 @doStepBomb, |
100 doStepHedgehog, |
100 @doStepHedgehog, |
101 doStepGrenade, |
101 @doStepGrenade, |
102 doStepHealthTag, |
102 @doStepHealthTag, |
103 doStepGrave, |
103 @doStepGrave, |
104 doStepUFO, |
104 @doStepUFO, |
105 doStepShotgunShot, |
105 @doStepShotgunShot, |
106 doStepPickHammer, |
106 @doStepPickHammer, |
107 doStepRope, |
107 @doStepRope, |
108 doStepSmokeTrace, |
108 @doStepSmokeTrace, |
109 doStepExplosion, |
109 @doStepExplosion, |
110 doStepMine, |
110 @doStepMine, |
111 doStepCase, |
111 @doStepCase, |
112 doStepDEagleShot, |
112 @doStepDEagleShot, |
113 doStepDynamite, |
113 @doStepDynamite, |
114 doStepTeamHealthSorter, |
114 @doStepTeamHealthSorter, |
115 doStepBomb, |
115 @doStepBomb, |
116 doStepCluster, |
116 @doStepCluster, |
117 doStepShover, |
117 @doStepShover, |
118 doStepFlame, |
118 @doStepFlame, |
119 doStepFirePunch, |
119 @doStepFirePunch, |
120 doStepActionTimer, |
120 @doStepActionTimer, |
121 doStepActionTimer, |
121 @doStepActionTimer, |
122 doStepActionTimer, |
122 @doStepActionTimer, |
123 doStepParachute, |
123 @doStepParachute, |
124 doStepAirAttack, |
124 @doStepAirAttack, |
125 doStepAirBomb, |
125 @doStepAirBomb, |
126 doStepBlowTorch |
126 @doStepBlowTorch |
127 ); |
127 ); |
128 |
128 |
129 procedure InsertGearToList(Gear: PGear); |
129 procedure InsertGearToList(Gear: PGear); |
130 var tmp: PGear; |
130 var tmp: PGear; |
131 begin |
131 begin |
132 if GearsList = nil then |
132 if GearsList = nil then |
133 GearsList:= Gear |
133 GearsList:= Gear |
134 else begin |
134 else begin |
135 // WARNING: this code assumes that the first gears added to the list are clouds (have maximal Z) |
135 // WARNING: this code assumes that the first gears added to the list are clouds (have maximal Z) |
136 tmp:= GearsList; |
136 tmp:= GearsList; |
137 while (tmp <> nil) and (tmp.Z < Gear.Z) do |
137 while (tmp <> nil) and (tmp^.Z < Gear^.Z) do |
138 tmp:= tmp.NextGear; |
138 tmp:= tmp^.NextGear; |
139 |
139 |
140 if tmp.PrevGear <> nil then tmp.PrevGear.NextGear:= Gear; |
140 if tmp^.PrevGear <> nil then tmp^.PrevGear^.NextGear:= Gear; |
141 Gear.PrevGear:= tmp.PrevGear; |
141 Gear^.PrevGear:= tmp^.PrevGear; |
142 tmp.PrevGear:= Gear; |
142 tmp^.PrevGear:= Gear; |
143 Gear.NextGear:= tmp; |
143 Gear^.NextGear:= tmp; |
144 if GearsList = tmp then GearsList:= Gear |
144 if GearsList = tmp then GearsList:= Gear |
145 end |
145 end |
146 end; |
146 end; |
147 |
147 |
148 procedure RemoveGearFromList(Gear: PGear); |
148 procedure RemoveGearFromList(Gear: PGear); |
149 begin |
149 begin |
150 if Gear.NextGear <> nil then Gear.NextGear.PrevGear:= Gear.PrevGear; |
150 if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear; |
151 if Gear.PrevGear <> nil then Gear.PrevGear.NextGear:= Gear.NextGear |
151 if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear |
152 else begin |
152 else begin |
153 GearsList:= Gear.NextGear; |
153 GearsList:= Gear^.NextGear; |
154 if GearsList <> nil then GearsList.PrevGear:= nil |
154 if GearsList <> nil then GearsList^.PrevGear:= nil |
155 end; |
155 end; |
156 end; |
156 end; |
157 |
157 |
158 function AddGear(X, Y: integer; Kind: TGearType; State: Longword; const dX: Double=0.0; dY: Double=0.0; Timer: LongWord=0): PGear; |
158 function AddGear(X, Y: integer; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear; |
159 const Counter: Longword = 0; |
159 const Counter: Longword = 0; |
|
160 var Result: PGear; |
160 begin |
161 begin |
161 inc(Counter); |
162 inc(Counter); |
162 {$IFDEF DEBUGFILE}AddFileLog('AddGear: ('+inttostr(x)+','+inttostr(y)+'), d('+floattostr(dX)+','+floattostr(dY)+')');{$ENDIF} |
163 {$IFDEF DEBUGFILE}AddFileLog('AddGear: ('+inttostr(x)+','+inttostr(y)+'), d('+floattostr(dX)+','+floattostr(dY)+')');{$ENDIF} |
163 New(Result); |
164 New(Result); |
164 {$IFDEF DEBUGFILE}AddFileLog('AddGear: type = '+inttostr(ord(Kind))+'; handle = '+inttostr(integer(Result)));{$ENDIF} |
165 {$IFDEF DEBUGFILE}AddFileLog('AddGear: type = '+inttostr(ord(Kind))+'; handle = '+inttostr(integer(Result)));{$ENDIF} |
165 FillChar(Result^, sizeof(TGear), 0); |
166 FillChar(Result^, sizeof(TGear), 0); |
166 Result.X:= X; |
167 Result^.X:= X; |
167 Result.Y:= Y; |
168 Result^.Y:= Y; |
168 Result.Kind := Kind; |
169 Result^.Kind := Kind; |
169 Result.State:= State; |
170 Result^.State:= State; |
170 Result.Active:= true; |
171 Result^.Active:= true; |
171 Result.dX:= dX; |
172 Result^.dX:= dX; |
172 Result.dY:= dY; |
173 Result^.dY:= dY; |
173 Result.doStep:= doStepHandlers[Kind]; |
174 Result^.doStep:= doStepHandlers[Kind]; |
174 Result.CollIndex:= High(Longword); |
175 Result^.CollIndex:= High(Longword); |
175 Result.Timer:= Timer; |
176 Result^.Timer:= Timer; |
176 if CurrentTeam <> nil then |
177 if CurrentTeam <> nil then |
177 Result.Hedgehog:= @CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog]; |
178 Result^.Hedgehog:= @(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]); |
178 case Kind of |
179 case Kind of |
179 gtCloud: Result.Z:= High(Result.Z); |
180 gtCloud: Result^.Z:= High(Result^.Z); |
180 gtAmmo_Bomb: begin |
181 gtAmmo_Bomb: begin |
181 Result.Radius:= 4; |
182 Result^.Radius:= 4; |
182 Result.Elasticity:= 0.6; |
183 Result^.Elasticity:= _0_6; |
183 Result.Friction:= 0.995; |
184 Result^.Friction:= _0_995; |
184 end; |
185 end; |
185 gtHedgehog: begin |
186 gtHedgehog: begin |
186 Result.Radius:= cHHRadius; |
187 Result^.Radius:= cHHRadius; |
187 Result.Elasticity:= 0.35; |
188 Result^.Elasticity:= _0_35; |
188 Result.Friction:= 0.999; |
189 Result^.Friction:= _0_999; |
189 Result.Angle:= cMaxAngle div 2; |
190 Result^.Angle:= cMaxAngle div 2; |
190 Result.Z:= cHHZ; |
191 Result^.Z:= cHHZ; |
191 end; |
192 end; |
192 gtAmmo_Grenade: begin |
193 gtAmmo_Grenade: begin |
193 Result.Radius:= 4; |
194 Result^.Radius:= 4; |
194 end; |
195 end; |
195 gtHealthTag: begin |
196 gtHealthTag: begin |
196 Result.Timer:= 1500; |
197 Result^.Timer:= 1500; |
197 Result.Z:= 2000; |
198 Result^.Z:= 2000; |
198 end; |
199 end; |
199 gtGrave: begin |
200 gtGrave: begin |
200 Result.Radius:= 10; |
201 Result^.Radius:= 10; |
201 Result.Elasticity:= 0.6; |
202 Result^.Elasticity:= _0_6; |
202 end; |
203 end; |
203 gtUFO: begin |
204 gtUFO: begin |
204 Result.Radius:= 5; |
205 Result^.Radius:= 5; |
205 Result.Timer:= 500; |
206 Result^.Timer:= 500; |
206 Result.Elasticity:= 0.9 |
207 Result^.Elasticity:= _0_9 |
207 end; |
208 end; |
208 gtShotgunShot: begin |
209 gtShotgunShot: begin |
209 Result.Timer:= 900; |
210 Result^.Timer:= 900; |
210 Result.Radius:= 2 |
211 Result^.Radius:= 2 |
211 end; |
212 end; |
212 gtPickHammer: begin |
213 gtPickHammer: begin |
213 Result.Radius:= 10; |
214 Result^.Radius:= 10; |
214 Result.Timer:= 4000 |
215 Result^.Timer:= 4000 |
215 end; |
216 end; |
216 gtSmokeTrace: begin |
217 gtSmokeTrace: begin |
217 Result.X:= Result.X - 16; |
218 Result^.X:= Result^.X - 16; |
218 Result.Y:= Result.Y - 16; |
219 Result^.Y:= Result^.Y - 16; |
219 Result.State:= 8 |
220 Result^.State:= 8 |
220 end; |
221 end; |
221 gtRope: begin |
222 gtRope: begin |
222 Result.Radius:= 3; |
223 Result^.Radius:= 3; |
223 Result.Friction:= 500; |
224 Result^.Friction:= 500; |
224 RopePoints.Count:= 0; |
225 RopePoints.Count:= 0; |
225 end; |
226 end; |
226 gtExplosion: begin |
227 gtExplosion: begin |
227 Result.X:= Result.X - 25; |
228 Result^.X:= Result^.X - 25; |
228 Result.Y:= Result.Y - 25; |
229 Result^.Y:= Result^.Y - 25; |
229 end; |
230 end; |
230 gtMine: begin |
231 gtMine: begin |
231 Result.Radius:= 3; |
232 Result^.Radius:= 3; |
232 Result.Elasticity:= 0.55; |
233 Result^.Elasticity:= _0_55; |
233 Result.Friction:= 0.995; |
234 Result^.Friction:= _0_995; |
234 Result.Timer:= 3000; |
235 Result^.Timer:= 3000; |
235 end; |
236 end; |
236 gtCase: begin |
237 gtCase: begin |
237 Result.Radius:= 16; |
238 Result^.Radius:= 16; |
238 Result.Elasticity:= 0.4 |
239 Result^.Elasticity:= _0_4 |
239 end; |
240 end; |
240 gtDEagleShot: begin |
241 gtDEagleShot: begin |
241 Result.Radius:= 1; |
242 Result^.Radius:= 1; |
242 Result.Radius:= 1; |
243 Result^.Radius:= 1; |
243 Result.Health:= 50 |
244 Result^.Health:= 50 |
244 end; |
245 end; |
245 gtDynamite: begin |
246 gtDynamite: begin |
246 Result.Radius:= 3; |
247 Result^.Radius:= 3; |
247 Result.Elasticity:= 0.55; |
248 Result^.Elasticity:= _0_55; |
248 Result.Friction:= 0.03; |
249 Result^.Friction:= _0_03; |
249 Result.Timer:= 5000; |
250 Result^.Timer:= 5000; |
250 end; |
251 end; |
251 gtClusterBomb: begin |
252 gtClusterBomb: begin |
252 Result.Radius:= 4; |
253 Result^.Radius:= 4; |
253 Result.Elasticity:= 0.6; |
254 Result^.Elasticity:= _0_6; |
254 Result.Friction:= 0.995; |
255 Result^.Friction:= _0_995; |
255 end; |
256 end; |
256 gtFlame: begin |
257 gtFlame: begin |
257 Result.Angle:= Counter mod 64; |
258 Result^.Angle:= Counter mod 64; |
258 Result.Radius:= 1; |
259 Result^.Radius:= 1; |
259 Result.Health:= 2; |
260 Result^.Health:= 2; |
260 Result.dY:= (getrandom - 0.8) * 0.03; |
261 Result^.dY:= (getrandom - _0_8) * _0_03; |
261 Result.dX:= (getrandom - 0.5) * 0.4 |
262 Result^.dX:= (getrandom - _0_5) * _0_4 |
262 end; |
263 end; |
263 gtFirePunch: begin |
264 gtFirePunch: begin |
264 Result.Radius:= 15; |
265 Result^.Radius:= 15; |
265 Result.Tag:= Y |
266 Result^.Tag:= Y |
266 end; |
267 end; |
267 gtAirBomb: begin |
268 gtAirBomb: begin |
268 Result.Radius:= 10; |
269 Result^.Radius:= 10; |
269 end; |
270 end; |
270 gtBlowTorch: begin |
271 gtBlowTorch: begin |
271 Result.Radius:= cHHRadius; |
272 Result^.Radius:= cHHRadius; |
272 Result.Timer:= 7500; |
273 Result^.Timer:= 7500; |
273 end; |
274 end; |
274 end; |
275 end; |
275 InsertGearToList(Result) |
276 InsertGearToList(Result); |
|
277 AddGear:= Result |
276 end; |
278 end; |
277 |
279 |
278 procedure DeleteGear(Gear: PGear); |
280 procedure DeleteGear(Gear: PGear); |
279 var team: PTeam; |
281 var team: PTeam; |
280 t: Longword; |
282 t: Longword; |
281 begin |
283 begin |
282 if Gear.CollIndex < High(Longword) then DeleteCI(Gear); |
284 if Gear^.CollIndex < High(Longword) then DeleteCI(Gear); |
283 if Gear.Surf <> nil then SDL_FreeSurface(Gear.Surf); |
285 if Gear^.Surf <> nil then SDL_FreeSurface(Gear^.Surf); |
284 if Gear.Kind = gtHedgehog then |
286 if Gear^.Kind = gtHedgehog then |
285 if CurAmmoGear <> nil then |
287 if CurAmmoGear <> nil then |
286 begin |
288 begin |
287 {$IFDEF DEBUGFILE}AddFileLog('DeleteGear: Sending gm_Destroy, hh handle = '+inttostr(integer(Gear)));{$ENDIF} |
289 {$IFDEF DEBUGFILE}AddFileLog('DeleteGear: Sending gm_Destroy, hh handle = '+inttostr(integer(Gear)));{$ENDIF} |
288 Gear.Message:= gm_Destroy; |
290 Gear^.Message:= gm_Destroy; |
289 CurAmmoGear.Message:= gm_Destroy; |
291 CurAmmoGear^.Message:= gm_Destroy; |
290 exit |
292 exit |
291 end else |
293 end else |
292 begin |
294 begin |
293 if Gear.Y >= cWaterLine then |
295 if not (Gear^.Y < cWaterLine) then |
294 begin |
296 begin |
295 t:= max(Gear.Damage, Gear.Health); |
297 t:= max(Gear^.Damage, Gear^.Health); |
296 AddGear(Round(Gear.X), Round(Gear.Y), gtHealthTag, t).Hedgehog:= Gear.Hedgehog; |
298 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtHealthTag, t, 0, 0, 0)^.Hedgehog:= Gear^.Hedgehog; |
297 inc(StepDamage, t) |
299 inc(StepDamage, t) |
298 end; |
300 end; |
299 team:= PHedgehog(Gear.Hedgehog).Team; |
301 team:= PHedgehog(Gear^.Hedgehog)^.Team; |
300 if CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].Gear = Gear then |
302 if CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear = Gear then |
301 FreeActionsList; // to avoid ThinkThread on drawned gear |
303 FreeActionsList; // to avoid ThinkThread on drawned gear |
302 PHedgehog(Gear.Hedgehog).Gear:= nil; |
304 PHedgehog(Gear^.Hedgehog)^.Gear:= nil; |
303 inc(KilledHHs); |
305 inc(KilledHHs); |
304 RecountTeamHealth(team); |
306 RecountTeamHealth(team); |
305 end; |
307 end; |
306 {$IFDEF DEBUGFILE}AddFileLog('DeleteGear: handle = '+inttostr(integer(Gear)));{$ENDIF} |
308 {$IFDEF DEBUGFILE}AddFileLog('DeleteGear: handle = '+inttostr(integer(Gear)));{$ENDIF} |
307 if CurAmmoGear = Gear then CurAmmoGear:= nil; |
309 if CurAmmoGear = Gear then CurAmmoGear:= nil; |
425 procedure SetAllToActive; |
427 procedure SetAllToActive; |
426 var t: PGear; |
428 var t: PGear; |
427 begin |
429 begin |
428 AllInactive:= false; |
430 AllInactive:= false; |
429 t:= GearsList; |
431 t:= GearsList; |
430 while t<>nil do |
432 while t <> nil do |
431 begin |
433 begin |
432 t.Active:= true; |
434 t^.Active:= true; |
433 t:= t.NextGear |
435 t:= t^.NextGear |
434 end |
436 end |
435 end; |
437 end; |
436 |
438 |
437 procedure SetAllHHToActive; |
439 procedure SetAllHHToActive; |
438 var t: PGear; |
440 var t: PGear; |
439 begin |
441 begin |
440 AllInactive:= false; |
442 AllInactive:= false; |
441 t:= GearsList; |
443 t:= GearsList; |
442 while t<>nil do |
444 while t <> nil do |
443 begin |
445 begin |
444 if t.Kind = gtHedgehog then t.Active:= true; |
446 if t^.Kind = gtHedgehog then t^.Active:= true; |
445 t:= t.NextGear |
447 t:= t^.NextGear |
446 end |
448 end |
447 end; |
449 end; |
448 |
450 |
449 procedure DrawHH(Gear: PGear; Surface: PSDL_Surface); |
451 procedure DrawHH(Gear: PGear; Surface: PSDL_Surface); |
450 var t: integer; |
452 var t: integer; |
451 begin |
453 begin |
452 DrawHedgehog(Round(Gear.X) - 14 + WorldDx, Round(Gear.Y) - 18 + WorldDy, |
454 DrawHedgehog(hwRound(Gear^.X) - 14 + WorldDx, hwRound(Gear^.Y) - 18 + WorldDy, |
453 hwSign(Gear.dX), 0, |
455 hwSign(Gear^.dX), 0, |
454 PHedgehog(Gear.Hedgehog).visStepPos div 2, |
456 PHedgehog(Gear^.Hedgehog)^.visStepPos div 2, |
455 Surface); |
457 Surface); |
456 |
458 |
457 with PHedgehog(Gear.Hedgehog)^ do |
459 with PHedgehog(Gear^.Hedgehog)^ do |
458 if Gear.State = 0 then |
460 if Gear^.State = 0 then |
459 begin |
461 begin |
460 t:= round(Gear.Y) - cHHRadius - 10 + WorldDy; |
462 t:= hwRound(Gear^.Y) - cHHRadius - 10 + WorldDy; |
461 dec(t, HealthTag.h + 2); |
463 dec(t, HealthTag^.h + 2); |
462 DrawCentered(round(Gear.X) + WorldDx, t, HealthTag, Surface); |
464 DrawCentered(hwRound(Gear^.X) + WorldDx, t, HealthTag, Surface); |
463 dec(t, NameTag.h + 2); |
465 dec(t, NameTag^.h + 2); |
464 DrawCentered(round(Gear.X) + WorldDx, t, NameTag, Surface); |
466 DrawCentered(hwRound(Gear^.X) + WorldDx, t, NameTag, Surface); |
465 dec(t, Team.NameTag.h + 2); |
467 dec(t, Team^.NameTag^.h + 2); |
466 DrawCentered(round(Gear.X) + WorldDx, t, Team.NameTag, Surface) |
468 DrawCentered(hwRound(Gear^.X) + WorldDx, t, Team^.NameTag, Surface) |
467 end else // Current hedgehog |
469 end else // Current hedgehog |
468 begin |
470 begin |
469 if bShowFinger and ((Gear.State and gstHHDriven) <> 0) then |
471 if bShowFinger and ((Gear^.State and gstHHDriven) <> 0) then |
470 DrawSprite(sprFinger, round(Gear.X) - 16 + WorldDx, round(Gear.Y) - 64 + WorldDy, |
472 DrawSprite(sprFinger, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 64 + WorldDy, |
471 GameTicks div 32 mod 16, Surface); |
473 GameTicks div 32 mod 16, Surface); |
472 if (Gear.State and (gstMoving or gstDrowning or gstFalling)) = 0 then |
474 if (Gear^.State and (gstMoving or gstDrowning or gstFalling)) = 0 then |
473 if (Gear.State and gstHHThinking) <> 0 then |
475 if (Gear^.State and gstHHThinking) <> 0 then |
474 DrawGear(sQuestion, Round(Gear.X) - 10 + WorldDx, Round(Gear.Y) - cHHRadius - 34 + WorldDy, Surface) |
476 DrawGear(sQuestion, hwRound(Gear^.X) - 10 + WorldDx, hwRound(Gear^.Y) - cHHRadius - 34 + WorldDy, Surface) |
475 else |
477 else |
476 if ShowCrosshair and ((Gear.State and gstAttacked) = 0) then |
478 if ShowCrosshair and ((Gear^.State and gstAttacked) = 0) then |
477 DrawSurfSprite(Round(Gear.X + hwSign(Gear.dX) * Sin(Gear.Angle*pi/cMaxAngle)*60) + WorldDx - 11, |
479 DrawSurfSprite(Round(hwRound(Gear^.X) + hwSign(Gear^.dX) * Sin(Gear^.Angle*pi/cMaxAngle)*60) + WorldDx - 11, |
478 Round(Gear.Y - Cos(Gear.Angle*pi/cMaxAngle)*60) + WorldDy - 12, |
480 Round(hwRound(Gear^.Y) - Cos(Gear^.Angle*pi/cMaxAngle)*60) + WorldDy - 12, |
479 24, (18 + hwSign(Gear.dX) * integer(((Gear.Angle * 72 div cMaxAngle) + 1) div 2) mod 18) mod 18, |
481 24, (18 + hwSign(Gear^.dX) * integer(((Gear^.Angle * 72 div cMaxAngle) + 1) div 2) mod 18) mod 18, |
480 Team.CrosshairSurf, Surface); |
482 Team^.CrosshairSurf, Surface); |
481 end; |
483 end; |
482 end; |
484 end; |
483 |
485 |
484 procedure DrawGears(Surface: PSDL_Surface); |
486 procedure DrawGears(Surface: PSDL_Surface); |
485 var Gear: PGear; |
487 var Gear: PGear; |
486 i: Longword; |
488 i: Longword; |
487 roplen: Double; |
489 roplen: hwFloat; |
488 |
490 |
489 procedure DrawRopeLine(X1, Y1, X2, Y2: integer); |
491 procedure DrawRopeLine(X1, Y1, X2, Y2: integer); |
490 const nodlen = 5; |
492 const nodlen = 5; |
491 var i, x, y: integer; |
493 var i, x, y: integer; |
492 t, k, ladd: Double; |
494 t, k, ladd: hwFloat; |
493 begin |
495 begin |
494 if (X1 = X2) and (Y1 = Y2) then |
496 if (X1 = X2) and (Y1 = Y2) then |
495 begin |
497 begin |
496 OutError('WARNING: zero length rope line!'); |
498 OutError('WARNING: zero length rope line!', false); |
497 exit |
499 exit |
498 end; |
500 end; |
499 if abs(X1 - X2) > abs(Y1 - Y2) then |
501 { if abs(X1 - X2) > abs(Y1 - Y2) then |
500 begin |
502 begin |
501 if X1 > X2 then |
503 if X1 > X2 then |
502 begin |
504 begin |
503 i:= X1; |
505 i:= X1; |
504 X1:= X2; |
506 X1:= X2; |
553 roplen:= roplen - nodlen; |
555 roplen:= roplen - nodlen; |
554 end; |
556 end; |
555 t:= t + k; |
557 t:= t + k; |
556 end; |
558 end; |
557 end |
559 end |
558 end; |
560 } end; |
559 |
561 |
560 begin |
562 begin |
561 Gear:= GearsList; |
563 Gear:= GearsList; |
562 while Gear<>nil do |
564 while Gear<>nil do |
563 begin |
565 begin |
564 case Gear.Kind of |
566 case Gear^.Kind of |
565 gtCloud: DrawSprite(sprCloud , Round(Gear.X) + WorldDx, Round(Gear.Y) + WorldDy, Gear.State, Surface); |
567 gtCloud: DrawSprite(sprCloud , hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.State, Surface); |
566 gtAmmo_Bomb: DrawSprite(sprBomb , Round(Gear.X) - 8 + WorldDx, Round(Gear.Y) - 8 + WorldDy, trunc(Gear.DirAngle), Surface); |
568 gtAmmo_Bomb: DrawSprite(sprBomb , hwRound(Gear^.X) - 8 + WorldDx, hwRound(Gear^.Y) - 8 + WorldDy, hwRound(Gear^.DirAngle), Surface); |
567 gtHedgehog: DrawHH(Gear, Surface); |
569 gtHedgehog: DrawHH(Gear, Surface); |
568 gtAmmo_Grenade: DrawSprite(sprGrenade , Round(Gear.X) - 16 + WorldDx, Round(Gear.Y) - 16 + WorldDy, DxDy2Angle32(Gear.dY, Gear.dX), Surface); |
570 gtAmmo_Grenade: DrawSprite(sprGrenade , hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 16 + WorldDy, DxDy2Angle32(Gear^.dY.QWordValue, Gear^.dX.QWordValue), Surface); |
569 gtHealthTag: if Gear.Surf <> nil then DrawCentered(Round(Gear.X) + WorldDx, Round(Gear.Y) + WorldDy, Gear.Surf, Surface); |
571 gtHealthTag: if Gear^.Surf <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Surf, Surface); |
570 gtGrave: DrawSpriteFromRect(PHedgehog(Gear.Hedgehog).Team.GraveRect, Round(Gear.X) + WorldDx - 16, Round(Gear.Y) + WorldDy - 16, 32, (GameTicks shr 7) and 7, Surface); |
572 gtGrave: DrawSpriteFromRect(PHedgehog(Gear^.Hedgehog)^.Team^.GraveRect, hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 32, (GameTicks shr 7) and 7, Surface); |
571 gtUFO: DrawSprite(sprUFO, Round(Gear.X) - 16 + WorldDx, Round(Gear.Y) - 16 + WorldDy, (GameTicks shr 7) mod 4, Surface); |
573 gtUFO: DrawSprite(sprUFO, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 16 + WorldDy, (GameTicks shr 7) mod 4, Surface); |
572 gtSmokeTrace: if Gear.State < 8 then DrawSprite(sprSmokeTrace, Round(Gear.X) + WorldDx, Round(Gear.Y) + WorldDy, Gear.State, Surface); |
574 gtSmokeTrace: if Gear^.State < 8 then DrawSprite(sprSmokeTrace, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.State, Surface); |
573 gtRope: begin |
575 gtRope: begin |
574 roplen:= 0; |
576 roplen:= 0; |
575 if RopePoints.Count > 0 then |
577 if RopePoints.Count > 0 then |
576 begin |
578 begin |
577 i:= 0; |
579 i:= 0; |
578 while i < Pred(RopePoints.Count) do |
580 while i < Pred(RopePoints.Count) do |
579 begin |
581 begin |
580 DrawRopeLine(Round(RopePoints.ar[i].X) + WorldDx, Round(RopePoints.ar[i].Y) + WorldDy, |
582 DrawRopeLine(hwRound(RopePoints.ar[i].X) + WorldDx, hwRound(RopePoints.ar[i].Y) + WorldDy, |
581 Round(RopePoints.ar[Succ(i)].X) + WorldDx, Round(RopePoints.ar[Succ(i)].Y) + WorldDy); |
583 hwRound(RopePoints.ar[Succ(i)].X) + WorldDx, hwRound(RopePoints.ar[Succ(i)].Y) + WorldDy); |
582 inc(i) |
584 inc(i) |
583 end; |
585 end; |
584 DrawRopeLine(Round(RopePoints.ar[i].X) + WorldDx, Round(RopePoints.ar[i].Y) + WorldDy, |
586 DrawRopeLine(hwRound(RopePoints.ar[i].X) + WorldDx, hwRound(RopePoints.ar[i].Y) + WorldDy, |
585 Round(Gear.X) + WorldDx, Round(Gear.Y) + WorldDy); |
587 hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy); |
586 DrawRopeLine(Round(Gear.X) + WorldDx, Round(Gear.Y) + WorldDy, |
588 DrawRopeLine(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, |
587 Round(PHedgehog(Gear.Hedgehog).Gear.X) + WorldDx, Round(PHedgehog(Gear.Hedgehog).Gear.Y) + WorldDy); |
589 hwRound(PHedgehog(Gear^.Hedgehog)^.Gear^.X) + WorldDx, hwRound(PHedgehog(Gear^.Hedgehog)^.Gear^.Y) + WorldDy); |
588 DrawSprite(sprRopeHook, Round(RopePoints.ar[0].X) + WorldDx - 16, Round(RopePoints.ar[0].Y) + WorldDy - 16, RopePoints.HookAngle, Surface); |
590 DrawSprite(sprRopeHook, hwRound(RopePoints.ar[0].X) + WorldDx - 16, hwRound(RopePoints.ar[0].Y) + WorldDy - 16, RopePoints.HookAngle, Surface); |
589 end else |
591 end else |
590 begin |
592 begin |
591 DrawRopeLine(Round(Gear.X) + WorldDx, Round(Gear.Y) + WorldDy, |
593 DrawRopeLine(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, |
592 Round(PHedgehog(Gear.Hedgehog).Gear.X) + WorldDx, Round(PHedgehog(Gear.Hedgehog).Gear.Y) + WorldDy); |
594 hwRound(PHedgehog(Gear^.Hedgehog)^.Gear^.X) + WorldDx, hwRound(PHedgehog(Gear^.Hedgehog)^.Gear^.Y) + WorldDy); |
593 DrawSprite(sprRopeHook, Round(Gear.X) - 16 + WorldDx, Round(Gear.Y) - 16 + WorldDy, DxDy2Angle32(Gear.dY, Gear.dX), Surface); |
595 DrawSprite(sprRopeHook, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 16 + WorldDy, DxDy2Angle32(Gear^.dY.QWordValue, Gear^.dX.QWordValue), Surface); |
594 end; |
596 end; |
595 end; |
597 end; |
596 gtExplosion: DrawSprite(sprExplosion50, Round(Gear.X) + WorldDx, Round(Gear.Y) + WorldDy, Gear.State, Surface); |
598 gtExplosion: DrawSprite(sprExplosion50, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.State, Surface); |
597 gtMine: if ((Gear.State and gstAttacking) = 0)or((Gear.Timer and $3FF) < 420) |
599 gtMine: if ((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420) |
598 then DrawSprite(sprMineOff , Round(Gear.X) - 8 + WorldDx, Round(Gear.Y) - 8 + WorldDy, trunc(Gear.DirAngle), Surface) |
600 then DrawSprite(sprMineOff , hwRound(Gear^.X) - 8 + WorldDx, hwRound(Gear^.Y) - 8 + WorldDy, hwRound(Gear^.DirAngle), Surface) |
599 else DrawSprite(sprMineOn , Round(Gear.X) - 8 + WorldDx, Round(Gear.Y) - 8 + WorldDy, trunc(Gear.DirAngle), Surface); |
601 else DrawSprite(sprMineOn , hwRound(Gear^.X) - 8 + WorldDx, hwRound(Gear^.Y) - 8 + WorldDy, hwRound(Gear^.DirAngle), Surface); |
600 gtDynamite: DrawSprite2(sprDynamite, Round(Gear.X) - 16 + WorldDx, Round(Gear.Y) - 25 + WorldDy, Gear.Tag and 1, Gear.Tag shr 1, Surface); |
602 gtDynamite: DrawSprite2(sprDynamite, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 25 + WorldDy, Gear^.Tag and 1, Gear^.Tag shr 1, Surface); |
601 gtCase: case Gear.Pos of |
603 gtCase: case Gear^.Pos of |
602 posCaseAmmo : DrawSprite(sprCase, Round(Gear.X) - 16 + WorldDx, Round(Gear.Y) - 16 + WorldDy, 0, Surface); |
604 posCaseAmmo : DrawSprite(sprCase, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 16 + WorldDy, 0, Surface); |
603 posCaseHealth: DrawSprite(sprFAid, Round(Gear.X) - 24 + WorldDx, Round(Gear.Y) - 24 + WorldDy, (GameTicks shr 6) mod 13, Surface); |
605 posCaseHealth: DrawSprite(sprFAid, hwRound(Gear^.X) - 24 + WorldDx, hwRound(Gear^.Y) - 24 + WorldDy, (GameTicks shr 6) mod 13, Surface); |
604 end; |
606 end; |
605 gtClusterBomb: DrawSprite(sprClusterBomb, Round(Gear.X) - 8 + WorldDx, Round(Gear.Y) - 8 + WorldDy, trunc(Gear.DirAngle), Surface); |
607 gtClusterBomb: DrawSprite(sprClusterBomb, hwRound(Gear^.X) - 8 + WorldDx, hwRound(Gear^.Y) - 8 + WorldDy, hwRound(Gear^.DirAngle), Surface); |
606 gtCluster: DrawSprite(sprClusterParticle, Round(Gear.X) - 8 + WorldDx, Round(Gear.Y) - 8 + WorldDy, 0, Surface); |
608 gtCluster: DrawSprite(sprClusterParticle, hwRound(Gear^.X) - 8 + WorldDx, hwRound(Gear^.Y) - 8 + WorldDy, 0, Surface); |
607 gtFlame: DrawSprite(sprFlame, Round(Gear.X) - 8 + WorldDx, Round(Gear.Y) - 8 + WorldDy,(GameTicks div 128 + Gear.Angle) mod 8, Surface); |
609 gtFlame: DrawSprite(sprFlame, hwRound(Gear^.X) - 8 + WorldDx, hwRound(Gear^.Y) - 8 + WorldDy,(GameTicks div 128 + Gear^.Angle) mod 8, Surface); |
608 gtAirBomb: DrawSprite(sprAirBomb , Round(Gear.X) - 16 + WorldDx, Round(Gear.Y) - 16 + WorldDy, DxDy2Angle32(Gear.dY, Gear.dX), Surface); |
610 gtAirBomb: DrawSprite(sprAirBomb , hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 16 + WorldDy, DxDy2Angle32(Gear^.dY.QWordValue, Gear^.dX.QWordValue), Surface); |
609 gtAirAttack: DrawSprite(sprAirplane, Round(Gear.X) - 60 + WorldDx, Round(Gear.Y) - 25 + WorldDy, 0, Surface); |
611 gtAirAttack: DrawSprite(sprAirplane, hwRound(Gear^.X) - 60 + WorldDx, hwRound(Gear^.Y) - 25 + WorldDy, 0, Surface); |
610 end; |
612 end; |
611 Gear:= Gear.NextGear |
613 Gear:= Gear^.NextGear |
612 end; |
614 end; |
613 end; |
615 end; |
614 |
616 |
615 procedure FreeGearsList; |
617 procedure FreeGearsList; |
616 var t, tt: PGear; |
618 var t, tt: PGear; |
618 tt:= GearsList; |
620 tt:= GearsList; |
619 GearsList:= nil; |
621 GearsList:= nil; |
620 while tt<>nil do |
622 while tt<>nil do |
621 begin |
623 begin |
622 t:= tt; |
624 t:= tt; |
623 tt:= tt.NextGear; |
625 tt:= tt^.NextGear; |
624 Dispose(t) |
626 Dispose(t) |
625 end; |
627 end; |
626 end; |
628 end; |
627 |
629 |
628 procedure AddMiscGears; |
630 procedure AddMiscGears; |
629 var i: integer; |
631 var i: integer; |
630 begin |
632 begin |
631 AddGear(0, 0, gtATStartGame, 0, 0, 0, 2000); |
633 AddGear(0, 0, gtATStartGame, 0, 0, 0, 2000); |
632 if (GameFlags and gfForts) = 0 then |
634 if (GameFlags and gfForts) = 0 then |
633 for i:= 0 to 3 do |
635 for i:= 0 to 3 do |
634 FindPlace(AddGear(0, 0, gtMine, 0), false, 0, 2048); |
636 FindPlace(AddGear(0, 0, gtMine, 0, 0, 0, 0), false, 0, 2048); |
635 end; |
637 end; |
636 |
638 |
637 procedure AddClouds; |
639 procedure AddClouds; |
638 var i: integer; |
640 var i: integer; |
639 begin |
641 begin |
640 for i:= 0 to cCloudsNumber do |
642 for i:= 0 to cCloudsNumber do |
641 AddGear( - cScreenWidth + i * ((cScreenWidth * 2 + 2304) div cCloudsNumber), -140, gtCloud, random(4), |
643 AddGear( - cScreenWidth + i * ((cScreenWidth * 2 + 2304) div cCloudsNumber), -140, gtCloud, random(4), |
642 (0.5-random)*0.1, ((i mod 2) * 2 - 1) * (0.005 + 0.015*random)) |
644 // (0.5-random)*0.1, ((i mod 2) * 2 - 1) * (0.005 + 0.015*random), 0) |
|
645 0, 0, 0) |
643 end; |
646 end; |
644 |
647 |
645 procedure doMakeExplosion(X, Y, Radius: integer; Mask: LongWord); |
648 procedure doMakeExplosion(X, Y, Radius: integer; Mask: LongWord); |
646 var Gear: PGear; |
649 var Gear: PGear; |
647 dmg: integer; |
650 dmg: integer; |
648 begin |
651 begin |
649 TargetPoint.X:= NoPointX; |
652 TargetPoint.X:= NoPointX; |
650 {$IFDEF DEBUGFILE}if Radius > 3 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')');{$ENDIF} |
653 {$IFDEF DEBUGFILE}if Radius > 3 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')');{$ENDIF} |
651 if (Mask and EXPLDontDraw) = 0 then DrawExplosion(X, Y, Radius); |
654 if (Mask and EXPLDontDraw) = 0 then DrawExplosion(X, Y, Radius); |
652 if Radius = 50 then AddGear(X, Y, gtExplosion, 0); |
655 if Radius = 50 then AddGear(X, Y, gtExplosion, 0, 0, 0, 0); |
653 if (Mask and EXPLAutoSound)<>0 then PlaySound(sndExplosion); |
656 if (Mask and EXPLAutoSound)<>0 then PlaySound(sndExplosion, false); |
654 if (Mask and EXPLAllDamageInRadius)=0 then Radius:= Radius shl 1; |
657 if (Mask and EXPLAllDamageInRadius)=0 then Radius:= Radius shl 1; |
655 Gear:= GearsList; |
658 Gear:= GearsList; |
656 while Gear <> nil do |
659 while Gear <> nil do |
657 begin |
660 begin |
658 dmg:= Radius - Round(sqrt(sqr(Gear.X - X) + sqr(Gear.Y - Y))); |
661 dmg:= Radius - hwRound(Distance(Gear^.X - X, Gear^.Y - Y)); |
659 if dmg > 0 then |
662 if dmg > 0 then |
660 begin |
663 begin |
661 dmg:= dmg shr 1; |
664 dmg:= dmg shr 1; |
662 case Gear.Kind of |
665 case Gear^.Kind of |
663 gtHedgehog, |
666 gtHedgehog, |
664 gtMine, |
667 gtMine, |
665 gtCase, |
668 gtCase, |
666 gtFlame: begin |
669 gtFlame: begin |
667 if (Mask and EXPLNoDamage) = 0 then inc(Gear.Damage, dmg); |
670 if (Mask and EXPLNoDamage) = 0 then inc(Gear^.Damage, dmg); |
668 if ((Mask and EXPLDoNotTouchHH) = 0) or (Gear.Kind <> gtHedgehog) then |
671 if ((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog) then |
669 begin |
672 begin |
670 Gear.dX:= Gear.dX + (dmg / 200 + cHHKick)* hwSign(Gear.X - X); |
673 Gear^.dX:= Gear^.dX + (_0_005 * dmg + cHHKick)* hwSign(Gear^.X - X); |
671 Gear.dY:= Gear.dY + (dmg / 200 + cHHKick)* hwSign(Gear.Y - Y); |
674 Gear^.dY:= Gear^.dY + (_0_005 * dmg + cHHKick)* hwSign(Gear^.Y - Y); |
672 Gear.Active:= true; |
675 Gear^.Active:= true; |
673 FollowGear:= Gear |
676 FollowGear:= Gear |
674 end; |
677 end; |
675 end; |
678 end; |
676 gtGrave: begin |
679 gtGrave: begin |
677 Gear.dY:= - dmg / 250; |
680 Gear^.dY:= - _0_004 * dmg; |
678 Gear.Active:= true; |
681 Gear^.Active:= true; |
679 end; |
682 end; |
680 end; |
683 end; |
681 end; |
684 end; |
682 Gear:= Gear.NextGear |
685 Gear:= Gear^.NextGear |
683 end; |
686 end; |
684 uAIMisc.AwareOfExplosion(0, 0, 0) |
687 //uAIMisc.AwareOfExplosion(0, 0, 0) |
685 end; |
688 end; |
686 |
689 |
687 procedure AmmoShove(Ammo: PGear; Damage, Power: integer); |
690 procedure AmmoShove(Ammo: PGear; Damage, Power: integer); |
688 var t: PGearArray; |
691 var t: PGearArray; |
689 i: integer; |
692 i: integer; |
690 hh: PHedgehog; |
693 hh: PHedgehog; |
691 begin |
694 begin |
692 t:= CheckGearsCollision(Ammo); |
695 t:= CheckGearsCollision(Ammo); |
693 i:= t.Count; |
696 i:= t^.Count; |
694 hh:= Ammo.Hedgehog; |
697 hh:= Ammo^.Hedgehog; |
695 while i > 0 do |
698 while i > 0 do |
696 begin |
699 begin |
697 dec(i); |
700 dec(i); |
698 if (t.ar[i].State and gstNoDamage) = 0 then |
701 if (t^.ar[i]^.State and gstNoDamage) = 0 then |
699 case t.ar[i].Kind of |
702 case t^.ar[i]^.Kind of |
700 gtHedgehog, |
703 gtHedgehog, |
701 gtMine, |
704 gtMine, |
702 gtCase: begin |
705 gtCase: begin |
703 inc(t.ar[i].Damage, Damage); |
706 inc(t^.ar[i]^.Damage, Damage); |
704 inc(hh.DamageGiven, Damage); |
707 inc(hh^.DamageGiven, Damage); |
705 t.ar[i].dX:= Ammo.dX * Power * 0.01; |
708 t^.ar[i]^.dX:= Ammo^.dX * Power * _0_01; |
706 t.ar[i].dY:= Ammo.dY * Power * 0.01; |
709 t^.ar[i]^.dY:= Ammo^.dY * Power * _0_01; |
707 t.ar[i].Active:= true; |
710 t^.ar[i]^.Active:= true; |
708 DeleteCI(t.ar[i]); |
711 DeleteCI(t^.ar[i]); |
709 FollowGear:= t.ar[i] |
712 FollowGear:= t^.ar[i] |
710 end; |
713 end; |
711 end |
714 end |
712 end; |
715 end; |
713 SetAllToActive |
716 SetAllToActive |
714 end; |
717 end; |
776 t:= GearsList; |
776 t:= GearsList; |
777 rX:= sqr(rX); |
777 rX:= sqr(rX); |
778 rY:= sqr(rY); |
778 rY:= sqr(rY); |
779 while t <> nil do |
779 while t <> nil do |
780 begin |
780 begin |
781 if t.Kind in Kind then |
781 if t^.Kind in Kind then |
782 if sqr(mX - t.X) / rX + sqr(mY - t.Y) / rY <= 1 then |
782 if not (hwSqr(mX - t^.X) / rX + hwSqr(mY - t^.Y) / rY > 1) then |
783 begin |
783 exit(t); |
784 Result:= t; |
784 t:= t^.NextGear |
785 exit |
785 end; |
786 end; |
786 CheckGearsNear:= nil |
787 t:= t.NextGear |
|
788 end; |
|
789 Result:= nil |
|
790 end; |
787 end; |
791 |
788 |
792 function CountGears(Kind: TGearType): Longword; |
789 function CountGears(Kind: TGearType): Longword; |
793 var t: PGear; |
790 var t: PGear; |
|
791 Result: Longword; |
794 begin |
792 begin |
795 Result:= 0; |
793 Result:= 0; |
796 t:= GearsList; |
794 t:= GearsList; |
797 while t <> nil do |
795 while t <> nil do |
798 begin |
796 begin |
799 if t.Kind = Kind then inc(Result); |
797 if t^.Kind = Kind then inc(Result); |
800 t:= t.NextGear |
798 t:= t^.NextGear |
801 end; |
799 end; |
|
800 CountGears:= Result |
802 end; |
801 end; |
803 |
802 |
804 procedure SpawnBoxOfSmth; |
803 procedure SpawnBoxOfSmth; |
805 begin |
804 begin |
806 if (CountGears(gtCase) >= 5) or (getrandom(cCaseFactor) <> 0) then exit; |
805 if (CountGears(gtCase) >= 5) or (getrandom(cCaseFactor) <> 0) then exit; |
807 FollowGear:= AddGear(0, 0, gtCase, 0); |
806 FollowGear:= AddGear(0, 0, gtCase, 0, 0, 0, 0); |
808 case getrandom(2) of |
807 case getrandom(2) of |
809 0: begin |
808 0: begin |
810 FollowGear.Health:= 25; |
809 FollowGear^.Health:= 25; |
811 FollowGear.Pos:= posCaseHealth |
810 FollowGear^.Pos:= posCaseHealth |
812 end; |
811 end; |
813 1: begin |
812 1: begin |
814 FollowGear.Pos:= posCaseAmmo; |
813 FollowGear^.Pos:= posCaseAmmo; |
815 FollowGear.State:= Longword(amMineStrike) |
814 FollowGear^.State:= Longword(amMineStrike) |
816 end; |
815 end; |
817 end; |
816 end; |
818 FindPlace(FollowGear, true, 0, 2048) |
817 FindPlace(FollowGear, true, 0, 2048) |
819 end; |
818 end; |
820 |
819 |
821 procedure FindPlace(Gear: PGear; withFall: boolean; Left, Right: integer); |
820 procedure FindPlace(Gear: PGear; withFall: boolean; Left, Right: integer); |
822 |
821 |
823 function CountNonZeroz(x, y, r: integer): integer; |
822 function CountNonZeroz(x, y, r: integer): integer; |
824 var i: integer; |
823 var i: integer; |
|
824 Result: integer; |
825 begin |
825 begin |
826 Result:= 0; |
826 Result:= 0; |
827 if (y and $FFFFFC00) <> 0 then exit; |
827 if (y and $FFFFFC00) <> 0 then exit; |
828 for i:= max(x - r, 0) to min(x + r, 2043) do |
828 for i:= max(x - r, 0) to min(x + r, 2043) do |
829 if Land[y, i] <> 0 then inc(Result) |
829 if Land[y, i] <> 0 then inc(Result); |
|
830 CountNonZeroz:= Result |
830 end; |
831 end; |
831 |
832 |
832 var fx, x: integer; |
833 var fx, x: integer; |
833 y, sy: integer; |
834 y, sy: integer; |
834 ar: array[0..512] of TPoint; |
835 ar: array[0..512] of TPoint; |
837 fx:= Left + integer(GetRandom(Right - Left)); |
838 fx:= Left + integer(GetRandom(Right - Left)); |
838 x:= fx; |
839 x:= fx; |
839 delta:= 130; |
840 delta:= 130; |
840 repeat |
841 repeat |
841 repeat |
842 repeat |
842 inc(x, Gear.Radius); |
843 inc(x, Gear^.Radius); |
843 if x > Right then x:= Left + (x mod (Right - left)); |
844 if x > Right then x:= Left + (x mod (Right - left)); |
844 cnt:= 0; |
845 cnt:= 0; |
845 y:= -Gear.Radius * 2; |
846 y:= -Gear^.Radius * 2; |
846 while y < 1023 do |
847 while y < 1023 do |
847 begin |
848 begin |
848 repeat |
849 repeat |
849 inc(y, 2); |
850 inc(y, 2); |
850 until (y > 1023) or (CountNonZeroz(x, y, Gear.Radius - 1) = 0); |
851 until (y > 1023) or (CountNonZeroz(x, y, Gear^.Radius - 1) = 0); |
851 sy:= y; |
852 sy:= y; |
852 repeat |
853 repeat |
853 inc(y); |
854 inc(y); |
854 until (y > 1023) or (CountNonZeroz(x, y, Gear.Radius - 1) <> 0); |
855 until (y > 1023) or (CountNonZeroz(x, y, Gear^.Radius - 1) <> 0); |
855 if (y - sy > Gear.Radius * 2) |
856 if (y - sy > Gear^.Radius * 2) |
856 and (y < 1023) |
857 and (y < 1023) |
857 and (CheckGearsNear(x, y - Gear.Radius, [gtHedgehog, gtMine, gtCase], 110, 110) = nil) then |
858 and (CheckGearsNear(x, y - Gear^.Radius, [gtHedgehog, gtMine, gtCase], 110, 110) = nil) then |
858 begin |
859 begin |
859 ar[cnt].X:= x; |
860 ar[cnt].X:= x; |
860 if withFall then ar[cnt].Y:= sy + Gear.Radius |
861 if withFall then ar[cnt].Y:= sy + Gear^.Radius |
861 else ar[cnt].Y:= y - Gear.Radius; |
862 else ar[cnt].Y:= y - Gear^.Radius; |
862 inc(cnt) |
863 inc(cnt) |
863 end; |
864 end; |
864 inc(y, 80) |
865 inc(y, 80) |
865 end; |
866 end; |
866 if cnt > 0 then |
867 if cnt > 0 then |
867 with ar[GetRandom(cnt)] do |
868 with ar[GetRandom(cnt)] do |
868 begin |
869 begin |
869 Gear.X:= x; |
870 Gear^.X:= x; |
870 Gear.Y:= y; |
871 Gear^.Y:= y; |
871 {$IFDEF DEBUGFILE} |
872 {$IFDEF DEBUGFILE} |
872 AddFileLog('Assigned Gear ' + inttostr(integer(Gear)) + |
873 AddFileLog('Assigned Gear ' + inttostr(integer(Gear)) + |
873 ' coordinates (' + inttostr(x) + |
874 ' coordinates (' + inttostr(x) + |
874 ',' + inttostr(y) + ')'); |
875 ',' + inttostr(y) + ')'); |
875 {$ENDIF} |
876 {$ENDIF} |
876 exit |
877 exit |
877 end |
878 end |
878 until (x - Gear.Radius < fx) and (x + Gear.Radius > fx); |
879 until (x - Gear^.Radius < fx) and (x + Gear^.Radius > fx); |
879 dec(Delta, 20) |
880 dec(Delta, 20) |
880 until (Delta < 70); |
881 until (Delta < 70); |
881 OutError('Couldn''t find place for Gear ' + inttostr(integer(Gear)), false); |
882 OutError('Couldn''t find place for Gear ' + inttostr(integer(Gear)), false); |
882 DeleteGear(Gear) |
883 DeleteGear(Gear) |
883 end; |
884 end; |