114 if FollowGear = HH^.Gear then |
114 if FollowGear = HH^.Gear then |
115 FollowGear:= nil; |
115 FollowGear:= nil; |
116 |
116 |
117 if lastGearByUID = HH^.Gear then |
117 if lastGearByUID = HH^.Gear then |
118 lastGearByUID := nil; |
118 lastGearByUID := nil; |
119 |
119 |
120 RemoveGearFromList(HH^.Gear); |
120 HH^.Gear^.Message:= HH^.Gear^.Message or gmRemoveFromList; |
121 with HH^.Gear^ do |
121 with HH^.Gear^ do |
122 begin |
122 begin |
123 Z := cHHZ; |
123 Z := cHHZ; |
124 Active := false; |
124 HH^.Gear^.Active:= false; |
125 State:= State and (not (gstHHDriven or gstAttacking or gstAttacked)); |
125 State:= State and (not (gstHHDriven or gstAttacking or gstAttacked)); |
126 Message := Message and (not gmAttack); |
126 Message := Message and (not gmAttack); |
127 end; |
127 end; |
128 HH^.GearHidden:= HH^.Gear; |
128 HH^.GearHidden:= HH^.Gear; |
129 HH^.Gear:= nil |
129 HH^.Gear:= nil |
731 end; |
731 end; |
732 |
732 |
733 //////////////////////////////////////////////////////////////////////////////// |
733 //////////////////////////////////////////////////////////////////////////////// |
734 procedure doStepGrave(Gear: PGear); |
734 procedure doStepGrave(Gear: PGear); |
735 begin |
735 begin |
|
736 if (Gear^.Message and gmDestroy) <> 0 then |
|
737 begin |
|
738 DeleteGear(Gear); |
|
739 exit |
|
740 end; |
|
741 |
736 AllInactive := false; |
742 AllInactive := false; |
|
743 |
737 if Gear^.dY.isNegative then |
744 if Gear^.dY.isNegative then |
738 if TestCollisionY(Gear, -1) then |
745 if TestCollisionY(Gear, -1) then |
739 Gear^.dY := _0; |
746 Gear^.dY := _0; |
740 |
747 |
741 if not Gear^.dY.isNegative then |
748 if not Gear^.dY.isNegative then |
2112 if Gear^.Health <= 0 then |
2120 if Gear^.Health <= 0 then |
2113 exBoom := true; |
2121 exBoom := true; |
2114 end |
2122 end |
2115 else |
2123 else |
2116 begin |
2124 begin |
|
2125 if (Gear^.Pos <> posCaseHealth) and (GameTicks and $3FF = 0) then // stir it up every second or so |
|
2126 begin |
|
2127 gi := GearsList; |
|
2128 while gi <> nil do |
|
2129 begin |
|
2130 if gi^.Kind = gtGenericFaller then |
|
2131 begin |
|
2132 gi^.Active:= true; |
|
2133 gi^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX); |
|
2134 gi^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY); |
|
2135 gi^.dX:= _90-(GetRandomf*_360); |
|
2136 gi^.dY:= _90-(GetRandomf*_360) |
|
2137 end; |
|
2138 gi := gi^.NextGear |
|
2139 end |
|
2140 end; |
|
2141 |
2117 if Gear^.Timer = 500 then |
2142 if Gear^.Timer = 500 then |
2118 begin |
2143 begin |
2119 (* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up |
2144 (* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up |
2120 voices. Reinforcements voices is heard for active team, not team-to-be. Either that or change crate spawn from end of turn to start, although that |
2145 voices. Reinforcements voices is heard for active team, not team-to-be. Either that or change crate spawn from end of turn to start, although that |
2121 has its own complexities. *) |
2146 has its own complexities. *) |
2379 else if ((GameTicks and $3) = 3) then |
2404 else if ((GameTicks and $3) = 3) then |
2380 doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage); |
2405 doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage); |
2381 //DrawExplosion(gX, gY, 4); |
2406 //DrawExplosion(gX, gY, 4); |
2382 |
2407 |
2383 if ((GameTicks and $7) = 0) and (Random(2) = 0) then |
2408 if ((GameTicks and $7) = 0) and (Random(2) = 0) then |
2384 for i:= 1 to Random(2)+1 do |
2409 for i:= Random(2) downto 0 do |
2385 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2410 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2386 |
2411 |
2387 if Gear^.Health > 0 then |
2412 if Gear^.Health > 0 then |
2388 dec(Gear^.Health); |
2413 dec(Gear^.Health); |
2389 Gear^.Timer := 450 - Gear^.Tag * 8 |
2414 Gear^.Timer := 450 - Gear^.Tag * 8 |
2393 // Modified fire |
2418 // Modified fire |
2394 if ((GameTicks and $7FF) = 0) and ((GameFlags and gfSolidLand) = 0) then |
2419 if ((GameTicks and $7FF) = 0) and ((GameFlags and gfSolidLand) = 0) then |
2395 begin |
2420 begin |
2396 DrawExplosion(gX, gY, 4); |
2421 DrawExplosion(gX, gY, 4); |
2397 |
2422 |
2398 for i:= 0 to Random(3) do |
2423 for i:= Random(3) downto 0 do |
2399 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2424 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2400 end; |
2425 end; |
2401 |
2426 |
2402 // This one is interesting. I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom. |
2427 // This one is interesting. I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom. |
2403 Gear^.Timer := 100 - Gear^.Tag * 3; |
2428 Gear^.Timer := 100 - Gear^.Tag * 3; |
2411 gX := hwRound(Gear^.X); |
2436 gX := hwRound(Gear^.X); |
2412 gY := hwRound(Gear^.Y); |
2437 gY := hwRound(Gear^.Y); |
2413 if not sticky then |
2438 if not sticky then |
2414 begin |
2439 begin |
2415 if ((GameTicks and $3) = 0) and (Random(1) = 0) then |
2440 if ((GameTicks and $3) = 0) and (Random(1) = 0) then |
2416 begin |
2441 for i:= Random(2) downto 0 do |
2417 for i:= 1 to Random(2)+1 do |
|
2418 begin |
|
2419 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2442 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2420 end; |
|
2421 end; |
|
2422 end |
2443 end |
2423 else |
2444 else |
2424 begin |
2445 for i:= Random(3) downto 0 do |
2425 for i:= 0 to Random(3) do |
|
2426 begin |
|
2427 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2446 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2428 end; |
|
2429 end; |
|
2430 |
2447 |
2431 DeleteGear(Gear) |
2448 DeleteGear(Gear) |
2432 end; |
2449 end; |
2433 end; |
2450 end; |
2434 |
2451 |
2773 HHGear := CurrentHedgehog^.Gear; |
2790 HHGear := CurrentHedgehog^.Gear; |
2774 HHGear^.Message := HHGear^.Message and (not gmSwitch); |
2791 HHGear^.Message := HHGear^.Message and (not gmSwitch); |
2775 Gear^.Message := Gear^.Message and (not gmSwitch); |
2792 Gear^.Message := Gear^.Message and (not gmSwitch); |
2776 State := HHGear^.State; |
2793 State := HHGear^.State; |
2777 HHGear^.State := 0; |
2794 HHGear^.State := 0; |
|
2795 HHGear^.Z := cHHZ; |
2778 HHGear^.Active := false; |
2796 HHGear^.Active := false; |
2779 HHGear^.Z := cHHZ; |
2797 HHGear^.Message:= HHGear^.Message or gmRemoveFromList or gmAddToList; |
2780 RemoveGearFromList(HHGear); |
|
2781 InsertGearToList(HHGear); |
|
2782 |
2798 |
2783 PlaySound(sndSwitchHog); |
2799 PlaySound(sndSwitchHog); |
2784 |
2800 |
2785 repeat |
2801 repeat |
2786 CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber); |
2802 CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber); |
2792 HHGear := CurrentHedgehog^.Gear; |
2808 HHGear := CurrentHedgehog^.Gear; |
2793 HHGear^.State := State; |
2809 HHGear^.State := State; |
2794 HHGear^.Active := true; |
2810 HHGear^.Active := true; |
2795 FollowGear := HHGear; |
2811 FollowGear := HHGear; |
2796 HHGear^.Z := cCurrHHZ; |
2812 HHGear^.Z := cCurrHHZ; |
2797 RemoveGearFromList(HHGear); |
2813 HHGear^.Message:= HHGear^.Message or gmRemoveFromList or gmAddToList; |
2798 InsertGearToList(HHGear); |
|
2799 Gear^.X := HHGear^.X; |
2814 Gear^.X := HHGear^.X; |
2800 Gear^.Y := HHGear^.Y |
2815 Gear^.Y := HHGear^.Y |
2801 end; |
2816 end; |
2802 end; |
2817 end; |
2803 |
2818 |
3066 |
3080 |
3067 inc(Gear^.Tag); |
3081 inc(Gear^.Tag); |
3068 if Gear^.Tag < 7 then |
3082 if Gear^.Tag < 7 then |
3069 exit; |
3083 exit; |
3070 |
3084 |
|
3085 dec(Gear^.Health); |
|
3086 Gear^.Timer := Gear^.Health*10; |
|
3087 if Gear^.Health mod 100 = 0 then |
|
3088 Gear^.PortalCounter:= 0; |
|
3089 // This is not seconds, but at least it is *some* feedback |
|
3090 if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then |
|
3091 begin |
|
3092 FollowGear := Gear; |
|
3093 Gear^.RenderTimer := false; |
|
3094 Gear^.doStep := @doStepCakeDown; |
|
3095 exit |
|
3096 end; |
|
3097 |
3071 cakeStep(Gear); |
3098 cakeStep(Gear); |
3072 |
3099 |
3073 if Gear^.Tag = 0 then |
3100 if Gear^.Tag = 0 then |
3074 begin |
3101 begin |
3075 CakeI := (CakeI + 1) mod cakeh; |
3102 CakeI := (CakeI + 1) mod cakeh; |
3077 tdy := - CakePoints[CakeI].y + Gear^.Y; |
3104 tdy := - CakePoints[CakeI].y + Gear^.Y; |
3078 CakePoints[CakeI].x := Gear^.X; |
3105 CakePoints[CakeI].x := Gear^.X; |
3079 CakePoints[CakeI].y := Gear^.Y; |
3106 CakePoints[CakeI].y := Gear^.Y; |
3080 Gear^.DirAngle := DxDy2Angle(tdx, tdy); |
3107 Gear^.DirAngle := DxDy2Angle(tdx, tdy); |
3081 end; |
3108 end; |
3082 |
|
3083 dec(Gear^.Health); |
|
3084 Gear^.Timer := Gear^.Health*10; |
|
3085 if Gear^.Health mod 100 = 0 then |
|
3086 Gear^.PortalCounter:= 0; |
|
3087 // This is not seconds, but at least it is *some* feedback |
|
3088 if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then |
|
3089 begin |
|
3090 FollowGear := Gear; |
|
3091 Gear^.RenderTimer := false; |
|
3092 Gear^.doStep := @doStepCakeDown |
|
3093 end |
|
3094 end; |
3109 end; |
3095 |
3110 |
3096 procedure doStepCakeUp(Gear: PGear); |
3111 procedure doStepCakeUp(Gear: PGear); |
3097 var |
3112 var |
3098 i: Longword; |
3113 i: Longword; |
4294 and (iterator = CurrentHedgehog^.Gear) |
4309 and (iterator = CurrentHedgehog^.Gear) |
4295 and (CurAmmoGear <> nil) |
4310 and (CurAmmoGear <> nil) |
4296 and (CurAmmoGear^.Kind =gtRope) then |
4311 and (CurAmmoGear^.Kind =gtRope) then |
4297 CurAmmoGear^.PortalCounter:= 1; |
4312 CurAmmoGear^.PortalCounter:= 1; |
4298 |
4313 |
4299 if not isbullet |
4314 if not isbullet and (iterator^.State and gstInvisible = 0) |
4300 and (iterator^.Kind <> gtFlake) then |
4315 and (iterator^.Kind <> gtFlake) then |
4301 FollowGear := iterator; |
4316 FollowGear := iterator; |
4302 |
4317 |
4303 // store X/Y values of exit for net bullet trail |
4318 // store X/Y values of exit for net bullet trail |
4304 if isbullet then |
4319 if isbullet then |
4373 begin |
4388 begin |
4374 Gear^.State := Gear^.State or gstCollision; |
4389 Gear^.State := Gear^.State or gstCollision; |
4375 Gear^.State := Gear^.State and (not gstMoving); |
4390 Gear^.State := Gear^.State and (not gstMoving); |
4376 |
4391 |
4377 if (Land[y, x] and lfBouncy <> 0) |
4392 if (Land[y, x] and lfBouncy <> 0) |
4378 or not CalcSlopeTangent(Gear, x, y, tx, ty, 255) |
4393 or (not CalcSlopeTangent(Gear, x, y, tx, ty, 255)) |
4379 or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain |
4394 or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain |
4380 begin |
4395 begin |
4381 loadNewPortalBall(Gear, true); |
4396 loadNewPortalBall(Gear, true); |
4382 EXIT; |
4397 EXIT; |
4383 end; |
4398 end; |
4653 dec(Gear^.Health, Gear^.Damage); |
4668 dec(Gear^.Health, Gear^.Damage); |
4654 Gear^.Damage := 0; |
4669 Gear^.Damage := 0; |
4655 |
4670 |
4656 // add some fire to the tunnel |
4671 // add some fire to the tunnel |
4657 if getRandom(6) = 0 then |
4672 if getRandom(6) = 0 then |
4658 AddGear(x - Gear^.Radius + LongInt(getRandom(2 * Gear^.Radius)), y - |
4673 begin |
4659 getRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0); |
4674 tmp:= GetRandom(2 * Gear^.Radius); |
|
4675 AddGear(x - Gear^.Radius + tmp, y - GetRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0) |
|
4676 end |
4660 end; |
4677 end; |
4661 |
4678 |
4662 if getRandom(100) = 0 then |
4679 if random(100) = 0 then |
4663 AddVisualGear(x, y, vgtSmokeTrace); |
4680 AddVisualGear(x, y, vgtSmokeTrace); |
4664 end |
4681 end |
4665 else dec(Gear^.Health, 5); // if underwater get additional damage |
4682 else dec(Gear^.Health, 5); // if underwater get additional damage |
4666 end; |
4683 end; |
4667 |
4684 |
5067 if graves.size <= Gear^.Tag then Gear^.Tag:= 0; |
5084 if graves.size <= Gear^.Tag then Gear^.Tag:= 0; |
5068 dec(hh^.Gear^.Health); |
5085 dec(hh^.Gear^.Health); |
5069 if (hh^.Gear^.Health = 0) and (hh^.Gear^.Damage = 0) then |
5086 if (hh^.Gear^.Health = 0) and (hh^.Gear^.Damage = 0) then |
5070 hh^.Gear^.Damage:= 1; |
5087 hh^.Gear^.Damage:= 1; |
5071 RenderHealth(hh^); |
5088 RenderHealth(hh^); |
|
5089 RecountTeamHealth(hh^.Team); |
5072 inc(graves.ar^[Gear^.Tag]^.Health); |
5090 inc(graves.ar^[Gear^.Tag]^.Health); |
5073 inc(Gear^.Tag) |
5091 inc(Gear^.Tag) |
5074 {-for i:= 0 to High(graves) do begin |
5092 {-for i:= 0 to High(graves) do begin |
5075 if hh^.Gear^.Health > 0 then begin |
5093 if hh^.Gear^.Health > 0 then begin |
5076 dec(hh^.Gear^.Health); |
5094 dec(hh^.Gear^.Health); |
5086 begin |
5104 begin |
5087 resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0); |
5105 resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0); |
5088 resgear^.Hedgehog := graves.ar^[i]^.Hedgehog; |
5106 resgear^.Hedgehog := graves.ar^[i]^.Hedgehog; |
5089 resgear^.Health := graves.ar^[i]^.Health; |
5107 resgear^.Health := graves.ar^[i]^.Health; |
5090 PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := resgear; |
5108 PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := resgear; |
5091 DeleteGear(graves.ar^[i]); |
5109 graves.ar^[i]^.Message:= graves.ar^[i]^.Message or gmDestroy; |
|
5110 graves.ar^[i]^.Active:= true; |
5092 RenderHealth(resgear^.Hedgehog^); |
5111 RenderHealth(resgear^.Hedgehog^); |
5093 RecountTeamHealth(resgear^.Hedgehog^.Team); |
5112 RecountTeamHealth(resgear^.Hedgehog^.Team); |
5094 resgear^.Hedgehog^.Effects[heResurrected]:= 1; |
5113 resgear^.Hedgehog^.Effects[heResurrected]:= 1; |
5095 // only make hat-less hedgehogs look like zombies, preserve existing hats |
5114 // only make hat-less hedgehogs look like zombies, preserve existing hats |
5096 |
5115 |
5097 if resgear^.Hedgehog^.Hat = 'NoHat' then |
5116 if resgear^.Hedgehog^.Hat = 'NoHat' then |
5098 LoadHedgehogHat(resgear, 'Reserved/Zombie'); |
5117 LoadHedgehogHat(resgear, 'Reserved/Zombie'); |
5099 end; |
5118 end; |
5100 |
5119 |
5101 hh^.Gear^.dY := _0; |
5120 hh^.Gear^.dY := _0; |
5530 Y:= HHGear^.Y |
5549 Y:= HHGear^.Y |
5531 end |
5550 end |
5532 end |
5551 end |
5533 end; |
5552 end; |
5534 end; |
5553 end; |
|
5554 |
|
5555 procedure doStepAddAmmo(Gear: PGear); |
|
5556 var a: TAmmoType; |
|
5557 gi: PGear; |
|
5558 begin |
|
5559 if Gear^.Timer > 0 then dec(Gear^.Timer) |
|
5560 else |
|
5561 begin |
|
5562 if Gear^.Pos = posCaseUtility then |
|
5563 a:= GetUtility(Gear^.Hedgehog) |
|
5564 else |
|
5565 a:= GetAmmo(Gear^.Hedgehog); |
|
5566 CheckSum:= CheckSum xor GameTicks; |
|
5567 gi := GearsList; |
|
5568 while gi <> nil do |
|
5569 begin |
|
5570 with gi^ do CheckSum:= CheckSum xor X.round xor X.frac xor dX.round xor dX.frac xor Y.round xor Y.frac xor dY.round xor dY.frac; |
|
5571 AddRandomness(CheckSum); |
|
5572 gi := gi^.NextGear |
|
5573 end; |
|
5574 AddPickup(Gear^.Hedgehog^, a, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y)); |
|
5575 DeleteGear(Gear) |
|
5576 end; |
|
5577 end; |
|
5578 |
|
5579 procedure doStepGenericFaller(Gear: PGear); |
|
5580 begin |
|
5581 if Gear^.Timer < $FFFFFFFF then |
|
5582 if Gear^.Timer > 0 then |
|
5583 dec(Gear^.Timer) |
|
5584 else |
|
5585 begin |
|
5586 DeleteGear(Gear); |
|
5587 exit |
|
5588 end; |
|
5589 |
|
5590 doStepFallingGear(Gear); |
|
5591 end; |