58 |
58 |
59 |
59 |
60 function MakeHedgehogsStep(Gear: PGear) : boolean; |
60 function MakeHedgehogsStep(Gear: PGear) : boolean; |
61 |
61 |
62 var doStepHandlers: array[TGearType] of TGearStepProcedure; |
62 var doStepHandlers: array[TGearType] of TGearStepProcedure; |
63 |
|
64 |
63 |
65 implementation |
64 implementation |
66 uses uSound, uCollisions, uUtils, uConsts, uVisualGears, uAIMisc, |
65 uses uSound, uCollisions, uUtils, uConsts, uVisualGears, uAIMisc, |
67 uVariables, uLandGraphics, uScript, uStats, uCaptions, uTeams, uStore, |
66 uVariables, uLandGraphics, uScript, uStats, uCaptions, uTeams, uStore, |
68 uLocale, uTextures, uRenderUtils, uRandom, SDLh, uDebug, |
67 uLocale, uTextures, uRenderUtils, uRandom, SDLh, uDebug, |
134 begin |
133 begin |
135 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
134 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
136 //AddFileLog('Damage: ' + inttostr(dmg)); |
135 //AddFileLog('Damage: ' + inttostr(dmg)); |
137 if (Mask and EXPLNoDamage) = 0 then |
136 if (Mask and EXPLNoDamage) = 0 then |
138 begin |
137 begin |
139 if not Gear^.Invulnerable then |
138 if Gear^.Hedgehog^.Effects[heInvulnerable] = 0 then |
140 ApplyDamage(Gear, AttackingHog, dmg, dsExplosion) |
139 ApplyDamage(Gear, AttackingHog, dmg, dsExplosion) |
141 else |
140 else |
142 Gear^.State:= Gear^.State or gstWinner; |
141 Gear^.State:= Gear^.State or gstWinner; |
143 end; |
142 end; |
144 if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then |
143 if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then |
147 Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, tdX)/(Gear^.Density/_3); |
146 Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, tdX)/(Gear^.Density/_3); |
148 Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, tdY)/(Gear^.Density/_3); |
147 Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, tdY)/(Gear^.Density/_3); |
149 |
148 |
150 Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser); |
149 Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser); |
151 if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision); |
150 if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision); |
152 if not Gear^.Invulnerable then |
151 if Gear^.Hedgehog^.Effects[heInvulnerable] = 0 then |
153 Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner); |
152 Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner); |
154 Gear^.Active:= true; |
153 Gear^.Active:= true; |
155 if Gear^.Kind <> gtFlame then FollowGear:= Gear |
154 if Gear^.Kind <> gtFlame then FollowGear:= Gear |
156 end; |
155 end; |
157 if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) and ((Gear^.State and gstHHDeath) = 0) then |
156 if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heInvulnerable] = 0) and (Gear^.State and gstHHDeath = 0) then |
158 Gear^.Hedgehog^.Effects[hePoisoned] := 1; |
157 Gear^.Hedgehog^.Effects[hePoisoned] := 1; |
159 end; |
158 end; |
160 |
159 |
161 end; |
160 end; |
162 gtGrave: begin |
161 gtGrave: if Mask and EXPLDoNotTouchAny = 0 then |
163 // Run the calcs only once we know we have a type that will need damage |
162 // Run the calcs only once we know we have a type that will need damage |
164 tdX:= Gear^.X-fX; |
|
165 tdY:= Gear^.Y-fY; |
|
166 if LongInt(tdX.Round + tdY.Round + 2) < dmgBase then |
|
167 dmg:= dmgBase - hwRound(Distance(tdX, tdY)); |
|
168 if dmg > 1 then |
|
169 begin |
163 begin |
170 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
164 tdX:= Gear^.X-fX; |
171 Gear^.dY:= - _0_004 * dmg; |
165 tdY:= Gear^.Y-fY; |
172 Gear^.Active:= true |
166 if LongInt(tdX.Round + tdY.Round + 2) < dmgBase then |
173 end |
167 dmg:= dmgBase - hwRound(Distance(tdX, tdY)); |
174 end; |
168 if dmg > 1 then |
|
169 begin |
|
170 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
|
171 Gear^.dY:= - _0_004 * dmg; |
|
172 Gear^.Active:= true |
|
173 end |
|
174 end; |
175 end; |
175 end; |
176 end; |
176 end; |
177 Gear:= Gear^.NextGear |
177 Gear:= Gear^.NextGear |
178 end; |
178 end; |
179 |
179 |
314 PlaySound(sndBump) |
313 PlaySound(sndBump) |
315 else PlaySound(sndFrozenHogImpact); |
314 else PlaySound(sndFrozenHogImpact); |
316 if dmg < 1 then |
315 if dmg < 1 then |
317 exit; |
316 exit; |
318 |
317 |
319 for i:= min(12, (3 + dmg div 10)) downto 0 do |
318 for i:= min(12, 3 + dmg div 10) downto 0 do |
320 begin |
319 begin |
321 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
320 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
322 if particle <> nil then |
321 if particle <> nil then |
323 particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480); |
322 particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480); |
324 end; |
323 end; |
325 |
324 |
326 if (Gear^.Invulnerable) then |
325 if ((Gear^.Hedgehog^.Effects[heInvulnerable] <> 0)) then |
327 exit; |
326 exit; |
328 |
327 |
329 //if _0_6 < Gear^.dY then |
328 //if _0_6 < Gear^.dY then |
330 // PlaySound(sndOw4, Gear^.Hedgehog^.Team^.voicepack) |
329 // PlaySound(sndOw4, Gear^.Hedgehog^.Team^.voicepack) |
331 //else |
330 //else |
596 ignoreNearObjects:= false; // try not skipping proximity at first |
595 ignoreNearObjects:= false; // try not skipping proximity at first |
597 ignoreOverlap:= false; // this not only skips proximity, but allows overlapping objects (barrels, mines, hogs, crates). Saving it for a 3rd pass. With this active, winning AI Survival goes back to virtual impossibility |
596 ignoreOverlap:= false; // this not only skips proximity, but allows overlapping objects (barrels, mines, hogs, crates). Saving it for a 3rd pass. With this active, winning AI Survival goes back to virtual impossibility |
598 tryAgain:= true; |
597 tryAgain:= true; |
599 if WorldEdge <> weNone then |
598 if WorldEdge <> weNone then |
600 begin |
599 begin |
601 Left:= max(Left,leftX+Gear^.Radius); |
600 Left:= max(Left, LongInt(leftX) + Gear^.Radius); |
602 Right:= min(Right,rightX-Gear^.Radius) |
601 Right:= min(Right,rightX-Gear^.Radius) |
603 end; |
602 end; |
604 while tryAgain do |
603 while tryAgain do |
605 begin |
604 begin |
606 delta:= LAND_WIDTH div 16; |
605 delta:= LAND_WIDTH div 16; |
712 CheckGearNear:= nil |
711 CheckGearNear:= nil |
713 end; |
712 end; |
714 |
713 |
715 procedure CheckCollision(Gear: PGear); inline; |
714 procedure CheckCollision(Gear: PGear); inline; |
716 begin |
715 begin |
717 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) |
716 if (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0) |
718 or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then |
717 or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then |
719 Gear^.State := Gear^.State or gstCollision |
718 Gear^.State := Gear^.State or gstCollision |
720 else |
719 else |
721 Gear^.State := Gear^.State and (not gstCollision) |
720 Gear^.State := Gear^.State and (not gstCollision) |
722 end; |
721 end; |
723 |
722 |
724 procedure CheckCollisionWithLand(Gear: PGear); inline; |
723 procedure CheckCollisionWithLand(Gear: PGear); inline; |
725 begin |
724 begin |
726 if TestCollisionX(Gear, hwSign(Gear^.dX)) |
725 if (TestCollisionX(Gear, hwSign(Gear^.dX)) <> 0) |
727 or TestCollisionY(Gear, hwSign(Gear^.dY)) then |
726 or (TestCollisionY(Gear, hwSign(Gear^.dY)) <> 0) then |
728 Gear^.State := Gear^.State or gstCollision |
727 Gear^.State := Gear^.State or gstCollision |
729 else |
728 else |
730 Gear^.State := Gear^.State and (not gstCollision) |
729 Gear^.State := Gear^.State and (not gstCollision) |
731 end; |
730 end; |
732 |
731 |
733 function MakeHedgehogsStep(Gear: PGear) : boolean; |
732 function MakeHedgehogsStep(Gear: PGear) : boolean; |
734 begin |
733 begin |
735 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
734 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then |
736 begin |
735 begin |
737 Gear^.Y:= Gear^.Y - _1; |
736 Gear^.Y:= Gear^.Y - _1; |
738 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
737 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then |
739 begin |
738 begin |
740 Gear^.Y:= Gear^.Y - _1; |
739 Gear^.Y:= Gear^.Y - _1; |
741 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
740 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then |
742 begin |
741 begin |
743 Gear^.Y:= Gear^.Y - _1; |
742 Gear^.Y:= Gear^.Y - _1; |
744 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
743 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then |
745 begin |
744 begin |
746 Gear^.Y:= Gear^.Y - _1; |
745 Gear^.Y:= Gear^.Y - _1; |
747 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
746 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then |
748 begin |
747 begin |
749 Gear^.Y:= Gear^.Y - _1; |
748 Gear^.Y:= Gear^.Y - _1; |
750 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then |
749 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then if (TestCollisionYwithGear(Gear, -1) = 0) then |
751 begin |
750 begin |
752 Gear^.Y:= Gear^.Y - _1; |
751 Gear^.Y:= Gear^.Y - _1; |
753 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
752 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then |
754 Gear^.Y:= Gear^.Y + _6 |
753 Gear^.Y:= Gear^.Y + _6 |
755 end else Gear^.Y:= Gear^.Y + _5 else |
754 end else Gear^.Y:= Gear^.Y + _5 else |
756 end else Gear^.Y:= Gear^.Y + _4 else |
755 end else Gear^.Y:= Gear^.Y + _4 else |
757 end else Gear^.Y:= Gear^.Y + _3 else |
756 end else Gear^.Y:= Gear^.Y + _3 else |
758 end else Gear^.Y:= Gear^.Y + _2 else |
757 end else Gear^.Y:= Gear^.Y + _2 else |
759 end else Gear^.Y:= Gear^.Y + _1 |
758 end else Gear^.Y:= Gear^.Y + _1 |
760 end; |
759 end; |
761 |
760 |
762 if not TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
761 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) = 0 then |
763 begin |
762 begin |
764 Gear^.X:= Gear^.X + SignAs(_1, Gear^.dX); |
763 Gear^.X:= Gear^.X + SignAs(_1, Gear^.dX); |
765 MakeHedgehogsStep:= true |
764 MakeHedgehogsStep:= true |
766 end else |
765 end else |
767 MakeHedgehogsStep:= false; |
766 MakeHedgehogsStep:= false; |
976 Gear^.Active:= true; |
975 Gear^.Active:= true; |
977 DeleteCI(Gear); |
976 DeleteCI(Gear); |
978 Gear^.State:= Gear^.State or gstMoving; |
977 Gear^.State:= Gear^.State or gstMoving; |
979 if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision); |
978 if Gear^.Kind = gtKnife then Gear^.State:= Gear^.State and (not gstCollision); |
980 // move the gear upwards a bit to throw it over tiny obstacles at start |
979 // move the gear upwards a bit to throw it over tiny obstacles at start |
981 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
980 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then |
982 begin |
981 begin |
983 if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) |
982 if (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) = 0) and |
984 or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
983 (TestCollisionYwithGear(Gear, -1) = 0) then |
985 Gear^.Y:= Gear^.Y - _1; |
984 Gear^.Y:= Gear^.Y - _1; |
986 if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) |
985 if (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) = 0) and |
987 or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
986 (TestCollisionYwithGear(Gear, -1) = 0) then |
988 Gear^.Y:= Gear^.Y - _1; |
987 Gear^.Y:= Gear^.Y - _1; |
989 if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) |
988 if (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) = 0) and |
990 or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
989 (TestCollisionYwithGear(Gear, -1) = 0) then |
991 Gear^.Y:= Gear^.Y - _1; |
990 Gear^.Y:= Gear^.Y - _1; |
992 end |
991 end |
993 end; |
992 end; |
994 |
993 |
995 |
994 |
1228 function WorldWrap(var Gear: PGear): boolean; |
1227 function WorldWrap(var Gear: PGear): boolean; |
1229 var tdx: hwFloat; |
1228 var tdx: hwFloat; |
1230 begin |
1229 begin |
1231 WorldWrap:= false; |
1230 WorldWrap:= false; |
1232 if WorldEdge = weNone then exit(false); |
1231 if WorldEdge = weNone then exit(false); |
1233 if (hwRound(Gear^.X)-Gear^.Radius < leftX) or |
1232 if (hwRound(Gear^.X) - Gear^.Radius < LongInt(leftX)) or |
1234 (hwRound(Gear^.X)+Gear^.Radius > rightX) then |
1233 (hwRound(Gear^.X) + LongInt(Gear^.Radius) > LongInt(rightX)) then |
1235 begin |
1234 begin |
1236 if WorldEdge = weWrap then |
1235 if WorldEdge = weWrap then |
1237 begin |
1236 begin |
1238 if (hwRound(Gear^.X)-Gear^.Radius < leftX) then |
1237 if (hwRound(Gear^.X) - Gear^.Radius < LongInt(leftX)) then |
1239 Gear^.X:= int2hwfloat(rightX-Gear^.Radius) |
1238 Gear^.X:= int2hwfloat(rightX - Gear^.Radius) |
1240 else Gear^.X:= int2hwfloat(leftX+Gear^.Radius) |
1239 else Gear^.X:= int2hwfloat(LongInt(leftX) + Gear^.Radius); |
|
1240 LeftImpactTimer:= 150; |
|
1241 RightImpactTimer:= 150 |
1241 end |
1242 end |
1242 else if WorldEdge = weBounce then |
1243 else if WorldEdge = weBounce then |
1243 begin |
1244 begin |
1244 if (hwRound(Gear^.X)-Gear^.Radius < leftX) then |
1245 if (hwRound(Gear^.X) - Gear^.Radius < LongInt(leftX)) then |
1245 begin |
1246 begin |
|
1247 LeftImpactTimer:= 333; |
1246 Gear^.dX.isNegative:= false; |
1248 Gear^.dX.isNegative:= false; |
1247 Gear^.X:= int2hwfloat(leftX+Gear^.Radius) |
1249 Gear^.X:= int2hwfloat(LongInt(leftX) + Gear^.Radius) |
1248 end |
1250 end |
1249 else |
1251 else |
1250 begin |
1252 begin |
|
1253 RightImpactTimer:= 333; |
1251 Gear^.dX.isNegative:= true; |
1254 Gear^.dX.isNegative:= true; |
1252 Gear^.X:= int2hwfloat(rightX-Gear^.Radius) |
1255 Gear^.X:= int2hwfloat(rightX-Gear^.Radius) |
1253 end |
1256 end; |
|
1257 if (Gear^.Radius > 2) and (Gear^.dX.QWordValue > _0_001.QWordValue) then |
|
1258 PlaySound(sndMelonImpact) |
1254 end |
1259 end |
1255 else if WorldEdge = weSea then |
1260 else if WorldEdge = weSea then |
1256 begin |
1261 begin |
1257 if (hwRound(Gear^.Y) > cWaterLine) and (Gear^.State and gstSubmersible <> 0) then |
1262 if (hwRound(Gear^.Y) > cWaterLine) and (Gear^.State and gstSubmersible <> 0) then |
1258 Gear^.State:= Gear^.State and (not gstSubmersible) |
1263 Gear^.State:= Gear^.State and (not gstSubmersible) |