160 KnownExplosion.Radius:= r |
160 KnownExplosion.Radius:= r |
161 end; |
161 end; |
162 |
162 |
163 function RatePlace(Gear: PGear): LongInt; |
163 function RatePlace(Gear: PGear): LongInt; |
164 var i, r: LongInt; |
164 var i, r: LongInt; |
165 Result: LongInt; |
165 rate: LongInt; |
166 begin |
166 begin |
167 Result:= 0; |
167 rate:= 0; |
168 for i:= 0 to Pred(bonuses.Count) do |
168 for i:= 0 to Pred(bonuses.Count) do |
169 with bonuses.ar[i] do |
169 with bonuses.ar[i] do |
170 begin |
170 begin |
171 r:= hwRound(Distance(Gear^.X - int2hwFloat(X), Gear^.Y - int2hwFloat(Y))); |
171 r:= hwRound(Distance(Gear^.X - int2hwFloat(X), Gear^.Y - int2hwFloat(Y))); |
172 if r < Radius then |
172 if r < Radius then |
173 inc(Result, Score * (Radius - r)) |
173 inc(rate, Score * (Radius - r)) |
174 end; |
174 end; |
175 RatePlace:= Result |
175 RatePlace:= rate; |
176 end; |
176 end; |
177 |
177 |
178 // Wrapper to test various approaches. If it works reasonably, will just replace. |
178 // Wrapper to test various approaches. If it works reasonably, will just replace. |
179 // Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with... |
179 // Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with... |
180 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; |
180 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; |
202 if b then exit(true); |
202 if b then exit(true); |
203 TestColl:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0) |
203 TestColl:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0) |
204 end; |
204 end; |
205 |
205 |
206 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; |
206 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; |
207 var i, dmg, Result: LongInt; |
207 var i, dmg, rate: LongInt; |
208 begin |
208 begin |
209 Result:= 0; |
209 rate:= 0; |
210 // add our virtual position |
210 // add our virtual position |
211 with Targets.ar[Targets.Count] do |
211 with Targets.ar[Targets.Count] do |
212 begin |
212 begin |
213 Point.x:= hwRound(Me^.X); |
213 Point.x:= hwRound(Me^.X); |
214 Point.y:= hwRound(Me^.Y); |
214 Point.y:= hwRound(Me^.Y); |
221 dmg:= r + cHHRadius div 2 - hwRound(DistanceI(Point.x - x, Point.y - y)); |
221 dmg:= r + cHHRadius div 2 - hwRound(DistanceI(Point.x - x, Point.y - y)); |
222 if dmg > 0 then |
222 if dmg > 0 then |
223 begin |
223 begin |
224 dmg:= min(dmg div 2, r); |
224 dmg:= min(dmg div 2, r); |
225 if dmg >= abs(Score) then |
225 if dmg >= abs(Score) then |
226 if Score > 0 then inc(Result, KillScore) |
226 if Score > 0 then inc(rate, KillScore) |
227 else dec(Result, KillScore * friendlyfactor div 100) |
227 else dec(rate, KillScore * friendlyfactor div 100) |
228 else |
228 else |
229 if Score > 0 then inc(Result, dmg) |
229 if Score > 0 then inc(rate, dmg) |
230 else dec(Result, dmg * friendlyfactor div 100) |
230 else dec(rate, dmg * friendlyfactor div 100) |
231 end; |
231 end; |
232 end; |
232 end; |
233 RateExplosion:= Result * 1024 |
233 RateExplosion:= rate * 1024; |
234 end; |
234 end; |
235 |
235 |
236 function RateShove(Me: PGear; x, y, r, power: LongInt): LongInt; |
236 function RateShove(Me: PGear; x, y, r, power: LongInt): LongInt; |
237 var i, dmg, Result: LongInt; |
237 var i, dmg, rate: LongInt; |
238 begin |
238 begin |
239 Result:= 0; |
239 rate:= 0; |
240 for i:= 0 to Pred(Targets.Count) do |
240 for i:= 0 to Pred(Targets.Count) do |
241 with Targets.ar[i] do |
241 with Targets.ar[i] do |
242 begin |
242 begin |
243 dmg:= r - hwRound(DistanceI(Point.x - x, Point.y - y)); |
243 dmg:= r - hwRound(DistanceI(Point.x - x, Point.y - y)); |
244 if dmg > 0 then |
244 if dmg > 0 then |
245 begin |
245 begin |
246 if power >= abs(Score) then |
246 if power >= abs(Score) then |
247 if Score > 0 then inc(Result, KillScore) |
247 if Score > 0 then inc(rate, KillScore) |
248 else dec(Result, KillScore * friendlyfactor div 100) |
248 else dec(rate, KillScore * friendlyfactor div 100) |
249 else |
249 else |
250 if Score > 0 then inc(Result, power) |
250 if Score > 0 then inc(rate, power) |
251 else dec(Result, power * friendlyfactor div 100) |
251 else dec(rate, power * friendlyfactor div 100) |
252 end; |
252 end; |
253 end; |
253 end; |
254 RateShove:= Result * 1024 |
254 RateShove:= rate * 1024 |
255 end; |
255 end; |
256 |
256 |
257 function RateShotgun(Me: PGear; x, y: LongInt): LongInt; |
257 function RateShotgun(Me: PGear; x, y: LongInt): LongInt; |
258 const |
258 const |
259 REUSE_BONUS = 1.35; |
259 REUSE_BONUS = 1.35; |
260 var i, dmg, Result: LongInt; |
260 var i, dmg, rate: LongInt; |
261 begin |
261 begin |
262 Result:= 0; |
262 rate:= 0; |
263 // add our virtual position |
263 // add our virtual position |
264 with Targets.ar[Targets.Count] do |
264 with Targets.ar[Targets.Count] do |
265 begin |
265 begin |
266 Point.x:= hwRound(Me^.X); |
266 Point.x:= hwRound(Me^.X); |
267 Point.y:= hwRound(Me^.Y); |
267 Point.y:= hwRound(Me^.Y); |
274 dmg:= min(cHHRadius + cShotgunRadius - hwRound(DistanceI(Point.x - x, Point.y - y)), 25); |
274 dmg:= min(cHHRadius + cShotgunRadius - hwRound(DistanceI(Point.x - x, Point.y - y)), 25); |
275 dmg := round(dmg * REUSE_BONUS); |
275 dmg := round(dmg * REUSE_BONUS); |
276 if dmg > 0 then |
276 if dmg > 0 then |
277 begin |
277 begin |
278 if dmg >= abs(Score) then dmg := KillScore; |
278 if dmg >= abs(Score) then dmg := KillScore; |
279 if Score > 0 then inc(Result, dmg) |
279 if Score > 0 then inc(rate, dmg) |
280 else dec(Result, dmg * friendlyfactor div 100); |
280 else dec(rate, dmg * friendlyfactor div 100); |
281 end; |
281 end; |
282 end; |
282 end; |
283 RateShotgun:= Result * 1024 |
283 RateShotgun:= rate * 1024; |
284 end; |
284 end; |
285 |
285 |
286 function HHJump(Gear: PGear; JumpType: TJumpType; var GoInfo: TGoInfo): boolean; |
286 function HHJump(Gear: PGear; JumpType: TJumpType; var GoInfo: TGoInfo): boolean; |
287 var bX, bY: LongInt; |
287 var bX, bY: LongInt; |
288 Result: boolean; |
288 bRes: boolean; |
289 begin |
289 begin |
290 Result:= false; |
290 bRes:= false; |
291 GoInfo.Ticks:= 0; |
291 GoInfo.Ticks:= 0; |
292 GoInfo.FallPix:= 0; |
292 GoInfo.FallPix:= 0; |
293 GoInfo.JumpType:= jmpNone; |
293 GoInfo.JumpType:= jmpNone; |
294 bX:= hwRound(Gear^.X); |
294 bX:= hwRound(Gear^.X); |
295 bY:= hwRound(Gear^.Y); |
295 bY:= hwRound(Gear^.Y); |
296 case JumpType of |
296 case JumpType of |
297 jmpNone: exit(Result); |
297 jmpNone: exit(bRes); |
298 jmpHJump: if not TestCollisionYwithGear(Gear, -1) then |
298 jmpHJump: if not TestCollisionYwithGear(Gear, -1) then |
299 begin |
299 begin |
300 Gear^.dY:= -_0_2; |
300 Gear^.dY:= -_0_2; |
301 SetLittle(Gear^.dX); |
301 SetLittle(Gear^.dX); |
302 Gear^.State:= Gear^.State or gstMoving or gstHHJumping; |
302 Gear^.State:= Gear^.State or gstMoving or gstHHJumping; |
303 end else exit(Result); |
303 end else exit(bRes); |
304 jmpLJump: begin |
304 jmpLJump: begin |
305 if not TestCollisionYwithGear(Gear, -1) then |
305 if not TestCollisionYwithGear(Gear, -1) then |
306 if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then Gear^.Y:= Gear^.Y - int2hwFloat(2) else |
306 if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then Gear^.Y:= Gear^.Y - int2hwFloat(2) else |
307 if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then Gear^.Y:= Gear^.Y - _1; |
307 if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then Gear^.Y:= Gear^.Y - _1; |
308 if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) |
308 if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) |
309 or TestCollisionYwithGear(Gear, -1)) then |
309 or TestCollisionYwithGear(Gear, -1)) then |
310 begin |
310 begin |
311 Gear^.dY:= -_0_15; |
311 Gear^.dY:= -_0_15; |
312 Gear^.dX:= SignAs(_0_15, Gear^.dX); |
312 Gear^.dX:= SignAs(_0_15, Gear^.dX); |
313 Gear^.State:= Gear^.State or gstMoving or gstHHJumping |
313 Gear^.State:= Gear^.State or gstMoving or gstHHJumping |
314 end else exit(Result) |
314 end else exit(bRes) |
315 end |
315 end |
316 end; |
316 end; |
317 |
317 |
318 repeat |
318 repeat |
319 if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then exit(Result); |
319 if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then exit(bRes); |
320 if (Gear^.State and gstMoving) <> 0 then |
320 if (Gear^.State and gstMoving) <> 0 then |
321 begin |
321 begin |
322 if (GoInfo.Ticks = 350) then |
322 if (GoInfo.Ticks = 350) then |
323 if (not (hwAbs(Gear^.dX) > cLittle)) and (Gear^.dY < -_0_02) then |
323 if (not (hwAbs(Gear^.dX) > cLittle)) and (Gear^.dY < -_0_02) then |
324 begin |
324 begin |
327 end; |
327 end; |
328 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then SetLittle(Gear^.dX); |
328 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then SetLittle(Gear^.dX); |
329 Gear^.X:= Gear^.X + Gear^.dX; |
329 Gear^.X:= Gear^.X + Gear^.dX; |
330 inc(GoInfo.Ticks); |
330 inc(GoInfo.Ticks); |
331 Gear^.dY:= Gear^.dY + cGravity; |
331 Gear^.dY:= Gear^.dY + cGravity; |
332 if Gear^.dY > _0_4 then exit(Result); |
332 if Gear^.dY > _0_4 then exit(bRes); |
333 if (Gear^.dY.isNegative)and TestCollisionYwithGear(Gear, -1) then Gear^.dY:= _0; |
333 if (Gear^.dY.isNegative)and TestCollisionYwithGear(Gear, -1) then Gear^.dY:= _0; |
334 Gear^.Y:= Gear^.Y + Gear^.dY; |
334 Gear^.Y:= Gear^.Y + Gear^.dY; |
335 if (not Gear^.dY.isNegative)and TestCollisionYwithGear(Gear, 1) then |
335 if (not Gear^.dY.isNegative)and TestCollisionYwithGear(Gear, 1) then |
336 begin |
336 begin |
337 Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); |
337 Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); |
338 Gear^.dY:= _0; |
338 Gear^.dY:= _0; |
339 case JumpType of |
339 case JumpType of |
340 jmpHJump: if bY - hwRound(Gear^.Y) > 5 then |
340 jmpHJump: if bY - hwRound(Gear^.Y) > 5 then |
341 begin |
341 begin |
342 Result:= true; |
342 bRes:= true; |
343 GoInfo.JumpType:= jmpHJump; |
343 GoInfo.JumpType:= jmpHJump; |
344 inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after |
344 inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after |
345 end; |
345 end; |
346 jmpLJump: if abs(bX - hwRound(Gear^.X)) > 30 then |
346 jmpLJump: if abs(bX - hwRound(Gear^.X)) > 30 then |
347 begin |
347 begin |
348 Result:= true; |
348 bRes:= true; |
349 GoInfo.JumpType:= jmpLJump; |
349 GoInfo.JumpType:= jmpLJump; |
350 inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after |
350 inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after |
351 end; |
351 end; |
352 end; |
352 end; |
353 exit(Result) |
353 exit(bRes) |
354 end; |
354 end; |
355 end; |
355 end; |
356 until false |
356 until false |
357 end; |
357 end; |
358 |
358 |
359 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
359 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
360 var pX, pY: LongInt; |
360 var pX, pY: LongInt; |
361 Result: boolean; |
361 bRes: boolean; |
362 begin |
362 begin |
363 Result:= false; |
363 bRes:= false; |
364 AltGear^:= Gear^; |
364 AltGear^:= Gear^; |
365 |
365 |
366 GoInfo.Ticks:= 0; |
366 GoInfo.Ticks:= 0; |
367 GoInfo.FallPix:= 0; |
367 GoInfo.FallPix:= 0; |
368 GoInfo.JumpType:= jmpNone; |
368 GoInfo.JumpType:= jmpNone; |
376 Gear^.dY:= Gear^.dY + cGravity; |
376 Gear^.dY:= Gear^.dY + cGravity; |
377 if Gear^.dY > _0_4 then |
377 if Gear^.dY > _0_4 then |
378 begin |
378 begin |
379 Goinfo.FallPix:= 0; |
379 Goinfo.FallPix:= 0; |
380 HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall with damage |
380 HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall with damage |
381 exit(Result) |
381 exit(bRes) |
382 end; |
382 end; |
383 Gear^.Y:= Gear^.Y + Gear^.dY; |
383 Gear^.Y:= Gear^.Y + Gear^.dY; |
384 if hwRound(Gear^.Y) > pY then inc(GoInfo.FallPix); |
384 if hwRound(Gear^.Y) > pY then inc(GoInfo.FallPix); |
385 if TestCollisionYwithGear(Gear, 1) then |
385 if TestCollisionYwithGear(Gear, 1) then |
386 begin |
386 begin |
387 inc(GoInfo.Ticks, 410); |
387 inc(GoInfo.Ticks, 410); |
388 Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); |
388 Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); |
389 Gear^.dY:= _0; |
389 Gear^.dY:= _0; |
390 Result:= true; |
390 bRes:= true; |
391 HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall |
391 HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall |
392 exit(Result) |
392 exit(bRes) |
393 end; |
393 end; |
394 continue |
394 continue |
395 end; |
395 end; |
396 if (Gear^.Message and gm_Left )<>0 then Gear^.dX:= -cLittle else |
396 if (Gear^.Message and gm_Left )<>0 then Gear^.dX:= -cLittle else |
397 if (Gear^.Message and gm_Right )<>0 then Gear^.dX:= cLittle else exit(Result); |
397 if (Gear^.Message and gm_Right )<>0 then Gear^.dX:= cLittle else exit(bRes); |
398 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
398 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
399 begin |
399 begin |
400 if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX)) |
400 if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX)) |
401 or TestCollisionYwithGear(Gear, -1)) then Gear^.Y:= Gear^.Y - _1; |
401 or TestCollisionYwithGear(Gear, -1)) then Gear^.Y:= Gear^.Y - _1; |
402 if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX)) |
402 if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX)) |