477 else if Gear^.AdvBounce = 1 then |
476 else if Gear^.AdvBounce = 1 then |
478 begin |
477 begin |
479 xland:= TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)); |
478 xland:= TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)); |
480 if xland <> 0 then collH := -hwSign(Gear^.dX) |
479 if xland <> 0 then collH := -hwSign(Gear^.dX) |
481 end; |
480 end; |
482 //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then |
|
483 if (collV <> 0) and (collH <> 0) and |
481 if (collV <> 0) and (collH <> 0) and |
484 (((Gear^.AdvBounce=1) and ((collV=-1) or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)))) then |
482 (((Gear^.AdvBounce=1) and ((collV=-1) or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)))) then |
485 //or ((xland or land) and lfBouncy <> 0)) then |
|
486 begin |
483 begin |
487 if (xland or land) and lfBouncy = 0 then |
484 if (xland or land) and lfBouncy = 0 then |
488 begin |
485 begin |
489 Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction; |
486 Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction; |
490 Gear^.dY := tdX*Gear^.Elasticity; |
487 Gear^.dY := tdX*Gear^.Elasticity; |
866 if DirAngle < 0 then |
854 if DirAngle < 0 then |
867 DirAngle := DirAngle + 360 |
855 DirAngle := DirAngle + 360 |
868 else if 360 < DirAngle then |
856 else if 360 < DirAngle then |
869 DirAngle := DirAngle - 360; |
857 DirAngle := DirAngle - 360; |
870 end; |
858 end; |
871 (* |
|
872 We aren't using frametick right now, so just a waste of cycles. |
|
873 inc(Health, 8); |
|
874 if longword(Health) > vobFrameTicks then |
|
875 begin |
|
876 dec(Health, vobFrameTicks); |
|
877 inc(Timer); |
|
878 if Timer = vobFramesCount then |
|
879 Timer:= 0 |
|
880 end; |
|
881 *) |
|
882 // move back to cloud layer |
859 // move back to cloud layer |
883 if CheckCoordInWater(xx, yy) then |
860 if CheckCoordInWater(xx, yy) then |
884 move:= true |
861 move:= true |
885 else if (xx > snowRight) or (xx < snowLeft) then |
862 else if (xx > snowRight) or (xx < snowLeft) then |
886 move:=true |
863 move:=true |
2394 dmg:= hwRound(dxdy * _50); |
2371 dmg:= hwRound(dxdy * _50); |
2395 inc(Gear^.Damage, dmg); |
2372 inc(Gear^.Damage, dmg); |
2396 ScriptCall('onGearDamage', Gear^.UID, dmg) |
2373 ScriptCall('onGearDamage', Gear^.UID, dmg) |
2397 end; |
2374 end; |
2398 CalcRotationDirAngle(Gear); |
2375 CalcRotationDirAngle(Gear); |
2399 //CheckGearDrowning(Gear) |
|
2400 end |
2376 end |
2401 else |
2377 else |
2402 begin |
2378 begin |
2403 Gear^.State := Gear^.State or gsttmpFlag; |
2379 Gear^.State := Gear^.State or gsttmpFlag; |
2404 AddCI(Gear) |
2380 AddCI(Gear) |
2405 end; |
2381 end; |
2406 |
|
2407 (* |
|
2408 Attempt to make a barrel knock itself over an edge. Would need more checks to avoid issues like burn damage |
|
2409 begin |
|
2410 x:= hwRound(Gear^.X); |
|
2411 y:= hwRound(Gear^.Y); |
|
2412 if (((y+1) and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then |
|
2413 if (Land[y+1, x] = 0) then |
|
2414 begin |
|
2415 if (((y+1) and LAND_HEIGHT_MASK) = 0) and (((x+Gear^.Radius-2) and LAND_WIDTH_MASK) = 0) and (Land[y+1, x+Gear^.Radius-2] = 0) then |
|
2416 Gear^.dX:= -_0_08 |
|
2417 else if (((y+1 and LAND_HEIGHT_MASK)) = 0) and (((x-(Gear^.Radius-2)) and LAND_WIDTH_MASK) = 0) and (Land[y+1, x-(Gear^.Radius-2)] = 0) then |
|
2418 Gear^.dX:= _0_08; |
|
2419 end; |
|
2420 if Gear^.dX.QWordValue = 0 then AddCI(Gear) |
|
2421 end; *) |
|
2422 |
2382 |
2423 if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
2383 if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
2424 Gear^.dY := _0; |
2384 Gear^.dY := _0; |
2425 if hwAbs(Gear^.dX) < _0_001 then |
2385 if hwAbs(Gear^.dX) < _0_001 then |
2426 Gear^.dX := _0; |
2386 Gear^.dX := _0; |
2739 else begin |
2697 else begin |
2740 if Gear^.dX.QWordValue > _0_01.QWordValue then |
2698 if Gear^.dX.QWordValue > _0_01.QWordValue then |
2741 Gear^.dX := Gear^.dX * _0_995; |
2699 Gear^.dX := Gear^.dX * _0_995; |
2742 |
2700 |
2743 Gear^.dY := Gear^.dY + cGravity; |
2701 Gear^.dY := Gear^.dY + cGravity; |
2744 // if sticky then Gear^.dY := Gear^.dY + cGravity; |
|
2745 |
2702 |
2746 if Gear^.dY.QWordValue > _0_2.QWordValue then |
2703 if Gear^.dY.QWordValue > _0_2.QWordValue then |
2747 Gear^.dY := Gear^.dY * _0_995; |
2704 Gear^.dY := Gear^.dY * _0_995; |
2748 |
2705 |
2749 //if sticky then Gear^.X := Gear^.X + Gear^.dX else |
|
2750 Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640; |
2706 Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640; |
2751 Gear^.Y := Gear^.Y + Gear^.dY; |
2707 Gear^.Y := Gear^.Y + Gear^.dY; |
2752 end; |
2708 end; |
2753 |
2709 |
2754 gX := hwRound(Gear^.X); |
2710 gX := hwRound(Gear^.X); |
3031 case Gear^.State of |
2986 case Gear^.State of |
3032 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
2987 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
3033 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
2988 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
3034 2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
2989 2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
3035 3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed * Gear^.Tag, _0, Gear^.Timer + 1); |
2990 3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed * Gear^.Tag, _0, Gear^.Timer + 1); |
3036 //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed * |
|
3037 // Gear^.Tag, _0, 5000); |
|
3038 end; |
2991 end; |
3039 Gear^.dX := Gear^.dX + int2hwFloat(Gear^.Damage * Gear^.Tag); |
2992 Gear^.dX := Gear^.dX + int2hwFloat(Gear^.Damage * Gear^.Tag); |
3040 if CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then |
2993 if CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then |
3041 FollowGear^.State:= FollowGear^.State or gstSubmersible; |
2994 FollowGear^.State:= FollowGear^.State or gstSubmersible; |
3042 end; |
2995 end; |
3910 else if Hedgehog^.Effects[heFrozen] > 255 then |
3854 else if Hedgehog^.Effects[heFrozen] > 255 then |
3911 Hedgehog^.Effects[heFrozen]:= 255 |
3855 Hedgehog^.Effects[heFrozen]:= 255 |
3912 end ; |
3856 end ; |
3913 AfterAttack; |
3857 AfterAttack; |
3914 DeleteGear(Gear); |
3858 DeleteGear(Gear); |
3915 |
|
3916 (* |
|
3917 Gear^.X := Gear^.X + Gear^.dX; |
|
3918 Gear^.Y := Gear^.Y + Gear^.dY; |
|
3919 x := hwRound(Gear^.X); |
|
3920 y := hwRound(Gear^.Y); |
|
3921 |
|
3922 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then |
|
3923 if (Land[y, x] <> 0) then |
|
3924 begin |
|
3925 Gear^.dX.isNegative := not Gear^.dX.isNegative; |
|
3926 Gear^.dY.isNegative := not Gear^.dY.isNegative; |
|
3927 Gear^.dX := Gear^.dX * _1_5; |
|
3928 Gear^.dY := Gear^.dY * _1_5 - _0_3; |
|
3929 AmmoShove(Gear, 0, 40); |
|
3930 AfterAttack; |
|
3931 DeleteGear(Gear) |
|
3932 end |
|
3933 else |
|
3934 else |
|
3935 begin |
|
3936 AfterAttack; |
|
3937 DeleteGear(Gear) |
|
3938 end*) |
|
3939 end; |
3859 end; |
3940 |
3860 |
3941 procedure doStepSeductionWear(Gear: PGear); |
3861 procedure doStepSeductionWear(Gear: PGear); |
3942 var heart: PVisualGear; |
3862 var heart: PVisualGear; |
3943 HHGear: PGear; |
3863 HHGear: PGear; |
4413 isUnderwater:= CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y) + Gear^.Radius); |
4324 isUnderwater:= CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y) + Gear^.Radius); |
4414 if Gear^.Pos > 0 then |
4325 if Gear^.Pos > 0 then |
4415 dec(Gear^.Pos); |
4326 dec(Gear^.Pos); |
4416 AllInactive := false; |
4327 AllInactive := false; |
4417 HHGear := Gear^.Hedgehog^.Gear; |
4328 HHGear := Gear^.Hedgehog^.Gear; |
4418 //dec(Gear^.Timer); |
|
4419 move := _0_2; |
4329 move := _0_2; |
4420 fuel := 50; |
4330 fuel := 50; |
4421 (*if (HHGear^.Message and gmPrecise) <> 0 then |
|
4422 begin |
|
4423 move:= _0_02; |
|
4424 fuel:= 5; |
|
4425 end;*) |
|
4426 if HHGear^.Message and gmPrecise <> 0 then |
4331 if HHGear^.Message and gmPrecise <> 0 then |
4427 HedgehogChAngle(HHGear) |
4332 HedgehogChAngle(HHGear) |
4428 else if (Gear^.Health > 0) or (Gear^.Health = JETPACK_FUEL_INFINITE) then |
4333 else if (Gear^.Health > 0) or (Gear^.Health = JETPACK_FUEL_INFINITE) then |
4429 begin |
4334 begin |
4430 if HHGear^.Message and gmUp <> 0 then |
4335 if HHGear^.Message and gmUp <> 0 then |
4518 |
4423 |
4519 if ((Gear^.State and gsttmpFlag) = 0) |
4424 if ((Gear^.State and gsttmpFlag) = 0) |
4520 or (HHGear^.dY < _0) then |
4425 or (HHGear^.dY < _0) then |
4521 doStepHedgehogMoving(HHGear); |
4426 doStepHedgehogMoving(HHGear); |
4522 |
4427 |
4523 if // (Gear^.Health = 0) |
4428 if |
4524 (HHGear^.Damage <> 0) |
4429 (HHGear^.Damage <> 0) |
4525 //or CheckGearDrowning(HHGear) |
|
4526 // drown if too deep under water |
4430 // drown if too deep under water |
4527 or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y)) |
4431 or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y)) |
4528 or (TurnTimeLeft = 0) |
4432 or (TurnTimeLeft = 0) |
4529 // allow brief ground touches - to be fair on this, might need another counter |
4433 // allow brief ground touches - to be fair on this, might need another counter |
4530 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0)) |
4434 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0)) |
4538 end; |
4442 end; |
4539 if (GetAmmoEntry(HHGear^.Hedgehog^, amJetpack)^.Count >= 1) and ((Ammoz[HHGear^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) and (HHGear^.Hedgehog^.MultiShootAttacks = 0) then |
4443 if (GetAmmoEntry(HHGear^.Hedgehog^, amJetpack)^.Count >= 1) and ((Ammoz[HHGear^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) and (HHGear^.Hedgehog^.MultiShootAttacks = 0) then |
4540 HHGear^.Hedgehog^.CurAmmoType:= amJetpack; |
4444 HHGear^.Hedgehog^.CurAmmoType:= amJetpack; |
4541 isCursorVisible := false; |
4445 isCursorVisible := false; |
4542 ApplyAmmoChanges(HHGear^.Hedgehog^); |
4446 ApplyAmmoChanges(HHGear^.Hedgehog^); |
4543 // if Gear^.Tex <> nil then FreeTexture(Gear^.Tex); |
|
4544 |
|
4545 // Gear^.Tex:= RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + '%', cWhiteColor, fntSmall) |
|
4546 |
|
4547 //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
|
4548 DeleteGear(Gear); |
4447 DeleteGear(Gear); |
4549 end |
4448 end |
4550 end; |
4449 end; |
4551 |
4450 |
4552 procedure doStepJetpack(Gear: PGear); |
4451 procedure doStepJetpack(Gear: PGear); |
4787 i: LongInt; |
4686 i: LongInt; |
4788 begin |
4687 begin |
4789 AllInactive := false; |
4688 AllInactive := false; |
4790 Gear^.dX := Gear^.dX; |
4689 Gear^.dX := Gear^.dX; |
4791 doStepFallingGear(Gear); |
4690 doStepFallingGear(Gear); |
4792 // CheckGearDrowning(Gear); // already checked for in doStepFallingGear |
|
4793 CalcRotationDirAngle(Gear); |
4691 CalcRotationDirAngle(Gear); |
4794 |
4692 |
4795 if (Gear^.State and gstCollision) <> 0 then |
4693 if (Gear^.State and gstCollision) <> 0 then |
4796 begin |
4694 begin |
4797 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLPoisoned, $C0E0FFE0); |
4695 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLPoisoned, $C0E0FFE0); |
5741 |
5639 |
5742 flame:= AddGear(gx, gy, gtFlame, gstTmpFlag, |
5640 flame:= AddGear(gx, gy, gtFlame, gstTmpFlag, |
5743 SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx, |
5641 SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx, |
5744 AngleCos(HHGear^.Angle) * ( - speed) + ry, 0); |
5642 AngleCos(HHGear^.Angle) * ( - speed) + ry, 0); |
5745 flame^.CollisionMask:= lfNotCurHogCrate; |
5643 flame^.CollisionMask:= lfNotCurHogCrate; |
5746 //flame^.FlightTime:= 500; use the default huge value to avoid sticky flame suddenly being damaging as opposed to other flames |
|
5747 |
5644 |
5748 if (Gear^.Health mod 30) = 0 then |
5645 if (Gear^.Health mod 30) = 0 then |
5749 begin |
5646 begin |
5750 flame:= AddGear(gx, gy, gtFlame, 0, |
5647 flame:= AddGear(gx, gy, gtFlame, 0, |
5751 SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx, |
5648 SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx, |
5752 AngleCos(HHGear^.Angle) * ( - speed) + ry, 0); |
5649 AngleCos(HHGear^.Angle) * ( - speed) + ry, 0); |
5753 flame^.CollisionMask:= lfNotCurHogCrate; |
5650 flame^.CollisionMask:= lfNotCurHogCrate; |
5754 //flame^.FlightTime:= 500; |
|
5755 end |
5651 end |
5756 end; |
5652 end; |
5757 Gear^.Timer:= Gear^.Tag |
5653 Gear^.Timer:= Gear^.Tag |
5758 end; |
5654 end; |
5759 |
5655 |
6350 end; |
6225 end; |
6351 |
6226 |
6352 //////////////////////////////////////////////////////////////////////////////// |
6227 //////////////////////////////////////////////////////////////////////////////// |
6353 |
6228 |
6354 (* |
6229 (* |
6355 WIP. The ice gun will have the following effects. It has been proposed by sheepluva that it take the appearance of a large freezer |
6230 The ice gun has the following effects: |
6356 spewing ice cubes. The cubes will be visual gears only. The scatter from them and the impact snow dust should help hide imprecisions in things like the GearsNear effect. |
6231 A "ray" like a deagle is projected out from the gun. |
6357 For now we assume a "ray" like a deagle projected out from the gun. |
|
6358 All these effects assume the ray's angle is not changed and that the target type was unchanged over a number of ticks. This is a simplifying assumption for "gun was applying freezing effect to the same target". |
6232 All these effects assume the ray's angle is not changed and that the target type was unchanged over a number of ticks. This is a simplifying assumption for "gun was applying freezing effect to the same target". |
6359 * When fired at water a layer of ice textured land is added above the water. |
6233 * When fired at water a layer of ice textured land is added above the water. |
6360 * When fired at non-ice land (land and lfLandMask and not lfIce) the land is overlaid with a thin layer of ice textured land around that point (say, 1 or 2px into land, 1px above). For attractiveness, a slope would probably be needed. |
6234 * When fired at non-ice land (land and lfLandMask and not lfIce) the land is overlaid with a thin layer of ice textured land around that point (say, 1 or 2px into land, 1px above). For attractiveness, a slope would probably be needed. |
6361 * When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen. |
6235 * When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen. |
6362 As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head. |
6236 As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head. |
6363 If the effect is interrupted before reaching the top, the freezing state is cleared. |
6237 If the effect is interrupted before reaching the top, the freezing state is cleared. |
6364 A frozen hog will animate differently. |
6238 A frozen hog will animate differently. |
6365 To be decided, but possibly in a similar fashion to a grave when it comes to explosions. |
6239 Frozen hogs take less damage and are harder to push. |
6366 The hog might (possibly) not be damaged by explosions. |
|
6367 This might make freezing potentially useful for friendlies in a bad position. |
6240 This might make freezing potentially useful for friendlies in a bad position. |
6368 It might be better to allow damage though. |
|
6369 A frozen hog stays frozen for a certain number of turns. |
6241 A frozen hog stays frozen for a certain number of turns. |
6370 Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again. |
6242 Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again. |
6371 *) |
6243 *) |
6372 |
6244 |
6373 |
6245 |
6423 end; |
6293 end; |
6424 |
6294 |
6425 procedure doStepIceGun(Gear: PGear); |
6295 procedure doStepIceGun(Gear: PGear); |
6426 const iceWaitCollision = 0; |
6296 const iceWaitCollision = 0; |
6427 const iceCollideWithGround = 1; |
6297 const iceCollideWithGround = 1; |
6428 //const iceWaitNextTarget:Longint = 2; |
|
6429 //const iceCollideWithHog:Longint = 4; |
|
6430 const iceCollideWithWater = 5; |
6298 const iceCollideWithWater = 5; |
6431 //const waterFreezingTime:Longint = 500; |
|
6432 const groundFreezingTime = 1000; |
6299 const groundFreezingTime = 1000; |
6433 const iceRadius = 32; |
6300 const iceRadius = 32; |
6434 const iceHeight = 40; |
6301 const iceHeight = 40; |
6435 var |
6302 var |
6436 HHGear, iter: PGear; |
6303 HHGear, iter: PGear; |
6622 else |
6488 else |
6623 DrawIceBreak(Target.X-iceHeight-5, Target.Y, iceRadius, iceHeight); |
6489 DrawIceBreak(Target.X-iceHeight-5, Target.Y, iceRadius, iceHeight); |
6624 SetAllHHToActive; |
6490 SetAllHHToActive; |
6625 Timer := iceWaitCollision; |
6491 Timer := iceWaitCollision; |
6626 end; |
6492 end; |
6627 (* |
|
6628 Any ideas for something that would look good here? |
|
6629 if (Target.X <> NoPointX) and ((Timer = iceCollideWithGround) or (Timer = iceCollideWithWater)) and (GameTicks mod max((groundFreezingTime-((GameTicks - Power)*2)),2) = 0) then //and CheckLandValue(Target.X, Target.Y, lfIce) then |
|
6630 begin |
|
6631 vg:= AddVisualGear(Target.X+random(20)-10, Target.Y+random(40)-10, vgtDust, 1); |
|
6632 if vg <> nil then |
|
6633 begin |
|
6634 i:= random(100) + 155; |
|
6635 vg^.Tint:= IceColor or $FF; |
|
6636 vg^.Angle:= random(360); |
|
6637 vg^.dx:= 0.001 * random(80); |
|
6638 vg^.dy:= 0.001 * random(80) |
|
6639 end |
|
6640 end; |
|
6641 *) |
|
6642 |
|
6643 // freeze nearby hogs |
6493 // freeze nearby hogs |
6644 hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2); |
6494 hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2); |
6645 if hogs.size > 0 then |
6495 if hogs.size > 0 then |
6646 for i:= 0 to hogs.size - 1 do |
6496 for i:= 0 to hogs.size - 1 do |
6647 if hogs.ar^[i] <> HHGear then |
6497 if hogs.ar^[i] <> HHGear then |
6930 CalcRotationDirAngle(Gear); |
6778 CalcRotationDirAngle(Gear); |
6931 Gear^.DirAngle:= a+(Gear^.DirAngle-a)*2*hwSign(Gear^.dX) // double rotation |
6779 Gear^.DirAngle:= a+(Gear^.DirAngle-a)*2*hwSign(Gear^.dX) // double rotation |
6932 end |
6780 end |
6933 else if (Gear^.CollisionIndex = -1) and (Gear^.Timer = 0) then |
6781 else if (Gear^.CollisionIndex = -1) and (Gear^.Timer = 0) then |
6934 begin |
6782 begin |
6935 (*ox:= 0; oy:= 0; |
|
6936 if TestCollisionYwithGear(Gear, -1) <> 0 then oy:= -1; |
|
6937 if TestCollisionXwithGear(Gear, 1) <> 0 then ox:= 1; |
|
6938 if TestCollisionXwithGear(Gear, -1) <> 0 then ox:= -1; |
|
6939 if TestCollisionYwithGear(Gear, 1) <> 0 then oy:= 1; |
|
6940 |
|
6941 la:= _10000; |
|
6942 if (ox <> 0) or (oy <> 0) then |
|
6943 la:= CalcSlopeNearGear(Gear, ox, oy); |
|
6944 if la = _10000 then |
|
6945 begin |
|
6946 // debug for when we couldn't get an angle |
|
6947 //AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeWhite); |
|
6948 *) |
|
6949 if Gear^.Health > 0 then |
6783 if Gear^.Health > 0 then |
6950 PlaySound(Gear^.ImpactSound); |
6784 PlaySound(Gear^.ImpactSound); |
6951 |
6785 |
6952 Gear^.DirAngle:= DxDy2Angle(Gear^.dX, Gear^.dY) + (random(30)-15); |
6786 Gear^.DirAngle:= DxDy2Angle(Gear^.dX, Gear^.dY) + (random(30)-15); |
6953 if (Gear^.dX.isNegative and Gear^.dY.isNegative) or |
6787 if (Gear^.dX.isNegative and Gear^.dY.isNegative) or |
6954 ((not Gear^.dX.isNegative) and (not Gear^.dY.isNegative)) then Gear^.DirAngle:= Gear^.DirAngle-90; |
6788 ((not Gear^.dX.isNegative) and (not Gear^.dY.isNegative)) then Gear^.DirAngle:= Gear^.DirAngle-90; |
6955 // end |
|
6956 // else Gear^.DirAngle:= hwFloat2Float(la)*90; // sheepluva's comment claims 45deg = 0.5 - yet orientation doesn't seem consistent? |
|
6957 // AddFileLog('la: '+floattostr(la)+' DirAngle: '+inttostr(round(Gear^.DirAngle))); |
|
6958 Gear^.dX:= _0; |
6789 Gear^.dX:= _0; |
6959 Gear^.dY:= _0; |
6790 Gear^.dY:= _0; |
6960 Gear^.State:= Gear^.State and (not gstMoving) or gstCollision; |
6791 Gear^.State:= Gear^.State and (not gstMoving) or gstCollision; |
6961 Gear^.Radius:= 16; |
6792 Gear^.Radius:= 16; |
6962 if Gear^.Health > 0 then AmmoShove(Gear, Gear^.Health, 0); |
6793 if Gear^.Health > 0 then AmmoShove(Gear, Gear^.Health, 0); |
7054 Gear^.Y := Gear^.Y + Gear^.dY * 2; |
6885 Gear^.Y := Gear^.Y + Gear^.dY * 2; |
7055 Gear^.FlightTime := 0; |
6886 Gear^.FlightTime := 0; |
7056 Gear^.doStep := @doStepBulletWork |
6887 Gear^.doStep := @doStepBulletWork |
7057 end; |
6888 end; |
7058 |
6889 |
7059 (* |
|
7060 This didn't end up getting used, but, who knows, might be reasonable for javellin or something |
|
7061 // Make the knife initial angle based on the hog attack angle, or is that too hard? |
|
7062 procedure doStepKnife(Gear: PGear); |
|
7063 var t, |
|
7064 gx, gy, ga, // gear x,y,angle |
|
7065 lx, ly, la, // land x,y,angle |
|
7066 ox, oy, // x,y offset |
|
7067 w, h, // wXh of clip area |
|
7068 tx, ty // tip position in sprite |
|
7069 : LongInt; |
|
7070 surf: PSDL_Surface; |
|
7071 s: hwFloat; |
|
7072 |
|
7073 begin |
|
7074 Gear^.dY := Gear^.dY + cGravity; |
|
7075 if (GameFlags and gfMoreWind) <> 0 then |
|
7076 Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density; |
|
7077 Gear^.X := Gear^.X + Gear^.dX; |
|
7078 Gear^.Y := Gear^.Y + Gear^.dY; |
|
7079 CheckGearDrowning(Gear); |
|
7080 gx:= hwRound(Gear^.X); |
|
7081 gy:= hwRound(Gear^.Y); |
|
7082 if Gear^.State and gstDrowning <> 0 then exit; |
|
7083 with Gear^ do |
|
7084 begin |
|
7085 if CheckLandValue(gx, gy, lfLandMask) then |
|
7086 begin |
|
7087 t:= Angle + hwRound((hwAbs(dX)+hwAbs(dY)) * _10); |
|
7088 |
|
7089 if t < 0 then inc(t, 4096) |
|
7090 else if 4095 < t then dec(t, 4096); |
|
7091 Angle:= t; |
|
7092 |
|
7093 DirAngle:= Angle / 4096 * 360 |
|
7094 end |
|
7095 else |
|
7096 begin |
|
7097 //This is the set of postions for the knife. |
|
7098 //Using FlipSurface and copyToXY the knife can be written to the LandPixels at 32 positions, and an appropriate line drawn in Land. |
|
7099 t:= Angle mod 1024; |
|
7100 case t div 128 of |
|
7101 0: begin |
|
7102 ox:= 2; oy:= 5; |
|
7103 w := 25; h:= 5; |
|
7104 tx:= 0; ty:= 2 |
|
7105 end; |
|
7106 1: begin |
|
7107 ox:= 2; oy:= 15; |
|
7108 w:= 24; h:= 8; |
|
7109 tx:= 0; ty:= 7 |
|
7110 end; |
|
7111 2: begin |
|
7112 ox:= 2; oy:= 27; |
|
7113 w:= 23; h:= 12; |
|
7114 tx:= -12; ty:= -5 |
|
7115 end; |
|
7116 3: begin |
|
7117 ox:= 2; oy:= 43; |
|
7118 w:= 21; h:= 15; |
|
7119 tx:= 0; ty:= 14 |
|
7120 end; |
|
7121 4: begin |
|
7122 ox:= 29; oy:= 8; |
|
7123 w:= 19; h:= 19; |
|
7124 tx:= 0; ty:= 17 |
|
7125 end; |
|
7126 5: begin |
|
7127 ox:= 29; oy:= 32; |
|
7128 w:= 15; h:= 21; |
|
7129 tx:= 0; ty:= 20 |
|
7130 end; |
|
7131 6: begin |
|
7132 ox:= 51; oy:= 3; |
|
7133 w:= 11; h:= 23; |
|
7134 tx:= 0; ty:= 22 |
|
7135 end; |
|
7136 7: begin |
|
7137 ox:= 51; oy:= 34; |
|
7138 w:= 7; h:= 24; |
|
7139 tx:= 0; ty:= 23 |
|
7140 end |
|
7141 end; |
|
7142 |
|
7143 surf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask); |
|
7144 copyToXYFromRect(SpritesData[sprKnife].Surface, surf, ox, oy, w, h, 0, 0); |
|
7145 // try to make the knife hit point first |
|
7146 lx := 0; |
|
7147 ly := 0; |
|
7148 if CalcSlopeTangent(Gear, gx, gy, lx, ly, 255) then |
|
7149 begin |
|
7150 la:= vector2Angle(int2hwFloat(lx), int2hwFloat(ly)); |
|
7151 ga:= vector2Angle(dX, dY); |
|
7152 AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle)); |
|
7153 // change to 0 to 4096 forced by LongWord in Gear |
|
7154 if la < 0 then la:= 4096+la; |
|
7155 if ga < 0 then ga:= 4096+ga; |
|
7156 if ((Angle > ga) and (Angle < la)) or ((Angle < ga) and (Angle > la)) then |
|
7157 begin |
|
7158 if Angle >= 2048 then dec(Angle, 2048) |
|
7159 else if Angle < 2048 then inc(Angle, 2048) |
|
7160 end; |
|
7161 AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle)) |
|
7162 end; |
|
7163 case Angle div 1024 of |
|
7164 0: begin |
|
7165 flipSurface(surf, true); |
|
7166 flipSurface(surf, true); |
|
7167 BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-(h-ty), w, surf) |
|
7168 end; |
|
7169 1: begin |
|
7170 flipSurface(surf, false); |
|
7171 BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-ty, w, surf) |
|
7172 end; |
|
7173 2: begin // knife was actually drawn facing this way... |
|
7174 BlitImageAndGenerateCollisionInfo(gx-tx, gy-ty, w, surf) |
|
7175 end; |
|
7176 3: begin |
|
7177 flipSurface(surf, true); |
|
7178 BlitImageAndGenerateCollisionInfo(gx-tx, gy-(h-ty), w, surf) |
|
7179 end |
|
7180 end; |
|
7181 SDL_FreeSurface(surf); |
|
7182 // this needs to calculate actual width/height + land clipping since update texture doesn't. |
|
7183 // i.e. this will crash if you fire near sides of map, but until I get the blit right, not going to put real values |
|
7184 UpdateLandTexture(hwRound(X)-32, 64, hwRound(Y)-32, 64, true); |
|
7185 DeleteGear(Gear); |
|
7186 exit |
|
7187 end |
|
7188 end; |
|
7189 end; |
|
7190 *) |
|
7191 |
|
7192 end. |
6890 end. |