15 * along with this program; if not, write to the Free Software |
15 * along with this program; if not, write to the Free Software |
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 procedure makeHogsWorry(x, y: hwFloat; r: LongInt); |
19 procedure makeHogsWorry(x, y: hwFloat; r: LongInt); |
20 var gi: PGear; |
20 var |
21 d: LongInt; |
21 gi: PGear; |
22 begin |
22 d: LongInt; |
23 gi:= GearsList; |
23 begin |
|
24 gi := GearsList; |
24 while gi <> nil do |
25 while gi <> nil do |
25 begin |
26 begin |
26 if (gi^.Kind = gtHedgehog) then |
27 if (gi^.Kind = gtHedgehog) then |
|
28 begin |
|
29 d := r - hwRound(Distance(gi^.X - x, gi^.Y - y)); |
|
30 if (d > 1) and not gi^.Invulnerable and (GetRandom(2) = 0) then |
27 begin |
31 begin |
28 d:= r - hwRound(Distance(gi^.X - x, gi^.Y - y)); |
|
29 if (d > 1) and not gi^.Invulnerable and (GetRandom(2) = 0) then |
|
30 begin |
|
31 if (CurrentHedgehog^.Gear = gi) then |
32 if (CurrentHedgehog^.Gear = gi) then |
32 PlaySound(sndOops, PHedgehog(gi^.Hedgehog)^.Team^.voicepack) |
33 PlaySound(sndOops, PHedgehog(gi^.Hedgehog)^.Team^.voicepack) |
33 else |
34 else |
34 begin |
35 begin |
35 if (gi^.State and gstMoving) = 0 then |
36 if (gi^.State and gstMoving) = 0 then |
36 gi^.State:= gi^.State or gstLoser; |
37 gi^.State := gi^.State or gstLoser; |
37 if d > r div 2 then |
38 if d > r div 2 then |
38 PlaySound(sndNooo, PHedgehog(gi^.Hedgehog)^.Team^.voicepack) |
39 PlaySound(sndNooo, PHedgehog(gi^.Hedgehog)^.Team^.voicepack) |
39 else |
40 else |
40 PlaySound(sndUhOh, PHedgehog(gi^.Hedgehog)^.Team^.voicepack); |
41 PlaySound(sndUhOh, PHedgehog(gi^.Hedgehog)^.Team^.voicepack); |
41 end; |
|
42 end; |
42 end; |
43 end; |
43 end; |
44 gi:= gi^.NextGear |
44 end; |
45 end; |
45 gi := gi^.NextGear |
46 end; |
46 end; |
47 //////////////////////////////////////////////////////////////////////////////// |
47 end; |
48 procedure doStepDrowningGear(Gear: PGear); forward; |
48 //////////////////////////////////////////////////////////////////////////////// |
|
49 procedure doStepDrowningGear(Gear: PGear); |
|
50 forward; |
49 |
51 |
50 function CheckGearDrowning(Gear: PGear): boolean; |
52 function CheckGearDrowning(Gear: PGear): boolean; |
51 var skipSpeed, skipAngle, skipDecay: hwFloat; |
53 var |
|
54 skipSpeed, skipAngle, skipDecay: hwFloat; |
52 i, maxDrops: LongInt; |
55 i, maxDrops: LongInt; |
53 particle: PVisualGear; |
56 particle: PVisualGear; |
54 begin |
57 begin |
55 // probably needs tweaking. might need to be in a case statement based upon gear type |
58 // probably needs tweaking. might need to be in a case statement based upon gear type |
56 if cWaterLine < hwRound(Gear^.Y) + Gear^.Radius then |
59 if cWaterLine < hwRound(Gear^.Y) + Gear^.Radius then |
57 begin |
60 begin |
58 skipSpeed:= _0_25; |
61 skipSpeed := _0_25; |
59 skipAngle:= _1_9; |
62 skipAngle := _1_9; |
60 skipDecay:= _0_87; // this could perhaps be a tiny bit higher. |
63 skipDecay := _0_87; |
61 if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed) and |
64 // this could perhaps be a tiny bit higher. |
62 (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then |
65 if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed) and |
63 begin |
66 (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then |
64 Gear^.dY.isNegative:= true; |
67 begin |
65 Gear^.dY:= Gear^.dY * skipDecay; |
68 Gear^.dY.isNegative := true; |
66 Gear^.dX:= Gear^.dX * skipDecay; |
69 Gear^.dY := Gear^.dY * skipDecay; |
67 CheckGearDrowning:= false; |
70 Gear^.dX := Gear^.dX * skipDecay; |
68 PlaySound(sndSkip) |
71 CheckGearDrowning := false; |
69 end |
72 PlaySound(sndSkip) |
70 else |
73 end |
71 begin |
74 else |
72 CheckGearDrowning:= true; |
75 begin |
73 Gear^.State:= gstDrowning; |
76 CheckGearDrowning := true; |
74 Gear^.RenderTimer:= false; |
77 Gear^.State := gstDrowning; |
75 if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then |
78 Gear^.RenderTimer := false; |
76 Gear^.doStep:= @doStepDrowningGear; |
79 if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then |
77 if Gear^.Kind = gtHedgehog then |
80 Gear^.doStep := @doStepDrowningGear; |
|
81 if Gear^.Kind = gtHedgehog then |
78 begin |
82 begin |
79 Gear^.State:= Gear^.State and (not gstHHDriven); |
83 Gear^.State := Gear^.State and (not gstHHDriven); |
80 AddCaption(Format(GetEventString(eidDrowned), PHedgehog(Gear^.Hedgehog)^.Name), cWhiteColor, capgrpMessage); |
84 AddCaption(Format(GetEventString(eidDrowned), PHedgehog(Gear^.Hedgehog)^.Name), |
|
85 cWhiteColor, capgrpMessage); |
81 end; |
86 end; |
82 if hwRound(Gear^.Y) < cWaterLine + 64 + Gear^.Radius then // don't play splash if they are already way past the surface |
87 if hwRound(Gear^.Y) < cWaterLine + 64 + Gear^.Radius then |
83 PlaySound(sndSplash) |
88 // don't play splash if they are already way past the surface |
84 end; |
89 PlaySound(sndSplash) |
85 |
90 end; |
86 if not cReducedQuality and (hwRound(Gear^.Y) < cWaterLine + 64 + Gear^.Radius) then |
91 |
87 begin |
92 if not cReducedQuality and (hwRound(Gear^.Y) < cWaterLine + 64 + Gear^.Radius) then |
88 AddVisualGear(hwRound(Gear^.X), cWaterLine, vgtSplash); |
93 begin |
89 |
94 AddVisualGear(hwRound(Gear^.X), cWaterLine, vgtSplash); |
90 maxDrops := (Gear^.Radius div 2) + hwRound(Gear^.dX * Gear^.Radius * 2) + hwRound(Gear^.dY * Gear^.Radius * 2); |
95 |
91 for i:= max(maxDrops div 3, min(32, Random(maxDrops))) downto 0 do |
96 maxDrops := (Gear^.Radius div 2) + hwRound(Gear^.dX * Gear^.Radius * 2) + hwRound(Gear^. |
|
97 dY * Gear^.Radius * 2); |
|
98 for i:= max(maxDrops div 3, min(32, Random(maxDrops))) downto 0 do |
92 begin |
99 begin |
93 particle := AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), cWaterLine, vgtDroplet); |
100 particle := AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), cWaterLine, vgtDroplet); |
94 if particle <> nil then |
101 if particle <> nil then |
95 begin |
102 begin |
96 particle^.dX := particle^.dX - (Gear^.dX / 10); |
103 particle^.dX := particle^.dX - (Gear^.dX / 10); |
97 particle^.dY := particle^.dY - (Gear^.dY / 5) |
104 particle^.dY := particle^.dY - (Gear^.dY / 5) |
98 end |
105 end |
99 end |
106 end |
100 end; |
107 end; |
101 end |
108 end |
102 else |
109 else |
103 CheckGearDrowning:= false |
110 CheckGearDrowning := false |
104 end; |
111 end; |
105 |
112 |
106 procedure CheckCollision(Gear: PGear); |
113 procedure CheckCollision(Gear: PGear); |
107 begin |
114 begin |
108 if TestCollisionXwithGear(Gear, hwSign(Gear^.X)) or TestCollisionYwithGear(Gear, hwSign(Gear^.Y)) |
115 if TestCollisionXwithGear(Gear, hwSign(Gear^.X)) or TestCollisionYwithGear(Gear, hwSign(Gear^.Y) |
109 then Gear^.State:= Gear^.State or gstCollision |
116 ) |
110 else Gear^.State:= Gear^.State and not gstCollision |
117 then Gear^.State := Gear^.State or gstCollision |
|
118 else Gear^.State := Gear^.State and not gstCollision |
111 end; |
119 end; |
112 |
120 |
113 procedure CheckHHDamage(Gear: PGear); |
121 procedure CheckHHDamage(Gear: PGear); |
114 var |
122 var |
115 dmg: Longword; |
123 dmg: Longword; |
116 i: LongInt; |
124 i: LongInt; |
117 particle: PVisualGear; |
125 particle: PVisualGear; |
118 begin |
126 begin |
119 if _0_4 < Gear^.dY then |
127 if _0_4 < Gear^.dY then |
120 begin |
128 begin |
121 dmg:= ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear); |
129 dmg := ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear); |
122 if dmg < 1 then exit; |
130 if dmg < 1 then exit; |
123 |
131 |
124 for i:= min(12, (3 + dmg div 10)) downto 0 do begin |
132 for i:= min(12, (3 + dmg div 10)) downto 0 do |
125 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
133 begin |
126 if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX / 5); |
134 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, |
127 end; |
135 vgtDust); |
128 |
136 if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX / 5); |
129 if(Gear^.Invulnerable) then exit; |
137 end; |
130 |
138 |
131 if _0_6 < Gear^.dY then |
139 if (Gear^.Invulnerable) then exit; |
132 PlaySound(sndOw4, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack) |
140 |
|
141 if _0_6 < Gear^.dY then |
|
142 PlaySound(sndOw4, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack) |
|
143 else |
|
144 PlaySound(sndOw1, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack); |
|
145 |
|
146 ApplyDamage(Gear, dmg); |
|
147 end |
|
148 end; |
|
149 |
|
150 //////////////////////////////////////////////////////////////////////////////// |
|
151 //////////////////////////////////////////////////////////////////////////////// |
|
152 procedure CalcRotationDirAngle(Gear: PGear); |
|
153 var |
|
154 dAngle: real; |
|
155 begin |
|
156 dAngle := (Gear^.dX.QWordValue + Gear^.dY.QWordValue) / $80000000; |
|
157 if not Gear^.dX.isNegative then |
|
158 Gear^.DirAngle := Gear^.DirAngle + dAngle |
133 else |
159 else |
134 PlaySound(sndOw1, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack); |
160 Gear^.DirAngle := Gear^.DirAngle - dAngle; |
135 |
161 |
136 ApplyDamage(Gear, dmg); |
162 if Gear^.DirAngle < 0 then Gear^.DirAngle := Gear^.DirAngle + 360 |
137 end |
163 else if 360 < Gear^.DirAngle then Gear^.DirAngle := Gear^.DirAngle - 360 |
138 end; |
|
139 |
|
140 //////////////////////////////////////////////////////////////////////////////// |
|
141 //////////////////////////////////////////////////////////////////////////////// |
|
142 procedure CalcRotationDirAngle(Gear: PGear); |
|
143 var dAngle: real; |
|
144 begin |
|
145 dAngle:= (Gear^.dX.QWordValue + Gear^.dY.QWordValue) / $80000000; |
|
146 if not Gear^.dX.isNegative then |
|
147 Gear^.DirAngle:= Gear^.DirAngle + dAngle |
|
148 else |
|
149 Gear^.DirAngle:= Gear^.DirAngle - dAngle; |
|
150 |
|
151 if Gear^.DirAngle < 0 then Gear^.DirAngle:= Gear^.DirAngle + 360 |
|
152 else if 360 < Gear^.DirAngle then Gear^.DirAngle:= Gear^.DirAngle - 360 |
|
153 end; |
164 end; |
154 |
165 |
155 //////////////////////////////////////////////////////////////////////////////// |
166 //////////////////////////////////////////////////////////////////////////////// |
156 procedure doStepDrowningGear(Gear: PGear); |
167 procedure doStepDrowningGear(Gear: PGear); |
157 begin |
168 begin |
158 AllInactive:= false; |
169 AllInactive := false; |
159 Gear^.Y:= Gear^.Y + cDrownSpeed; |
170 Gear^.Y := Gear^.Y + cDrownSpeed; |
160 Gear^.X:= Gear^.X + Gear^.dX * cDrownSpeed; |
171 Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed; |
161 if (cWaterOpacity > $FE) or (hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater) then DeleteGear(Gear); |
172 if (cWaterOpacity > $FE) or (hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater) then |
162 // Create some bubbles (0.5% might be better but causes too few bubbles sometimes) |
173 DeleteGear(Gear); |
163 if (cWaterOpacity < $FF) and ((GameTicks and $1F) = 0) then |
174 // Create some bubbles (0.5% might be better but causes too few bubbles sometimes) |
164 if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then |
175 if (cWaterOpacity < $FF) and ((GameTicks and $1F) = 0) then |
165 AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble) |
176 if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then |
|
177 AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, |
|
178 vgtBubble) |
166 else if Random(12) = 0 then |
179 else if Random(12) = 0 then |
167 AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble) |
180 AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, |
|
181 vgtBubble) |
168 end; |
182 end; |
169 |
183 |
170 //////////////////////////////////////////////////////////////////////////////// |
184 //////////////////////////////////////////////////////////////////////////////// |
171 procedure doStepFallingGear(Gear: PGear); |
185 procedure doStepFallingGear(Gear: PGear); |
172 var isFalling: boolean; |
186 var |
|
187 isFalling: boolean; |
173 //tmp: QWord; |
188 //tmp: QWord; |
174 tdX, tdY: hwFloat; |
189 tdX, tdY: hwFloat; |
175 collV, collH: LongInt; |
190 collV, collH: LongInt; |
176 begin |
191 begin |
177 if Gear^.dX > _0_995 then Gear^.dX:= _0_995; |
192 if Gear^.dX > _0_995 then Gear^.dX := _0_995; |
178 if Gear^.dY > _0_995 then Gear^.dY:= _0_995; |
193 if Gear^.dY > _0_995 then Gear^.dY := _0_995; |
179 Gear^.State:= Gear^.State and not gstCollision; |
194 Gear^.State := Gear^.State and not gstCollision; |
180 collV:= 0; |
195 collV := 0; |
181 collH:= 0; |
196 collH := 0; |
182 tdX:= Gear^.dX; |
197 tdX := Gear^.dX; |
183 tdY:= Gear^.dY; |
198 tdY := Gear^.dY; |
|
199 |
184 |
200 |
185 // might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips) |
201 // might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips) |
186 if (hwRound(Gear^.X) < LAND_WIDTH div -2) or (hwRound(Gear^.X) > LAND_WIDTH * 3 div 2) then |
202 if (hwRound(Gear^.X) < LAND_WIDTH div -2) or (hwRound(Gear^.X) > LAND_WIDTH * 3 div 2) then |
187 begin |
203 begin |
188 Gear^.State:= Gear^.State or gstCollision; |
204 Gear^.State := Gear^.State or gstCollision; |
189 exit |
205 exit |
190 end; |
206 end; |
191 |
207 |
192 if Gear^.dY.isNegative then |
208 if Gear^.dY.isNegative then |
193 begin |
209 begin |
194 isFalling:= true; |
210 isFalling := true; |
195 if TestCollisionYwithGear(Gear, -1) then |
211 if TestCollisionYwithGear(Gear, -1) then |
196 begin |
212 begin |
197 collV:= -1; |
213 collV := -1; |
198 Gear^.dX:= Gear^.dX * Gear^.Friction; |
214 Gear^.dX := Gear^.dX * Gear^.Friction; |
199 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
215 Gear^.dY := - Gear^.dY * Gear^.Elasticity; |
200 Gear^.State:= Gear^.State or gstCollision |
216 Gear^.State := Gear^.State or gstCollision |
201 end |
217 end |
202 else if (Gear^.AdvBounce=1) and TestCollisionYwithGear(Gear, 1) then collV:= 1; |
218 else if (Gear^.AdvBounce=1) and TestCollisionYwithGear(Gear, 1) then collV := 1; |
203 end |
219 end |
204 else if TestCollisionYwithGear(Gear, 1) then |
220 else if TestCollisionYwithGear(Gear, 1) then |
205 begin |
221 begin |
206 collV:= 1; |
222 collV := 1; |
207 isFalling:= false; |
223 isFalling := false; |
208 Gear^.dX:= Gear^.dX * Gear^.Friction; |
224 Gear^.dX := Gear^.dX * Gear^.Friction; |
209 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
225 Gear^.dY := - Gear^.dY * Gear^.Elasticity; |
210 Gear^.State:= Gear^.State or gstCollision |
226 Gear^.State := Gear^.State or gstCollision |
211 end |
227 end |
212 else |
228 else |
213 begin |
229 begin |
214 isFalling:= true; |
230 isFalling := true; |
215 if (Gear^.AdvBounce=1) and not Gear^.dY.isNegative and TestCollisionYwithGear(Gear, -1) then collV:= -1; |
231 if (Gear^.AdvBounce=1) and not Gear^.dY.isNegative and TestCollisionYwithGear(Gear, -1) then |
216 end; |
232 collV := -1; |
217 |
233 end; |
218 |
234 |
219 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
235 |
220 begin |
236 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
221 collH:= hwSign(Gear^.dX); |
237 begin |
222 Gear^.dX:= - Gear^.dX * Gear^.Elasticity; |
238 collH := hwSign(Gear^.dX); |
223 Gear^.dY:= Gear^.dY * Gear^.Elasticity; |
239 Gear^.dX := - Gear^.dX * Gear^.Elasticity; |
224 Gear^.State:= Gear^.State or gstCollision |
240 Gear^.dY := Gear^.dY * Gear^.Elasticity; |
225 end |
241 Gear^.State := Gear^.State or gstCollision |
226 else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then collH:= -hwSign(Gear^.dX); |
242 end |
227 |
243 else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then |
228 //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then |
244 collH := -hwSign(Gear^.dX); |
229 if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1) or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)) then |
245 //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then |
230 begin |
246 if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1) or ((tdX.QWordValue + |
231 Gear^.dX:= tdY*Gear^.Elasticity*Gear^.Friction; |
247 tdY.QWordValue) > _0_2.QWordValue)) then |
232 Gear^.dY:= tdX*Gear^.Elasticity;//*Gear^.Friction; |
248 begin |
233 Gear^.dY.isNegative:= not tdY.isNegative; |
249 Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction; |
234 isFalling:= false; |
250 Gear^.dY := tdX*Gear^.Elasticity; |
235 Gear^.AdvBounce:= 10; |
251 //*Gear^.Friction; |
236 end; |
252 Gear^.dY.isNegative := not tdY.isNegative; |
237 |
253 isFalling := false; |
238 if Gear^.AdvBounce > 1 then dec(Gear^.AdvBounce); |
254 Gear^.AdvBounce := 10; |
239 |
255 end; |
240 if isFalling then Gear^.dY:= Gear^.dY + cGravity; |
256 |
241 |
257 if Gear^.AdvBounce > 1 then dec(Gear^.AdvBounce); |
242 Gear^.X:= Gear^.X + Gear^.dX; |
258 |
243 Gear^.Y:= Gear^.Y + Gear^.dY; |
259 if isFalling then Gear^.dY := Gear^.dY + cGravity; |
244 CheckGearDrowning(Gear); |
260 |
245 //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and |
261 Gear^.X := Gear^.X + Gear^.dX; |
246 if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) and |
262 Gear^.Y := Gear^.Y + Gear^.dY; |
247 (not isFalling) then |
263 CheckGearDrowning(Gear); |
248 Gear^.State:= Gear^.State and not gstMoving |
264 //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and |
249 else |
265 if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) and |
250 Gear^.State:= Gear^.State or gstMoving; |
266 (not isFalling) then |
251 |
267 Gear^.State := Gear^.State and not gstMoving |
252 if (Gear^.nImpactSounds > 0) then |
268 else |
253 if ((Gear^.Damage <> 0) or ((Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving))) and |
269 Gear^.State := Gear^.State or gstMoving; |
254 ((Gear^.dX.QWordValue > _0_1.QWordValue) or (Gear^.dY.QWordValue > _0_1.QWordValue)) then |
270 |
255 PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true); |
271 if (Gear^.nImpactSounds > 0) then |
|
272 if ((Gear^.Damage <> 0) or ((Gear^.State and (gstCollision or gstMoving)) = (gstCollision or |
|
273 gstMoving))) and |
|
274 ((Gear^.dX.QWordValue > _0_1.QWordValue) or (Gear^.dY.QWordValue > _0_1.QWordValue)) then |
|
275 PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true |
|
276 ); |
256 end; |
277 end; |
257 |
278 |
258 //////////////////////////////////////////////////////////////////////////////// |
279 //////////////////////////////////////////////////////////////////////////////// |
259 procedure doStepBomb(Gear: PGear); |
280 procedure doStepBomb(Gear: PGear); |
260 var i, x, y: LongInt; |
281 var |
|
282 i, x, y: LongInt; |
261 dX, dY: hwFloat; |
283 dX, dY: hwFloat; |
262 Fire: PGear; |
284 Fire: PGear; |
263 begin |
285 begin |
264 AllInactive:= false; |
286 AllInactive := false; |
265 |
287 |
266 doStepFallingGear(Gear); |
288 doStepFallingGear(Gear); |
267 |
289 |
268 dec(Gear^.Timer); |
290 dec(Gear^.Timer); |
269 if Gear^.Timer = 1000 then // might need adjustments |
291 if Gear^.Timer = 1000 then // might need adjustments |
270 case Gear^.Kind of |
292 case Gear^.Kind of |
271 gtAmmo_Bomb: makeHogsWorry(Gear^.X, Gear^.Y, 50); |
293 gtAmmo_Bomb: makeHogsWorry(Gear^.X, Gear^.Y, 50); |
272 gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20); |
294 gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20); |
273 gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75); |
295 gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75); |
274 gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90); |
296 gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90); |
275 gtGasBomb: makeHogsWorry(Gear^.X, Gear^.Y, 50); |
297 gtGasBomb: makeHogsWorry(Gear^.X, Gear^.Y, 50); |
276 end; |
298 end; |
277 |
299 |
278 if (Gear^.Kind = gtBall) and ((Gear^.State and gstTmpFlag) <> 0) then |
300 if (Gear^.Kind = gtBall) and ((Gear^.State and gstTmpFlag) <> 0) then |
279 begin |
301 begin |
280 CheckCollision(Gear); |
302 CheckCollision(Gear); |
281 if (Gear^.State and gstCollision) <> 0 then |
303 if (Gear^.State and gstCollision) <> 0 then |
282 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLDontDraw or EXPLNoGfx); |
304 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLDontDraw or EXPLNoGfx); |
283 end; |
305 end; |
284 |
306 |
285 if Gear^.Timer = 0 then |
307 if Gear^.Timer = 0 then |
286 begin |
308 begin |
287 case Gear^.Kind of |
309 case Gear^.Kind of |
288 gtAmmo_Bomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
310 gtAmmo_Bomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
289 gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, EXPLAutoSound); |
311 gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, EXPLAutoSound); |
290 gtClusterBomb: begin |
312 gtClusterBomb: |
291 x:= hwRound(Gear^.X); |
313 begin |
292 y:= hwRound(Gear^.Y); |
314 x := hwRound(Gear^.X); |
293 doMakeExplosion(x, y, 20, EXPLAutoSound); |
315 y := hwRound(Gear^.Y); |
294 for i:= 0 to 4 do |
316 doMakeExplosion(x, y, 20, EXPLAutoSound); |
295 begin |
317 for i:= 0 to 4 do |
296 dX:= rndSign(GetRandom * _0_1); |
318 begin |
297 dY:= (GetRandom - _3) * _0_08; |
319 dX := rndSign(GetRandom * _0_1); |
298 AddGear(x, y, gtCluster, 0, dX, dY, 25); |
320 dY := (GetRandom - _3) * _0_08; |
299 end |
321 AddGear(x, y, gtCluster, 0, dX, dY, 25); |
300 end; |
322 end |
301 gtWatermelon: begin |
323 end; |
302 x:= hwRound(Gear^.X); |
324 gtWatermelon: |
303 y:= hwRound(Gear^.Y); |
325 begin |
304 doMakeExplosion(x, y, 75, EXPLAutoSound); |
326 x := hwRound(Gear^.X); |
305 for i:= 0 to 5 do |
327 y := hwRound(Gear^.Y); |
306 begin |
328 doMakeExplosion(x, y, 75, EXPLAutoSound); |
307 dX:= rndSign(GetRandom * _0_1); |
329 for i:= 0 to 5 do |
308 dY:= (GetRandom - _1_5) * _0_3; |
330 begin |
309 AddGear(x, y, gtMelonPiece, 0, dX, dY, 75)^.DirAngle:= i * 60; |
331 dX := rndSign(GetRandom * _0_1); |
310 end |
332 dY := (GetRandom - _1_5) * _0_3; |
311 end; |
333 AddGear(x, y, gtMelonPiece, 0, dX, dY, 75)^.DirAngle := i * 60; |
312 gtHellishBomb: begin |
334 end |
313 x:= hwRound(Gear^.X); |
335 end; |
314 y:= hwRound(Gear^.Y); |
336 gtHellishBomb: |
315 doMakeExplosion(x, y, 90, EXPLAutoSound); |
337 begin |
316 |
338 x := hwRound(Gear^.X); |
317 for i:= 0 to 127 do |
339 y := hwRound(Gear^.Y); |
318 begin |
340 doMakeExplosion(x, y, 90, EXPLAutoSound); |
319 dX:= AngleCos(i * 16) * _0_5 * (GetRandom + _1); |
341 |
320 dY:= AngleSin(i * 16) * _0_5 * (GetRandom + _1); |
342 for i:= 0 to 127 do |
321 Fire:= AddGear(x, y, gtFlame, 0, dX, dY, 0); |
343 begin |
322 if i mod 2 = 0 then Fire^.State:= Fire^.State or gsttmpFlag; |
344 dX := AngleCos(i * 16) * _0_5 * (GetRandom + _1); |
323 Fire:= AddGear(x, y, gtFlame, 0, dX, -dY, 0); |
345 dY := AngleSin(i * 16) * _0_5 * (GetRandom + _1); |
324 if i mod 2 <> 0 then Fire^.State:= Fire^.State or gsttmpFlag; |
346 Fire := AddGear(x, y, gtFlame, 0, dX, dY, 0); |
325 end |
347 if i mod 2 = 0 then Fire^.State := Fire^.State or gsttmpFlag; |
326 end; |
348 Fire := AddGear(x, y, gtFlame, 0, dX, -dY, 0); |
327 gtGasBomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound or EXPLPoisoned); |
349 if i mod 2 <> 0 then Fire^.State := Fire^.State or gsttmpFlag; |
328 end; |
350 end |
329 DeleteGear(Gear); |
351 end; |
330 exit |
352 gtGasBomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound or EXPLPoisoned); |
331 end; |
353 end; |
|
354 DeleteGear(Gear); |
|
355 exit |
|
356 end; |
332 |
357 |
333 CalcRotationDirAngle(Gear); |
358 CalcRotationDirAngle(Gear); |
334 |
359 |
335 if Gear^.Kind = gtHellishBomb then |
360 if Gear^.Kind = gtHellishBomb then |
336 begin |
361 begin |
337 |
362 |
338 if Gear^.Timer = 3000 then |
363 if Gear^.Timer = 3000 then |
339 begin |
364 begin |
340 Gear^.nImpactSounds:= 0; |
365 Gear^.nImpactSounds := 0; |
341 PlaySound(sndHellish); |
366 PlaySound(sndHellish); |
342 end; |
367 end; |
343 |
368 |
344 if (GameTicks and $3F) = 0 then |
369 if (GameTicks and $3F) = 0 then |
345 if (Gear^.State and gstCollision) = 0 then |
370 if (Gear^.State and gstCollision) = 0 then |
346 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace); |
371 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace); |
347 end; |
372 end; |
348 end; |
373 end; |
349 //////////////////////////////////////////////////////////////////////////////// |
374 //////////////////////////////////////////////////////////////////////////////// |
350 procedure doStepMolotov(Gear: PGear); |
375 procedure doStepMolotov(Gear: PGear); |
351 var i, gX, gY: LongInt; |
376 var |
|
377 i, gX, gY: LongInt; |
352 dX, dY: hwFloat; |
378 dX, dY: hwFloat; |
353 Fire: PGear; |
379 Fire: PGear; |
354 begin |
380 begin |
355 AllInactive:= false; |
381 AllInactive := false; |
356 |
382 |
357 doStepFallingGear(Gear); |
383 doStepFallingGear(Gear); |
358 CalcRotationDirAngle(Gear); |
384 CalcRotationDirAngle(Gear); |
359 |
385 |
360 if (Gear^.State and gstCollision) <> 0 then begin |
386 if (Gear^.State and gstCollision) <> 0 then |
|
387 begin |
361 PlaySound(sndMolotov); |
388 PlaySound(sndMolotov); |
362 gX:= hwRound(Gear^.X); |
389 gX := hwRound(Gear^.X); |
363 gY:= hwRound(Gear^.Y); |
390 gY := hwRound(Gear^.Y); |
364 //doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 5, EXPLAutoSound); |
391 //doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 5, EXPLAutoSound); |
365 for i:= 0 to 20 do begin |
392 for i:= 0 to 20 do |
366 dX:= AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandom + _1); |
393 begin |
367 dY:= AngleSin(i * 8) * _0_5 * (GetRandom + _1); |
394 dX := AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandom + _1); |
368 Fire:= AddGear(gX, gY, gtFlame, 0, dX, dY, 0); |
395 dY := AngleSin(i * 8) * _0_5 * (GetRandom + _1); |
369 Fire^.State:= Fire^.State or gsttmpFlag; |
396 Fire := AddGear(gX, gY, gtFlame, 0, dX, dY, 0); |
370 Fire:= AddGear(gX, gY, gtFlame, 0, dX, -dY, 0); |
397 Fire^.State := Fire^.State or gsttmpFlag; |
371 Fire^.State:= Fire^.State or gsttmpFlag; |
398 Fire := AddGear(gX, gY, gtFlame, 0, dX, -dY, 0); |
372 Fire:= AddGear(gX, gY, gtFlame, 0, -dX, dY, 0); |
399 Fire^.State := Fire^.State or gsttmpFlag; |
373 Fire^.State:= Fire^.State or gsttmpFlag; |
400 Fire := AddGear(gX, gY, gtFlame, 0, -dX, dY, 0); |
374 Fire:= AddGear(gX, gY, gtFlame, 0, -dX, -dY, 0); |
401 Fire^.State := Fire^.State or gsttmpFlag; |
375 Fire^.State:= Fire^.State or gsttmpFlag; |
402 Fire := AddGear(gX, gY, gtFlame, 0, -dX, -dY, 0); |
|
403 Fire^.State := Fire^.State or gsttmpFlag; |
376 end; |
404 end; |
377 DeleteGear(Gear); |
405 DeleteGear(Gear); |
378 exit |
406 exit |
379 end; |
407 end; |
380 end; |
408 end; |
381 |
409 |
382 procedure doStepWatermelon(Gear: PGear); |
410 procedure doStepWatermelon(Gear: PGear); |
383 begin |
411 begin |
384 AllInactive:= false; |
412 AllInactive := false; |
385 Gear^.doStep:= @doStepBomb |
413 Gear^.doStep := @doStepBomb |
386 end; |
414 end; |
387 |
415 |
388 procedure doStepCluster(Gear: PGear); |
416 procedure doStepCluster(Gear: PGear); |
389 begin |
417 begin |
390 AllInactive:= false; |
418 AllInactive := false; |
391 doStepFallingGear(Gear); |
419 doStepFallingGear(Gear); |
392 if (Gear^.State and gstCollision) <> 0 then |
420 if (Gear^.State and gstCollision) <> 0 then |
393 begin |
421 begin |
394 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, EXPLAutoSound); |
422 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, EXPLAutoSound); |
395 DeleteGear(Gear); |
423 DeleteGear(Gear); |
396 exit |
424 exit |
397 end; |
425 end; |
398 |
426 |
399 if (Gear^.Kind = gtMelonPiece) or (Gear^.Kind = gtBall) then |
427 if (Gear^.Kind = gtMelonPiece) or (Gear^.Kind = gtBall) then |
400 CalcRotationDirAngle(Gear) |
428 CalcRotationDirAngle(Gear) |
401 else |
429 else if (GameTicks and $1F) = 0 then |
402 if (GameTicks and $1F) = 0 then |
|
403 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
430 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
404 end; |
431 end; |
405 |
432 |
406 //////////////////////////////////////////////////////////////////////////////// |
433 //////////////////////////////////////////////////////////////////////////////// |
407 procedure doStepGrenade(Gear: PGear); |
434 procedure doStepGrenade(Gear: PGear); |
408 begin |
435 begin |
409 AllInactive:= false; |
436 AllInactive := false; |
410 Gear^.dX:= Gear^.dX + cWindSpeed; |
437 Gear^.dX := Gear^.dX + cWindSpeed; |
411 doStepFallingGear(Gear); |
438 doStepFallingGear(Gear); |
412 if (Gear^.State and gstCollision) <> 0 then |
439 if (Gear^.State and gstCollision) <> 0 then |
413 begin |
440 begin |
414 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
441 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
415 DeleteGear(Gear); |
442 DeleteGear(Gear); |
416 exit |
443 exit |
417 end; |
444 end; |
418 if (GameTicks and $3F) = 0 then |
445 if (GameTicks and $3F) = 0 then |
419 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
446 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
420 end; |
447 end; |
421 |
448 |
422 //////////////////////////////////////////////////////////////////////////////// |
449 //////////////////////////////////////////////////////////////////////////////// |
423 procedure doStepGrave(Gear: PGear); |
450 procedure doStepGrave(Gear: PGear); |
424 begin |
451 begin |
425 AllInactive:= false; |
452 AllInactive := false; |
426 if Gear^.dY.isNegative then |
453 if Gear^.dY.isNegative then |
427 if TestCollisionY(Gear, -1) then Gear^.dY:= _0; |
454 if TestCollisionY(Gear, -1) then Gear^.dY := _0; |
428 |
455 |
429 if not Gear^.dY.isNegative then |
456 if not Gear^.dY.isNegative then |
430 if TestCollisionY(Gear, 1) then |
457 if TestCollisionY(Gear, 1) then |
431 begin |
458 begin |
432 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
459 Gear^.dY := - Gear^.dY * Gear^.Elasticity; |
433 if Gear^.dY > - _1div1024 then |
460 if Gear^.dY > - _1div1024 then |
434 begin |
461 begin |
435 Gear^.Active:= false; |
462 Gear^.Active := false; |
436 exit |
463 exit |
437 end else if Gear^.dY < - _0_03 then PlaySound(Gear^.ImpactSound) |
464 end |
438 end; |
465 else if Gear^.dY < - _0_03 then PlaySound(Gear^.ImpactSound) |
439 |
466 end; |
440 Gear^.Y:= Gear^.Y + Gear^.dY; |
467 |
441 CheckGearDrowning(Gear); |
468 Gear^.Y := Gear^.Y + Gear^.dY; |
442 Gear^.dY:= Gear^.dY + cGravity |
469 CheckGearDrowning(Gear); |
|
470 Gear^.dY := Gear^.dY + cGravity |
443 end; |
471 end; |
444 |
472 |
445 //////////////////////////////////////////////////////////////////////////////// |
473 //////////////////////////////////////////////////////////////////////////////// |
446 procedure doStepBeeWork(Gear: PGear); |
474 procedure doStepBeeWork(Gear: PGear); |
447 var t: hwFloat; |
475 var |
|
476 t: hwFloat; |
448 gX,gY: LongInt; |
477 gX,gY: LongInt; |
449 nuw: boolean; |
478 nuw: boolean; |
450 const uw: boolean = false; |
479 |
451 begin |
480 const uw: boolean = false; |
452 AllInactive:= false; |
481 begin |
453 gX:= hwRound(Gear^.X); |
482 AllInactive := false; |
454 gY:= hwRound(Gear^.Y); |
483 gX := hwRound(Gear^.X); |
455 nuw:= (cWaterLine < hwRound(Gear^.Y) + Gear^.Radius); |
484 gY := hwRound(Gear^.Y); |
456 if nuw and not uw then |
485 nuw := (cWaterLine < hwRound(Gear^.Y) + Gear^.Radius); |
457 begin |
486 if nuw and not uw then |
458 AddVisualGear(gX, cWaterLine, vgtSplash); |
487 begin |
459 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
488 AddVisualGear(gX, cWaterLine, vgtSplash); |
460 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
489 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
461 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
490 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
462 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
491 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
463 StopSound(Gear^.SoundChannel); |
492 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
464 Gear^.SoundChannel:= LoopSound(sndBeeWater); |
493 StopSound(Gear^.SoundChannel); |
465 uw:= nuw |
494 Gear^.SoundChannel := LoopSound(sndBeeWater); |
466 end |
495 uw := nuw |
467 else if not nuw and uw then |
496 end |
468 begin |
497 else if not nuw and uw then |
469 AddVisualGear(gX, cWaterLine, vgtSplash); |
498 begin |
470 StopSound(Gear^.SoundChannel); |
499 AddVisualGear(gX, cWaterLine, vgtSplash); |
471 Gear^.SoundChannel:= LoopSound(sndBee); |
500 StopSound(Gear^.SoundChannel); |
472 uw:= nuw |
501 Gear^.SoundChannel := LoopSound(sndBee); |
473 end; |
502 uw := nuw |
474 |
503 end; |
475 |
504 |
476 t:= Distance(Gear^.dX, Gear^.dY); |
505 |
477 Gear^.dX:= Gear^.Elasticity * (Gear^.dX + _0_000004 * (TargetPoint.X - gX)); |
506 t := Distance(Gear^.dX, Gear^.dY); |
478 Gear^.dY:= Gear^.Elasticity * (Gear^.dY + _0_000004 * (TargetPoint.Y - gY)); |
507 Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000004 * (TargetPoint.X - gX)); |
479 |
508 Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000004 * (TargetPoint.Y - gY)); |
480 t:= t / Distance(Gear^.dX, Gear^.dY); |
509 |
481 Gear^.dX:= Gear^.dX * t; |
510 t := t / Distance(Gear^.dX, Gear^.dY); |
482 Gear^.dY:= Gear^.dY * t; |
511 Gear^.dX := Gear^.dX * t; |
483 Gear^.X:= Gear^.X + Gear^.dX; |
512 Gear^.dY := Gear^.dY * t; |
484 Gear^.Y:= Gear^.Y + Gear^.dY; |
513 Gear^.X := Gear^.X + Gear^.dX; |
485 |
514 Gear^.Y := Gear^.Y + Gear^.dY; |
486 if (GameTicks and $3F) = 0 then |
515 |
487 begin |
516 if (GameTicks and $3F) = 0 then |
488 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBeeTrace); |
517 begin |
489 end; |
518 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBeeTrace); |
490 |
519 end; |
491 CheckCollision(Gear); |
520 |
492 dec(Gear^.Timer); |
521 CheckCollision(Gear); |
493 if ((Gear^.State and gstCollision) <> 0) or (Gear^.Timer = 0) then |
522 dec(Gear^.Timer); |
494 begin |
523 if ((Gear^.State and gstCollision) <> 0) or (Gear^.Timer = 0) then |
495 StopSound(Gear^.SoundChannel); |
524 begin |
496 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
525 StopSound(Gear^.SoundChannel); |
497 DeleteGear(Gear); |
526 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
498 end; |
527 DeleteGear(Gear); |
|
528 end; |
499 end; |
529 end; |
500 |
530 |
501 procedure doStepBee(Gear: PGear); |
531 procedure doStepBee(Gear: PGear); |
502 begin |
532 begin |
503 AllInactive:= false; |
533 AllInactive := false; |
504 Gear^.X:= Gear^.X + Gear^.dX; |
534 Gear^.X := Gear^.X + Gear^.dX; |
505 Gear^.Y:= Gear^.Y + Gear^.dY; |
535 Gear^.Y := Gear^.Y + Gear^.dY; |
506 Gear^.dY:= Gear^.dY + cGravity; |
536 Gear^.dY := Gear^.dY + cGravity; |
507 CheckCollision(Gear); |
537 CheckCollision(Gear); |
508 if (Gear^.State and gstCollision) <> 0 then |
538 if (Gear^.State and gstCollision) <> 0 then |
509 begin |
539 begin |
510 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
540 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
511 DeleteGear(Gear); |
541 DeleteGear(Gear); |
512 exit |
542 exit |
513 end; |
543 end; |
514 dec(Gear^.Timer); |
|
515 if Gear^.Timer = 0 then |
|
516 begin |
|
517 Gear^.SoundChannel:= LoopSound(sndBee); |
|
518 Gear^.Timer:= 5000; |
|
519 Gear^.doStep:= @doStepBeeWork |
|
520 end; |
|
521 end; |
|
522 |
|
523 //////////////////////////////////////////////////////////////////////////////// |
|
524 procedure doStepShotIdle(Gear: PGear); |
|
525 begin |
|
526 AllInactive:= false; |
|
527 inc(Gear^.Timer); |
|
528 if Gear^.Timer > 75 then |
|
529 begin |
|
530 DeleteGear(Gear); |
|
531 AfterAttack |
|
532 end |
|
533 end; |
|
534 |
|
535 procedure doStepShotgunShot(Gear: PGear); |
|
536 var i: LongWord; |
|
537 shell: PVisualGear; |
|
538 begin |
|
539 AllInactive:= false; |
|
540 |
|
541 if ((Gear^.State and gstAnimation) = 0) then |
|
542 begin |
|
543 dec(Gear^.Timer); |
544 dec(Gear^.Timer); |
544 if Gear^.Timer = 0 then |
545 if Gear^.Timer = 0 then |
545 begin |
546 begin |
546 PlaySound(sndShotgunFire); |
547 Gear^.SoundChannel := LoopSound(sndBee); |
547 shell:= AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); |
548 Gear^.Timer := 5000; |
|
549 Gear^.doStep := @doStepBeeWork |
|
550 end; |
|
551 end; |
|
552 |
|
553 //////////////////////////////////////////////////////////////////////////////// |
|
554 procedure doStepShotIdle(Gear: PGear); |
|
555 begin |
|
556 AllInactive := false; |
|
557 inc(Gear^.Timer); |
|
558 if Gear^.Timer > 75 then |
|
559 begin |
|
560 DeleteGear(Gear); |
|
561 AfterAttack |
|
562 end |
|
563 end; |
|
564 |
|
565 procedure doStepShotgunShot(Gear: PGear); |
|
566 var |
|
567 i: LongWord; |
|
568 shell: PVisualGear; |
|
569 begin |
|
570 AllInactive := false; |
|
571 |
|
572 if ((Gear^.State and gstAnimation) = 0) then |
|
573 begin |
|
574 dec(Gear^.Timer); |
|
575 if Gear^.Timer = 0 then |
|
576 begin |
|
577 PlaySound(sndShotgunFire); |
|
578 shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); |
|
579 if shell <> nil then |
|
580 begin |
|
581 shell^.dX := gear^.dX / -4; |
|
582 shell^.dY := gear^.dY / -4; |
|
583 shell^.Frame := 0 |
|
584 end; |
|
585 Gear^.State := Gear^.State or gstAnimation |
|
586 end; |
|
587 exit |
|
588 end |
|
589 else inc(Gear^.Timer); |
|
590 |
|
591 i := 200; |
|
592 repeat |
|
593 Gear^.X := Gear^.X + Gear^.dX; |
|
594 Gear^.Y := Gear^.Y + Gear^.dY; |
|
595 CheckCollision(Gear); |
|
596 if (Gear^.State and gstCollision) <> 0 then |
|
597 begin |
|
598 Gear^.X := Gear^.X + Gear^.dX * 8; |
|
599 Gear^.Y := Gear^.Y + Gear^.dY * 8; |
|
600 ShotgunShot(Gear); |
|
601 Gear^.doStep := @doStepShotIdle; |
|
602 exit |
|
603 end; |
|
604 |
|
605 CheckGearDrowning(Gear); |
|
606 if (Gear^.State and gstDrowning) <> 0 then |
|
607 begin |
|
608 Gear^.doStep := @doStepShotIdle; |
|
609 exit |
|
610 end; |
|
611 dec(i) |
|
612 until i = 0; |
|
613 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) |
|
614 then |
|
615 Gear^.doStep := @doStepShotIdle |
|
616 end; |
|
617 |
|
618 //////////////////////////////////////////////////////////////////////////////// |
|
619 procedure doStepBulletWork(Gear: PGear); |
|
620 var |
|
621 i, x, y: LongWord; |
|
622 oX, oY: hwFloat; |
|
623 begin |
|
624 AllInactive := false; |
|
625 inc(Gear^.Timer); |
|
626 i := 80; |
|
627 oX := Gear^.X; |
|
628 oY := Gear^.Y; |
|
629 repeat |
|
630 Gear^.X := Gear^.X + Gear^.dX; |
|
631 Gear^.Y := Gear^.Y + Gear^.dY; |
|
632 x := hwRound(Gear^.X); |
|
633 y := hwRound(Gear^.Y); |
|
634 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
|
635 and (Land[y, x] <> 0) then inc(Gear^.Damage); |
|
636 if Gear^.Damage > 5 then |
|
637 if Gear^.Ammo^.AmmoType = amDEagle then |
|
638 AmmoShove(Gear, 7, 20) |
|
639 else |
|
640 AmmoShove(Gear, Gear^.Timer, 20); |
|
641 CheckGearDrowning(Gear); |
|
642 dec(i) |
|
643 until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0); |
|
644 if Gear^.Damage > 0 then |
|
645 begin |
|
646 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1); |
|
647 dec(Gear^.Health, Gear^.Damage); |
|
648 Gear^.Damage := 0 |
|
649 end; |
|
650 if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and (cWaterOpacity < $FF) then |
|
651 begin |
|
652 for i:=(Gear^.Health - Gear^.Damage) * 4 downto 0 do |
|
653 begin |
|
654 if Random(6) = 0 then |
|
655 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble); |
|
656 Gear^.X := Gear^.X + Gear^.dX; |
|
657 Gear^.Y := Gear^.Y + Gear^.dY; |
|
658 end; |
|
659 end; |
|
660 |
|
661 if (Gear^.Health <= 0) |
|
662 or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) |
|
663 or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then |
|
664 begin |
|
665 if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then |
|
666 cLaserSighting := false; |
|
667 if (Gear^.Ammo^.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and |
|
668 ((GameFlags and gfArtillery) = 0) then cArtillery := false; |
|
669 Gear^.doStep := @doStepShotIdle |
|
670 end; |
|
671 end; |
|
672 |
|
673 procedure doStepDEagleShot(Gear: PGear); |
|
674 begin |
|
675 PlaySound(sndGun); |
|
676 Gear^.doStep := @doStepBulletWork |
|
677 end; |
|
678 |
|
679 procedure doStepSniperRifleShot(Gear: PGear); |
|
680 var |
|
681 HHGear: PGear; |
|
682 shell: PVisualGear; |
|
683 begin |
|
684 cArtillery := true; |
|
685 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
686 HHGear^.State := HHGear^.State or gstNotKickable; |
|
687 HedgehogChAngle(HHGear); |
|
688 if not cLaserSighting then |
|
689 // game does not have default laser sight. turn it on and give them a chance to aim |
|
690 begin |
|
691 cLaserSighting := true; |
|
692 HHGear^.Message := 0; |
|
693 if (HHGear^.Angle - 32 >= 0) then dec(HHGear^.Angle,32) |
|
694 end; |
|
695 |
|
696 if (HHGear^.Message and gm_Attack) <> 0 then |
|
697 begin |
|
698 shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); |
548 if shell <> nil then |
699 if shell <> nil then |
549 begin |
700 begin |
550 shell^.dX:= gear^.dX / -4; |
701 shell^.dX := gear^.dX / -2; |
551 shell^.dY:= gear^.dY / -4; |
702 shell^.dY := gear^.dY / -2; |
552 shell^.Frame:= 0 |
703 shell^.Frame := 1 |
553 end; |
704 end; |
554 Gear^.State:= Gear^.State or gstAnimation |
705 Gear^.State := Gear^.State or gstAnimation; |
555 end; |
706 Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _0_5; |
556 exit |
707 Gear^.dY := -AngleCos(HHGear^.Angle) * _0_5; |
557 end |
708 PlaySound(sndGun); |
558 else inc(Gear^.Timer); |
709 Gear^.doStep := @doStepBulletWork; |
559 |
710 end |
560 i:= 200; |
711 else |
561 repeat |
712 if (GameTicks mod 32) = 0 then |
562 Gear^.X:= Gear^.X + Gear^.dX; |
713 if (GameTicks mod 4096) < 2048 then |
563 Gear^.Y:= Gear^.Y + Gear^.dY; |
|
564 CheckCollision(Gear); |
|
565 if (Gear^.State and gstCollision) <> 0 then |
|
566 begin |
|
567 Gear^.X:= Gear^.X + Gear^.dX * 8; |
|
568 Gear^.Y:= Gear^.Y + Gear^.dY * 8; |
|
569 ShotgunShot(Gear); |
|
570 Gear^.doStep:= @doStepShotIdle; |
|
571 exit |
|
572 end; |
|
573 |
|
574 CheckGearDrowning(Gear); |
|
575 if (Gear^.State and gstDrowning) <> 0 then |
|
576 begin |
|
577 Gear^.doStep:= @doStepShotIdle; |
|
578 exit |
|
579 end; |
|
580 dec(i) |
|
581 until i = 0; |
|
582 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then |
|
583 Gear^.doStep:= @doStepShotIdle |
|
584 end; |
|
585 |
|
586 //////////////////////////////////////////////////////////////////////////////// |
|
587 procedure doStepBulletWork(Gear: PGear); |
|
588 var i, x, y: LongWord; |
|
589 oX, oY: hwFloat; |
|
590 begin |
|
591 AllInactive:= false; |
|
592 inc(Gear^.Timer); |
|
593 i:= 80; |
|
594 oX:= Gear^.X; |
|
595 oY:= Gear^.Y; |
|
596 repeat |
|
597 Gear^.X:= Gear^.X + Gear^.dX; |
|
598 Gear^.Y:= Gear^.Y + Gear^.dY; |
|
599 x:= hwRound(Gear^.X); |
|
600 y:= hwRound(Gear^.Y); |
|
601 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
|
602 and (Land[y, x] <> 0) then inc(Gear^.Damage); |
|
603 if Gear^.Damage > 5 then |
|
604 if Gear^.Ammo^.AmmoType = amDEagle then |
|
605 AmmoShove(Gear, 7, 20) |
|
606 else |
|
607 AmmoShove(Gear, Gear^.Timer, 20); |
|
608 CheckGearDrowning(Gear); |
|
609 dec(i) |
|
610 until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0); |
|
611 if Gear^.Damage > 0 then |
|
612 begin |
|
613 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1); |
|
614 dec(Gear^.Health, Gear^.Damage); |
|
615 Gear^.Damage:= 0 |
|
616 end; |
|
617 if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and (cWaterOpacity < $FF) then |
|
618 begin |
|
619 for i:=(Gear^.Health - Gear^.Damage) * 4 downto 0 do |
|
620 begin |
|
621 if Random(6) = 0 then |
|
622 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble); |
|
623 Gear^.X:= Gear^.X + Gear^.dX; |
|
624 Gear^.Y:= Gear^.Y + Gear^.dY; |
|
625 end; |
|
626 end; |
|
627 |
|
628 if (Gear^.Health <= 0) |
|
629 or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) |
|
630 or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then |
|
631 begin |
|
632 if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then cLaserSighting:= false; |
|
633 if (Gear^.Ammo^.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and |
|
634 ((GameFlags and gfArtillery) = 0) then cArtillery:= false; |
|
635 Gear^.doStep:= @doStepShotIdle |
|
636 end; |
|
637 end; |
|
638 |
|
639 procedure doStepDEagleShot(Gear: PGear); |
|
640 begin |
|
641 PlaySound(sndGun); |
|
642 Gear^.doStep:= @doStepBulletWork |
|
643 end; |
|
644 |
|
645 procedure doStepSniperRifleShot(Gear: PGear); |
|
646 var HHGear: PGear; |
|
647 shell: PVisualGear; |
|
648 begin |
|
649 cArtillery:= true; |
|
650 HHGear:=PHedgehog(Gear^.Hedgehog)^.Gear; |
|
651 HHGear^.State:= HHGear^.State or gstNotKickable; |
|
652 HedgehogChAngle(HHGear); |
|
653 if not cLaserSighting then // game does not have default laser sight. turn it on and give them a chance to aim |
|
654 begin |
|
655 cLaserSighting:= true; |
|
656 HHGear^.Message:= 0; |
|
657 if(HHGear^.Angle - 32 >= 0) then dec(HHGear^.Angle,32) |
|
658 end; |
|
659 |
|
660 if (HHGear^.Message and gm_Attack) <> 0 then |
|
661 begin |
|
662 shell:= AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); |
|
663 if shell <> nil then |
|
664 begin |
|
665 shell^.dX:= gear^.dX / -2; |
|
666 shell^.dY:= gear^.dY / -2; |
|
667 shell^.Frame:= 1 |
|
668 end; |
|
669 Gear^.State:= Gear^.State or gstAnimation; |
|
670 Gear^.dX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _0_5; |
|
671 Gear^.dY:= -AngleCos(HHGear^.Angle) * _0_5; |
|
672 PlaySound(sndGun); |
|
673 Gear^.doStep:= @doStepBulletWork; |
|
674 end |
|
675 else |
|
676 if (GameTicks mod 32) = 0 then |
|
677 if (GameTicks mod 4096) < 2048 then |
|
678 begin |
714 begin |
679 if(HHGear^.Angle + 1 <= cMaxAngle) then inc(HHGear^.Angle) |
715 if (HHGear^.Angle + 1 <= cMaxAngle) then inc(HHGear^.Angle) |
680 end |
716 end |
681 else |
717 else |
682 if(HHGear^.Angle - 1 >= 0) then dec(HHGear^.Angle); |
718 if (HHGear^.Angle - 1 >= 0) then dec(HHGear^.Angle); |
683 |
719 |
684 if (TurnTimeLeft > 0) then |
720 if (TurnTimeLeft > 0) then |
685 dec(TurnTimeLeft) |
721 dec(TurnTimeLeft) |
686 else |
722 else |
687 begin |
723 begin |
688 DeleteGear(Gear); |
724 DeleteGear(Gear); |
689 AfterAttack |
725 AfterAttack |
690 end; |
726 end; |
691 end; |
727 end; |
692 |
728 |
693 //////////////////////////////////////////////////////////////////////////////// |
729 //////////////////////////////////////////////////////////////////////////////// |
694 procedure doStepActionTimer(Gear: PGear); |
730 procedure doStepActionTimer(Gear: PGear); |
695 begin |
731 begin |
696 dec(Gear^.Timer); |
732 dec(Gear^.Timer); |
697 case Gear^.Kind of |
733 case Gear^.Kind of |
698 gtATStartGame: begin |
734 gtATStartGame: |
699 AllInactive:= false; |
735 begin |
700 if Gear^.Timer = 0 then |
736 AllInactive := false; |
701 begin |
737 if Gear^.Timer = 0 then |
702 AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState); |
738 begin |
703 end |
739 AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState); |
704 end; |
740 end |
705 gtATSmoothWindCh: begin |
741 end; |
706 if Gear^.Timer = 0 then |
742 gtATSmoothWindCh: |
707 begin |
743 begin |
708 if WindBarWidth < Gear^.Tag then inc(WindBarWidth) |
744 if Gear^.Timer = 0 then |
709 else if WindBarWidth > Gear^.Tag then dec(WindBarWidth); |
745 begin |
710 if WindBarWidth <> Gear^.Tag then Gear^.Timer:= 10; |
746 if WindBarWidth < Gear^.Tag then inc(WindBarWidth) |
711 end |
747 else if WindBarWidth > Gear^.Tag then dec(WindBarWidth); |
712 end; |
748 if WindBarWidth <> Gear^.Tag then Gear^.Timer := 10; |
713 gtATFinishGame: begin |
749 end |
714 AllInactive:= false; |
750 end; |
715 if Gear^.Timer = 1000 then |
751 gtATFinishGame: |
716 begin |
752 begin |
717 ScreenFade:= sfToBlack; |
753 AllInactive := false; |
718 ScreenFadeValue:= 0; |
754 if Gear^.Timer = 1000 then |
719 ScreenFadeSpeed:= 1; |
755 begin |
720 end; |
756 ScreenFade := sfToBlack; |
721 if Gear^.Timer = 0 then |
757 ScreenFadeValue := 0; |
722 begin |
758 ScreenFadeSpeed := 1; |
723 SendIPC('N'); |
759 end; |
724 SendIPC('q'); |
760 if Gear^.Timer = 0 then |
725 GameState:= gsExit |
761 begin |
726 end |
762 SendIPC('N'); |
727 end; |
763 SendIPC('q'); |
728 end; |
764 GameState := gsExit |
|
765 end |
|
766 end; |
|
767 end; |
729 if Gear^.Timer = 0 then DeleteGear(Gear) |
768 if Gear^.Timer = 0 then DeleteGear(Gear) |
730 end; |
769 end; |
731 |
770 |
732 //////////////////////////////////////////////////////////////////////////////// |
771 //////////////////////////////////////////////////////////////////////////////// |
733 procedure doStepPickHammerWork(Gear: PGear); |
772 procedure doStepPickHammerWork(Gear: PGear); |
734 var i, ei: LongInt; |
773 var |
|
774 i, ei: LongInt; |
735 HHGear: PGear; |
775 HHGear: PGear; |
736 begin |
776 begin |
737 AllInactive:= false; |
777 AllInactive := false; |
738 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
778 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
739 dec(Gear^.Timer); |
779 dec(Gear^.Timer); |
740 if (Gear^.Timer = 0)or((Gear^.Message and gm_Destroy) <> 0)or((HHGear^.State and gstHHDriven) = 0) then |
780 if (Gear^.Timer = 0)or((Gear^.Message and gm_Destroy) <> 0)or((HHGear^.State and gstHHDriven) = |
741 begin |
781 0) then |
742 StopSound(Gear^.SoundChannel); |
782 begin |
743 DeleteGear(Gear); |
783 StopSound(Gear^.SoundChannel); |
744 AfterAttack; |
784 DeleteGear(Gear); |
745 exit |
785 AfterAttack; |
746 end; |
786 exit |
747 |
787 end; |
748 if (Gear^.Timer mod 33) = 0 then |
788 |
749 begin |
789 if (Gear^.Timer mod 33) = 0 then |
750 HHGear^.State:= HHGear^.State or gstNoDamage; |
790 begin |
751 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y) + 7, 6, EXPLDontDraw); |
791 HHGear^.State := HHGear^.State or gstNoDamage; |
752 HHGear^.State:= HHGear^.State and not gstNoDamage |
792 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y) + 7, 6, EXPLDontDraw); |
753 end; |
793 HHGear^.State := HHGear^.State and not gstNoDamage |
754 |
794 end; |
755 if (Gear^.Timer mod 47) = 0 then |
795 |
756 begin |
796 if (Gear^.Timer mod 47) = 0 then |
757 i:= hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2)); |
797 begin |
758 ei:= hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2)); |
798 i := hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2)); |
759 while i <= ei do |
799 ei := hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2)); |
760 begin |
800 while i <= ei do |
761 DrawExplosion(i, hwRound(Gear^.Y) + 3, 3); |
801 begin |
762 inc(i, 1) |
802 DrawExplosion(i, hwRound(Gear^.Y) + 3, 3); |
763 end; |
803 inc(i, 1) |
764 |
804 end; |
765 if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9), COLOR_INDESTRUCTIBLE) then |
805 |
766 begin |
806 if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9) |
767 Gear^.X:= Gear^.X + Gear^.dX; |
807 , COLOR_INDESTRUCTIBLE) then |
768 Gear^.Y:= Gear^.Y + _1_9; |
808 begin |
769 end; |
809 Gear^.X := Gear^.X + Gear^.dX; |
770 SetAllHHToActive; |
810 Gear^.Y := Gear^.Y + _1_9; |
771 end; |
811 end; |
772 if TestCollisionYwithGear(Gear, 1) then |
812 SetAllHHToActive; |
773 begin |
813 end; |
774 Gear^.dY:= _0; |
814 if TestCollisionYwithGear(Gear, 1) then |
775 SetLittle(HHGear^.dX); |
815 begin |
776 HHGear^.dY:= _0; |
816 Gear^.dY := _0; |
777 end else |
817 SetLittle(HHGear^.dX); |
778 begin |
818 HHGear^.dY := _0; |
779 Gear^.dY:= Gear^.dY + cGravity; |
819 end |
780 Gear^.Y:= Gear^.Y + Gear^.dY; |
820 else |
781 if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer:= 1 |
821 begin |
782 end; |
822 Gear^.dY := Gear^.dY + cGravity; |
783 |
823 Gear^.Y := Gear^.Y + Gear^.dY; |
784 Gear^.X:= Gear^.X + HHGear^.dX; |
824 if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer := 1 |
785 HHGear^.X:= Gear^.X; |
825 end; |
786 HHGear^.Y:= Gear^.Y - int2hwFloat(cHHRadius); |
826 |
787 |
827 Gear^.X := Gear^.X + HHGear^.dX; |
788 if (Gear^.Message and gm_Attack) <> 0 then |
828 HHGear^.X := Gear^.X; |
789 if (Gear^.State and gsttmpFlag) <> 0 then Gear^.Timer:= 1 else else |
829 HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius); |
790 if (Gear^.State and gsttmpFlag) = 0 then Gear^.State:= Gear^.State or gsttmpFlag; |
830 |
791 if ((Gear^.Message and gm_Left) <> 0) then Gear^.dX:= - _0_3 else |
831 if (Gear^.Message and gm_Attack) <> 0 then |
792 if ((Gear^.Message and gm_Right) <> 0) then Gear^.dX:= _0_3 |
832 if (Gear^.State and gsttmpFlag) <> 0 then Gear^.Timer := 1 |
793 else Gear^.dX:= _0; |
833 else |
|
834 else |
|
835 if (Gear^.State and gsttmpFlag) = 0 then Gear^.State := Gear^.State or gsttmpFlag; |
|
836 if ((Gear^.Message and gm_Left) <> 0) then Gear^.dX := - _0_3 |
|
837 else |
|
838 if ((Gear^.Message and gm_Right) <> 0) then Gear^.dX := _0_3 |
|
839 else Gear^.dX := _0; |
794 end; |
840 end; |
795 |
841 |
796 procedure doStepPickHammer(Gear: PGear); |
842 procedure doStepPickHammer(Gear: PGear); |
797 var i, y: LongInt; |
843 var |
|
844 i, y: LongInt; |
798 ar: TRangeArray; |
845 ar: TRangeArray; |
799 HHGear: PGear; |
846 HHGear: PGear; |
800 begin |
847 begin |
801 i:= 0; |
848 i := 0; |
802 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
849 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
803 |
850 |
804 y:= hwRound(Gear^.Y) - cHHRadius * 2; |
851 y := hwRound(Gear^.Y) - cHHRadius * 2; |
805 while y < hwRound(Gear^.Y) do |
852 while y < hwRound(Gear^.Y) do |
806 begin |
853 begin |
807 ar[i].Left := hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2)); |
854 ar[i].Left := hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2)); |
808 ar[i].Right:= hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2)); |
855 ar[i].Right := hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2)); |
809 inc(y, 2); |
856 inc(y, 2); |
810 inc(i) |
857 inc(i) |
811 end; |
858 end; |
812 |
859 |
813 DrawHLinesExplosions(@ar, 3, hwRound(Gear^.Y) - cHHRadius * 2, 2, Pred(i)); |
860 DrawHLinesExplosions(@ar, 3, hwRound(Gear^.Y) - cHHRadius * 2, 2, Pred(i)); |
814 Gear^.dY:= HHGear^.dY; |
861 Gear^.dY := HHGear^.dY; |
815 DeleteCI(HHGear); |
862 DeleteCI(HHGear); |
816 |
863 |
817 Gear^.SoundChannel:= LoopSound(sndPickhammer); |
864 Gear^.SoundChannel := LoopSound(sndPickhammer); |
818 doStepPickHammerWork(Gear); |
865 doStepPickHammerWork(Gear); |
819 Gear^.doStep:= @doStepPickHammerWork |
866 Gear^.doStep := @doStepPickHammerWork |
820 end; |
867 end; |
821 |
868 |
822 //////////////////////////////////////////////////////////////////////////////// |
869 //////////////////////////////////////////////////////////////////////////////// |
823 var BTPrevAngle, BTSteps: LongInt; |
870 var |
|
871 BTPrevAngle, BTSteps: LongInt; |
824 |
872 |
825 procedure doStepBlowTorchWork(Gear: PGear); |
873 procedure doStepBlowTorchWork(Gear: PGear); |
826 var HHGear: PGear; |
874 var |
|
875 HHGear: PGear; |
827 b: boolean; |
876 b: boolean; |
828 prevX: LongInt; |
877 prevX: LongInt; |
829 begin |
878 begin |
830 AllInactive:= false; |
879 AllInactive := false; |
831 dec(Gear^.Timer); |
880 dec(Gear^.Timer); |
832 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
881 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
833 |
882 |
834 HedgehogChAngle(HHGear); |
883 HedgehogChAngle(HHGear); |
835 |
884 |
836 b:= false; |
885 b := false; |
837 |
886 |
838 if abs(LongInt(HHGear^.Angle) - BTPrevAngle) > 7 then |
887 if abs(LongInt(HHGear^.Angle) - BTPrevAngle) > 7 then |
839 begin |
888 begin |
840 Gear^.dX:= SignAs(AngleSin(HHGear^.Angle) * _0_5, HHGear^.dX); |
889 Gear^.dX := SignAs(AngleSin(HHGear^.Angle) * _0_5, HHGear^.dX); |
841 Gear^.dY:= AngleCos(HHGear^.Angle) * ( - _0_5); |
890 Gear^.dY := AngleCos(HHGear^.Angle) * ( - _0_5); |
842 BTPrevAngle:= HHGear^.Angle; |
891 BTPrevAngle := HHGear^.Angle; |
843 b:= true |
892 b := true |
844 end; |
893 end; |
845 |
894 |
846 if ((HHGear^.State and gstMoving) <> 0) then |
895 if ((HHGear^.State and gstMoving) <> 0) then |
847 begin |
896 begin |
848 doStepHedgehogMoving(HHGear); |
897 doStepHedgehogMoving(HHGear); |
849 if (HHGear^.State and gstHHDriven) = 0 then Gear^.Timer:= 0 |
898 if (HHGear^.State and gstHHDriven) = 0 then Gear^.Timer := 0 |
850 end; |
899 end; |
851 |
900 |
852 if Gear^.Timer mod cHHStepTicks = 0 then |
901 if Gear^.Timer mod cHHStepTicks = 0 then |
853 begin |
902 begin |
854 b:= true; |
903 b := true; |
855 if Gear^.dX.isNegative then |
904 if Gear^.dX.isNegative then |
856 HHGear^.Message:= (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Left |
905 HHGear^.Message := (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Left |
857 else |
906 else |
858 HHGear^.Message:= (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Right; |
907 HHGear^.Message := (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Right; |
859 |
908 |
860 if ((HHGear^.State and gstMoving) = 0) then |
909 if ((HHGear^.State and gstMoving) = 0) then |
861 begin |
910 begin |
862 HHGear^.State:= HHGear^.State and not gstAttacking; |
911 HHGear^.State := HHGear^.State and not gstAttacking; |
863 prevX:= hwRound(HHGear^.X); |
912 prevX := hwRound(HHGear^.X); |
864 |
913 |
865 // why the call to HedgehogStep then a further increment of X? |
914 // why the call to HedgehogStep then a further increment of X? |
866 if (prevX = hwRound(HHGear^.X)) and |
915 if (prevX = hwRound(HHGear^.X)) and |
867 CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), COLOR_INDESTRUCTIBLE) then HedgehogStep(HHGear); |
916 CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), |
868 |
917 COLOR_INDESTRUCTIBLE) then HedgehogStep(HHGear); |
869 if (prevX = hwRound(HHGear^.X)) and |
918 |
870 CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), COLOR_INDESTRUCTIBLE) then HHGear^.X:= HHGear^.X + SignAs(_1, HHGear^.dX); |
919 if (prevX = hwRound(HHGear^.X)) and |
871 HHGear^.State:= HHGear^.State or gstAttacking |
920 CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), |
872 end; |
921 COLOR_INDESTRUCTIBLE) then HHGear^.X := HHGear^.X + SignAs(_1, HHGear^.dX); |
873 |
922 HHGear^.State := HHGear^.State or gstAttacking |
874 inc(BTSteps); |
923 end; |
875 if BTSteps = 7 then |
924 |
876 begin |
925 inc(BTSteps); |
877 BTSteps:= 0; |
926 if BTSteps = 7 then |
878 if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)), COLOR_INDESTRUCTIBLE) then |
927 begin |
|
928 BTSteps := 0; |
|
929 if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6, |
|
930 Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)), |
|
931 COLOR_INDESTRUCTIBLE) then |
879 begin |
932 begin |
880 Gear^.X:= HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC); |
933 Gear^.X := HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC); |
881 Gear^.Y:= HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC); |
934 Gear^.Y := HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC); |
882 end; |
935 end; |
883 HHGear^.State:= HHGear^.State or gstNoDamage; |
936 HHGear^.State := HHGear^.State or gstNoDamage; |
884 AmmoShove(Gear, 2, 15); |
937 AmmoShove(Gear, 2, 15); |
885 HHGear^.State:= HHGear^.State and not gstNoDamage |
938 HHGear^.State := HHGear^.State and not gstNoDamage |
886 end; |
939 end; |
887 end; |
940 end; |
888 |
941 |
889 if b then |
942 if b then |
890 DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs(Gear^.dY) * 7, |
943 DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs( |
891 Gear^.dX, Gear^.dY, |
944 Gear^.dY) * 7, |
892 cHHRadius * 5, cHHRadius * 2 + 7); |
945 Gear^.dX, Gear^.dY, |
893 |
946 cHHRadius * 5, cHHRadius * 2 + 7); |
894 if (Gear^.Timer = 0) or ((HHGear^.Message and gm_Attack) <> 0) then |
947 |
895 begin |
948 if (Gear^.Timer = 0) or ((HHGear^.Message and gm_Attack) <> 0) then |
896 HHGear^.Message:= 0; |
949 begin |
897 HHGear^.State:= HHGear^.State and (not gstNotKickable); |
950 HHGear^.Message := 0; |
898 DeleteGear(Gear); |
951 HHGear^.State := HHGear^.State and (not gstNotKickable); |
899 AfterAttack |
952 DeleteGear(Gear); |
|
953 AfterAttack |
900 end |
954 end |
901 end; |
955 end; |
902 |
956 |
903 procedure doStepBlowTorch(Gear: PGear); |
957 procedure doStepBlowTorch(Gear: PGear); |
904 var HHGear: PGear; |
958 var |
905 begin |
959 HHGear: PGear; |
906 BTPrevAngle:= High(LongInt); |
960 begin |
907 BTSteps:= 0; |
961 BTPrevAngle := High(LongInt); |
908 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
962 BTSteps := 0; |
909 HHGear^.Message:= 0; |
963 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
910 HHGear^.State:= HHGear^.State or gstNotKickable; |
964 HHGear^.Message := 0; |
911 Gear^.doStep:= @doStepBlowTorchWork |
965 HHGear^.State := HHGear^.State or gstNotKickable; |
912 end; |
966 Gear^.doStep := @doStepBlowTorchWork |
913 |
967 end; |
914 //////////////////////////////////////////////////////////////////////////////// |
968 |
915 |
969 //////////////////////////////////////////////////////////////////////////////// |
916 procedure doStepRope(Gear: PGear); forward; |
970 |
|
971 procedure doStepRope(Gear: PGear); |
|
972 forward; |
917 |
973 |
918 procedure doStepRopeAfterAttack(Gear: PGear); |
974 procedure doStepRopeAfterAttack(Gear: PGear); |
919 var HHGear: PGear; |
975 var |
920 begin |
976 HHGear: PGear; |
921 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
977 begin |
922 if ((HHGear^.State and gstHHDriven) = 0) |
978 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
923 or (CheckGearDrowning(HHGear)) |
979 if ((HHGear^.State and gstHHDriven) = 0) |
924 or TestCollisionYwithGear(HHGear, 1) then |
980 or (CheckGearDrowning(HHGear)) |
925 begin |
981 or TestCollisionYwithGear(HHGear, 1) then |
926 DeleteGear(Gear); |
982 begin |
927 isCursorVisible:= false; |
983 DeleteGear(Gear); |
928 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
984 isCursorVisible := false; |
929 exit |
985 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
930 end; |
986 exit |
931 |
987 end; |
932 HedgehogChAngle(HHGear); |
988 |
933 |
989 HedgehogChAngle(HHGear); |
934 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX); |
990 |
935 |
991 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX); |
936 if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY:= _0; |
992 |
937 HHGear^.X:= HHGear^.X + HHGear^.dX; |
993 if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY := _0; |
938 HHGear^.Y:= HHGear^.Y + HHGear^.dY; |
994 HHGear^.X := HHGear^.X + HHGear^.dX; |
939 HHGear^.dY:= HHGear^.dY + cGravity; |
995 HHGear^.Y := HHGear^.Y + HHGear^.dY; |
940 |
996 HHGear^.dY := HHGear^.dY + cGravity; |
941 if (Gear^.Message and gm_Attack) <> 0 then |
997 |
942 begin |
998 if (Gear^.Message and gm_Attack) <> 0 then |
943 Gear^.X:= HHGear^.X; |
999 begin |
944 Gear^.Y:= HHGear^.Y; |
1000 Gear^.X := HHGear^.X; |
945 |
1001 Gear^.Y := HHGear^.Y; |
946 ApplyAngleBounds(PHedgehog(Gear^.Hedgehog)^, amRope); |
1002 |
947 |
1003 ApplyAngleBounds(PHedgehog(Gear^.Hedgehog)^, amRope); |
948 Gear^.dX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX); |
1004 |
949 Gear^.dY:= -AngleCos(HHGear^.Angle); |
1005 Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX); |
950 Gear^.Friction:= _450; |
1006 Gear^.dY := -AngleCos(HHGear^.Angle); |
951 Gear^.Elasticity:= _0; |
1007 Gear^.Friction := _450; |
952 Gear^.State:= Gear^.State and not gsttmpflag; |
1008 Gear^.Elasticity := _0; |
953 Gear^.doStep:= @doStepRope; |
1009 Gear^.State := Gear^.State and not gsttmpflag; |
|
1010 Gear^.doStep := @doStepRope; |
954 end |
1011 end |
955 end; |
1012 end; |
956 |
1013 |
957 procedure doStepRopeWork(Gear: PGear); |
1014 procedure doStepRopeWork(Gear: PGear); |
958 var HHGear: PGear; |
1015 var |
|
1016 HHGear: PGear; |
959 len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; |
1017 len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; |
960 lx, ly: LongInt; |
1018 lx, ly: LongInt; |
961 haveCollision, |
1019 haveCollision, |
962 haveDivided: boolean; |
1020 haveDivided: boolean; |
963 |
1021 |
964 procedure DeleteMe; |
1022 procedure DeleteMe; |
965 begin |
1023 begin |
966 with HHGear^ do |
1024 with HHGear^ do |
967 begin |
1025 begin |
968 Message:= Message and not gm_Attack; |
1026 Message := Message and not gm_Attack; |
969 State:= (State or gstMoving) and not gstWinner; |
1027 State := (State or gstMoving) and not gstWinner; |
970 end; |
1028 end; |
971 DeleteGear(Gear) |
1029 DeleteGear(Gear) |
972 end; |
1030 end; |
973 |
1031 |
974 procedure WaitCollision; |
1032 procedure WaitCollision; |
975 begin |
1033 begin |
976 with HHGear^ do |
1034 with HHGear^ do |
977 begin |
1035 begin |
978 Message:= Message and not gm_Attack; |
1036 Message := Message and not gm_Attack; |
979 State:= State or gstMoving; |
1037 State := State or gstMoving; |
980 end; |
1038 end; |
981 RopePoints.Count:= 0; |
1039 RopePoints.Count := 0; |
982 Gear^.Elasticity:= _0; |
1040 Gear^.Elasticity := _0; |
983 Gear^.doStep:= @doStepRopeAfterAttack |
1041 Gear^.doStep := @doStepRopeAfterAttack |
984 end; |
1042 end; |
985 |
1043 |
986 begin |
1044 begin |
987 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
1045 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
988 |
1046 |
989 if ((HHGear^.State and gstHHDriven) = 0) |
1047 if ((HHGear^.State and gstHHDriven) = 0) |
990 or (CheckGearDrowning(HHGear)) then |
1048 or (CheckGearDrowning(HHGear)) then |
991 begin |
1049 begin |
992 PlaySound(sndRopeRelease); |
1050 PlaySound(sndRopeRelease); |
993 DeleteMe; |
1051 DeleteMe; |
994 exit |
1052 exit |
995 end; |
1053 end; |
996 |
1054 |
997 if (Gear^.Message and gm_Left <> 0) then HHGear^.dX:= HHGear^.dX - _0_0002 else |
1055 if (Gear^.Message and gm_Left <> 0) then HHGear^.dX := HHGear^.dX - _0_0002 |
998 if (Gear^.Message and gm_Right <> 0) then HHGear^.dX:= HHGear^.dX + _0_0002; |
1056 else |
999 |
1057 if (Gear^.Message and gm_Right <> 0) then HHGear^.dX := HHGear^.dX + _0_0002; |
1000 if not TestCollisionYwithGear(HHGear, 1) then HHGear^.dY:= HHGear^.dY + cGravity; |
1058 |
1001 |
1059 if not TestCollisionYwithGear(HHGear, 1) then HHGear^.dY := HHGear^.dY + cGravity; |
1002 ropeDx:= HHGear^.X - Gear^.X; // vector between hedgehog and rope attaching point |
1060 |
1003 ropeDy:= HHGear^.Y - Gear^.Y; |
1061 ropeDx := HHGear^.X - Gear^.X; |
1004 |
1062 // vector between hedgehog and rope attaching point |
1005 mdX:= ropeDx + HHGear^.dX; |
1063 ropeDy := HHGear^.Y - Gear^.Y; |
1006 mdY:= ropeDy + HHGear^.dY; |
1064 |
1007 len:= _1 / Distance(mdX, mdY); |
1065 mdX := ropeDx + HHGear^.dX; |
1008 mdX:= mdX * len; // rope vector plus hedgehog direction vector normalized |
1066 mdY := ropeDy + HHGear^.dY; |
1009 mdY:= mdY * len; |
1067 len := _1 / Distance(mdX, mdY); |
1010 |
1068 mdX := mdX * len; |
1011 Gear^.dX:= mdX; // for visual purposes only |
1069 // rope vector plus hedgehog direction vector normalized |
1012 Gear^.dY:= mdY; |
1070 mdY := mdY * len; |
1013 |
1071 |
1014 ///// |
1072 Gear^.dX := mdX; |
1015 tx:= HHGear^.X; |
1073 // for visual purposes only |
1016 ty:= HHGear^.Y; |
1074 Gear^.dY := mdY; |
|
1075 |
|
1076 ///// |
|
1077 tx := HHGear^.X; |
|
1078 ty := HHGear^.Y; |
1017 |
1079 |
1018 if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then |
1080 if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then |
1019 if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx)) |
1081 if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx)) |
1020 or TestCollisionYwithGear(HHGear, hwSign(ropeDy))) then |
1082 or TestCollisionYwithGear(HHGear, hwSign(ropeDy))) then |
1021 Gear^.Elasticity:= Gear^.Elasticity + _0_3; |
1083 Gear^.Elasticity := Gear^.Elasticity + _0_3; |
1022 |
1084 |
1023 if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > _30) then |
1085 if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > _30) then |
1024 if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx)) |
1086 if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx)) |
1025 or TestCollisionYwithGear(HHGear, -hwSign(ropeDy))) then |
1087 or TestCollisionYwithGear(HHGear, -hwSign(ropeDy))) then |
1026 Gear^.Elasticity:= Gear^.Elasticity - _0_3; |
1088 Gear^.Elasticity := Gear^.Elasticity - _0_3; |
1027 |
1089 |
1028 HHGear^.X:= Gear^.X + mdX * Gear^.Elasticity; |
1090 HHGear^.X := Gear^.X + mdX * Gear^.Elasticity; |
1029 HHGear^.Y:= Gear^.Y + mdY * Gear^.Elasticity; |
1091 HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity; |
1030 |
1092 |
1031 HHGear^.dX:= HHGear^.X - tx; |
1093 HHGear^.dX := HHGear^.X - tx; |
1032 HHGear^.dY:= HHGear^.Y - ty; |
1094 HHGear^.dY := HHGear^.Y - ty; |
1033 //// |
1095 //// |
1034 |
1096 |
1035 |
1097 |
1036 haveDivided:= false; |
1098 haveDivided := false; |
1037 // check whether rope needs dividing |
1099 // check whether rope needs dividing |
1038 len:= _1 / Distance(ropeDx, ropeDy); // old rope pos |
1100 len := _1 / Distance(ropeDx, ropeDy); |
1039 nx:= ropeDx * len; |
1101 // old rope pos |
1040 ny:= ropeDy * len; |
1102 nx := ropeDx * len; |
1041 |
1103 ny := ropeDy * len; |
1042 len:= Gear^.Elasticity - _5; |
1104 |
|
1105 len := Gear^.Elasticity - _5; |
1043 while len > _3 do |
1106 while len > _3 do |
|
1107 begin |
|
1108 lx := hwRound(Gear^.X + mdX * len); |
|
1109 ly := hwRound(Gear^.Y + mdY * len); |
|
1110 if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and (Land[ly, lx] <> 0 |
|
1111 ) then |
|
1112 begin |
|
1113 with RopePoints.ar[RopePoints.Count] do |
1044 begin |
1114 begin |
1045 lx:= hwRound(Gear^.X + mdX * len); |
1115 X := Gear^.X; |
1046 ly:= hwRound(Gear^.Y + mdY * len); |
1116 Y := Gear^.Y; |
1047 if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and (Land[ly, lx] <> 0) then |
1117 if RopePoints.Count = 0 then RopePoints.HookAngle := DxDy2Angle(Gear^.dY, Gear^.dX); |
1048 begin |
1118 b := (nx * HHGear^.dY) > (ny * HHGear^.dX); |
1049 with RopePoints.ar[RopePoints.Count] do |
1119 dLen := len |
1050 begin |
|
1051 X:= Gear^.X; |
|
1052 Y:= Gear^.Y; |
|
1053 if RopePoints.Count = 0 then RopePoints.HookAngle:= DxDy2Angle(Gear^.dY, Gear^.dX); |
|
1054 b:= (nx * HHGear^.dY) > (ny * HHGear^.dX); |
|
1055 dLen:= len |
|
1056 end; |
|
1057 with RopePoints.rounded[RopePoints.Count] do |
|
1058 begin |
|
1059 X:= hwRound(Gear^.X); |
|
1060 Y:= hwRound(Gear^.Y); |
|
1061 end; |
|
1062 |
|
1063 Gear^.X:= Gear^.X + nx * len; |
|
1064 Gear^.Y:= Gear^.Y + ny * len; |
|
1065 inc(RopePoints.Count); |
|
1066 TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true); |
|
1067 Gear^.Elasticity:= Gear^.Elasticity - len; |
|
1068 Gear^.Friction:= Gear^.Friction - len; |
|
1069 haveDivided:= true; |
|
1070 break |
|
1071 end; |
|
1072 len:= len - _0_3 // should be the same as increase step |
|
1073 end; |
1120 end; |
1074 |
1121 with RopePoints.rounded[RopePoints.Count] do |
1075 if not haveDivided then |
|
1076 if RopePoints.Count > 0 then // check whether the last dividing point could be removed |
|
1077 begin |
|
1078 tx:= RopePoints.ar[Pred(RopePoints.Count)].X; |
|
1079 ty:= RopePoints.ar[Pred(RopePoints.Count)].Y; |
|
1080 mdX:= tx - Gear^.X; |
|
1081 mdY:= ty - Gear^.Y; |
|
1082 if RopePoints.ar[Pred(RopePoints.Count)].b xor (mdX * (ty - HHGear^.Y) > (tx - HHGear^.X) * mdY) then |
|
1083 begin |
1122 begin |
1084 dec(RopePoints.Count); |
1123 X := hwRound(Gear^.X); |
1085 Gear^.X:= RopePoints.ar[RopePoints.Count].X; |
1124 Y := hwRound(Gear^.Y); |
1086 Gear^.Y:= RopePoints.ar[RopePoints.Count].Y; |
1125 end; |
1087 Gear^.Elasticity:= Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; |
1126 |
1088 Gear^.Friction:= Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen; |
1127 Gear^.X := Gear^.X + nx * len; |
1089 |
1128 Gear^.Y := Gear^.Y + ny * len; |
1090 // restore hog position |
1129 inc(RopePoints.Count); |
1091 len:= _1 / Distance(mdX, mdY); |
1130 TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true); |
1092 mdX:= mdX * len; |
1131 Gear^.Elasticity := Gear^.Elasticity - len; |
1093 mdY:= mdY * len; |
1132 Gear^.Friction := Gear^.Friction - len; |
1094 |
1133 haveDivided := true; |
1095 HHGear^.X:= Gear^.X - mdX * Gear^.Elasticity; |
1134 break |
1096 HHGear^.Y:= Gear^.Y - mdY * Gear^.Elasticity; |
1135 end; |
|
1136 len := len - _0_3 // should be the same as increase step |
|
1137 end; |
|
1138 |
|
1139 if not haveDivided then |
|
1140 if RopePoints.Count > 0 then // check whether the last dividing point could be removed |
|
1141 begin |
|
1142 tx := RopePoints.ar[Pred(RopePoints.Count)].X; |
|
1143 ty := RopePoints.ar[Pred(RopePoints.Count)].Y; |
|
1144 mdX := tx - Gear^.X; |
|
1145 mdY := ty - Gear^.Y; |
|
1146 if RopePoints.ar[Pred(RopePoints.Count)].b xor (mdX * (ty - HHGear^.Y) > (tx - HHGear^.X |
|
1147 ) * mdY) then |
|
1148 begin |
|
1149 dec(RopePoints.Count); |
|
1150 Gear^.X := RopePoints.ar[RopePoints.Count].X; |
|
1151 Gear^.Y := RopePoints.ar[RopePoints.Count].Y; |
|
1152 Gear^.Elasticity := Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; |
|
1153 Gear^.Friction := Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen; |
|
1154 |
|
1155 // restore hog position |
|
1156 len := _1 / Distance(mdX, mdY); |
|
1157 mdX := mdX * len; |
|
1158 mdY := mdY * len; |
|
1159 |
|
1160 HHGear^.X := Gear^.X - mdX * Gear^.Elasticity; |
|
1161 HHGear^.Y := Gear^.Y - mdY * Gear^.Elasticity; |
1097 end |
1162 end |
1098 end; |
1163 end; |
1099 |
1164 |
1100 haveCollision:= false; |
1165 haveCollision := false; |
1101 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
1166 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
1102 begin |
1167 begin |
1103 HHGear^.dX:= -_0_6 * HHGear^.dX; |
1168 HHGear^.dX := -_0_6 * HHGear^.dX; |
1104 haveCollision:= true |
1169 haveCollision := true |
1105 end; |
1170 end; |
1106 if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then |
1171 if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then |
1107 begin |
1172 begin |
1108 HHGear^.dY:= -_0_6 * HHGear^.dY; |
1173 HHGear^.dY := -_0_6 * HHGear^.dY; |
1109 haveCollision:= true |
1174 haveCollision := true |
1110 end; |
1175 end; |
1111 |
1176 |
1112 if haveCollision |
1177 if haveCollision |
1113 and (Gear^.Message and (gm_Left or gm_Right) <> 0) |
1178 and (Gear^.Message and (gm_Left or gm_Right) <> 0) |
1114 and (Gear^.Message and (gm_Up or gm_Down) <> 0) then |
1179 and (Gear^.Message and (gm_Up or gm_Down) <> 0) then |
1115 begin |
1180 begin |
1116 HHGear^.dX:= SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX); |
1181 HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX); |
1117 HHGear^.dY:= SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY) |
1182 HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY) |
1118 end; |
1183 end; |
1119 |
1184 |
1120 len:= Distance(HHGear^.dX, HHGear^.dY); |
1185 len := Distance(HHGear^.dX, HHGear^.dY); |
1121 if len > _0_8 then |
1186 if len > _0_8 then |
1122 begin |
1187 begin |
1123 len:= _0_8 / len; |
1188 len := _0_8 / len; |
1124 HHGear^.dX:= HHGear^.dX * len; |
1189 HHGear^.dX := HHGear^.dX * len; |
1125 HHGear^.dY:= HHGear^.dY * len; |
1190 HHGear^.dY := HHGear^.dY * len; |
1126 end; |
1191 end; |
1127 |
1192 |
1128 if (Gear^.Message and gm_Attack) <> 0 then |
1193 if (Gear^.Message and gm_Attack) <> 0 then |
1129 if (Gear^.State and gsttmpFlag) <> 0 then |
1194 if (Gear^.State and gsttmpFlag) <> 0 then |
1130 with PHedgehog(Gear^.Hedgehog)^ do |
1195 with PHedgehog(Gear^.Hedgehog)^ do |
1131 begin |
1196 begin |
1132 PlaySound(sndRopeRelease); |
1197 PlaySound(sndRopeRelease); |
1133 if Ammo^[CurSlot, CurAmmo].AmmoType <> amParachute then |
1198 if Ammo^[CurSlot, CurAmmo].AmmoType <> amParachute then |
1134 WaitCollision |
1199 WaitCollision |
1135 else |
1200 else |
1136 DeleteMe |
1201 DeleteMe |
1137 end |
1202 end |
1138 else |
1203 else |
1139 else |
1204 else |
1140 if (Gear^.State and gsttmpFlag) = 0 then |
1205 if (Gear^.State and gsttmpFlag) = 0 then |
1141 Gear^.State:= Gear^.State or gsttmpFlag; |
1206 Gear^.State := Gear^.State or gsttmpFlag; |
1142 end; |
1207 end; |
1143 |
1208 |
1144 procedure doStepRopeAttach(Gear: PGear); |
1209 procedure doStepRopeAttach(Gear: PGear); |
1145 var HHGear: PGear; |
1210 var |
|
1211 HHGear: PGear; |
1146 tx, ty, tt: hwFloat; |
1212 tx, ty, tt: hwFloat; |
1147 |
1213 |
1148 procedure RemoveFromAmmo; |
1214 procedure RemoveFromAmmo; |
1149 begin |
1215 begin |
1150 if (Gear^.State and gstAttacked) = 0 then |
1216 if (Gear^.State and gstAttacked) = 0 then |
1151 begin |
1217 begin |
1152 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); |
1218 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); |
1153 Gear^.State:= Gear^.State or gstAttacked |
1219 Gear^.State := Gear^.State or gstAttacked |
1154 end; |
1220 end; |
1155 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^) |
1221 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^) |
1156 end; |
1222 end; |
1157 |
1223 |
1158 begin |
1224 begin |
1159 Gear^.X:= Gear^.X - Gear^.dX; |
1225 Gear^.X := Gear^.X - Gear^.dX; |
1160 Gear^.Y:= Gear^.Y - Gear^.dY; |
1226 Gear^.Y := Gear^.Y - Gear^.dY; |
1161 Gear^.Elasticity:= Gear^.Elasticity + _1; |
1227 Gear^.Elasticity := Gear^.Elasticity + _1; |
1162 |
1228 |
1163 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
1229 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
1164 DeleteCI(HHGear); |
1230 DeleteCI(HHGear); |
1165 |
1231 |
1166 if (HHGear^.State and gstMoving) <> 0 then |
1232 if (HHGear^.State and gstMoving) <> 0 then |
1167 begin |
1233 begin |
1168 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX); |
1234 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX); |
1169 if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY:= _0; |
1235 if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY := _0; |
1170 |
1236 |
1171 HHGear^.X:= HHGear^.X + HHGear^.dX; |
1237 HHGear^.X := HHGear^.X + HHGear^.dX; |
1172 Gear^.X:= Gear^.X + HHGear^.dX; |
1238 Gear^.X := Gear^.X + HHGear^.dX; |
1173 |
1239 |
1174 if TestCollisionYwithGear(HHGear, 1) then |
1240 if TestCollisionYwithGear(HHGear, 1) then |
1175 begin |
1241 begin |
1176 CheckHHDamage(HHGear); |
1242 CheckHHDamage(HHGear); |
1177 HHGear^.dY:= _0; |
1243 HHGear^.dY := _0; |
1178 //HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump); |
1244 //HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump); |
1179 end else |
1245 end |
1180 begin |
1246 else |
1181 HHGear^.Y:= HHGear^.Y + HHGear^.dY; |
1247 begin |
1182 Gear^.Y:= Gear^.Y + HHGear^.dY; |
1248 HHGear^.Y := HHGear^.Y + HHGear^.dY; |
1183 HHGear^.dY:= HHGear^.dY + cGravity; |
1249 Gear^.Y := Gear^.Y + HHGear^.dY; |
1184 end; |
1250 HHGear^.dY := HHGear^.dY + cGravity; |
1185 |
1251 end; |
1186 tt:= Gear^.Elasticity; |
1252 |
1187 tx:= _0; |
1253 tt := Gear^.Elasticity; |
1188 ty:= _0; |
1254 tx := _0; |
1189 while tt > _20 do |
1255 ty := _0; |
1190 begin |
1256 while tt > _20 do |
1191 if TestCollisionXwithXYShift(Gear, tx, hwRound(ty), -hwSign(Gear^.dX)) |
1257 begin |
1192 or TestCollisionYwithXYShift(Gear, hwRound(tx), hwRound(ty), -hwSign(Gear^.dY)) then |
1258 if TestCollisionXwithXYShift(Gear, tx, hwRound(ty), -hwSign(Gear^.dX)) |
|
1259 or TestCollisionYwithXYShift(Gear, hwRound(tx), hwRound(ty), -hwSign(Gear^.dY)) then |
1193 begin |
1260 begin |
1194 Gear^.X:= Gear^.X + tx; |
1261 Gear^.X := Gear^.X + tx; |
1195 Gear^.Y:= Gear^.Y + ty; |
1262 Gear^.Y := Gear^.Y + ty; |
1196 Gear^.Elasticity:= tt; |
1263 Gear^.Elasticity := tt; |
1197 Gear^.doStep:= @doStepRopeWork; |
1264 Gear^.doStep := @doStepRopeWork; |
1198 PlaySound(sndRopeAttach); |
1265 PlaySound(sndRopeAttach); |
1199 with HHGear^ do State:= State and not (gstAttacking or gstHHJumping or gstHHHJump); |
1266 with HHGear^ do |
1200 |
1267 State := State and not (gstAttacking or gstHHJumping or gstHHHJump); |
1201 RemoveFromAmmo; |
1268 |
1202 |
1269 RemoveFromAmmo; |
1203 tt:= _0; |
1270 |
1204 exit |
1271 tt := _0; |
|
1272 exit |
1205 end; |
1273 end; |
1206 tx:= tx + Gear^.dX + Gear^.dX; |
1274 tx := tx + Gear^.dX + Gear^.dX; |
1207 ty:= ty + Gear^.dY + Gear^.dY; |
1275 ty := ty + Gear^.dY + Gear^.dY; |
1208 tt:= tt - _2; |
1276 tt := tt - _2; |
1209 end; |
1277 end; |
1210 end; |
1278 end; |
1211 |
1279 |
1212 CheckCollision(Gear); |
1280 CheckCollision(Gear); |
1213 |
1281 |
1214 if (Gear^.State and gstCollision) <> 0 then |
1282 if (Gear^.State and gstCollision) <> 0 then |
1215 if Gear^.Elasticity < _10 then |
1283 if Gear^.Elasticity < _10 then |
1216 Gear^.Elasticity:= _10000 |
1284 Gear^.Elasticity := _10000 |
1217 else |
1285 else |
1218 begin |
1286 begin |
1219 Gear^.doStep:= @doStepRopeWork; |
1287 Gear^.doStep := @doStepRopeWork; |
1220 PlaySound(sndRopeAttach); |
1288 PlaySound(sndRopeAttach); |
1221 with HHGear^ do State:= State and not (gstAttacking or gstHHJumping or gstHHHJump); |
1289 with HHGear^ do |
|
1290 State := State and not (gstAttacking or gstHHJumping or gstHHHJump); |
1222 |
1291 |
1223 RemoveFromAmmo; |
1292 RemoveFromAmmo; |
1224 |
1293 |
1225 exit |
1294 exit |
1226 end; |
1295 end; |
1227 |
1296 |
1228 if (Gear^.Elasticity > Gear^.Friction) |
1297 if (Gear^.Elasticity > Gear^.Friction) |
1229 or ((Gear^.Message and gm_Attack) = 0) |
1298 or ((Gear^.Message and gm_Attack) = 0) |
1230 or ((HHGear^.State and gstHHDriven) = 0) |
1299 or ((HHGear^.State and gstHHDriven) = 0) |
1231 or (HHGear^.Damage > 0) then |
1300 or (HHGear^.Damage > 0) then |
1232 begin |
1301 begin |
1233 with PHedgehog(Gear^.Hedgehog)^.Gear^ do |
1302 with PHedgehog(Gear^.Hedgehog)^.Gear^ do |
1234 begin |
1303 begin |
1235 State:= State and not gstAttacking; |
1304 State := State and not gstAttacking; |
1236 Message:= Message and not gm_Attack |
1305 Message := Message and not gm_Attack |
1237 end; |
1306 end; |
1238 DeleteGear(Gear) |
1307 DeleteGear(Gear) |
1239 end |
1308 end |
1240 end; |
1309 end; |
1241 |
1310 |
1242 procedure doStepRope(Gear: PGear); |
1311 procedure doStepRope(Gear: PGear); |
1243 begin |
1312 begin |
1244 Gear^.dX:= - Gear^.dX; |
1313 Gear^.dX := - Gear^.dX; |
1245 Gear^.dY:= - Gear^.dY; |
1314 Gear^.dY := - Gear^.dY; |
1246 Gear^.doStep:= @doStepRopeAttach; |
1315 Gear^.doStep := @doStepRopeAttach; |
1247 PlaySound(sndRopeShot) |
1316 PlaySound(sndRopeShot) |
1248 end; |
1317 end; |
1249 |
1318 |
1250 //////////////////////////////////////////////////////////////////////////////// |
1319 //////////////////////////////////////////////////////////////////////////////// |
1251 procedure doStepMine(Gear: PGear); |
1320 procedure doStepMine(Gear: PGear); |
1252 begin |
1321 begin |
1253 if (Gear^.State and gstMoving) <> 0 then |
1322 if (Gear^.State and gstMoving) <> 0 then |
1254 begin |
1323 begin |
1255 DeleteCI(Gear); |
1324 DeleteCI(Gear); |
1256 doStepFallingGear(Gear); |
|
1257 if (Gear^.State and gstMoving) = 0 then |
|
1258 begin |
|
1259 AddGearCI(Gear); |
|
1260 Gear^.dX:= _0; |
|
1261 Gear^.dY:= _0 |
|
1262 end; |
|
1263 CalcRotationDirAngle(Gear); |
|
1264 AllInactive:= false |
|
1265 end else |
|
1266 if ((GameTicks and $3F) = 25) then |
|
1267 doStepFallingGear(Gear); |
1325 doStepFallingGear(Gear); |
1268 |
1326 if (Gear^.State and gstMoving) = 0 then |
1269 if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then |
1327 begin |
1270 if ((Gear^.State and gstAttacking) = 0) then |
1328 AddGearCI(Gear); |
1271 begin |
1329 Gear^.dX := _0; |
1272 if ((GameTicks and $1F) = 0) then |
1330 Gear^.dY := _0 |
1273 if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State:= Gear^.State or gstAttacking |
1331 end; |
1274 end else // gstAttacking <> 0 |
1332 CalcRotationDirAngle(Gear); |
1275 begin |
1333 AllInactive := false |
1276 AllInactive:= false; |
1334 end |
|
1335 else |
|
1336 if ((GameTicks and $3F) = 25) then |
|
1337 doStepFallingGear(Gear); |
|
1338 |
|
1339 if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then |
|
1340 if ((Gear^.State and gstAttacking) = 0) then |
|
1341 begin |
|
1342 if ((GameTicks and $1F) = 0) then |
|
1343 if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State := Gear^.State or |
|
1344 gstAttacking |
|
1345 end |
|
1346 else // gstAttacking <> 0 |
|
1347 begin |
|
1348 AllInactive := false; |
1277 if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick); |
1349 if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick); |
1278 if Gear^.Timer = 0 then |
1350 if Gear^.Timer = 0 then |
1279 begin |
1351 begin |
1280 if ((Gear^.State and gstWait) <> 0) or |
1352 if ((Gear^.State and gstWait) <> 0) or |
1281 (cMineDudPercent = 0) or |
1353 (cMineDudPercent = 0) or |
1282 (getRandom(100) > cMineDudPercent) then |
1354 (getRandom(100) > cMineDudPercent) then |
1283 begin |
1355 begin |
1284 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
1356 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
1285 DeleteGear(Gear) |
1357 DeleteGear(Gear) |
1286 end |
1358 end |
1287 else |
1359 else |
1288 begin |
1360 begin |
1289 AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke); |
1361 AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), |
1290 PlaySound(sndVaporize); |
1362 vgtSmoke); |
1291 Gear^.Health:= 0; |
1363 PlaySound(sndVaporize); |
1292 end; |
1364 Gear^.Health := 0; |
|
1365 end; |
1293 exit |
1366 exit |
1294 end; |
1367 end; |
1295 dec(Gear^.Timer); |
1368 dec(Gear^.Timer); |
1296 end else // gsttmpFlag = 0 |
1369 end |
1297 if TurnTimeLeft = 0 then Gear^.State:= Gear^.State or gsttmpFlag; |
1370 else // gsttmpFlag = 0 |
|
1371 if TurnTimeLeft = 0 then Gear^.State := Gear^.State or gsttmpFlag; |
1298 end; |
1372 end; |
1299 |
1373 |
1300 //////////////////////////////////////////////////////////////////////////////// |
1374 //////////////////////////////////////////////////////////////////////////////// |
1301 procedure doStepDynamite(Gear: PGear); |
1375 procedure doStepDynamite(Gear: PGear); |
1302 begin |
1376 begin |
1303 doStepFallingGear(Gear); |
1377 doStepFallingGear(Gear); |
1304 AllInactive:= false; |
1378 AllInactive := false; |
1305 if Gear^.Timer mod 166 = 0 then inc(Gear^.Tag); |
1379 if Gear^.Timer mod 166 = 0 then inc(Gear^.Tag); |
1306 if Gear^.Timer = 1000 then // might need better timing |
1380 if Gear^.Timer = 1000 then // might need better timing |
1307 makeHogsWorry(Gear^.X, Gear^.Y, 75); |
1381 makeHogsWorry(Gear^.X, Gear^.Y, 75); |
1308 if Gear^.Timer = 0 then |
1382 if Gear^.Timer = 0 then |
1309 begin |
1383 begin |
1310 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound); |
1384 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound); |
1311 DeleteGear(Gear); |
1385 DeleteGear(Gear); |
1312 exit |
1386 exit |
1313 end; |
1387 end; |
1314 dec(Gear^.Timer); |
1388 dec(Gear^.Timer); |
1315 end; |
1389 end; |
1316 |
1390 |
1317 /////////////////////////////////////////////////////////////////////////////// |
1391 /////////////////////////////////////////////////////////////////////////////// |
1318 |
1392 |
1319 (* |
1393 (* |
1320 TODO |
1394 TODO |
1321 Increase damage as barrel smokes? |
1395 Increase damage as barrel smokes? |
1322 Try tweaking friction some more |
1396 Try tweaking friction some more |
1323 *) |
1397 *) |
1324 procedure doStepRollingBarrel(Gear: PGear); |
1398 procedure doStepRollingBarrel(Gear: PGear); |
1325 var i: LongInt; |
1399 var |
|
1400 i: LongInt; |
1326 particle: PVisualGear; |
1401 particle: PVisualGear; |
1327 begin |
1402 begin |
1328 Gear^.State:= Gear^.State or gstAnimation; |
1403 Gear^.State := Gear^.State or gstAnimation; |
1329 if ((Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0)) then |
1404 if ((Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0)) then |
1330 begin |
1405 begin |
1331 DeleteCI(Gear); |
1406 DeleteCI(Gear); |
1332 AllInactive:= false; |
1407 AllInactive := false; |
1333 if not Gear^.dY.isNegative and (Gear^.dY > _0_03) and TestCollisionYwithGear(Gear, 1) then |
1408 if not Gear^.dY.isNegative and (Gear^.dY > _0_03) and TestCollisionYwithGear(Gear, 1) then |
1334 begin |
1409 begin |
1335 Gear^.State:= Gear^.State or gsttmpFlag; |
1410 Gear^.State := Gear^.State or gsttmpFlag; |
1336 inc(Gear^.Damage, hwRound(Gear^.dY * _50)); |
1411 inc(Gear^.Damage, hwRound(Gear^.dY * _50)); |
1337 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
1412 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
1338 begin |
1413 begin |
1339 particle:= AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
1414 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, |
1340 if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX / 5) |
1415 vgtDust); |
|
1416 if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX / 5) |
1341 end |
1417 end |
1342 end |
1418 end |
1343 else if not Gear^.dX.isNegative and (Gear^.dX > _0_03) and TestCollisionXwithGear(Gear, 1) then |
1419 else if not Gear^.dX.isNegative and (Gear^.dX > _0_03) and TestCollisionXwithGear(Gear, 1) |
1344 inc(Gear^.Damage, hwRound(Gear^.dX * _50)) |
1420 then |
1345 else if Gear^.dY.isNegative and (Gear^.dY < -_0_03) and TestCollisionYwithGear(Gear, -1) then |
1421 inc(Gear^.Damage, hwRound(Gear^.dX * _50)) |
1346 inc(Gear^.Damage, hwRound(Gear^.dY * -_50)) |
1422 else if Gear^.dY.isNegative and (Gear^.dY < -_0_03) and TestCollisionYwithGear(Gear, -1) |
1347 else if Gear^.dX.isNegative and (Gear^.dX < -_0_03) and TestCollisionXwithGear(Gear, -1) then |
1423 then |
1348 inc(Gear^.Damage, hwRound(Gear^.dX * -_50)); |
1424 inc(Gear^.Damage, hwRound(Gear^.dY * -_50)) |
1349 |
1425 else if Gear^.dX.isNegative and (Gear^.dX < -_0_03) and TestCollisionXwithGear(Gear, -1) |
1350 doStepFallingGear(Gear); |
1426 then |
1351 CalcRotationDirAngle(Gear); |
1427 inc(Gear^.Damage, hwRound(Gear^.dX * -_50)); |
1352 //CheckGearDrowning(Gear) |
1428 |
1353 end |
1429 doStepFallingGear(Gear); |
1354 else |
1430 CalcRotationDirAngle(Gear); |
1355 begin |
1431 //CheckGearDrowning(Gear) |
1356 Gear^.State:= Gear^.State or gsttmpFlag; |
1432 end |
1357 AddGearCI(Gear) |
1433 else |
1358 end; |
1434 begin |
|
1435 Gear^.State := Gear^.State or gsttmpFlag; |
|
1436 AddGearCI(Gear) |
|
1437 end; |
|
1438 |
1359 (* |
1439 (* |
1360 Attempt to make a barrel knock itself over an edge. Would need more checks to avoid issues like burn damage |
1440 Attempt to make a barrel knock itself over an edge. Would need more checks to avoid issues like burn damage |
1361 begin |
1441 begin |
1362 x:= hwRound(Gear^.X); |
1442 x:= hwRound(Gear^.X); |
1363 y:= hwRound(Gear^.Y); |
1443 y:= hwRound(Gear^.Y); |
1370 Gear^.dX:= _0_08; |
1450 Gear^.dX:= _0_08; |
1371 end; |
1451 end; |
1372 if Gear^.dX.QWordValue = 0 then AddGearCI(Gear) |
1452 if Gear^.dX.QWordValue = 0 then AddGearCI(Gear) |
1373 end; *) |
1453 end; *) |
1374 |
1454 |
1375 if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and TestCollisionYwithGear(Gear, 1) then Gear^.dY:= _0; |
1455 if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and TestCollisionYwithGear(Gear, 1) then Gear |
1376 if hwAbs(Gear^.dX) < _0_001 then Gear^.dX:= _0; |
1456 ^.dY := _0; |
1377 |
1457 if hwAbs(Gear^.dX) < _0_001 then Gear^.dX := _0; |
1378 if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
1458 |
1379 if (cBarrelHealth div Gear^.Health) > 2 then |
1459 if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
1380 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
1460 if (cBarrelHealth div Gear^.Health) > 2 then |
|
1461 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
1381 else |
1462 else |
1382 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
1463 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
1383 dec(Gear^.Health, Gear^.Damage); |
1464 dec(Gear^.Health, Gear^.Damage); |
1384 Gear^.Damage:= 0; |
1465 Gear^.Damage := 0; |
1385 if Gear^.Health <= 0 then Gear^.doStep:= @doStepCase; // Hand off to doStepCase for the explosion |
1466 if Gear^.Health <= 0 then Gear^.doStep := @doStepCase; |
|
1467 // Hand off to doStepCase for the explosion |
1386 |
1468 |
1387 end; |
1469 end; |
1388 |
1470 |
1389 procedure doStepCase(Gear: PGear); |
1471 procedure doStepCase(Gear: PGear); |
1390 var i, x, y: LongInt; |
1472 var |
|
1473 i, x, y: LongInt; |
1391 k: TGearType; |
1474 k: TGearType; |
1392 exBoom: boolean; |
1475 exBoom: boolean; |
1393 dX, dY: HWFloat; |
1476 dX, dY: HWFloat; |
1394 begin |
1477 begin |
1395 k:= Gear^.Kind; |
1478 k := Gear^.Kind; |
1396 exBoom:= false; |
1479 exBoom := false; |
1397 |
1480 |
1398 if (Gear^.Message and gm_Destroy) > 0 then |
1481 if (Gear^.Message and gm_Destroy) > 0 then |
1399 begin |
1482 begin |
1400 DeleteGear(Gear); |
1483 DeleteGear(Gear); |
1401 FreeActionsList; |
1484 FreeActionsList; |
1402 SetAllToActive; // something (hh, mine, etc...) could be on top of the case |
1485 SetAllToActive; |
1403 with CurrentHedgehog^ do |
1486 // something (hh, mine, etc...) could be on top of the case |
1404 if Gear <> nil then Gear^.Message:= Gear^.Message and not (gm_LJump or gm_HJump); |
1487 with CurrentHedgehog^ do |
1405 exit |
1488 if Gear <> nil then Gear^.Message := Gear^.Message and not (gm_LJump or gm_HJump); |
1406 end; |
1489 exit |
1407 |
1490 end; |
1408 if k = gtExplosives then |
1491 |
1409 begin |
1492 if k = gtExplosives then |
1410 //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation; |
1493 begin |
1411 if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then Gear^.doStep:= @doStepRollingBarrel; |
1494 //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation; |
1412 |
1495 if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) |
1413 if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
1496 then Gear^.doStep := @doStepRollingBarrel; |
1414 if (cBarrelHealth div Gear^.Health) > 2 then |
1497 |
1415 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
1498 if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
|
1499 if (cBarrelHealth div Gear^.Health) > 2 then |
|
1500 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
1416 else |
1501 else |
1417 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
1502 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
1418 dec(Gear^.Health, Gear^.Damage); |
1503 dec(Gear^.Health, Gear^.Damage); |
1419 Gear^.Damage:= 0; |
1504 Gear^.Damage := 0; |
1420 if Gear^.Health <= 0 then |
1505 if Gear^.Health <= 0 then |
1421 exBoom:= true; |
1506 exBoom := true; |
1422 end; |
1507 end; |
1423 |
1508 |
1424 if (Gear^.Damage > 0) or exBoom then |
1509 if (Gear^.Damage > 0) or exBoom then |
1425 begin |
1510 begin |
1426 x:= hwRound(Gear^.X); |
1511 x := hwRound(Gear^.X); |
1427 y:= hwRound(Gear^.Y); |
1512 y := hwRound(Gear^.Y); |
1428 DeleteGear(Gear); // <-- delete gear! |
1513 DeleteGear(Gear); |
1429 |
1514 // <-- delete gear! |
1430 if k = gtCase then |
1515 |
1431 begin |
1516 if k = gtCase then |
1432 doMakeExplosion(x, y, 25, EXPLAutoSound); |
1517 begin |
1433 for i:= 0 to 63 do |
1518 doMakeExplosion(x, y, 25, EXPLAutoSound); |
1434 AddGear(x, y, gtFlame, 0, _0, _0, 0); |
1519 for i:= 0 to 63 do |
|
1520 AddGear(x, y, gtFlame, 0, _0, _0, 0); |
1435 end |
1521 end |
1436 else if k = gtExplosives then |
1522 else if k = gtExplosives then |
1437 begin |
|
1438 doMakeExplosion(x, y, 75, EXPLAutoSound); |
|
1439 for i:= 0 to 31 do |
|
1440 begin |
1523 begin |
1441 dX:= AngleCos(i * 64) * _0_5 * (getrandom + _1); |
1524 doMakeExplosion(x, y, 75, EXPLAutoSound); |
1442 dY:= AngleSin(i * 64) * _0_5 * (getrandom + _1); |
1525 for i:= 0 to 31 do |
1443 AddGear(x, y, gtFlame, 0, dX, dY, 0); |
1526 begin |
1444 AddGear(x, y, gtFlame, 0, -dX, -dY, 0)^.State:= gsttmpFlag; |
1527 dX := AngleCos(i * 64) * _0_5 * (getrandom + _1); |
|
1528 dY := AngleSin(i * 64) * _0_5 * (getrandom + _1); |
|
1529 AddGear(x, y, gtFlame, 0, dX, dY, 0); |
|
1530 AddGear(x, y, gtFlame, 0, -dX, -dY, 0)^.State := gsttmpFlag; |
|
1531 end |
|
1532 end; |
|
1533 exit |
|
1534 end; |
|
1535 |
|
1536 if (Gear^.dY.QWordValue <> 0) or (not TestCollisionYwithGear(Gear, 1)) then |
|
1537 begin |
|
1538 AllInactive := false; |
|
1539 Gear^.dY := Gear^.dY + cGravity; |
|
1540 Gear^.Y := Gear^.Y + Gear^.dY; |
|
1541 if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then SetAllHHToActive; |
|
1542 if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, -1) then Gear^.dY := _0; |
|
1543 if (not Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, 1) then |
|
1544 begin |
|
1545 if (Gear^.dY > _0_02) and (k = gtExplosives) then |
|
1546 inc(Gear^.Damage, hwRound(Gear^.dY * _40)); |
|
1547 |
|
1548 if Gear^.dY > _0_2 then |
|
1549 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
|
1550 AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust) |
|
1551 ; |
|
1552 Gear^.dY := - Gear^.dY * Gear^.Elasticity; |
|
1553 if Gear^.dY > - _0_001 then Gear^.dY := _0 |
|
1554 else if Gear^.dY < - _0_03 then |
|
1555 PlaySound(Gear^.ImpactSound); |
|
1556 end; |
|
1557 //if Gear^.dY > - _0_001 then Gear^.dY:= _0 |
|
1558 CheckGearDrowning(Gear); |
|
1559 end; |
|
1560 |
|
1561 if (Gear^.dY.QWordValue = 0) then AddGearCI(Gear) |
|
1562 else if (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear) |
|
1563 end; |
|
1564 |
|
1565 //////////////////////////////////////////////////////////////////////////////// |
|
1566 |
|
1567 procedure doStepTarget(Gear: PGear); |
|
1568 begin |
|
1569 if (Gear^.Timer = 0) and (Gear^.Tag = 0) then |
|
1570 PlaySound(sndWarp); |
|
1571 |
|
1572 if (Gear^.Tag = 0) and (Gear^.Timer < 1000) then |
|
1573 inc(Gear^.Timer) |
|
1574 else if Gear^.Tag = 1 then |
|
1575 begin |
|
1576 Gear^.Tag := 2; |
|
1577 if (TrainingFlags and tfTimeTrial) <> 0 then |
|
1578 begin |
|
1579 inc(TurnTimeLeft, TrainingTimeInc); |
|
1580 |
|
1581 if TrainingTimeInc > TrainingTimeInM then |
|
1582 dec(TrainingTimeInc, TrainingTimeInD); |
|
1583 if TurnTimeLeft > TrainingTimeMax then |
|
1584 TurnTimeLeft := TrainingTimeMax; |
|
1585 end; |
|
1586 end |
|
1587 else if Gear^.Tag = 2 then |
|
1588 if Gear^.Timer > 0 then |
|
1589 dec(Gear^.Timer) |
|
1590 else |
|
1591 begin |
|
1592 if (TrainingFlags and tfTargetRespawn) <> 0 then |
|
1593 begin |
|
1594 TrainingTargetGear := AddGear(0, 0, gtTarget, 0, _0, _0, 0); |
|
1595 FindPlace(TrainingTargetGear, false, 0, LAND_WIDTH); |
|
1596 end; |
|
1597 DeleteGear(Gear); |
|
1598 exit; |
|
1599 end; |
|
1600 |
|
1601 doStepCase(Gear) |
|
1602 end; |
|
1603 |
|
1604 //////////////////////////////////////////////////////////////////////////////// |
|
1605 procedure doStepIdle(Gear: PGear); |
|
1606 begin |
|
1607 AllInactive := false; |
|
1608 dec(Gear^.Timer); |
|
1609 if Gear^.Timer = 0 then |
|
1610 begin |
|
1611 DeleteGear(Gear); |
|
1612 AfterAttack |
|
1613 end |
|
1614 end; |
|
1615 |
|
1616 procedure doStepShover(Gear: PGear); |
|
1617 var |
|
1618 HHGear: PGear; |
|
1619 begin |
|
1620 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1621 HHGear^.State := HHGear^.State or gstNoDamage; |
|
1622 DeleteCI(HHGear); |
|
1623 |
|
1624 AmmoShove(Gear, 30, 115); |
|
1625 |
|
1626 HHGear^.State := HHGear^.State and not gstNoDamage; |
|
1627 Gear^.Timer := 250; |
|
1628 Gear^.doStep := @doStepIdle |
|
1629 end; |
|
1630 |
|
1631 //////////////////////////////////////////////////////////////////////////////// |
|
1632 procedure doStepWhip(Gear: PGear); |
|
1633 var |
|
1634 HHGear: PGear; |
|
1635 i: LongInt; |
|
1636 begin |
|
1637 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1638 HHGear^.State := HHGear^.State or gstNoDamage; |
|
1639 DeleteCI(HHGear); |
|
1640 |
|
1641 for i:= 0 to 3 do |
|
1642 begin |
|
1643 AmmoShove(Gear, 30, 25); |
|
1644 Gear^.X := Gear^.X + Gear^.dX * 5 |
|
1645 end; |
|
1646 |
|
1647 HHGear^.State := HHGear^.State and not gstNoDamage; |
|
1648 Gear^.Timer := 250; |
|
1649 Gear^.doStep := @doStepIdle |
|
1650 end; |
|
1651 |
|
1652 //////////////////////////////////////////////////////////////////////////////// |
|
1653 procedure doStepFlame(Gear: PGear); |
|
1654 var |
|
1655 gX,gY,i: LongInt; |
|
1656 begin |
|
1657 if (Gear^.State and gsttmpFlag) = 0 then AllInactive := false; |
|
1658 |
|
1659 if not TestCollisionYwithGear(Gear, 1) then |
|
1660 begin |
|
1661 AllInactive := false; |
|
1662 if Gear^.dX.QWordValue > _0_01.QWordValue then |
|
1663 Gear^.dX := Gear^.dX * _0_995; |
|
1664 Gear^.dY := Gear^.dY + cGravity; |
|
1665 if (Gear^.State and gsttmpFlag) <> 0 then Gear^.dY := Gear^.dY + cGravity; |
|
1666 if Gear^.dY.QWordValue > _0_2.QWordValue then Gear^.dY := Gear^.dY * _0_995; |
|
1667 |
|
1668 if (Gear^.State and gsttmpFlag) <> 0 then Gear^.X := Gear^.X + Gear^.dX |
|
1669 else |
|
1670 Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640; |
|
1671 Gear^.Y := Gear^.Y + Gear^.dY; |
|
1672 |
|
1673 if (hwRound(Gear^.Y) > cWaterLine) then |
|
1674 begin |
|
1675 gX := hwRound(Gear^.X); |
|
1676 for i:= 0 to 3 do |
|
1677 AddVisualGear(gX - 16 + Random(32), cWaterLine - 16 + Random(16), vgtSteam); |
|
1678 PlaySound(sndVaporize); |
|
1679 DeleteGear(Gear); |
|
1680 exit |
|
1681 end |
|
1682 end |
|
1683 else |
|
1684 begin |
|
1685 if (Gear^.State and gsttmpFlag) <> 0 then |
|
1686 begin |
|
1687 Gear^.Radius := 9; |
|
1688 AmmoShove(Gear, 2, 30); |
|
1689 Gear^.Radius := 1 |
|
1690 end; |
|
1691 if Gear^.Timer > 0 then |
|
1692 begin |
|
1693 dec(Gear^.Timer); |
|
1694 inc(Gear^.Damage) |
|
1695 end |
|
1696 else |
|
1697 begin |
|
1698 // Standard fire |
|
1699 if (Gear^.State and gsttmpFlag) = 0 then |
|
1700 begin |
|
1701 Gear^.Radius := 9; |
|
1702 AmmoShove(Gear, 4, 100); |
|
1703 gX := hwRound(Gear^.X); |
|
1704 gY := hwRound(Gear^.Y); |
|
1705 Gear^.Radius := 1; |
|
1706 doMakeExplosion(gX, gY, 4, EXPLNoDamage); |
|
1707 if ((GameTicks and $7) = 0) and (Random(2) = 0) then |
|
1708 for i:= 1 to Random(2)+1 do |
|
1709 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
|
1710 if Gear^.Health > 0 then dec(Gear^.Health); |
|
1711 Gear^.Timer := 450 - Gear^.Tag * 8 |
1445 end |
1712 end |
1446 end; |
1713 else |
1447 exit |
|
1448 end; |
|
1449 |
|
1450 if (Gear^.dY.QWordValue <> 0) or (not TestCollisionYwithGear(Gear, 1)) then |
|
1451 begin |
|
1452 AllInactive:= false; |
|
1453 Gear^.dY:= Gear^.dY + cGravity; |
|
1454 Gear^.Y:= Gear^.Y + Gear^.dY; |
|
1455 if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then SetAllHHToActive; |
|
1456 if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, -1) then Gear^.dY:= _0; |
|
1457 if (not Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, 1) then |
|
1458 begin |
|
1459 if (Gear^.dY > _0_02) and (k = gtExplosives) then |
|
1460 inc(Gear^.Damage, hwRound(Gear^.dY * _40)); |
|
1461 |
|
1462 if Gear^.dY > _0_2 then |
|
1463 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
|
1464 AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
|
1465 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
|
1466 if Gear^.dY > - _0_001 then Gear^.dY:= _0 |
|
1467 else if Gear^.dY < - _0_03 then |
|
1468 PlaySound(Gear^.ImpactSound); |
|
1469 end; |
|
1470 //if Gear^.dY > - _0_001 then Gear^.dY:= _0 |
|
1471 CheckGearDrowning(Gear); |
|
1472 end; |
|
1473 |
|
1474 if (Gear^.dY.QWordValue = 0) then AddGearCI(Gear) |
|
1475 else if (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear) |
|
1476 end; |
|
1477 |
|
1478 //////////////////////////////////////////////////////////////////////////////// |
|
1479 |
|
1480 procedure doStepTarget(Gear: PGear); |
|
1481 begin |
|
1482 if (Gear^.Timer = 0) and (Gear^.Tag = 0) then |
|
1483 PlaySound(sndWarp); |
|
1484 |
|
1485 if (Gear^.Tag = 0) and (Gear^.Timer < 1000) then |
|
1486 inc(Gear^.Timer) |
|
1487 else if Gear^.Tag = 1 then |
|
1488 begin |
|
1489 Gear^.Tag:= 2; |
|
1490 if (TrainingFlags and tfTimeTrial) <> 0 then |
|
1491 begin |
1714 begin |
1492 inc(TurnTimeLeft, TrainingTimeInc); |
1715 // Modified fire |
1493 |
1716 if ((GameTicks and $7FF) = 0) and ((GameFlags and gfSolidLand) = 0) then |
1494 if TrainingTimeInc > TrainingTimeInM then |
1717 begin |
1495 dec(TrainingTimeInc, TrainingTimeInD); |
1718 DrawExplosion(gX, gY, 4); |
1496 if TurnTimeLeft > TrainingTimeMax then |
1719 |
1497 TurnTimeLeft:= TrainingTimeMax; |
1720 for i:= 0 to Random(3) do |
|
1721 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
|
1722 end; |
|
1723 |
|
1724 // 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. |
|
1725 Gear^.Timer := 100 - Gear^.Tag * 3; |
|
1726 if (Gear^.Damage > 3000+Gear^.Tag*1500) then Gear^.Health := 0 |
|
1727 end |
|
1728 end |
|
1729 end; |
|
1730 if Gear^.Health = 0 then |
|
1731 begin |
|
1732 gX := hwRound(Gear^.X); |
|
1733 gY := hwRound(Gear^.Y); |
|
1734 if (Gear^.State and gsttmpFlag) = 0 then |
|
1735 begin |
|
1736 if ((GameTicks and $3) = 0) and (Random(1) = 0) then |
|
1737 begin |
|
1738 for i:= 1 to Random(2)+1 do |
|
1739 begin |
|
1740 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
|
1741 end; |
1498 end; |
1742 end; |
1499 end |
1743 end |
1500 else if Gear^.Tag = 2 then |
1744 else |
1501 if Gear^.Timer > 0 then |
1745 begin |
1502 dec(Gear^.Timer) |
1746 for i:= 0 to Random(3) do |
|
1747 begin |
|
1748 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
|
1749 end; |
|
1750 end; |
|
1751 |
|
1752 DeleteGear(Gear) |
|
1753 end; |
|
1754 end; |
|
1755 |
|
1756 //////////////////////////////////////////////////////////////////////////////// |
|
1757 procedure doStepFirePunchWork(Gear: PGear); |
|
1758 var |
|
1759 HHGear: PGear; |
|
1760 begin |
|
1761 AllInactive := false; |
|
1762 if ((Gear^.Message and gm_Destroy) <> 0) then |
|
1763 begin |
|
1764 DeleteGear(Gear); |
|
1765 AfterAttack; |
|
1766 exit |
|
1767 end; |
|
1768 |
|
1769 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1770 if hwRound(HHGear^.Y) <= Gear^.Tag - 2 then |
|
1771 begin |
|
1772 Gear^.Tag := hwRound(HHGear^.Y); |
|
1773 DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4, 2); |
|
1774 HHGear^.State := HHGear^.State or gstNoDamage; |
|
1775 Gear^.Y := HHGear^.Y; |
|
1776 AmmoShove(Gear, 30, 40); |
|
1777 HHGear^.State := HHGear^.State and not gstNoDamage |
|
1778 end; |
|
1779 |
|
1780 HHGear^.dY := HHGear^.dY + cGravity; |
|
1781 if not (HHGear^.dY.isNegative) then |
|
1782 begin |
|
1783 HHGear^.State := HHGear^.State or gstMoving; |
|
1784 DeleteGear(Gear); |
|
1785 AfterAttack; |
|
1786 exit |
|
1787 end; |
|
1788 |
|
1789 if CheckLandValue(hwRound(HHGear^.X), hwRound(HHGear^.Y + HHGear^.dY + SignAs(_6,Gear^.dY)), |
|
1790 COLOR_INDESTRUCTIBLE) then |
|
1791 HHGear^.Y := HHGear^.Y + HHGear^.dY |
|
1792 end; |
|
1793 |
|
1794 procedure doStepFirePunch(Gear: PGear); |
|
1795 var |
|
1796 HHGear: PGear; |
|
1797 begin |
|
1798 AllInactive := false; |
|
1799 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1800 DeleteCI(HHGear); |
|
1801 HHGear^.X := int2hwFloat(hwRound(HHGear^.X)) - _0_5; |
|
1802 HHGear^.dX := SignAs(cLittle, Gear^.dX); |
|
1803 |
|
1804 HHGear^.dY := - _0_3; |
|
1805 |
|
1806 Gear^.X := HHGear^.X; |
|
1807 Gear^.dX := SignAs(_0_45, Gear^.dX); |
|
1808 Gear^.dY := - _0_9; |
|
1809 Gear^.doStep := @doStepFirePunchWork; |
|
1810 DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y + _1, _0_5, _0, cHHRadius * 4, 5); |
|
1811 |
|
1812 PlaySound(TSound(ord(sndFirePunch1) + GetRandom(6)), PHedgehog(HHGear^.Hedgehog)^.Team^. |
|
1813 voicepack) |
|
1814 end; |
|
1815 |
|
1816 //////////////////////////////////////////////////////////////////////////////// |
|
1817 |
|
1818 procedure doStepParachuteWork(Gear: PGear); |
|
1819 var |
|
1820 HHGear: PGear; |
|
1821 begin |
|
1822 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1823 |
|
1824 inc(Gear^.Timer); |
|
1825 |
|
1826 if TestCollisionYwithGear(HHGear, 1) |
|
1827 or ((HHGear^.State and gstHHDriven) = 0) |
|
1828 or CheckGearDrowning(HHGear) |
|
1829 or ((Gear^.Message and gm_Attack) <> 0) then |
|
1830 begin |
|
1831 with HHGear^ do |
|
1832 begin |
|
1833 Message := 0; |
|
1834 SetLittle(dX); |
|
1835 dY := _0; |
|
1836 State := State or gstMoving; |
|
1837 end; |
|
1838 DeleteGear(Gear); |
|
1839 isCursorVisible := false; |
|
1840 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
|
1841 exit |
|
1842 end; |
|
1843 |
|
1844 if not TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
|
1845 HHGear^.X := HHGear^.X + cWindSpeed * 200; |
|
1846 |
|
1847 if (Gear^.Message and gm_Left) <> 0 then HHGear^.X := HHGear^.X - cMaxWindSpeed * 80 |
|
1848 else if (Gear^.Message and gm_Right) <> 0 then HHGear^.X := HHGear^.X + cMaxWindSpeed * 80; |
|
1849 if (Gear^.Message and gm_Up) <> 0 then HHGear^.Y := HHGear^.Y - cGravity * 40 |
|
1850 else if (Gear^.Message and gm_Down) <> 0 then HHGear^.Y := HHGear^.Y + cGravity * 40; |
|
1851 |
|
1852 HHGear^.Y := HHGear^.Y + cGravity * 100; |
|
1853 Gear^.X := HHGear^.X; |
|
1854 Gear^.Y := HHGear^.Y |
|
1855 end; |
|
1856 |
|
1857 procedure doStepParachute(Gear: PGear); |
|
1858 var |
|
1859 HHGear: PGear; |
|
1860 begin |
|
1861 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1862 |
|
1863 DeleteCI(HHGear); |
|
1864 |
|
1865 AfterAttack; |
|
1866 |
|
1867 HHGear^.State := HHGear^.State and not (gstAttacking or gstAttacked or gstMoving); |
|
1868 HHGear^.Message := HHGear^.Message and not gm_Attack; |
|
1869 |
|
1870 Gear^.doStep := @doStepParachuteWork; |
|
1871 |
|
1872 Gear^.Message := HHGear^.Message; |
|
1873 doStepParachuteWork(Gear) |
|
1874 end; |
|
1875 |
|
1876 //////////////////////////////////////////////////////////////////////////////// |
|
1877 procedure doStepAirAttackWork(Gear: PGear); |
|
1878 var |
|
1879 i: Longint; |
|
1880 begin |
|
1881 AllInactive := false; |
|
1882 Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag; |
|
1883 |
|
1884 if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then |
|
1885 begin |
|
1886 dec(Gear^.Health); |
|
1887 case Gear^.State of |
|
1888 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * |
|
1889 Gear^.Tag, _0, 0); |
|
1890 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * |
|
1891 Gear^.Tag, _0, 0); |
|
1892 2: for i:= -19 to 19 do |
|
1893 FollowGear := AddGear(hwRound(Gear^.X) + i div 3, hwRound(Gear^.Y), gtFlame, 0, |
|
1894 _0_001 * i, _0, 0); |
|
1895 end; |
|
1896 Gear^.dX := Gear^.dX + int2hwFloat(30 * Gear^.Tag) |
|
1897 end; |
|
1898 |
|
1899 if (GameTicks and $3F) = 0 then |
|
1900 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
|
1901 |
|
1902 if (hwRound(Gear^.X) > (LAND_WIDTH+1024)) or (hwRound(Gear^.X) < -1024) then DeleteGear(Gear) |
|
1903 end; |
|
1904 |
|
1905 procedure doStepAirAttack(Gear: PGear); |
|
1906 begin |
|
1907 AllInactive := false; |
|
1908 |
|
1909 if Gear^.X.QWordValue = 0 then |
|
1910 begin |
|
1911 Gear^.Tag := 1; |
|
1912 Gear^.X := -_1024; |
|
1913 end |
1503 else |
1914 else |
1504 begin |
1915 begin |
1505 if (TrainingFlags and tfTargetRespawn) <> 0 then |
1916 Gear^.Tag := -1; |
1506 begin |
1917 Gear^.X := int2hwFloat(LAND_WIDTH + 1024); |
1507 TrainingTargetGear:= AddGear(0, 0, gtTarget, 0, _0, _0, 0); |
1918 end; |
1508 FindPlace(TrainingTargetGear, false, 0, LAND_WIDTH); |
1919 |
1509 end; |
1920 Gear^.Y := int2hwFloat(topY-300); |
|
1921 Gear^.dX := int2hwFloat(TargetPoint.X - 5 * Gear^.Tag * 15); |
|
1922 |
|
1923 if (int2hwFloat(TargetPoint.Y) - Gear^.Y > _0) and (Gear^.State <> 2) then |
|
1924 Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(TargetPoint.Y) - Gear^.Y) * 2 / |
|
1925 cGravity) * Gear^.Tag; |
|
1926 |
|
1927 Gear^.Health := 6; |
|
1928 Gear^.doStep := @doStepAirAttackWork; |
|
1929 end; |
|
1930 |
|
1931 //////////////////////////////////////////////////////////////////////////////// |
|
1932 |
|
1933 procedure doStepAirBomb(Gear: PGear); |
|
1934 begin |
|
1935 AllInactive := false; |
|
1936 doStepFallingGear(Gear); |
|
1937 if (Gear^.State and gstCollision) <> 0 then |
|
1938 begin |
|
1939 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); |
|
1940 DeleteGear(Gear); |
|
1941 exit |
|
1942 end; |
|
1943 if (GameTicks and $3F) = 0 then |
|
1944 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
|
1945 end; |
|
1946 |
|
1947 //////////////////////////////////////////////////////////////////////////////// |
|
1948 |
|
1949 procedure doStepGirder(Gear: PGear); |
|
1950 var |
|
1951 HHGear: PGear; |
|
1952 x, y, tx, ty: hwFloat; |
|
1953 begin |
|
1954 AllInactive := false; |
|
1955 |
|
1956 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1957 tx := int2hwFloat(TargetPoint.X); |
|
1958 ty := int2hwFloat(TargetPoint.Y); |
|
1959 x := HHGear^.X; |
|
1960 y := HHGear^.Y; |
|
1961 |
|
1962 if (Distance(tx - x, ty - y) > _256) or |
|
1963 not TryPlaceOnLand(TargetPoint.X - SpritesData[sprAmGirder].Width div 2, |
|
1964 TargetPoint.Y - SpritesData[sprAmGirder].Height div 2, |
|
1965 sprAmGirder, Gear^.State, true) then |
|
1966 begin |
|
1967 PlaySound(sndDenied); |
|
1968 HHGear^.Message := HHGear^.Message and not gm_Attack; |
|
1969 HHGear^.State := HHGear^.State and not gstAttacking; |
|
1970 HHGear^.State := HHGear^.State or gstHHChooseTarget; |
|
1971 isCursorVisible := true; |
|
1972 DeleteGear(Gear) |
|
1973 end |
|
1974 else |
|
1975 begin |
|
1976 PlaySound(sndPlaced); |
|
1977 DeleteGear(Gear); |
|
1978 AfterAttack; |
|
1979 end; |
|
1980 |
|
1981 HHGear^.State := HHGear^.State and not (gstAttacking or gstAttacked); |
|
1982 HHGear^.Message := HHGear^.Message and not gm_Attack; |
|
1983 TargetPoint.X := NoPointX |
|
1984 end; |
|
1985 |
|
1986 //////////////////////////////////////////////////////////////////////////////// |
|
1987 procedure doStepTeleportAfter(Gear: PGear); |
|
1988 var |
|
1989 HHGear: PGear; |
|
1990 begin |
|
1991 PHedgehog(Gear^.Hedgehog)^.Unplaced := false; |
|
1992 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1993 HHGear^.Y := HHGear^.Y + HHGear^.dY; |
|
1994 // hedgehog falling to collect cases |
|
1995 HHGear^.dY := HHGear^.dY + cGravity; |
|
1996 if TestCollisionYwithGear(HHGear, 1) |
|
1997 or CheckGearDrowning(HHGear) then |
|
1998 begin |
|
1999 DeleteGear(Gear); |
|
2000 AfterAttack |
|
2001 end |
|
2002 end; |
|
2003 |
|
2004 procedure doStepTeleportAnim(Gear: PGear); |
|
2005 begin |
|
2006 inc(Gear^.Timer); |
|
2007 if Gear^.Timer = 65 then |
|
2008 begin |
|
2009 Gear^.Timer := 0; |
|
2010 inc(Gear^.Pos); |
|
2011 if Gear^.Pos = 11 then |
|
2012 Gear^.doStep := @doStepTeleportAfter |
|
2013 end; |
|
2014 end; |
|
2015 |
|
2016 procedure doStepTeleport(Gear: PGear); |
|
2017 var |
|
2018 HHGear: PGear; |
|
2019 begin |
|
2020 AllInactive := false; |
|
2021 |
|
2022 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2023 if not TryPlaceOnLand(TargetPoint.X - SpritesData[sprHHTelepMask].Width div 2, |
|
2024 TargetPoint.Y - SpritesData[sprHHTelepMask].Height div 2, |
|
2025 sprHHTelepMask, 0, false) then |
|
2026 begin |
|
2027 HHGear^.Message := HHGear^.Message and not gm_Attack; |
|
2028 HHGear^.State := HHGear^.State and not gstAttacking; |
|
2029 HHGear^.State := HHGear^.State or gstHHChooseTarget; |
|
2030 DeleteGear(Gear); |
|
2031 isCursorVisible := true; |
|
2032 PlaySound(sndDenied) |
|
2033 end |
|
2034 else |
|
2035 begin |
|
2036 DeleteCI(HHGear); |
|
2037 SetAllHHToActive; |
|
2038 Gear^.doStep := @doStepTeleportAnim; |
|
2039 |
|
2040 // copy old HH position and direction to Gear (because we need them for drawing the vanishing hog) |
|
2041 Gear^.dX := HHGear^.dX; |
|
2042 // retrieve the cursor direction (it was previously copied to X so it doesn't get lost) |
|
2043 HHGear^.dX.isNegative := (Gear^.X.QWordValue <> 0); |
|
2044 Gear^.X := HHGear^.X; |
|
2045 Gear^.Y := HHGear^.Y; |
|
2046 HHGear^.X := int2hwFloat(TargetPoint.X); |
|
2047 HHGear^.Y := int2hwFloat(TargetPoint.Y); |
|
2048 HHGear^.State := HHGear^.State or gstMoving; |
|
2049 playSound(sndWarp) |
|
2050 end; |
|
2051 TargetPoint.X := NoPointX; |
|
2052 end; |
|
2053 |
|
2054 //////////////////////////////////////////////////////////////////////////////// |
|
2055 procedure doStepSwitcherWork(Gear: PGear); |
|
2056 var |
|
2057 HHGear: PGear; |
|
2058 Msg, State: Longword; |
|
2059 begin |
|
2060 AllInactive := false; |
|
2061 |
|
2062 if ((Gear^.Message and not gm_Switch) <> 0) or (TurnTimeLeft = 0) then |
|
2063 begin |
|
2064 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2065 Msg := Gear^.Message and not gm_Switch; |
|
2066 DeleteGear(Gear); |
|
2067 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); |
|
2068 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
|
2069 |
|
2070 HHGear := CurrentHedgehog^.Gear; |
|
2071 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
|
2072 HHGear^.Message := Msg; |
|
2073 exit |
|
2074 end; |
|
2075 |
|
2076 if (Gear^.Message and gm_Switch) <> 0 then |
|
2077 begin |
|
2078 HHGear := CurrentHedgehog^.Gear; |
|
2079 HHGear^.Message := HHGear^.Message and not gm_Switch; |
|
2080 Gear^.Message := Gear^.Message and not gm_Switch; |
|
2081 State := HHGear^.State; |
|
2082 HHGear^.State := 0; |
|
2083 HHGear^.Active := false; |
|
2084 HHGear^.Z := cHHZ; |
|
2085 RemoveGearFromList(HHGear); |
|
2086 InsertGearToList(HHGear); |
|
2087 |
|
2088 PlaySound(sndSwitchHog); |
|
2089 |
|
2090 repeat |
|
2091 CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^. |
|
2092 HedgehogsNumber); |
|
2093 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil); |
|
2094 |
|
2095 CurrentHedgehog := @CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]; |
|
2096 |
|
2097 HHGear := CurrentHedgehog^.Gear; |
|
2098 HHGear^.State := State; |
|
2099 HHGear^.Active := true; |
|
2100 FollowGear := HHGear; |
|
2101 HHGear^.Z := cCurrHHZ; |
|
2102 RemoveGearFromList(HHGear); |
|
2103 InsertGearToList(HHGear); |
|
2104 Gear^.X := HHGear^.X; |
|
2105 Gear^.Y := HHGear^.Y |
|
2106 end; |
|
2107 end; |
|
2108 |
|
2109 procedure doStepSwitcher(Gear: PGear); |
|
2110 var |
|
2111 HHGear: PGear; |
|
2112 begin |
|
2113 Gear^.doStep := @doStepSwitcherWork; |
|
2114 |
|
2115 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2116 with HHGear^ do |
|
2117 begin |
|
2118 State := State and not gstAttacking; |
|
2119 Message := Message and not gm_Attack |
|
2120 end |
|
2121 end; |
|
2122 |
|
2123 //////////////////////////////////////////////////////////////////////////////// |
|
2124 procedure doStepMortar(Gear: PGear); |
|
2125 var |
|
2126 dX, dY: hwFloat; |
|
2127 i: LongInt; |
|
2128 dxn, dyn: boolean; |
|
2129 begin |
|
2130 AllInactive := false; |
|
2131 dxn := Gear^.dX.isNegative; |
|
2132 dyn := Gear^.dY.isNegative; |
|
2133 |
|
2134 doStepFallingGear(Gear); |
|
2135 if (Gear^.State and gstCollision) <> 0 then |
|
2136 begin |
|
2137 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLAutoSound); |
|
2138 |
|
2139 Gear^.dX.isNegative := not dxn; |
|
2140 Gear^.dY.isNegative := not dyn; |
|
2141 for i:= 0 to 4 do |
|
2142 begin |
|
2143 dX := Gear^.dX + (GetRandom - _0_5) * _0_03; |
|
2144 dY := Gear^.dY + (GetRandom - _0_5) * _0_03; |
|
2145 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25); |
|
2146 end; |
|
2147 |
|
2148 DeleteGear(Gear); |
|
2149 exit |
|
2150 end; |
|
2151 |
|
2152 if (GameTicks and $3F) = 0 then |
|
2153 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
|
2154 end; |
|
2155 |
|
2156 //////////////////////////////////////////////////////////////////////////////// |
|
2157 procedure doStepKamikazeWork(Gear: PGear); |
|
2158 |
|
2159 const upd: Longword = 0; |
|
2160 var |
|
2161 i: LongWord; |
|
2162 HHGear: PGear; |
|
2163 begin |
|
2164 AllInactive := false; |
|
2165 |
|
2166 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2167 HHGear^.State := HHGear^.State or gstNoDamage; |
|
2168 DeleteCI(HHGear); |
|
2169 |
|
2170 i := 2; |
|
2171 repeat |
|
2172 Gear^.X := Gear^.X + HHGear^.dX; |
|
2173 Gear^.Y := Gear^.Y + HHGear^.dY; |
|
2174 HHGear^.X := Gear^.X; |
|
2175 HHGear^.Y := Gear^.Y; |
|
2176 |
|
2177 inc(Gear^.Damage, 2); |
|
2178 |
|
2179 // if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) |
|
2180 // or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3); |
|
2181 |
|
2182 dec(i) |
|
2183 until (i = 0) or (Gear^.Damage > Gear^.Health); |
|
2184 |
|
2185 inc(upd); |
|
2186 if upd > 3 then |
|
2187 begin |
|
2188 if Gear^.Health < 1500 then Gear^.Pos := 2; |
|
2189 |
|
2190 AmmoShove(Gear, 30, 40); |
|
2191 |
|
2192 DrawTunnel(HHGear^.X - HHGear^.dX * 10, |
|
2193 HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2, |
|
2194 HHGear^.dX, |
|
2195 HHGear^.dY, |
|
2196 20 + cHHRadius * 2, |
|
2197 cHHRadius * 2 + 6); |
|
2198 |
|
2199 upd := 0 |
|
2200 end; |
|
2201 |
|
2202 if Gear^.Health < Gear^.Damage then |
|
2203 begin |
|
2204 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); |
|
2205 AfterAttack; |
|
2206 DeleteGear(Gear); |
|
2207 DeleteGear(HHGear); |
|
2208 end |
|
2209 else |
|
2210 begin |
|
2211 dec(Gear^.Health, Gear^.Damage); |
|
2212 Gear^.Damage := 0 |
|
2213 end |
|
2214 end; |
|
2215 |
|
2216 procedure doStepKamikazeIdle(Gear: PGear); |
|
2217 begin |
|
2218 AllInactive := false; |
|
2219 dec(Gear^.Timer); |
|
2220 if Gear^.Timer = 0 then |
|
2221 begin |
|
2222 Gear^.Pos := 1; |
|
2223 PlaySound(sndKamikaze, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack); |
|
2224 Gear^.doStep := @doStepKamikazeWork |
|
2225 end |
|
2226 end; |
|
2227 |
|
2228 procedure doStepKamikaze(Gear: PGear); |
|
2229 var |
|
2230 HHGear: PGear; |
|
2231 begin |
|
2232 AllInactive := false; |
|
2233 |
|
2234 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2235 |
|
2236 HHGear^.dX := Gear^.dX; |
|
2237 HHGear^.dY := Gear^.dY; |
|
2238 |
|
2239 Gear^.dX := SignAs(_0_45, Gear^.dX); |
|
2240 Gear^.dY := - _0_9; |
|
2241 |
|
2242 Gear^.Timer := 550; |
|
2243 |
|
2244 Gear^.doStep := @doStepKamikazeIdle |
|
2245 end; |
|
2246 |
|
2247 //////////////////////////////////////////////////////////////////////////////// |
|
2248 |
|
2249 const cakeh = 27; |
|
2250 cakeDmg = 75; |
|
2251 var |
|
2252 CakePoints: array[0..Pred(cakeh)] of record |
|
2253 x, y: hwFloat; |
|
2254 end; |
|
2255 CakeI: Longword; |
|
2256 |
|
2257 procedure doStepCakeExpl(Gear: PGear); |
|
2258 begin |
|
2259 AllInactive := false; |
|
2260 |
|
2261 inc(Gear^.Tag); |
|
2262 if Gear^.Tag < 2250 then exit; |
|
2263 |
|
2264 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg, EXPLAutoSound); |
|
2265 AfterAttack; |
|
2266 DeleteGear(Gear) |
|
2267 end; |
|
2268 |
|
2269 procedure doStepCakeDown(Gear: PGear); |
|
2270 var |
|
2271 gi: PGear; |
|
2272 dmg: LongInt; |
|
2273 begin |
|
2274 AllInactive := false; |
|
2275 |
|
2276 inc(Gear^.Tag); |
|
2277 if Gear^.Tag < 100 then exit; |
|
2278 Gear^.Tag := 0; |
|
2279 |
|
2280 if Gear^.Pos = 0 then |
|
2281 begin |
|
2282 gi := GearsList; |
|
2283 while gi <> nil do |
|
2284 begin |
|
2285 dmg := cakeDmg * 2 - hwRound(Distance(gi^.X - Gear^.X, gi^.Y - Gear^.Y)); |
|
2286 if (dmg > 1) and (gi^.Kind = gtHedgehog) then |
|
2287 if (CurrentHedgehog^.Gear = gi) and (not gi^.Invulnerable) then |
|
2288 gi^.State := gi^.State or gstLoser |
|
2289 else |
|
2290 gi^.State := gi^.State or gstWinner; |
|
2291 gi := gi^.NextGear |
|
2292 end; |
|
2293 Gear^.doStep := @doStepCakeExpl; |
|
2294 PlaySound(sndCake) |
|
2295 end |
|
2296 else dec(Gear^.Pos) |
|
2297 end; |
|
2298 |
|
2299 |
|
2300 procedure doStepCakeWork(Gear: PGear); |
|
2301 |
|
2302 const dirs: array[0..3] of TPoint = ((x: 0; y: -1), (x: 1; y: 0),(x: 0; y: 1),(x: -1; y: 0)); |
|
2303 var |
|
2304 xx, yy, xxn, yyn: LongInt; |
|
2305 da: LongInt; |
|
2306 tdx, tdy: hwFloat; |
|
2307 |
|
2308 procedure PrevAngle; |
|
2309 begin |
|
2310 Gear^.Angle := (LongInt(Gear^.Angle) + 4 - dA) mod 4 |
|
2311 end; |
|
2312 |
|
2313 procedure NextAngle; |
|
2314 begin |
|
2315 Gear^.Angle := (LongInt(Gear^.Angle) + 4 + dA) mod 4 |
|
2316 end; |
|
2317 |
|
2318 begin |
|
2319 AllInactive := false; |
|
2320 |
|
2321 inc(Gear^.Tag); |
|
2322 if Gear^.Tag < 7 then exit; |
|
2323 |
|
2324 dA := hwSign(Gear^.dX); |
|
2325 xx := dirs[Gear^.Angle].x; |
|
2326 yy := dirs[Gear^.Angle].y; |
|
2327 xxn := dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].x; |
|
2328 yyn := dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].y; |
|
2329 |
|
2330 if (xx = 0) then |
|
2331 if TestCollisionYwithGear(Gear, yy) then |
|
2332 PrevAngle |
|
2333 else |
|
2334 begin |
|
2335 Gear^.Tag := 0; |
|
2336 Gear^.Y := Gear^.Y + int2hwFloat(yy); |
|
2337 if not TestCollisionXwithGear(Gear, xxn) then |
|
2338 begin |
|
2339 Gear^.X := Gear^.X + int2hwFloat(xxn); |
|
2340 NextAngle |
|
2341 end; |
|
2342 end; |
|
2343 |
|
2344 if (yy = 0) then |
|
2345 if TestCollisionXwithGear(Gear, xx) then |
|
2346 PrevAngle |
|
2347 else |
|
2348 begin |
|
2349 Gear^.Tag := 0; |
|
2350 Gear^.X := Gear^.X + int2hwFloat(xx); |
|
2351 if not TestCollisionYwithGear(Gear, yyn) then |
|
2352 begin |
|
2353 Gear^.Y := Gear^.Y + int2hwFloat(yyn); |
|
2354 NextAngle |
|
2355 end; |
|
2356 end; |
|
2357 |
|
2358 if Gear^.Tag = 0 then |
|
2359 begin |
|
2360 CakeI := (CakeI + 1) mod cakeh; |
|
2361 tdx := CakePoints[CakeI].x - Gear^.X; |
|
2362 tdy := - CakePoints[CakeI].y + Gear^.Y; |
|
2363 CakePoints[CakeI].x := Gear^.X; |
|
2364 CakePoints[CakeI].y := Gear^.Y; |
|
2365 Gear^.DirAngle := DxDy2Angle(tdx, tdy); |
|
2366 end; |
|
2367 |
|
2368 dec(Gear^.Health); |
|
2369 Gear^.Timer := Gear^.Health*10; |
|
2370 // This is not seconds, but at least it is *some* feedback |
|
2371 if (Gear^.Health = 0) or ((Gear^.Message and gm_Attack) <> 0) then |
|
2372 begin |
|
2373 FollowGear := Gear; |
|
2374 Gear^.RenderTimer := false; |
|
2375 Gear^.doStep := @doStepCakeDown |
|
2376 end |
|
2377 end; |
|
2378 |
|
2379 procedure doStepCakeUp(Gear: PGear); |
|
2380 var |
|
2381 i: Longword; |
|
2382 begin |
|
2383 AllInactive := false; |
|
2384 |
|
2385 inc(Gear^.Tag); |
|
2386 if Gear^.Tag < 100 then exit; |
|
2387 Gear^.Tag := 0; |
|
2388 |
|
2389 if Gear^.Pos = 6 then |
|
2390 begin |
|
2391 for i:= 0 to Pred(cakeh) do |
|
2392 begin |
|
2393 CakePoints[i].x := Gear^.X; |
|
2394 CakePoints[i].y := Gear^.Y |
|
2395 end; |
|
2396 CakeI := 0; |
|
2397 Gear^.doStep := @doStepCakeWork |
|
2398 end |
|
2399 else inc(Gear^.Pos) |
|
2400 end; |
|
2401 |
|
2402 procedure doStepCakeFall(Gear: PGear); |
|
2403 begin |
|
2404 AllInactive := false; |
|
2405 |
|
2406 Gear^.dY := Gear^.dY + cGravity; |
|
2407 if TestCollisionYwithGear(Gear, 1) then |
|
2408 Gear^.doStep := @doStepCakeUp |
|
2409 else |
|
2410 begin |
|
2411 Gear^.Y := Gear^.Y + Gear^.dY; |
|
2412 if CheckGearDrowning(Gear) then AfterAttack |
|
2413 end |
|
2414 end; |
|
2415 |
|
2416 procedure doStepCake(Gear: PGear); |
|
2417 var |
|
2418 HHGear: PGear; |
|
2419 begin |
|
2420 AllInactive := false; |
|
2421 |
|
2422 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2423 HHGear^.Message := HHGear^.Message and (not gm_Attack); |
|
2424 DeleteCI(HHGear); |
|
2425 |
|
2426 FollowGear := Gear; |
|
2427 |
|
2428 Gear^.doStep := @doStepCakeFall |
|
2429 end; |
|
2430 |
|
2431 //////////////////////////////////////////////////////////////////////////////// |
|
2432 procedure doStepSeductionWork(Gear: PGear); |
|
2433 var |
|
2434 x, y: LongInt; |
|
2435 begin |
|
2436 AllInactive := false; |
|
2437 |
|
2438 Gear^.X := Gear^.X + Gear^.dX; |
|
2439 Gear^.Y := Gear^.Y + Gear^.dY; |
|
2440 x := hwRound(Gear^.X); |
|
2441 y := hwRound(Gear^.Y); |
|
2442 |
|
2443 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then |
|
2444 if (Land[y, x] <> 0) then |
|
2445 begin |
|
2446 Gear^.dX.isNegative := not Gear^.dX.isNegative; |
|
2447 Gear^.dY.isNegative := not Gear^.dY.isNegative; |
|
2448 Gear^.dX := Gear^.dX * _1_5; |
|
2449 Gear^.dY := Gear^.dY * _1_5 - _0_3; |
|
2450 AmmoShove(Gear, 0, 40); |
|
2451 AfterAttack; |
|
2452 DeleteGear(Gear) |
|
2453 end |
|
2454 else |
|
2455 else |
|
2456 begin |
|
2457 AfterAttack; |
|
2458 DeleteGear(Gear) |
|
2459 end |
|
2460 end; |
|
2461 |
|
2462 procedure doStepSeductionWear(Gear: PGear); |
|
2463 begin |
|
2464 AllInactive := false; |
|
2465 inc(Gear^.Timer); |
|
2466 if Gear^.Timer > 250 then |
|
2467 begin |
|
2468 Gear^.Timer := 0; |
|
2469 inc(Gear^.Pos); |
|
2470 if Gear^.Pos = 5 then |
|
2471 PlaySound(sndYoohoo, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack) |
|
2472 end; |
|
2473 |
|
2474 if Gear^.Pos = 14 then |
|
2475 Gear^.doStep := @doStepSeductionWork |
|
2476 end; |
|
2477 |
|
2478 procedure doStepSeduction(Gear: PGear); |
|
2479 begin |
|
2480 AllInactive := false; |
|
2481 DeleteCI(PHedgehog(Gear^.Hedgehog)^.Gear); |
|
2482 Gear^.doStep := @doStepSeductionWear |
|
2483 end; |
|
2484 |
|
2485 //////////////////////////////////////////////////////////////////////////////// |
|
2486 procedure doStepWaterUp(Gear: PGear); |
|
2487 var |
|
2488 i: LongWord; |
|
2489 begin |
|
2490 AllInactive := false; |
|
2491 |
|
2492 inc(Gear^.Timer); |
|
2493 if Gear^.Timer = 17 then |
|
2494 Gear^.Timer := 0 |
|
2495 else |
|
2496 exit; |
|
2497 |
|
2498 if cWaterLine > 0 then |
|
2499 begin |
|
2500 dec(cWaterLine); |
|
2501 for i:= 0 to LAND_WIDTH - 1 do |
|
2502 Land[cWaterLine, i] := 0; |
|
2503 SetAllToActive |
|
2504 end; |
|
2505 |
|
2506 inc(Gear^.Tag); |
|
2507 if (Gear^.Tag = 47) or (cWaterLine = 0) then |
|
2508 DeleteGear(Gear) |
|
2509 end; |
|
2510 |
|
2511 //////////////////////////////////////////////////////////////////////////////// |
|
2512 procedure doStepDrillDrilling(Gear: PGear); |
|
2513 var |
|
2514 t: PGearArray; |
|
2515 ox, oy: hwFloat; |
|
2516 begin |
|
2517 AllInactive := false; |
|
2518 |
|
2519 if (Gear^.Timer > 0) and ((Gear^.Timer mod 10) = 0) then |
|
2520 begin |
|
2521 ox := Gear^.X; |
|
2522 oy := Gear^.Y; |
|
2523 Gear^.X := Gear^.X + Gear^.dX; |
|
2524 Gear^.Y := Gear^.Y + Gear^.dY; |
|
2525 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 2, 6); |
|
2526 if (CheckGearDrowning(Gear)) then |
|
2527 begin |
|
2528 StopSound(Gear^.SoundChannel); |
|
2529 exit |
|
2530 end |
|
2531 end; |
|
2532 |
|
2533 t := CheckGearsCollision(Gear); |
|
2534 //fixes drill not exploding when touching HH bug |
|
2535 if (Gear^.Timer = 0) |
|
2536 or (t^.Count <> 0) |
|
2537 or (not TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) |
|
2538 and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) |
|
2539 or (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] = COLOR_INDESTRUCTIBLE) then |
|
2540 begin |
|
2541 //out of time or exited ground |
|
2542 StopSound(Gear^.SoundChannel); |
|
2543 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
|
2544 DeleteGear(Gear); |
|
2545 exit |
|
2546 end; |
|
2547 |
|
2548 dec(Gear^.Timer); |
|
2549 end; |
|
2550 |
|
2551 procedure doStepDrill(Gear: PGear); |
|
2552 var |
|
2553 t: PGearArray; |
|
2554 oldDx, oldDy: hwFloat; |
|
2555 t2: hwFloat; |
|
2556 begin |
|
2557 AllInactive := false; |
|
2558 |
|
2559 Gear^.dX := Gear^.dX + cWindSpeed; |
|
2560 oldDx := Gear^.dX; |
|
2561 oldDy := Gear^.dY; |
|
2562 |
|
2563 doStepFallingGear(Gear); |
|
2564 |
|
2565 if (GameTicks and $3F) = 0 then |
|
2566 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
|
2567 |
|
2568 if ((Gear^.State and gstCollision) <> 0) then |
|
2569 begin |
|
2570 //hit |
|
2571 Gear^.dX := oldDx; |
|
2572 Gear^.dY := oldDy; |
|
2573 |
|
2574 t := CheckGearsCollision(Gear); |
|
2575 if (t^.Count = 0) then |
|
2576 begin |
|
2577 //hit the ground not the HH |
|
2578 t2 := _0_5 / Distance(Gear^.dX, Gear^.dY); |
|
2579 Gear^.dX := Gear^.dX * t2; |
|
2580 Gear^.dY := Gear^.dY * t2; |
|
2581 end |
|
2582 else |
|
2583 begin |
|
2584 //explode right on contact with HH |
|
2585 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
1510 DeleteGear(Gear); |
2586 DeleteGear(Gear); |
1511 exit; |
2587 exit; |
1512 end; |
2588 end; |
1513 |
2589 |
1514 doStepCase(Gear) |
2590 Gear^.SoundChannel := LoopSound(sndDrillRocket); |
1515 end; |
2591 Gear^.doStep := @doStepDrillDrilling; |
1516 |
2592 dec(Gear^.Timer) |
1517 //////////////////////////////////////////////////////////////////////////////// |
2593 end |
1518 procedure doStepIdle(Gear: PGear); |
2594 end; |
1519 begin |
2595 |
1520 AllInactive:= false; |
2596 //////////////////////////////////////////////////////////////////////////////// |
1521 dec(Gear^.Timer); |
2597 procedure doStepBallgunWork(Gear: PGear); |
1522 if Gear^.Timer = 0 then |
2598 var |
1523 begin |
|
1524 DeleteGear(Gear); |
|
1525 AfterAttack |
|
1526 end |
|
1527 end; |
|
1528 |
|
1529 procedure doStepShover(Gear: PGear); |
|
1530 var HHGear: PGear; |
|
1531 begin |
|
1532 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1533 HHGear^.State:= HHGear^.State or gstNoDamage; |
|
1534 DeleteCI(HHGear); |
|
1535 |
|
1536 AmmoShove(Gear, 30, 115); |
|
1537 |
|
1538 HHGear^.State:= HHGear^.State and not gstNoDamage; |
|
1539 Gear^.Timer:= 250; |
|
1540 Gear^.doStep:= @doStepIdle |
|
1541 end; |
|
1542 |
|
1543 //////////////////////////////////////////////////////////////////////////////// |
|
1544 procedure doStepWhip(Gear: PGear); |
|
1545 var HHGear: PGear; |
|
1546 i: LongInt; |
|
1547 begin |
|
1548 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1549 HHGear^.State:= HHGear^.State or gstNoDamage; |
|
1550 DeleteCI(HHGear); |
|
1551 |
|
1552 for i:= 0 to 3 do |
|
1553 begin |
|
1554 AmmoShove(Gear, 30, 25); |
|
1555 Gear^.X:= Gear^.X + Gear^.dX * 5 |
|
1556 end; |
|
1557 |
|
1558 HHGear^.State:= HHGear^.State and not gstNoDamage; |
|
1559 Gear^.Timer:= 250; |
|
1560 Gear^.doStep:= @doStepIdle |
|
1561 end; |
|
1562 |
|
1563 //////////////////////////////////////////////////////////////////////////////// |
|
1564 procedure doStepFlame(Gear: PGear); |
|
1565 var gX,gY,i: LongInt; |
|
1566 begin |
|
1567 if (Gear^.State and gsttmpFlag) = 0 then AllInactive:= false; |
|
1568 |
|
1569 if not TestCollisionYwithGear(Gear, 1) then |
|
1570 begin |
|
1571 AllInactive:= false; |
|
1572 if Gear^.dX.QWordValue > _0_01.QWordValue then |
|
1573 Gear^.dX:= Gear^.dX * _0_995; |
|
1574 Gear^.dY:= Gear^.dY + cGravity; |
|
1575 if (Gear^.State and gsttmpFlag) <> 0 then Gear^.dY:= Gear^.dY + cGravity; |
|
1576 if Gear^.dY.QWordValue > _0_2.QWordValue then Gear^.dY:= Gear^.dY * _0_995; |
|
1577 |
|
1578 if (Gear^.State and gsttmpFlag) <> 0 then Gear^.X:= Gear^.X + Gear^.dX else |
|
1579 Gear^.X:= Gear^.X + Gear^.dX + cWindSpeed * 640; |
|
1580 Gear^.Y:= Gear^.Y + Gear^.dY; |
|
1581 |
|
1582 if (hwRound(Gear^.Y) > cWaterLine) then |
|
1583 begin |
|
1584 gX:= hwRound(Gear^.X); |
|
1585 for i:= 0 to 3 do |
|
1586 AddVisualGear(gX - 16 + Random(32), cWaterLine - 16 + Random(16), vgtSteam); |
|
1587 PlaySound(sndVaporize); |
|
1588 DeleteGear(Gear); |
|
1589 exit |
|
1590 end |
|
1591 end else begin |
|
1592 if (Gear^.State and gsttmpFlag) <> 0 then |
|
1593 begin |
|
1594 Gear^.Radius:= 9; |
|
1595 AmmoShove(Gear, 2, 30); |
|
1596 Gear^.Radius:= 1 |
|
1597 end; |
|
1598 if Gear^.Timer > 0 then |
|
1599 begin |
|
1600 dec(Gear^.Timer); |
|
1601 inc(Gear^.Damage) |
|
1602 end |
|
1603 else begin |
|
1604 // Standard fire |
|
1605 if (Gear^.State and gsttmpFlag) = 0 then |
|
1606 begin |
|
1607 Gear^.Radius:= 9; |
|
1608 AmmoShove(Gear, 4, 100); |
|
1609 gX:= hwRound(Gear^.X); |
|
1610 gY:= hwRound(Gear^.Y); |
|
1611 Gear^.Radius:= 1; |
|
1612 doMakeExplosion(gX, gY, 4, EXPLNoDamage); |
|
1613 if ((GameTicks and $7) = 0) and (Random(2) = 0) then |
|
1614 for i:= 1 to Random(2)+1 do |
|
1615 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
|
1616 if Gear^.Health > 0 then dec(Gear^.Health); |
|
1617 Gear^.Timer:= 450 - Gear^.Tag * 8 |
|
1618 end |
|
1619 else begin |
|
1620 // Modified fire |
|
1621 if ((GameTicks and $7FF) = 0) and ((GameFlags and gfSolidLand) = 0) then begin |
|
1622 DrawExplosion(gX, gY, 4); |
|
1623 |
|
1624 for i:= 0 to Random(3) do |
|
1625 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
|
1626 end; |
|
1627 // 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. |
|
1628 Gear^.Timer:= 100 - Gear^.Tag * 3; |
|
1629 if (Gear^.Damage > 3000+Gear^.Tag*1500) then Gear^.Health:= 0 |
|
1630 end |
|
1631 end |
|
1632 end; |
|
1633 if Gear^.Health = 0 then begin |
|
1634 gX:= hwRound(Gear^.X); |
|
1635 gY:= hwRound(Gear^.Y); |
|
1636 if (Gear^.State and gsttmpFlag) = 0 then begin |
|
1637 if ((GameTicks and $3) = 0) and (Random(1) = 0) then begin |
|
1638 for i:= 1 to Random(2)+1 do begin |
|
1639 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
|
1640 end; |
|
1641 end; |
|
1642 end else begin |
|
1643 for i:= 0 to Random(3) do begin |
|
1644 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
|
1645 end; |
|
1646 end; |
|
1647 |
|
1648 DeleteGear(Gear) |
|
1649 end; |
|
1650 end; |
|
1651 |
|
1652 //////////////////////////////////////////////////////////////////////////////// |
|
1653 procedure doStepFirePunchWork(Gear: PGear); |
|
1654 var HHGear: PGear; |
|
1655 begin |
|
1656 AllInactive:= false; |
|
1657 if ((Gear^.Message and gm_Destroy) <> 0) then |
|
1658 begin |
|
1659 DeleteGear(Gear); |
|
1660 AfterAttack; |
|
1661 exit |
|
1662 end; |
|
1663 |
|
1664 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1665 if hwRound(HHGear^.Y) <= Gear^.Tag - 2 then |
|
1666 begin |
|
1667 Gear^.Tag:= hwRound(HHGear^.Y); |
|
1668 DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4, 2); |
|
1669 HHGear^.State:= HHGear^.State or gstNoDamage; |
|
1670 Gear^.Y:= HHGear^.Y; |
|
1671 AmmoShove(Gear, 30, 40); |
|
1672 HHGear^.State:= HHGear^.State and not gstNoDamage |
|
1673 end; |
|
1674 |
|
1675 HHGear^.dY:= HHGear^.dY + cGravity; |
|
1676 if not (HHGear^.dY.isNegative) then |
|
1677 begin |
|
1678 HHGear^.State:= HHGear^.State or gstMoving; |
|
1679 DeleteGear(Gear); |
|
1680 AfterAttack; |
|
1681 exit |
|
1682 end; |
|
1683 |
|
1684 if CheckLandValue(hwRound(HHGear^.X), hwRound(HHGear^.Y + HHGear^.dY + SignAs(_6,Gear^.dY)), COLOR_INDESTRUCTIBLE) then |
|
1685 HHGear^.Y:= HHGear^.Y + HHGear^.dY |
|
1686 end; |
|
1687 |
|
1688 procedure doStepFirePunch(Gear: PGear); |
|
1689 var HHGear: PGear; |
|
1690 begin |
|
1691 AllInactive:= false; |
|
1692 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1693 DeleteCI(HHGear); |
|
1694 HHGear^.X:= int2hwFloat(hwRound(HHGear^.X)) - _0_5; |
|
1695 HHGear^.dX:= SignAs(cLittle, Gear^.dX); |
|
1696 |
|
1697 HHGear^.dY:= - _0_3; |
|
1698 |
|
1699 Gear^.X:= HHGear^.X; |
|
1700 Gear^.dX:= SignAs(_0_45, Gear^.dX); |
|
1701 Gear^.dY:= - _0_9; |
|
1702 Gear^.doStep:= @doStepFirePunchWork; |
|
1703 DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y + _1, _0_5, _0, cHHRadius * 4, 5); |
|
1704 |
|
1705 PlaySound(TSound(ord(sndFirePunch1) + GetRandom(6)), PHedgehog(HHGear^.Hedgehog)^.Team^.voicepack) |
|
1706 end; |
|
1707 |
|
1708 //////////////////////////////////////////////////////////////////////////////// |
|
1709 |
|
1710 procedure doStepParachuteWork(Gear: PGear); |
|
1711 var HHGear: PGear; |
|
1712 begin |
|
1713 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1714 |
|
1715 inc(Gear^.Timer); |
|
1716 |
|
1717 if TestCollisionYwithGear(HHGear, 1) |
|
1718 or ((HHGear^.State and gstHHDriven) = 0) |
|
1719 or CheckGearDrowning(HHGear) |
|
1720 or ((Gear^.Message and gm_Attack) <> 0) then |
|
1721 begin |
|
1722 with HHGear^ do |
|
1723 begin |
|
1724 Message:= 0; |
|
1725 SetLittle(dX); |
|
1726 dY:= _0; |
|
1727 State:= State or gstMoving; |
|
1728 end; |
|
1729 DeleteGear(Gear); |
|
1730 isCursorVisible:= false; |
|
1731 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
|
1732 exit |
|
1733 end; |
|
1734 |
|
1735 if not TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
|
1736 HHGear^.X:= HHGear^.X + cWindSpeed * 200; |
|
1737 |
|
1738 if (Gear^.Message and gm_Left) <> 0 then HHGear^.X:= HHGear^.X - cMaxWindSpeed * 80 |
|
1739 else if (Gear^.Message and gm_Right) <> 0 then HHGear^.X:= HHGear^.X + cMaxWindSpeed * 80; |
|
1740 if (Gear^.Message and gm_Up) <> 0 then HHGear^.Y:= HHGear^.Y - cGravity * 40 |
|
1741 else if (Gear^.Message and gm_Down) <> 0 then HHGear^.Y:= HHGear^.Y + cGravity * 40; |
|
1742 |
|
1743 HHGear^.Y:= HHGear^.Y + cGravity * 100; |
|
1744 Gear^.X:= HHGear^.X; |
|
1745 Gear^.Y:= HHGear^.Y |
|
1746 end; |
|
1747 |
|
1748 procedure doStepParachute(Gear: PGear); |
|
1749 var HHGear: PGear; |
|
1750 begin |
|
1751 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1752 |
|
1753 DeleteCI(HHGear); |
|
1754 |
|
1755 AfterAttack; |
|
1756 |
|
1757 HHGear^.State:= HHGear^.State and not (gstAttacking or gstAttacked or gstMoving); |
|
1758 HHGear^.Message:= HHGear^.Message and not gm_Attack; |
|
1759 |
|
1760 Gear^.doStep:= @doStepParachuteWork; |
|
1761 |
|
1762 Gear^.Message:= HHGear^.Message; |
|
1763 doStepParachuteWork(Gear) |
|
1764 end; |
|
1765 |
|
1766 //////////////////////////////////////////////////////////////////////////////// |
|
1767 procedure doStepAirAttackWork(Gear: PGear); |
|
1768 var i: Longint; |
|
1769 begin |
|
1770 AllInactive:= false; |
|
1771 Gear^.X:= Gear^.X + cAirPlaneSpeed * Gear^.Tag; |
|
1772 |
|
1773 if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then |
|
1774 begin |
|
1775 dec(Gear^.Health); |
|
1776 case Gear^.State of |
|
1777 0: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
|
1778 1: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
|
1779 2: for i:= -19 to 19 do |
|
1780 FollowGear:= AddGear(hwRound(Gear^.X) + i div 3, hwRound(Gear^.Y), gtFlame, 0, _0_001 * i, _0, 0); |
|
1781 end; |
|
1782 Gear^.dX:= Gear^.dX + int2hwFloat(30 * Gear^.Tag) |
|
1783 end; |
|
1784 |
|
1785 if (GameTicks and $3F) = 0 then |
|
1786 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
|
1787 |
|
1788 if (hwRound(Gear^.X) > (LAND_WIDTH+1024)) or (hwRound(Gear^.X) < -1024) then DeleteGear(Gear) |
|
1789 end; |
|
1790 |
|
1791 procedure doStepAirAttack(Gear: PGear); |
|
1792 begin |
|
1793 AllInactive:= false; |
|
1794 |
|
1795 if Gear^.X.QWordValue = 0 then |
|
1796 begin |
|
1797 Gear^.Tag:= 1; |
|
1798 Gear^.X:= -_1024; |
|
1799 end |
|
1800 else |
|
1801 begin |
|
1802 Gear^.Tag:= -1; |
|
1803 Gear^.X:= int2hwFloat(LAND_WIDTH + 1024); |
|
1804 end; |
|
1805 |
|
1806 Gear^.Y:= int2hwFloat(topY-300); |
|
1807 Gear^.dX:= int2hwFloat(TargetPoint.X - 5 * Gear^.Tag * 15); |
|
1808 |
|
1809 if (int2hwFloat(TargetPoint.Y) - Gear^.Y > _0) and (Gear^.State <> 2) then |
|
1810 Gear^.dX:= Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(TargetPoint.Y) - Gear^.Y) * 2 / cGravity) * Gear^.Tag; |
|
1811 |
|
1812 Gear^.Health:= 6; |
|
1813 Gear^.doStep:= @doStepAirAttackWork; |
|
1814 end; |
|
1815 |
|
1816 //////////////////////////////////////////////////////////////////////////////// |
|
1817 |
|
1818 procedure doStepAirBomb(Gear: PGear); |
|
1819 begin |
|
1820 AllInactive:= false; |
|
1821 doStepFallingGear(Gear); |
|
1822 if (Gear^.State and gstCollision) <> 0 then |
|
1823 begin |
|
1824 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); |
|
1825 DeleteGear(Gear); |
|
1826 exit |
|
1827 end; |
|
1828 if (GameTicks and $3F) = 0 then |
|
1829 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
|
1830 end; |
|
1831 |
|
1832 //////////////////////////////////////////////////////////////////////////////// |
|
1833 |
|
1834 procedure doStepGirder(Gear: PGear); |
|
1835 var HHGear: PGear; |
|
1836 x, y, tx, ty: hwFloat; |
|
1837 begin |
|
1838 AllInactive:= false; |
|
1839 |
|
1840 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1841 tx:= int2hwFloat(TargetPoint.X); |
|
1842 ty:= int2hwFloat(TargetPoint.Y); |
|
1843 x:= HHGear^.X; |
|
1844 y:= HHGear^.Y; |
|
1845 |
|
1846 if (Distance(tx - x, ty - y) > _256) or |
|
1847 not TryPlaceOnLand(TargetPoint.X - SpritesData[sprAmGirder].Width div 2, |
|
1848 TargetPoint.Y - SpritesData[sprAmGirder].Height div 2, |
|
1849 sprAmGirder, Gear^.State, true) then |
|
1850 begin |
|
1851 PlaySound(sndDenied); |
|
1852 HHGear^.Message:= HHGear^.Message and not gm_Attack; |
|
1853 HHGear^.State:= HHGear^.State and not gstAttacking; |
|
1854 HHGear^.State:= HHGear^.State or gstHHChooseTarget; |
|
1855 isCursorVisible:= true; |
|
1856 DeleteGear(Gear) |
|
1857 end |
|
1858 else begin |
|
1859 PlaySound(sndPlaced); |
|
1860 DeleteGear(Gear); |
|
1861 AfterAttack; |
|
1862 end; |
|
1863 |
|
1864 HHGear^.State:= HHGear^.State and not (gstAttacking or gstAttacked); |
|
1865 HHGear^.Message:= HHGear^.Message and not gm_Attack; |
|
1866 TargetPoint.X:= NoPointX |
|
1867 end; |
|
1868 |
|
1869 //////////////////////////////////////////////////////////////////////////////// |
|
1870 procedure doStepTeleportAfter(Gear: PGear); |
|
1871 var HHGear: PGear; |
|
1872 begin |
|
1873 PHedgehog(Gear^.Hedgehog)^.Unplaced:= false; |
|
1874 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1875 HHGear^.Y:= HHGear^.Y + HHGear^.dY; // hedgehog falling to collect cases |
|
1876 HHGear^.dY:= HHGear^.dY + cGravity; |
|
1877 if TestCollisionYwithGear(HHGear, 1) |
|
1878 or CheckGearDrowning(HHGear) then |
|
1879 begin |
|
1880 DeleteGear(Gear); |
|
1881 AfterAttack |
|
1882 end |
|
1883 end; |
|
1884 |
|
1885 procedure doStepTeleportAnim(Gear: PGear); |
|
1886 begin |
|
1887 inc(Gear^.Timer); |
|
1888 if Gear^.Timer = 65 then |
|
1889 begin |
|
1890 Gear^.Timer:= 0; |
|
1891 inc(Gear^.Pos); |
|
1892 if Gear^.Pos = 11 then |
|
1893 Gear^.doStep:= @doStepTeleportAfter |
|
1894 end; |
|
1895 end; |
|
1896 |
|
1897 procedure doStepTeleport(Gear: PGear); |
|
1898 var HHGear: PGear; |
|
1899 begin |
|
1900 AllInactive:= false; |
|
1901 |
|
1902 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1903 if not TryPlaceOnLand(TargetPoint.X - SpritesData[sprHHTelepMask].Width div 2, |
|
1904 TargetPoint.Y - SpritesData[sprHHTelepMask].Height div 2, |
|
1905 sprHHTelepMask, 0, false) then |
|
1906 begin |
|
1907 HHGear^.Message:= HHGear^.Message and not gm_Attack; |
|
1908 HHGear^.State:= HHGear^.State and not gstAttacking; |
|
1909 HHGear^.State:= HHGear^.State or gstHHChooseTarget; |
|
1910 DeleteGear(Gear); |
|
1911 isCursorVisible:= true; |
|
1912 PlaySound(sndDenied) |
|
1913 end |
|
1914 else begin |
|
1915 DeleteCI(HHGear); |
|
1916 SetAllHHToActive; |
|
1917 Gear^.doStep:= @doStepTeleportAnim; |
|
1918 // copy old HH position and direction to Gear (because we need them for drawing the vanishing hog) |
|
1919 Gear^.dX:= HHGear^.dX; |
|
1920 // retrieve the cursor direction (it was previously copied to X so it doesn't get lost) |
|
1921 HHGear^.dX.isNegative := (Gear^.X.QWordValue <> 0); |
|
1922 Gear^.X:= HHGear^.X; |
|
1923 Gear^.Y:= HHGear^.Y; |
|
1924 HHGear^.X:= int2hwFloat(TargetPoint.X); |
|
1925 HHGear^.Y:= int2hwFloat(TargetPoint.Y); |
|
1926 HHGear^.State:= HHGear^.State or gstMoving; |
|
1927 playSound(sndWarp) |
|
1928 end; |
|
1929 TargetPoint.X:= NoPointX; |
|
1930 end; |
|
1931 |
|
1932 //////////////////////////////////////////////////////////////////////////////// |
|
1933 procedure doStepSwitcherWork(Gear: PGear); |
|
1934 var HHGear: PGear; |
|
1935 Msg, State: Longword; |
|
1936 begin |
|
1937 AllInactive:= false; |
|
1938 |
|
1939 if ((Gear^.Message and not gm_Switch) <> 0) or (TurnTimeLeft = 0) then |
|
1940 begin |
|
1941 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1942 Msg:= Gear^.Message and not gm_Switch; |
|
1943 DeleteGear(Gear); |
|
1944 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); |
|
1945 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
|
1946 |
|
1947 HHGear:= CurrentHedgehog^.Gear; |
|
1948 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
|
1949 HHGear^.Message:= Msg; |
|
1950 exit |
|
1951 end; |
|
1952 |
|
1953 if (Gear^.Message and gm_Switch) <> 0 then |
|
1954 begin |
|
1955 HHGear:= CurrentHedgehog^.Gear; |
|
1956 HHGear^.Message:= HHGear^.Message and not gm_Switch; |
|
1957 Gear^.Message:= Gear^.Message and not gm_Switch; |
|
1958 State:= HHGear^.State; |
|
1959 HHGear^.State:= 0; |
|
1960 HHGear^.Active:= false; |
|
1961 HHGear^.Z:= cHHZ; |
|
1962 RemoveGearFromList(HHGear); |
|
1963 InsertGearToList(HHGear); |
|
1964 |
|
1965 PlaySound(sndSwitchHog); |
|
1966 |
|
1967 repeat |
|
1968 CurrentTeam^.CurrHedgehog:= Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber); |
|
1969 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil); |
|
1970 |
|
1971 CurrentHedgehog:= @CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]; |
|
1972 |
|
1973 HHGear:= CurrentHedgehog^.Gear; |
|
1974 HHGear^.State:= State; |
|
1975 HHGear^.Active:= true; |
|
1976 FollowGear:= HHGear; |
|
1977 HHGear^.Z:= cCurrHHZ; |
|
1978 RemoveGearFromList(HHGear); |
|
1979 InsertGearToList(HHGear); |
|
1980 Gear^.X:= HHGear^.X; |
|
1981 Gear^.Y:= HHGear^.Y |
|
1982 end; |
|
1983 end; |
|
1984 |
|
1985 procedure doStepSwitcher(Gear: PGear); |
|
1986 var HHGear: PGear; |
|
1987 begin |
|
1988 Gear^.doStep:= @doStepSwitcherWork; |
|
1989 |
|
1990 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
1991 with HHGear^ do |
|
1992 begin |
|
1993 State:= State and not gstAttacking; |
|
1994 Message:= Message and not gm_Attack |
|
1995 end |
|
1996 end; |
|
1997 |
|
1998 //////////////////////////////////////////////////////////////////////////////// |
|
1999 procedure doStepMortar(Gear: PGear); |
|
2000 var dX, dY: hwFloat; |
|
2001 i: LongInt; |
|
2002 dxn, dyn: boolean; |
|
2003 begin |
|
2004 AllInactive:= false; |
|
2005 dxn:= Gear^.dX.isNegative; |
|
2006 dyn:= Gear^.dY.isNegative; |
|
2007 |
|
2008 doStepFallingGear(Gear); |
|
2009 if (Gear^.State and gstCollision) <> 0 then |
|
2010 begin |
|
2011 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLAutoSound); |
|
2012 |
|
2013 Gear^.dX.isNegative:= not dxn; |
|
2014 Gear^.dY.isNegative:= not dyn; |
|
2015 for i:= 0 to 4 do |
|
2016 begin |
|
2017 dX:= Gear^.dX + (GetRandom - _0_5) * _0_03; |
|
2018 dY:= Gear^.dY + (GetRandom - _0_5) * _0_03; |
|
2019 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25); |
|
2020 end; |
|
2021 |
|
2022 DeleteGear(Gear); |
|
2023 exit |
|
2024 end; |
|
2025 |
|
2026 if (GameTicks and $3F) = 0 then |
|
2027 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
|
2028 end; |
|
2029 |
|
2030 //////////////////////////////////////////////////////////////////////////////// |
|
2031 procedure doStepKamikazeWork(Gear: PGear); |
|
2032 const upd: Longword = 0; |
|
2033 var i: LongWord; |
|
2034 HHGear: PGear; |
2599 HHGear: PGear; |
2035 begin |
|
2036 AllInactive:= false; |
|
2037 |
|
2038 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2039 HHGear^.State:= HHGear^.State or gstNoDamage; |
|
2040 DeleteCI(HHGear); |
|
2041 |
|
2042 i:= 2; |
|
2043 repeat |
|
2044 Gear^.X:= Gear^.X + HHGear^.dX; |
|
2045 Gear^.Y:= Gear^.Y + HHGear^.dY; |
|
2046 HHGear^.X:= Gear^.X; |
|
2047 HHGear^.Y:= Gear^.Y; |
|
2048 |
|
2049 inc(Gear^.Damage, 2); |
|
2050 |
|
2051 // if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) |
|
2052 // or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3); |
|
2053 |
|
2054 dec(i) |
|
2055 until (i = 0) or (Gear^.Damage > Gear^.Health); |
|
2056 |
|
2057 inc(upd); |
|
2058 if upd > 3 then |
|
2059 begin |
|
2060 if Gear^.Health < 1500 then Gear^.Pos:= 2; |
|
2061 |
|
2062 AmmoShove(Gear, 30, 40); |
|
2063 |
|
2064 DrawTunnel(HHGear^.X - HHGear^.dX * 10, |
|
2065 HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2, |
|
2066 HHGear^.dX, |
|
2067 HHGear^.dY, |
|
2068 20 + cHHRadius * 2, |
|
2069 cHHRadius * 2 + 6); |
|
2070 |
|
2071 upd:= 0 |
|
2072 end; |
|
2073 |
|
2074 if Gear^.Health < Gear^.Damage then |
|
2075 begin |
|
2076 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); |
|
2077 AfterAttack; |
|
2078 DeleteGear(Gear); |
|
2079 DeleteGear(HHGear); |
|
2080 end else |
|
2081 begin |
|
2082 dec(Gear^.Health, Gear^.Damage); |
|
2083 Gear^.Damage:= 0 |
|
2084 end |
|
2085 end; |
|
2086 |
|
2087 procedure doStepKamikazeIdle(Gear: PGear); |
|
2088 begin |
|
2089 AllInactive:= false; |
|
2090 dec(Gear^.Timer); |
|
2091 if Gear^.Timer = 0 then |
|
2092 begin |
|
2093 Gear^.Pos:= 1; |
|
2094 PlaySound(sndKamikaze, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack); |
|
2095 Gear^.doStep:= @doStepKamikazeWork |
|
2096 end |
|
2097 end; |
|
2098 |
|
2099 procedure doStepKamikaze(Gear: PGear); |
|
2100 var HHGear: PGear; |
|
2101 begin |
|
2102 AllInactive:= false; |
|
2103 |
|
2104 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2105 |
|
2106 HHGear^.dX:= Gear^.dX; |
|
2107 HHGear^.dY:= Gear^.dY; |
|
2108 |
|
2109 Gear^.dX:= SignAs(_0_45, Gear^.dX); |
|
2110 Gear^.dY:= - _0_9; |
|
2111 |
|
2112 Gear^.Timer:= 550; |
|
2113 |
|
2114 Gear^.doStep:= @doStepKamikazeIdle |
|
2115 end; |
|
2116 |
|
2117 //////////////////////////////////////////////////////////////////////////////// |
|
2118 const cakeh = 27; |
|
2119 cakeDmg = 75; |
|
2120 var CakePoints: array[0..Pred(cakeh)] of record x, y: hwFloat; end; |
|
2121 CakeI: Longword; |
|
2122 |
|
2123 procedure doStepCakeExpl(Gear: PGear); |
|
2124 begin |
|
2125 AllInactive:= false; |
|
2126 |
|
2127 inc(Gear^.Tag); |
|
2128 if Gear^.Tag < 2250 then exit; |
|
2129 |
|
2130 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg, EXPLAutoSound); |
|
2131 AfterAttack; |
|
2132 DeleteGear(Gear) |
|
2133 end; |
|
2134 |
|
2135 procedure doStepCakeDown(Gear: PGear); |
|
2136 var gi: PGear; |
|
2137 dmg: LongInt; |
|
2138 begin |
|
2139 AllInactive:= false; |
|
2140 |
|
2141 inc(Gear^.Tag); |
|
2142 if Gear^.Tag < 100 then exit; |
|
2143 Gear^.Tag:= 0; |
|
2144 |
|
2145 if Gear^.Pos = 0 then |
|
2146 begin |
|
2147 gi:= GearsList; |
|
2148 while gi <> nil do |
|
2149 begin |
|
2150 dmg:= cakeDmg * 2 - hwRound(Distance(gi^.X - Gear^.X, gi^.Y - Gear^.Y)); |
|
2151 if (dmg > 1) and (gi^.Kind = gtHedgehog) then |
|
2152 if (CurrentHedgehog^.Gear = gi) and (not gi^.Invulnerable) then |
|
2153 gi^.State:= gi^.State or gstLoser |
|
2154 else |
|
2155 gi^.State:= gi^.State or gstWinner; |
|
2156 gi:= gi^.NextGear |
|
2157 end; |
|
2158 Gear^.doStep:= @doStepCakeExpl; |
|
2159 PlaySound(sndCake) |
|
2160 end else dec(Gear^.Pos) |
|
2161 end; |
|
2162 |
|
2163 |
|
2164 procedure doStepCakeWork(Gear: PGear); |
|
2165 const dirs: array[0..3] of TPoint = ((x: 0; y: -1), (x: 1; y: 0),(x: 0; y: 1),(x: -1; y: 0)); |
|
2166 var xx, yy, xxn, yyn: LongInt; |
|
2167 da: LongInt; |
|
2168 tdx, tdy: hwFloat; |
|
2169 |
|
2170 procedure PrevAngle; |
|
2171 begin |
|
2172 Gear^.Angle:= (LongInt(Gear^.Angle) + 4 - dA) mod 4 |
|
2173 end; |
|
2174 |
|
2175 procedure NextAngle; |
|
2176 begin |
|
2177 Gear^.Angle:= (LongInt(Gear^.Angle) + 4 + dA) mod 4 |
|
2178 end; |
|
2179 |
|
2180 begin |
|
2181 AllInactive:= false; |
|
2182 |
|
2183 inc(Gear^.Tag); |
|
2184 if Gear^.Tag < 7 then exit; |
|
2185 |
|
2186 dA:= hwSign(Gear^.dX); |
|
2187 xx:= dirs[Gear^.Angle].x; |
|
2188 yy:= dirs[Gear^.Angle].y; |
|
2189 xxn:= dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].x; |
|
2190 yyn:= dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].y; |
|
2191 |
|
2192 if (xx = 0) then |
|
2193 if TestCollisionYwithGear(Gear, yy) then |
|
2194 PrevAngle |
|
2195 else begin |
|
2196 Gear^.Tag:= 0; |
|
2197 Gear^.Y:= Gear^.Y + int2hwFloat(yy); |
|
2198 if not TestCollisionXwithGear(Gear, xxn) then |
|
2199 begin |
|
2200 Gear^.X:= Gear^.X + int2hwFloat(xxn); |
|
2201 NextAngle |
|
2202 end; |
|
2203 end; |
|
2204 |
|
2205 if (yy = 0) then |
|
2206 if TestCollisionXwithGear(Gear, xx) then |
|
2207 PrevAngle |
|
2208 else begin |
|
2209 Gear^.Tag:= 0; |
|
2210 Gear^.X:= Gear^.X + int2hwFloat(xx); |
|
2211 if not TestCollisionYwithGear(Gear, yyn) then |
|
2212 begin |
|
2213 Gear^.Y:= Gear^.Y + int2hwFloat(yyn); |
|
2214 NextAngle |
|
2215 end; |
|
2216 end; |
|
2217 |
|
2218 if Gear^.Tag = 0 then |
|
2219 begin |
|
2220 CakeI:= (CakeI + 1) mod cakeh; |
|
2221 tdx:= CakePoints[CakeI].x - Gear^.X; |
|
2222 tdy:= - CakePoints[CakeI].y + Gear^.Y; |
|
2223 CakePoints[CakeI].x:= Gear^.X; |
|
2224 CakePoints[CakeI].y:= Gear^.Y; |
|
2225 Gear^.DirAngle:= DxDy2Angle(tdx, tdy); |
|
2226 end; |
|
2227 |
|
2228 dec(Gear^.Health); |
|
2229 Gear^.Timer:= Gear^.Health*10; // This is not seconds, but at least it is *some* feedback |
|
2230 if (Gear^.Health = 0) or ((Gear^.Message and gm_Attack) <> 0) then |
|
2231 begin |
|
2232 FollowGear:= Gear; |
|
2233 Gear^.RenderTimer:= false; |
|
2234 Gear^.doStep:= @doStepCakeDown |
|
2235 end |
|
2236 end; |
|
2237 |
|
2238 procedure doStepCakeUp(Gear: PGear); |
|
2239 var i: Longword; |
|
2240 begin |
|
2241 AllInactive:= false; |
|
2242 |
|
2243 inc(Gear^.Tag); |
|
2244 if Gear^.Tag < 100 then exit; |
|
2245 Gear^.Tag:= 0; |
|
2246 |
|
2247 if Gear^.Pos = 6 then |
|
2248 begin |
|
2249 for i:= 0 to Pred(cakeh) do |
|
2250 begin |
|
2251 CakePoints[i].x:= Gear^.X; |
|
2252 CakePoints[i].y:= Gear^.Y |
|
2253 end; |
|
2254 CakeI:= 0; |
|
2255 Gear^.doStep:= @doStepCakeWork |
|
2256 end else inc(Gear^.Pos) |
|
2257 end; |
|
2258 |
|
2259 procedure doStepCakeFall(Gear: PGear); |
|
2260 begin |
|
2261 AllInactive:= false; |
|
2262 |
|
2263 Gear^.dY:= Gear^.dY + cGravity; |
|
2264 if TestCollisionYwithGear(Gear, 1) then |
|
2265 Gear^.doStep:= @doStepCakeUp |
|
2266 else |
|
2267 begin |
|
2268 Gear^.Y:= Gear^.Y + Gear^.dY; |
|
2269 if CheckGearDrowning(Gear) then AfterAttack |
|
2270 end |
|
2271 end; |
|
2272 |
|
2273 procedure doStepCake(Gear: PGear); |
|
2274 var HHGear: PGear; |
|
2275 begin |
|
2276 AllInactive:= false; |
|
2277 |
|
2278 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2279 HHGear^.Message:= HHGear^.Message and (not gm_Attack); |
|
2280 DeleteCI(HHGear); |
|
2281 |
|
2282 FollowGear:= Gear; |
|
2283 |
|
2284 Gear^.doStep:= @doStepCakeFall |
|
2285 end; |
|
2286 |
|
2287 //////////////////////////////////////////////////////////////////////////////// |
|
2288 procedure doStepSeductionWork(Gear: PGear); |
|
2289 var x, y: LongInt; |
|
2290 begin |
|
2291 AllInactive:= false; |
|
2292 |
|
2293 Gear^.X:= Gear^.X + Gear^.dX; |
|
2294 Gear^.Y:= Gear^.Y + Gear^.dY; |
|
2295 x:= hwRound(Gear^.X); |
|
2296 y:= hwRound(Gear^.Y); |
|
2297 |
|
2298 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then |
|
2299 if (Land[y, x] <> 0) then |
|
2300 begin |
|
2301 Gear^.dX.isNegative:= not Gear^.dX.isNegative; |
|
2302 Gear^.dY.isNegative:= not Gear^.dY.isNegative; |
|
2303 Gear^.dX:= Gear^.dX * _1_5; |
|
2304 Gear^.dY:= Gear^.dY * _1_5 - _0_3; |
|
2305 AmmoShove(Gear, 0, 40); |
|
2306 AfterAttack; |
|
2307 DeleteGear(Gear) |
|
2308 end |
|
2309 else |
|
2310 else |
|
2311 begin |
|
2312 AfterAttack; |
|
2313 DeleteGear(Gear) |
|
2314 end |
|
2315 end; |
|
2316 |
|
2317 procedure doStepSeductionWear(Gear: PGear); |
|
2318 begin |
|
2319 AllInactive:= false; |
|
2320 inc(Gear^.Timer); |
|
2321 if Gear^.Timer > 250 then |
|
2322 begin |
|
2323 Gear^.Timer:= 0; |
|
2324 inc(Gear^.Pos); |
|
2325 if Gear^.Pos = 5 then |
|
2326 PlaySound(sndYoohoo, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack) |
|
2327 end; |
|
2328 |
|
2329 if Gear^.Pos = 14 then |
|
2330 Gear^.doStep:= @doStepSeductionWork |
|
2331 end; |
|
2332 |
|
2333 procedure doStepSeduction(Gear: PGear); |
|
2334 begin |
|
2335 AllInactive:= false; |
|
2336 DeleteCI(PHedgehog(Gear^.Hedgehog)^.Gear); |
|
2337 Gear^.doStep:= @doStepSeductionWear |
|
2338 end; |
|
2339 |
|
2340 //////////////////////////////////////////////////////////////////////////////// |
|
2341 procedure doStepWaterUp(Gear: PGear); |
|
2342 var i: LongWord; |
|
2343 begin |
|
2344 AllInactive:= false; |
|
2345 |
|
2346 inc(Gear^.Timer); |
|
2347 if Gear^.Timer = 17 then |
|
2348 Gear^.Timer:= 0 |
|
2349 else |
|
2350 exit; |
|
2351 |
|
2352 if cWaterLine > 0 then |
|
2353 begin |
|
2354 dec(cWaterLine); |
|
2355 for i:= 0 to LAND_WIDTH - 1 do |
|
2356 Land[cWaterLine, i]:= 0; |
|
2357 SetAllToActive |
|
2358 end; |
|
2359 |
|
2360 inc(Gear^.Tag); |
|
2361 if (Gear^.Tag = 47) or (cWaterLine = 0) then |
|
2362 DeleteGear(Gear) |
|
2363 end; |
|
2364 |
|
2365 //////////////////////////////////////////////////////////////////////////////// |
|
2366 procedure doStepDrillDrilling(Gear: PGear); |
|
2367 var t: PGearArray; |
|
2368 ox, oy: hwFloat; |
|
2369 begin |
|
2370 AllInactive:= false; |
|
2371 |
|
2372 if (Gear^.Timer > 0) and ((Gear^.Timer mod 10) = 0) then |
|
2373 begin |
|
2374 ox:= Gear^.X; |
|
2375 oy:= Gear^.Y; |
|
2376 Gear^.X:= Gear^.X + Gear^.dX; |
|
2377 Gear^.Y:= Gear^.Y + Gear^.dY; |
|
2378 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 2, 6); |
|
2379 if(CheckGearDrowning(Gear)) then |
|
2380 begin |
|
2381 StopSound(Gear^.SoundChannel); |
|
2382 exit |
|
2383 end |
|
2384 end; |
|
2385 |
|
2386 t:= CheckGearsCollision(Gear); //fixes drill not exploding when touching HH bug |
|
2387 if (Gear^.Timer = 0) |
|
2388 or (t^.Count <> 0) |
|
2389 or (not TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) |
|
2390 and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) |
|
2391 or (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] = COLOR_INDESTRUCTIBLE) then |
|
2392 begin //out of time or exited ground |
|
2393 StopSound(Gear^.SoundChannel); |
|
2394 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
|
2395 DeleteGear(Gear); |
|
2396 exit |
|
2397 end; |
|
2398 |
|
2399 dec(Gear^.Timer); |
|
2400 end; |
|
2401 |
|
2402 procedure doStepDrill(Gear: PGear); |
|
2403 var t: PGearArray; |
|
2404 oldDx, oldDy: hwFloat; |
|
2405 t2: hwFloat; |
|
2406 begin |
|
2407 AllInactive:= false; |
|
2408 |
|
2409 Gear^.dX:= Gear^.dX + cWindSpeed; |
|
2410 oldDx:= Gear^.dX; |
|
2411 oldDy:= Gear^.dY; |
|
2412 |
|
2413 doStepFallingGear(Gear); |
|
2414 |
|
2415 if (GameTicks and $3F) = 0 then |
|
2416 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
|
2417 |
|
2418 if ((Gear^.State and gstCollision) <> 0) then begin //hit |
|
2419 Gear^.dX:= oldDx; |
|
2420 Gear^.dY:= oldDy; |
|
2421 |
|
2422 t:= CheckGearsCollision(Gear); |
|
2423 if (t^.Count = 0) then begin //hit the ground not the HH |
|
2424 t2 := _0_5 / Distance(Gear^.dX, Gear^.dY); |
|
2425 Gear^.dX:= Gear^.dX * t2; |
|
2426 Gear^.dY:= Gear^.dY * t2; |
|
2427 end else begin //explode right on contact with HH |
|
2428 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
|
2429 DeleteGear(Gear); |
|
2430 exit; |
|
2431 end; |
|
2432 |
|
2433 Gear^.SoundChannel:= LoopSound(sndDrillRocket); |
|
2434 Gear^.doStep:= @doStepDrillDrilling; |
|
2435 dec(Gear^.Timer) |
|
2436 end |
|
2437 end; |
|
2438 |
|
2439 //////////////////////////////////////////////////////////////////////////////// |
|
2440 procedure doStepBallgunWork(Gear: PGear); |
|
2441 var HHGear: PGear; |
|
2442 rx, ry: hwFloat; |
2600 rx, ry: hwFloat; |
2443 gX, gY: LongInt; |
2601 gX, gY: LongInt; |
2444 begin |
2602 begin |
2445 AllInactive:= false; |
2603 AllInactive := false; |
2446 dec(Gear^.Timer); |
2604 dec(Gear^.Timer); |
2447 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
2605 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
2448 HedgehogChAngle(HHGear); |
2606 HedgehogChAngle(HHGear); |
2449 gX:= hwRound(Gear^.X); |
2607 gX := hwRound(Gear^.X); |
2450 gY:= hwRound(Gear^.Y); |
2608 gY := hwRound(Gear^.Y); |
2451 if (Gear^.Timer mod 100) = 0 then |
2609 if (Gear^.Timer mod 100) = 0 then |
2452 begin |
2610 begin |
2453 rx:= rndSign(getRandom * _0_1); |
2611 rx := rndSign(getRandom * _0_1); |
2454 ry:= rndSign(getRandom * _0_1); |
2612 ry := rndSign(getRandom * _0_1); |
2455 |
2613 |
2456 AddGear(gx, gy, gtBall, 0, |
2614 AddGear(gx, gy, gtBall, 0, |
2457 SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, |
2615 SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, |
2458 AngleCos(HHGear^.Angle) * ( - _0_8) + ry, |
2616 AngleCos(HHGear^.Angle) * ( - _0_8) + ry, |
2459 0); |
2617 0); |
2460 |
2618 |
2461 PlaySound(sndGun); |
2619 PlaySound(sndGun); |
2462 end; |
2620 end; |
2463 |
2621 |
2464 if (Gear^.Timer = 0) or (HHGear^.Damage <> 0) then |
2622 if (Gear^.Timer = 0) or (HHGear^.Damage <> 0) then |
2465 begin |
2623 begin |
2466 DeleteGear(Gear); |
2624 DeleteGear(Gear); |
2467 AfterAttack |
2625 AfterAttack |
2468 end |
2626 end |
2469 end; |
2627 end; |
2470 |
2628 |
2471 procedure doStepBallgun(Gear: PGear); |
2629 procedure doStepBallgun(Gear: PGear); |
2472 var HHGear: PGear; |
2630 var |
2473 begin |
2631 HHGear: PGear; |
2474 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
2632 begin |
2475 HHGear^.Message:= HHGear^.Message and not (gm_Up or gm_Down); |
2633 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
2476 HHGear^.State:= HHGear^.State or gstNotKickable; |
2634 HHGear^.Message := HHGear^.Message and not (gm_Up or gm_Down); |
2477 Gear^.doStep:= @doStepBallgunWork |
2635 HHGear^.State := HHGear^.State or gstNotKickable; |
|
2636 Gear^.doStep := @doStepBallgunWork |
2478 end; |
2637 end; |
2479 |
2638 |
2480 //////////////////////////////////////////////////////////////////////////////// |
2639 //////////////////////////////////////////////////////////////////////////////// |
2481 procedure doStepRCPlaneWork(Gear: PGear); |
2640 procedure doStepRCPlaneWork(Gear: PGear); |
2482 const cAngleSpeed = 3; |
2641 |
2483 var HHGear: PGear; |
2642 const cAngleSpeed = 3; |
|
2643 var |
|
2644 HHGear: PGear; |
2484 i: LongInt; |
2645 i: LongInt; |
2485 dX, dY: hwFloat; |
2646 dX, dY: hwFloat; |
2486 fChanged: boolean; |
2647 fChanged: boolean; |
2487 trueAngle: Longword; |
2648 trueAngle: Longword; |
2488 t: PGear; |
2649 t: PGear; |
2489 begin |
2650 begin |
2490 AllInactive:= false; |
2651 AllInactive := false; |
2491 |
2652 |
2492 if ((TrainingFlags and tfRCPlane) = 0) and (Gear^.Timer > 0) then dec(Gear^.Timer); |
2653 if ((TrainingFlags and tfRCPlane) = 0) and (Gear^.Timer > 0) then dec(Gear^.Timer); |
2493 |
2654 |
2494 if ((TrainingFlags and tfRCPlane) <> 0) and ((TrainingFlags and tfTimeTrial) <> 0 ) and (TimeTrialStartTime = 0) then TimeTrialStartTime:= RealTicks; |
2655 if ((TrainingFlags and tfRCPlane) <> 0) and ((TrainingFlags and tfTimeTrial) <> 0 ) and ( |
2495 |
2656 TimeTrialStartTime = 0) then TimeTrialStartTime := RealTicks; |
2496 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
2657 |
2497 FollowGear:= Gear; |
2658 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
2498 |
2659 FollowGear := Gear; |
2499 fChanged:= false; |
2660 |
2500 if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then |
2661 fChanged := false; |
2501 begin |
2662 if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then |
2502 fChanged:= true; |
2663 begin |
2503 if Gear^.Angle > 2048 then dec(Gear^.Angle) else |
2664 fChanged := true; |
2504 if Gear^.Angle < 2048 then inc(Gear^.Angle) else fChanged:= false |
2665 if Gear^.Angle > 2048 then dec(Gear^.Angle) |
2505 end |
2666 else |
2506 else |
2667 if Gear^.Angle < 2048 then inc(Gear^.Angle) |
2507 begin |
2668 else fChanged := false |
2508 if ((Gear^.Message and gm_Left) <> 0) then |
2669 end |
2509 begin |
2670 else |
2510 fChanged:= true; |
2671 begin |
2511 Gear^.Angle:= (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096 |
2672 if ((Gear^.Message and gm_Left) <> 0) then |
2512 end; |
2673 begin |
2513 |
2674 fChanged := true; |
2514 if ((Gear^.Message and gm_Right) <> 0) then |
2675 Gear^.Angle := (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096 |
2515 begin |
2676 end; |
2516 fChanged:= true; |
2677 |
2517 Gear^.Angle:= (Gear^.Angle + cAngleSpeed) mod 4096 |
2678 if ((Gear^.Message and gm_Right) <> 0) then |
|
2679 begin |
|
2680 fChanged := true; |
|
2681 Gear^.Angle := (Gear^.Angle + cAngleSpeed) mod 4096 |
2518 end |
2682 end |
2519 end; |
2683 end; |
2520 |
2684 |
2521 if fChanged then |
2685 if fChanged then |
2522 begin |
2686 begin |
2523 Gear^.dX.isNegative:= (Gear^.Angle > 2048); |
2687 Gear^.dX.isNegative := (Gear^.Angle > 2048); |
2524 if Gear^.dX.isNegative then |
2688 if Gear^.dX.isNegative then |
2525 trueAngle:= 4096 - Gear^.Angle |
2689 trueAngle := 4096 - Gear^.Angle |
2526 else |
2690 else |
2527 trueAngle:= Gear^.Angle; |
2691 trueAngle := Gear^.Angle; |
2528 |
2692 |
2529 Gear^.dX:= SignAs(AngleSin(trueAngle), Gear^.dX) * _0_25; |
2693 Gear^.dX := SignAs(AngleSin(trueAngle), Gear^.dX) * _0_25; |
2530 Gear^.dY:= AngleCos(trueAngle) * -_0_25; |
2694 Gear^.dY := AngleCos(trueAngle) * -_0_25; |
2531 end; |
2695 end; |
2532 |
2696 |
2533 Gear^.X:= Gear^.X + Gear^.dX; |
2697 Gear^.X := Gear^.X + Gear^.dX; |
2534 Gear^.Y:= Gear^.Y + Gear^.dY; |
2698 Gear^.Y := Gear^.Y + Gear^.dY; |
2535 |
2699 |
2536 if (TrainingFlags and tfRCPlane) = 0 then |
2700 if (TrainingFlags and tfRCPlane) = 0 then |
2537 begin |
2701 begin |
2538 if (GameTicks and $FF) = 0 then |
2702 if (GameTicks and $FF) = 0 then |
2539 if Gear^.Timer < 3500 then |
2703 if Gear^.Timer < 3500 then |
2540 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace) |
2704 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace) |
2541 else |
2705 else |
2542 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
2706 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
2543 |
2707 |
2544 if ((HHGear^.Message and gm_Attack) <> 0) and (Gear^.Health <> 0) then |
2708 if ((HHGear^.Message and gm_Attack) <> 0) and (Gear^.Health <> 0) then |
2545 begin |
2709 begin |
2546 HHGear^.Message := HHGear^.Message and not gm_Attack; |
2710 HHGear^.Message := HHGear^.Message and not gm_Attack; |
2547 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * _0_5, 0); |
2711 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * |
2548 dec(Gear^.Health) |
2712 _0_5, 0); |
2549 end; |
2713 dec(Gear^.Health) |
2550 |
2714 end; |
2551 if ((HHGear^.Message and gm_LJump) <> 0) |
2715 |
2552 and ((Gear^.State and gsttmpFlag) = 0) then |
2716 if ((HHGear^.Message and gm_LJump) <> 0) |
2553 begin |
2717 and ((Gear^.State and gsttmpFlag) = 0) then |
2554 Gear^.State:= Gear^.State or gsttmpFlag; |
2718 begin |
2555 PauseMusic; |
2719 Gear^.State := Gear^.State or gsttmpFlag; |
2556 playSound(sndRideOfTheValkyries); |
2720 PauseMusic; |
2557 end; |
2721 playSound(sndRideOfTheValkyries); |
2558 |
2722 end; |
2559 // pickup bonuses |
2723 |
2560 t:= CheckGearNear(Gear, gtCase, 36, 36); |
2724 // pickup bonuses |
2561 if t <> nil then |
2725 t := CheckGearNear(Gear, gtCase, 36, 36); |
2562 PickUp(HHGear, t); |
2726 if t <> nil then |
2563 end |
2727 PickUp(HHGear, t); |
2564 else |
2728 end |
2565 begin |
2729 else |
2566 if (GameTicks and $FF) = 0 then |
2730 begin |
2567 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
2731 if (GameTicks and $FF) = 0 then |
2568 |
2732 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
2569 // pickup targets |
2733 |
2570 t:= CheckGearNear(Gear, gtTarget, 36, 36); |
2734 // pickup targets |
2571 if t <> nil then |
2735 t := CheckGearNear(Gear, gtTarget, 36, 36); |
2572 begin |
2736 if t <> nil then |
2573 if t^.Tag <> 0 then // collect it only once |
2737 begin |
|
2738 if t^.Tag <> 0 then // collect it only once |
|
2739 exit; |
|
2740 PlaySound(sndShotgunReload); |
|
2741 t^.Tag := 1; |
|
2742 TrainingTargetGear := nil; |
|
2743 // remove target cursor |
2574 exit; |
2744 exit; |
2575 PlaySound(sndShotgunReload); |
2745 end; |
2576 t^.Tag:= 1; |
2746 |
2577 TrainingTargetGear:= nil; // remove target cursor |
2747 if (TurnTimeLeft > 0) then |
2578 exit; |
2748 dec(TurnTimeLeft) |
2579 end; |
2749 end; |
2580 |
2750 |
2581 if (TurnTimeLeft > 0) then |
2751 CheckCollision(Gear); |
2582 dec(TurnTimeLeft) |
2752 |
2583 end; |
2753 if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and ( |
2584 |
2754 TurnTimeLeft = 0)) |
2585 CheckCollision(Gear); |
2755 or CheckGearDrowning(Gear) then |
2586 |
2756 begin |
2587 if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and (TurnTimeLeft = 0)) |
2757 if ((TrainingFlags and tfRCPlane) <> 0) and ((TrainingFlags and tfTimeTrial) <> 0 ) and ( |
2588 or CheckGearDrowning(Gear) then |
2758 TimeTrialStopTime = 0) then TimeTrialStopTime := RealTicks; |
2589 begin |
2759 StopSound(Gear^.SoundChannel); |
2590 if ((TrainingFlags and tfRCPlane) <> 0) and ((TrainingFlags and tfTimeTrial) <> 0 ) and (TimeTrialStopTime = 0) then TimeTrialStopTime:= RealTicks; |
2760 StopSound(sndRideOfTheValkyries); |
2591 StopSound(Gear^.SoundChannel); |
2761 ResumeMusic; |
2592 StopSound(sndRideOfTheValkyries); |
2762 |
2593 ResumeMusic; |
2763 if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and ( |
2594 |
2764 TurnTimeLeft = 0)) then |
2595 if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and (TurnTimeLeft = 0)) then |
2765 begin |
2596 begin |
2766 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, EXPLAutoSound); |
2597 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, EXPLAutoSound); |
2767 for i:= 0 to 32 do |
2598 for i:= 0 to 32 do |
|
2599 begin |
2768 begin |
2600 dX:= AngleCos(i * 64) * _0_5 * (GetRandom + _1); |
2769 dX := AngleCos(i * 64) * _0_5 * (GetRandom + _1); |
2601 dY:= AngleSin(i * 64) * _0_5 * (GetRandom + _1); |
2770 dY := AngleSin(i * 64) * _0_5 * (GetRandom + _1); |
2602 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); |
2771 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); |
2603 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); |
2772 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); |
2604 end; |
2773 end; |
2605 DeleteGear(Gear) |
2774 DeleteGear(Gear) |
2606 end; |
2775 end; |
2607 |
2776 |
2608 AfterAttack; |
2777 AfterAttack; |
2609 CurAmmoGear:= nil; |
2778 CurAmmoGear := nil; |
2610 TurnTimeLeft:= 14 * 125; |
2779 TurnTimeLeft := 14 * 125; |
2611 |
2780 |
2612 if (TrainingFlags and tfRCPlane) <> 0 then |
2781 if (TrainingFlags and tfRCPlane) <> 0 then |
2613 TurnTimeLeft:= 0; // HACK: RCPlane training allows unlimited plane starts in last 2 seconds |
2782 TurnTimeLeft := 0; |
2614 |
2783 // HACK: RCPlane training allows unlimited plane starts in last 2 seconds |
2615 HHGear^.Message:= 0; |
2784 |
2616 ParseCommand('/taunt '#1, true) |
2785 HHGear^.Message := 0; |
|
2786 ParseCommand('/taunt '#1, true) |
2617 end |
2787 end |
2618 end; |
2788 end; |
2619 |
2789 |
2620 procedure doStepRCPlane(Gear: PGear); |
2790 procedure doStepRCPlane(Gear: PGear); |
2621 var HHGear: PGear; |
2791 var |
2622 begin |
2792 HHGear: PGear; |
2623 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
2793 begin |
2624 HHGear^.Message:= 0; |
2794 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
2625 HHGear^.State:= HHGear^.State or gstNotKickable; |
2795 HHGear^.Message := 0; |
2626 Gear^.Angle:= HHGear^.Angle; |
2796 HHGear^.State := HHGear^.State or gstNotKickable; |
2627 Gear^.Tag:= hwSign(HHGear^.dX); |
2797 Gear^.Angle := HHGear^.Angle; |
2628 if HHGear^.dX.isNegative then Gear^.Angle:= 4096 - Gear^.Angle; |
2798 Gear^.Tag := hwSign(HHGear^.dX); |
2629 Gear^.doStep:= @doStepRCPlaneWork |
2799 if HHGear^.dX.isNegative then Gear^.Angle := 4096 - Gear^.Angle; |
|
2800 Gear^.doStep := @doStepRCPlaneWork |
2630 end; |
2801 end; |
2631 |
2802 |
2632 procedure doStepJetpackWork(Gear: PGear); |
2803 procedure doStepJetpackWork(Gear: PGear); |
2633 var HHGear: PGear; |
2804 var |
|
2805 HHGear: PGear; |
2634 fuel: LongInt; |
2806 fuel: LongInt; |
2635 move: hwFloat; |
2807 move: hwFloat; |
2636 begin |
2808 begin |
2637 AllInactive:= false; |
2809 AllInactive := false; |
2638 HHGear:=PHedgehog(Gear^.Hedgehog)^.Gear; |
2810 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
2639 //dec(Gear^.Timer); |
2811 //dec(Gear^.Timer); |
2640 move:= _0_1; |
2812 move := _0_1; |
2641 fuel:= 50; |
2813 fuel := 50; |
2642 (*if (HHGear^.Message and gm_Precise) <> 0 then |
2814 (*if (HHGear^.Message and gm_Precise) <> 0 then |
2643 begin |
2815 begin |
2644 move:= _0_02; |
2816 move:= _0_02; |
2645 fuel:= 5; |
2817 fuel:= 5; |
2646 end;*) |
2818 end;*) |
2647 |
2819 |
2648 if (HHGear^.Message and gm_Up) <> 0 then |
2820 if (HHGear^.Message and gm_Up) <> 0 then |
2649 begin |
2821 begin |
2650 if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then |
2822 if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then |
2651 HHGear^.dY:= HHGear^.dY - move; |
2823 HHGear^.dY := HHGear^.dY - move; |
2652 HHGear^.dY:= HHGear^.dY - move; |
2824 HHGear^.dY := HHGear^.dY - move; |
2653 dec(Gear^.Health, fuel); |
2825 dec(Gear^.Health, fuel); |
2654 Gear^.MsgParam:= Gear^.MsgParam or gm_Up; |
2826 Gear^.MsgParam := Gear^.MsgParam or gm_Up; |
2655 Gear^.Timer:= GameTicks |
2827 Gear^.Timer := GameTicks |
2656 end; |
2828 end; |
2657 if (HHGear^.Message and gm_Left) <> 0 then move.isNegative:= true; |
2829 if (HHGear^.Message and gm_Left) <> 0 then move.isNegative := true; |
2658 if (HHGear^.Message and (gm_Left or gm_Right)) <> 0 then |
2830 if (HHGear^.Message and (gm_Left or gm_Right)) <> 0 then |
2659 begin |
2831 begin |
2660 HHGear^.dX:= HHGear^.dX + (move * _0_2); |
2832 HHGear^.dX := HHGear^.dX + (move * _0_2); |
2661 dec(Gear^.Health, fuel div 5); |
2833 dec(Gear^.Health, fuel div 5); |
2662 Gear^.MsgParam:= Gear^.MsgParam or (HHGear^.Message and (gm_Left or gm_Right)); |
2834 Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gm_Left or gm_Right)); |
2663 Gear^.Timer:= GameTicks |
2835 Gear^.Timer := GameTicks |
2664 end; |
2836 end; |
2665 |
2837 |
2666 // erases them all at once :-/ |
2838 // erases them all at once :-/ |
2667 if (Gear^.Timer <> 0) and (GameTicks - Gear^.Timer > 250) then |
2839 if (Gear^.Timer <> 0) and (GameTicks - Gear^.Timer > 250) then |
2668 begin |
2840 begin |
2669 Gear^.Timer:= 0; |
2841 Gear^.Timer := 0; |
2670 Gear^.MsgParam:= 0 |
2842 Gear^.MsgParam := 0 |
2671 end; |
2843 end; |
2672 |
2844 |
2673 if Gear^.Health < 0 then Gear^.Health:= 0; |
2845 if Gear^.Health < 0 then Gear^.Health := 0; |
2674 if (GameTicks and $3F) = 0 then |
2846 if (GameTicks and $3F) = 0 then |
2675 begin |
2847 begin |
2676 //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
2848 //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
2677 if Gear^.Tex <> nil then FreeTexture(Gear^.Tex); |
2849 if Gear^.Tex <> nil then FreeTexture(Gear^.Tex); |
2678 Gear^.Tex:= RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + '%', cWhiteColor, fntSmall) |
2850 Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + |
2679 end; |
2851 '%', cWhiteColor, fntSmall) |
2680 |
2852 end; |
2681 if HHGear^.Message and (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right) <> 0 then Gear^.State:= Gear^.State and not gsttmpFlag; |
2853 |
2682 HHGear^.Message:= HHGear^.Message and not (gm_Up or gm_Precise or gm_Left or gm_Right); |
2854 if HHGear^.Message and (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right) <> 0 then Gear^ |
2683 HHGear^.State:= HHGear^.State or gstMoving; |
2855 .State := Gear^.State and not gsttmpFlag; |
2684 |
2856 HHGear^.Message := HHGear^.Message and not (gm_Up or gm_Precise or gm_Left or gm_Right); |
2685 Gear^.X:= HHGear^.X; |
2857 HHGear^.State := HHGear^.State or gstMoving; |
2686 Gear^.Y:= HHGear^.Y; |
2858 |
2687 // For some reason I need to reapply followgear here, something else grabs it otherwise. |
2859 Gear^.X := HHGear^.X; |
2688 if not bShowAmmoMenu then FollowGear:= HHGear; |
2860 Gear^.Y := HHGear^.Y; |
2689 |
2861 // For some reason I need to reapply followgear here, something else grabs it otherwise. |
2690 if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear); |
2862 if not bShowAmmoMenu then FollowGear := HHGear; |
2691 |
2863 |
2692 if (Gear^.Health = 0) |
2864 if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear); |
2693 or (HHGear^.Damage <> 0) |
2865 |
2694 or CheckGearDrowning(HHGear) |
2866 if (Gear^.Health = 0) |
2695 or (TurnTimeLeft = 0) |
2867 or (HHGear^.Damage <> 0) |
2696 // allow brief ground touches - to be fair on this, might need another counter |
2868 or CheckGearDrowning(HHGear) |
2697 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear(HHGear, 1)) |
2869 or (TurnTimeLeft = 0) |
2698 or ((Gear^.Message and gm_Attack) <> 0) then |
2870 // allow brief ground touches - to be fair on this, might need another counter |
2699 begin |
2871 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear( |
|
2872 HHGear, 1)) |
|
2873 or ((Gear^.Message and gm_Attack) <> 0) then |
|
2874 begin |
|
2875 with HHGear^ do |
|
2876 begin |
|
2877 Message := 0; |
|
2878 Active := true; |
|
2879 State := State or gstMoving |
|
2880 end; |
|
2881 DeleteGear(Gear); |
|
2882 isCursorVisible := false; |
|
2883 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
|
2884 // if Gear^.Tex <> nil then FreeTexture(Gear^.Tex); |
|
2885 |
|
2886 // Gear^.Tex:= RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + '%', cWhiteColor, fntSmall) |
|
2887 |
|
2888 //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
|
2889 end |
|
2890 end; |
|
2891 |
|
2892 //////////////////////////////////////////////////////////////////////////////// |
|
2893 procedure doStepJetpack(Gear: PGear); |
|
2894 var |
|
2895 HHGear: PGear; |
|
2896 begin |
|
2897 Gear^.doStep := @doStepJetpackWork; |
|
2898 |
|
2899 HHGear := PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2900 FollowGear := HHGear; |
|
2901 AfterAttack; |
2700 with HHGear^ do |
2902 with HHGear^ do |
2701 begin |
2903 begin |
2702 Message:= 0; |
2904 State := State and not gstAttacking; |
2703 Active:= true; |
2905 Message := Message and not (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right); |
2704 State:= State or gstMoving |
2906 if (dY < _0_1) and (dY > -_0_1) then |
2705 end; |
2907 begin |
2706 DeleteGear(Gear); |
2908 Gear^.State := Gear^.State or gsttmpFlag; |
2707 isCursorVisible:= false; |
2909 dY := dY - _0_2 |
2708 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
|
2709 // if Gear^.Tex <> nil then FreeTexture(Gear^.Tex); |
|
2710 // Gear^.Tex:= RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + '%', cWhiteColor, fntSmall) |
|
2711 //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
|
2712 end |
|
2713 end; |
|
2714 |
|
2715 //////////////////////////////////////////////////////////////////////////////// |
|
2716 procedure doStepJetpack(Gear: PGear); |
|
2717 var HHGear: PGear; |
|
2718 begin |
|
2719 Gear^.doStep:= @doStepJetpackWork; |
|
2720 |
|
2721 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
|
2722 FollowGear:= HHGear; |
|
2723 AfterAttack; |
|
2724 with HHGear^ do |
|
2725 begin |
|
2726 State:= State and not gstAttacking; |
|
2727 Message:= Message and not (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right); |
|
2728 if (dY < _0_1) and (dY > -_0_1) then |
|
2729 begin |
|
2730 Gear^.State:= Gear^.State or gsttmpFlag; |
|
2731 dY:= dY - _0_2 |
|
2732 end |
2910 end |
2733 end |
2911 end |
2734 end; |
2912 end; |
2735 |
2913 |
2736 //////////////////////////////////////////////////////////////////////////////// |
2914 //////////////////////////////////////////////////////////////////////////////// |
2737 procedure doStepBirdyDisappear(Gear: PGear); |
2915 procedure doStepBirdyDisappear(Gear: PGear); |
2738 begin |
2916 begin |
2739 AllInactive:= false; |
2917 AllInactive := false; |
2740 Gear^.Pos:= 0; |
2918 Gear^.Pos := 0; |
2741 if Gear^.Timer < 2000 then |
2919 if Gear^.Timer < 2000 then |
2742 inc(Gear^.Timer, 1) |
2920 inc(Gear^.Timer, 1) |
2743 else |
2921 else |
2744 begin |
2922 begin |
2745 DeleteGear(Gear); |
2923 DeleteGear(Gear); |
2746 end; |
2924 end; |
2747 end; |
2925 end; |
2748 |
2926 |
2749 //////////////////////////////////////////////////////////////////////////////// |
2927 //////////////////////////////////////////////////////////////////////////////// |
2750 procedure doStepBirdyFly(Gear: PGear); |
2928 procedure doStepBirdyFly(Gear: PGear); |
2751 var HHGear: PGear; |
2929 var |
|
2930 HHGear: PGear; |
2752 fuel, i: LongInt; |
2931 fuel, i: LongInt; |
2753 move: hwFloat; |
2932 move: hwFloat; |
2754 begin |
2933 begin |
2755 HHGear:= CurrentHedgehog^.Gear; |
2934 HHGear := CurrentHedgehog^.Gear; |
2756 |
2935 |
2757 move:= _0_1; |
2936 move := _0_1; |
2758 fuel:= 50; |
2937 fuel := 50; |
2759 |
2938 |
2760 if Gear^.Pos > 0 then |
2939 if Gear^.Pos > 0 then |
2761 dec(Gear^.Pos, 1) |
2940 dec(Gear^.Pos, 1) |
2762 else if (HHGear^.Message and (gm_Left or gm_Right or gm_Up)) <> 0 then |
2941 else if (HHGear^.Message and (gm_Left or gm_Right or gm_Up)) <> 0 then |
2763 Gear^.Pos:= 500; |
2942 Gear^.Pos := 500; |
2764 |
2943 |
2765 if HHGear^.dX.isNegative then |
2944 if HHGear^.dX.isNegative then |
2766 Gear^.Tag:= -1 |
2945 Gear^.Tag := -1 |
2767 else |
2946 else |
2768 Gear^.Tag:= 1; |
2947 Gear^.Tag := 1; |
2769 |
2948 |
2770 if (HHGear^.Message and gm_Up) <> 0 then |
2949 if (HHGear^.Message and gm_Up) <> 0 then |
2771 begin |
2950 begin |
2772 if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then |
2951 if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then |
2773 HHGear^.dY:= HHGear^.dY - move; |
2952 HHGear^.dY := HHGear^.dY - move; |
2774 HHGear^.dY:= HHGear^.dY - move; |
2953 HHGear^.dY := HHGear^.dY - move; |
2775 dec(Gear^.Health, fuel); |
2954 dec(Gear^.Health, fuel); |
2776 Gear^.MsgParam:= Gear^.MsgParam or gm_Up; |
2955 Gear^.MsgParam := Gear^.MsgParam or gm_Up; |
2777 end; |
2956 end; |
2778 if (HHGear^.Message and gm_Left) <> 0 then move.isNegative:= true; |
2957 if (HHGear^.Message and gm_Left) <> 0 then move.isNegative := true; |
2779 if (HHGear^.Message and (gm_Left or gm_Right)) <> 0 then |
2958 if (HHGear^.Message and (gm_Left or gm_Right)) <> 0 then |
2780 begin |
2959 begin |
2781 HHGear^.dX:= HHGear^.dX + (move * _0_2); |
2960 HHGear^.dX := HHGear^.dX + (move * _0_2); |
2782 dec(Gear^.Health, fuel div 5); |
2961 dec(Gear^.Health, fuel div 5); |
2783 Gear^.MsgParam:= Gear^.MsgParam or (HHGear^.Message and (gm_Left or gm_Right)); |
2962 Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gm_Left or gm_Right)); |
2784 end; |
2963 end; |
2785 |
2964 |
2786 if Gear^.Health < 0 then Gear^.Health:= 0; |
2965 if Gear^.Health < 0 then Gear^.Health := 0; |
2787 if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then |
2966 if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then |
2788 for i:= ((500-Gear^.Health) div 250) downto 0 do |
2967 for i:= ((500-Gear^.Health) div 250) downto 0 do |
2789 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather); |
2968 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather); |
2790 |
2969 |
2791 if (HHGear^.Message and gm_Attack <> 0) then begin |
2970 if (HHGear^.Message and gm_Attack <> 0) then |
|
2971 begin |
2792 HHGear^.Message := HHGear^.Message and not gm_Attack; |
2972 HHGear^.Message := HHGear^.Message and not gm_Attack; |
2793 if Gear^.FlightTime > 0 then begin |
2973 if Gear^.FlightTime > 0 then |
2794 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) + 32, gtEgg, 0, Gear^.dX * _0_5, Gear^.dY, 0); |
2974 begin |
|
2975 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) + 32, gtEgg, 0, Gear^.dX * _0_5, Gear^.dY, 0) |
|
2976 ; |
2795 PlaySound(sndBirdyLay); |
2977 PlaySound(sndBirdyLay); |
2796 dec(Gear^.FlightTime) |
2978 dec(Gear^.FlightTime) |
2797 end; |
2979 end; |
2798 end; |
2980 end; |
2799 |
2981 |
2800 if HHGear^.Message and (gm_Up or gm_Precise or gm_Left or gm_Right) <> 0 then Gear^.State:= Gear^.State and not gsttmpFlag; |
2982 if HHGear^.Message and (gm_Up or gm_Precise or gm_Left or gm_Right) <> 0 then Gear^.State := |
2801 HHGear^.Message:= HHGear^.Message and not (gm_Up or gm_Precise or gm_Left or gm_Right); |
2983 Gear |
2802 HHGear^.State:= HHGear^.State or gstMoving; |
2984 ^. |
2803 |
2985 State |
2804 Gear^.X:= HHGear^.X; |
2986 and |
2805 Gear^.Y:= HHGear^.Y - int2hwFloat(32); |
2987 not |
2806 // For some reason I need to reapply followgear here, something else grabs it otherwise. |
2988 gsttmpFlag |
2807 if not bShowAmmoMenu then FollowGear:= HHGear; |
2989 ; |
2808 |
2990 HHGear^.Message := HHGear^.Message and not (gm_Up or gm_Precise or gm_Left or gm_Right); |
2809 if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear); |
2991 HHGear^.State := HHGear^.State or gstMoving; |
2810 |
2992 |
2811 if (Gear^.Health = 0) |
2993 Gear^.X := HHGear^.X; |
2812 or (HHGear^.Damage <> 0) |
2994 Gear^.Y := HHGear^.Y - int2hwFloat(32); |
2813 or CheckGearDrowning(HHGear) |
2995 // For some reason I need to reapply followgear here, something else grabs it otherwise. |
2814 or (TurnTimeLeft = 0) |
2996 if not bShowAmmoMenu then FollowGear := HHGear; |
2815 // allow brief ground touches - to be fair on this, might need another counter |
2997 |
2816 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear(HHGear, 1)) |
2998 if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear); |
2817 or ((Gear^.Message and gm_Attack) <> 0) then |
2999 |
2818 begin |
3000 if (Gear^.Health = 0) |
|
3001 or (HHGear^.Damage <> 0) |
|
3002 or CheckGearDrowning(HHGear) |
|
3003 or (TurnTimeLeft = 0) |
|
3004 // allow brief ground touches - to be fair on this, might need another counter |
|
3005 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear( |
|
3006 HHGear, 1)) |
|
3007 or ((Gear^.Message and gm_Attack) <> 0) then |
|
3008 begin |
|
3009 with HHGear^ do |
|
3010 begin |
|
3011 Message := 0; |
|
3012 Active := true; |
|
3013 State := State or gstMoving |
|
3014 end; |
|
3015 Gear^.State := Gear^.State or gstAnimation or gstTmpFlag; |
|
3016 if HHGear^.dY < _0 then |
|
3017 begin |
|
3018 Gear^.dX := HHGear^.dX; |
|
3019 Gear^.dY := HHGear^.dY; |
|
3020 end; |
|
3021 Gear^.Timer := 0; |
|
3022 Gear^.doStep := @doStepBirdyDisappear; |
|
3023 CurAmmoGear := nil; |
|
3024 isCursorVisible := false; |
|
3025 AfterAttack; |
|
3026 end |
|
3027 end; |
|
3028 |
|
3029 //////////////////////////////////////////////////////////////////////////////// |
|
3030 procedure doStepBirdyDescend(Gear: PGear); |
|
3031 var |
|
3032 HHGear: PGear; |
|
3033 begin |
|
3034 if Gear^.Timer > 0 then |
|
3035 dec(Gear^.Timer, 1) |
|
3036 else if CurrentHedgehog = nil then |
|
3037 begin |
|
3038 DeleteGear(Gear); |
|
3039 AfterAttack; |
|
3040 exit |
|
3041 end; |
|
3042 HHGear := CurrentHedgehog^.Gear; |
|
3043 HHGear^.Message := HHGear^.Message and not (gm_Up or gm_Precise or gm_Left or gm_Right); |
|
3044 if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then |
|
3045 begin |
|
3046 if Gear^.Timer = 0 then |
|
3047 Gear^.Y := Gear^.Y + _0_1 |
|
3048 end |
|
3049 else if Gear^.Timer = 0 then |
|
3050 begin |
|
3051 Gear^.doStep := @doStepBirdyFly; |
|
3052 HHGear^.dY := -_0_2 |
|
3053 end |
|
3054 end; |
|
3055 |
|
3056 procedure doStepBirdyAppear(Gear: PGear); |
|
3057 begin |
|
3058 Gear^.Pos := 0; |
|
3059 if Gear^.Timer < 2000 then |
|
3060 inc(Gear^.Timer, 1) |
|
3061 else |
|
3062 begin |
|
3063 Gear^.Timer := 500; |
|
3064 Gear^.dX := _0; |
|
3065 Gear^.dY := _0; |
|
3066 Gear^.State := Gear^.State and not gstAnimation; |
|
3067 Gear^.doStep := @doStepBirdyDescend; |
|
3068 end |
|
3069 end; |
|
3070 |
|
3071 //////////////////////////////////////////////////////////////////////////////// |
|
3072 procedure doStepBirdy(Gear: PGear); |
|
3073 var |
|
3074 HHGear: PGear; |
|
3075 begin |
|
3076 gear^.State := gear^.State or gstAnimation and not gstTmpFlag; |
|
3077 Gear^.doStep := @doStepBirdyAppear; |
|
3078 if CurrentHedgehog = nil then |
|
3079 begin |
|
3080 DeleteGear(Gear); |
|
3081 exit |
|
3082 end; |
|
3083 |
|
3084 HHGear := CurrentHedgehog^.Gear; |
|
3085 |
|
3086 if HHGear^.dX.isNegative then |
|
3087 Gear^.Tag := -1 |
|
3088 else |
|
3089 Gear^.Tag := 1; |
|
3090 Gear^.Pos := 0; |
|
3091 AllInactive := false; |
|
3092 FollowGear := HHGear; |
2819 with HHGear^ do |
3093 with HHGear^ do |
2820 begin |
3094 begin |
2821 Message:= 0; |
3095 State := State and not gstAttacking; |
2822 Active:= true; |
3096 Message := Message and not (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right) |
2823 State:= State or gstMoving |
|
2824 end; |
|
2825 Gear^.State:= Gear^.State or gstAnimation or gstTmpFlag; |
|
2826 if HHGear^.dY < _0 then |
|
2827 begin |
|
2828 Gear^.dX:= HHGear^.dX; |
|
2829 Gear^.dY:= HHGear^.dY; |
|
2830 end; |
|
2831 Gear^.Timer:= 0; |
|
2832 Gear^.doStep:= @doStepBirdyDisappear; |
|
2833 CurAmmoGear:= nil; |
|
2834 isCursorVisible:= false; |
|
2835 AfterAttack; |
|
2836 end |
|
2837 end; |
|
2838 |
|
2839 //////////////////////////////////////////////////////////////////////////////// |
|
2840 procedure doStepBirdyDescend(Gear: PGear); |
|
2841 var HHGear: PGear; |
|
2842 begin |
|
2843 if Gear^.Timer > 0 then |
|
2844 dec(Gear^.Timer, 1) |
|
2845 else if CurrentHedgehog = nil then |
|
2846 begin |
|
2847 DeleteGear(Gear); |
|
2848 AfterAttack; |
|
2849 exit |
|
2850 end; |
|
2851 HHGear:= CurrentHedgehog^.Gear; |
|
2852 HHGear^.Message:= HHGear^.Message and not (gm_Up or gm_Precise or gm_Left or gm_Right); |
|
2853 if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then |
|
2854 begin |
|
2855 if Gear^.Timer = 0 then |
|
2856 Gear^.Y:= Gear^.Y + _0_1 |
|
2857 end |
|
2858 else if Gear^.Timer = 0 then |
|
2859 begin |
|
2860 Gear^.doStep:= @doStepBirdyFly; |
|
2861 HHGear^.dY:= -_0_2 |
|
2862 end |
|
2863 end; |
|
2864 |
|
2865 procedure doStepBirdyAppear(Gear: PGear); |
|
2866 begin |
|
2867 Gear^.Pos:= 0; |
|
2868 if Gear^.Timer < 2000 then |
|
2869 inc(Gear^.Timer, 1) |
|
2870 else |
|
2871 begin |
|
2872 Gear^.Timer:= 500; |
|
2873 Gear^.dX:= _0; |
|
2874 Gear^.dY:= _0; |
|
2875 Gear^.State:= Gear^.State and not gstAnimation; |
|
2876 Gear^.doStep:= @doStepBirdyDescend; |
|
2877 end |
|
2878 end; |
|
2879 |
|
2880 //////////////////////////////////////////////////////////////////////////////// |
|
2881 procedure doStepBirdy(Gear: PGear); |
|
2882 var HHGear: PGear; |
|
2883 begin |
|
2884 gear^.State:= gear^.State or gstAnimation and not gstTmpFlag; |
|
2885 Gear^.doStep:= @doStepBirdyAppear; |
|
2886 if CurrentHedgehog = nil then |
|
2887 begin |
|
2888 DeleteGear(Gear); |
|
2889 exit |
|
2890 end; |
|
2891 |
|
2892 HHGear:= CurrentHedgehog^.Gear; |
|
2893 |
|
2894 if HHGear^.dX.isNegative then |
|
2895 Gear^.Tag:= -1 |
|
2896 else |
|
2897 Gear^.Tag:= 1; |
|
2898 Gear^.Pos:= 0; |
|
2899 AllInactive:= false; |
|
2900 FollowGear:= HHGear; |
|
2901 with HHGear^ do |
|
2902 begin |
|
2903 State:= State and not gstAttacking; |
|
2904 Message:= Message and not (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right) |
|
2905 end |
3097 end |
2906 end; |
3098 end; |
2907 |
3099 |
2908 //////////////////////////////////////////////////////////////////////////////// |
3100 //////////////////////////////////////////////////////////////////////////////// |
2909 procedure doStepEggWork(Gear: PGear); |
3101 procedure doStepEggWork(Gear: PGear); |
2910 var vg: PVisualGear; |
3102 var |
2911 i: LongInt; |
3103 vg: PVisualGear; |
2912 begin |
3104 i: LongInt; |
2913 AllInactive:= false; |
3105 begin |
2914 Gear^.dX:= Gear^.dX; |
3106 AllInactive := false; |
|
3107 Gear^.dX := Gear^.dX; |
2915 doStepFallingGear(Gear); |
3108 doStepFallingGear(Gear); |
2916 // CheckGearDrowning(Gear); // already checked for in doStepFallingGear |
3109 // CheckGearDrowning(Gear); // already checked for in doStepFallingGear |
2917 CalcRotationDirAngle(Gear); |
3110 CalcRotationDirAngle(Gear); |
2918 |
3111 |
2919 if (Gear^.State and gstCollision) <> 0 then |
3112 if (Gear^.State and gstCollision) <> 0 then |
2920 begin |
3113 begin |
2921 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, EXPLPoisoned or EXPLNoGfx); |
3114 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, EXPLPoisoned or EXPLNoGfx); |
2922 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, EXPLPoisoned or EXPLNoGfx); |
3115 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, EXPLPoisoned or EXPLNoGfx); |
2923 PlaySound(sndEggBreak); |
3116 PlaySound(sndEggBreak); |
2924 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg); |
3117 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg); |
2925 vg:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg); |
3118 vg := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg); |
2926 if vg <> nil then vg^.Frame:= 2; |
3119 if vg <> nil then vg^.Frame := 2; |
2927 |
3120 |
2928 for i:= 10 downto 0 do begin |
3121 for i:= 10 downto 0 do |
2929 vg := AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), hwRound(Gear^.Y) - 3 + Random(6), vgtDust); |
3122 begin |
2930 if vg <> nil then vg^.dX := vg^.dX + (Gear^.dX / 5); |
3123 vg := AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), hwRound(Gear^.Y) - 3 + Random(6), |
|
3124 vgtDust); |
|
3125 if vg <> nil then vg^.dX := vg^.dX + (Gear^.dX / 5); |
2931 end; |
3126 end; |
2932 |
3127 |
2933 DeleteGear(Gear); |
3128 DeleteGear(Gear); |
2934 exit |
3129 exit |
2935 end; |
3130 end; |
2936 end; |
3131 end; |
2937 |
3132 |
2938 //////////////////////////////////////////////////////////////////////////////// |
3133 //////////////////////////////////////////////////////////////////////////////// |
2939 procedure doPortalColorSwitch(); |
3134 procedure doPortalColorSwitch(); |
2940 var flags: LongWord; |
3135 var |
2941 begin |
3136 flags: LongWord; |
2942 if (CurrentHedgehog <> nil) |
3137 begin |
2943 and (CurrentHedgehog^.Gear <> nil) |
3138 if (CurrentHedgehog <> nil) |
2944 and ((CurrentHedgehog^.Gear^.Message and gm_Switch) <> 0) then |
3139 and (CurrentHedgehog^.Gear <> nil) |
2945 With CurrentHedgehog^ do |
3140 and ((CurrentHedgehog^.Gear^.Message and gm_Switch) <> 0) then |
2946 if (Ammo^[CurSlot, CurAmmo].AmmoType = amPortalGun) then |
3141 With CurrentHedgehog^ do |
2947 begin |
3142 if (Ammo^[CurSlot, CurAmmo].AmmoType = amPortalGun) then |
2948 CurrentHedgehog^.Gear^.Message:= CurrentHedgehog^.Gear^.Message and not gm_Switch; |
3143 begin |
2949 |
3144 CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gm_Switch; |
2950 flags:= Ammo^[CurSlot, CurAmmo].Timer and not 2; |
3145 |
2951 if (flags and 1) = 0 then |
3146 flags := Ammo^[CurSlot, CurAmmo].Timer and not 2; |
2952 Ammo^[CurSlot, CurAmmo].Timer:= flags or 1 |
3147 if (flags and 1) = 0 then |
2953 else |
3148 Ammo^[CurSlot, CurAmmo].Timer := flags or 1 |
2954 Ammo^[CurSlot, CurAmmo].Timer:= flags and not 1; |
3149 else |
2955 end; |
3150 Ammo^[CurSlot, CurAmmo].Timer := flags and not 1; |
|
3151 end; |
2956 end; |
3152 end; |
2957 |
3153 |
2958 procedure doStepPortal(Gear: PGear); |
3154 procedure doStepPortal(Gear: PGear); |
2959 var iterator, conPortal: PGear; |
3155 var |
|
3156 iterator, conPortal: PGear; |
2960 s, acptRadius, cdxy: hwFloat; |
3157 s, acptRadius, cdxy: hwFloat; |
2961 noTrap, hasdxy: Boolean; |
3158 noTrap, hasdxy: Boolean; |
2962 begin |
3159 begin |
2963 doPortalColorSwitch(); |
3160 doPortalColorSwitch(); |
2964 |
3161 |
2965 // destroy portal if ground it was attached too is gone |
3162 // destroy portal if ground it was attached too is gone |
2966 if ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)] and $FF00) = 0) |
3163 if ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)] and $FF00) = 0) |
2967 or (Gear^.Timer < 1) |
3164 or (Gear^.Timer < 1) |
2968 or (hwRound(Gear^.Y) > cWaterLine) then |
3165 or (hwRound(Gear^.Y) > cWaterLine) then |
2969 begin |
3166 begin |
2970 deleteGear(Gear); |
3167 deleteGear(Gear); |
2971 EXIT; |
3168 EXIT; |
2972 end; |
3169 end; |
2973 |
3170 |
2974 if (TurnTimeLeft < 1) |
3171 if (TurnTimeLeft < 1) |
2975 or (Gear^.Health < 1) then |
3172 or (Gear^.Health < 1) then |
2976 dec(Gear^.Timer); |
3173 dec(Gear^.Timer); |
2977 |
3174 |
2978 if Gear^.Timer < 10000 then |
3175 if Gear^.Timer < 10000 then |
2979 gear^.RenderTimer:= true; |
3176 gear^.RenderTimer := true; |
2980 |
3177 |
2981 // abort if there is no other portal connected to this one |
3178 // abort if there is no other portal connected to this one |
2982 if (Gear^.IntersectGear = nil) then |
3179 if (Gear^.IntersectGear = nil) then |
2983 exit; |
3180 exit; |
2984 if ((Gear^.IntersectGear^.Tag and 1) = 0) then // or if it's still moving; |
3181 if ((Gear^.IntersectGear^.Tag and 1) = 0) then // or if it's still moving; |
2985 exit; |
3182 exit; |
2986 |
3183 |
2987 conPortal:= Gear^.IntersectGear; |
3184 conPortal := Gear^.IntersectGear; |
2988 |
3185 |
2989 // check all gears for stuff to port through |
3186 // check all gears for stuff to port through |
2990 iterator:= nil; |
3187 iterator := nil; |
2991 while true do |
3188 while true do |
2992 begin |
3189 begin |
2993 |
3190 |
2994 if iterator = nil then |
3191 if iterator = nil then |
2995 iterator:= GearsList // start |
3192 iterator := GearsList // start |
2996 else |
3193 else |
2997 iterator:= iterator^.NextGear; // iterate through GearsList |
3194 iterator := iterator^.NextGear; |
2998 |
3195 // iterate through GearsList |
|
3196 |
2999 if iterator = nil then |
3197 if iterator = nil then |
3000 break; // end of list |
3198 break; |
|
3199 // end of list |
3001 |
3200 |
3002 // don't port portals or other gear that wouldn't make sense |
3201 // don't port portals or other gear that wouldn't make sense |
3003 if (iterator^.Kind = gtPortal) |
3202 if (iterator^.Kind = gtPortal) or (iterator^.Kind = gtRope) then |
3004 or (iterator^.Kind = gtRope) then |
|
3005 continue; |
3203 continue; |
3006 |
3204 |
3007 // don't port hogs on rope |
3205 // don't port hogs on rope |
3008 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) |
3206 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) |
3009 and (iterator = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtRope) then |
3207 and (iterator = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = |
3010 continue; |
3208 gtRope) then |
|
3209 continue; |
3011 |
3210 |
3012 if (iterator^.Radius > Gear^.Radius) then |
3211 if (iterator^.Radius > Gear^.Radius) then |
3013 continue; // sorry, you're too fat! |
3212 continue; |
|
3213 // sorry, you're too fat! |
3014 |
3214 |
3015 // this is the range we accept incoming gears in |
3215 // this is the range we accept incoming gears in |
3016 acptRadius:= Int2hwFloat(iterator^.Radius+Gear^.Radius); |
3216 acptRadius := Int2hwFloat(iterator^.Radius+Gear^.Radius); |
3017 |
3217 |
3018 if (iterator^.X < Gear^.X - acptRadius) |
3218 if (iterator^.X < Gear^.X - acptRadius) |
3019 or (iterator^.X > Gear^.X + acptRadius) |
3219 or (iterator^.X > Gear^.X + acptRadius) |
3020 or (iterator^.Y < Gear^.Y - acptRadius) |
3220 or (iterator^.Y < Gear^.Y - acptRadius) |
3021 or (iterator^.Y > Gear^.Y + acptRadius) then |
3221 or (iterator^.Y > Gear^.Y + acptRadius) then |
3022 continue; // too far away! |
3222 continue; |
3023 |
3223 // too far away! |
3024 hasdxy:= ((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)); |
3224 |
|
3225 hasdxy := ((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)); |
3025 |
3226 |
3026 if hasdxy and not (Gear^.dX*iterator^.dX + Gear^.dY*iterator^.dY).isNegative then |
3227 if hasdxy and not (Gear^.dX*iterator^.dX + Gear^.dY*iterator^.dY).isNegative then |
3027 continue; // won't port stuff that moves away from me! |
3228 continue; |
|
3229 // won't port stuff that moves away from me! |
3028 |
3230 |
3029 // wow! good candidate there, let's see if the distance really is small enough! |
3231 // wow! good candidate there, let's see if the distance really is small enough! |
3030 if (Distance(Gear^.X-iterator^.X,Gear^.Y-iterator^.Y) > acptRadius) then |
3232 if (Distance(Gear^.X-iterator^.X,Gear^.Y-iterator^.Y) > acptRadius) then |
3031 continue; |
3233 continue; |
3032 |
3234 |
3033 noTrap:= ((not Gear^.dY.isNegative or (Gear^.dY.QWordValue = 0)) // can't be entered from above |
3235 noTrap := ((not Gear^.dY.isNegative or (Gear^.dY.QWordValue = 0)) |
3034 or ((conPortal^.dY.isNegative and not (conPortal^.dY.QWordValue = 0)))); // can't be left downwards; |
3236 // can't be entered from above |
3035 |
3237 or ((conPortal^.dY.isNegative and not (conPortal^.dY.QWordValue = 0)))); |
|
3238 // can't be left downwards; |
|
3239 |
3036 // prevent getting stuck in a ground portal loop |
3240 // prevent getting stuck in a ground portal loop |
3037 if noTrap and (iterator^.dY.QWordValue < _0_08.QWordValue) then |
3241 if noTrap and (iterator^.dY.QWordValue < _0_08.QWordValue) then |
3038 continue; |
3242 continue; |
3039 |
3243 |
3040 iterator^.Active:= true; |
3244 iterator^.Active := true; |
3041 iterator^.State:= iterator^.State or gstMoving; |
3245 iterator^.State := iterator^.State or gstMoving; |
3042 DeleteCI(iterator); |
3246 DeleteCI(iterator); |
3043 |
3247 |
3044 // TODO: more accurate porting |
3248 // TODO: more accurate porting |
3045 cdxy:= Distance(conPortal^.dX, conPortal^.dY); |
3249 cdxy := Distance(conPortal^.dX, conPortal^.dY); |
3046 s:= (Int2hwFloat(Gear^.Radius)) / cdxy; |
3250 s := (Int2hwFloat(Gear^.Radius)) / cdxy; |
3047 |
3251 |
3048 iterator^.X:= conPortal^.X + s * conPortal^.dX; |
3252 iterator^.X := conPortal^.X + s * conPortal^.dX; |
3049 iterator^.Y:= conPortal^.Y + s * conPortal^.dY; |
3253 iterator^.Y := conPortal^.Y + s * conPortal^.dY; |
3050 |
3254 |
3051 s:= Distance(iterator^.dX, iterator^.dY) / cdxy; |
3255 s := Distance(iterator^.dX, iterator^.dY) / cdxy; |
3052 |
3256 |
3053 iterator^.dX:= s * conPortal^.dX; |
3257 iterator^.dX := s * conPortal^.dX; |
3054 iterator^.dY:= s * conPortal^.dY; |
3258 iterator^.dY := s * conPortal^.dY; |
3055 |
3259 |
3056 FollowGear:= iterator; |
3260 FollowGear := iterator; |
3057 |
3261 |
3058 s:= _0_2 + _0_008 * Gear^.Health; |
3262 s := _0_2 + _0_008 * Gear^.Health; |
3059 iterator^.dX:= s * iterator^.dX; |
3263 iterator^.dX := s * iterator^.dX; |
3060 iterator^.dY:= s * iterator^.dY; |
3264 iterator^.dY := s * iterator^.dY; |
3061 |
3265 |
3062 if Gear^.Health > 1 then |
3266 if Gear^.Health > 1 then |
3063 begin |
3267 begin |
3064 dec(Gear^.Health); |
3268 dec(Gear^.Health); |
3065 dec(iterator^.Health); |
3269 dec(iterator^.Health); |
3066 end; |
3270 end; |
3067 |
3271 |
3068 // breaks (some) loops |
3272 // breaks (some) loops |
3069 if Distance(iterator^.dX, iterator^.dY) > _0_96 then |
3273 if Distance(iterator^.dX, iterator^.dY) > _0_96 then |
|
3274 begin |
|
3275 iterator^.dX := iterator^.dX + signAs(cGravity * getRandom(1000),iterator^.dX); |
|
3276 iterator^.dY := iterator^.dY + signAs(cGravity * getRandom(1000),iterator^.dY); |
|
3277 s := _0_96 / Distance(iterator^.dX, iterator^.dY); |
|
3278 iterator^.dX := s * iterator^.dX; |
|
3279 iterator^.dY := s * iterator^.dX; |
|
3280 end; |
|
3281 end; |
|
3282 end; |
|
3283 |
|
3284 procedure doStepMovingPortal(Gear: PGear); |
|
3285 var |
|
3286 x, y, tx, ty: LongInt; |
|
3287 //, bx, by, tangle: LongInt; |
|
3288 s, dx, dy: hwFloat; |
|
3289 |
|
3290 procedure loadNewPortalBall(oldPortal: PGear; destroyGear: Boolean); |
|
3291 var |
|
3292 flags: LongWord; |
|
3293 begin |
|
3294 if CurrentHedgehog <> nil then |
|
3295 With CurrentHedgehog^ do |
|
3296 if (Ammo^[CurSlot, CurAmmo].AmmoType = amPortalGun) then |
3070 begin |
3297 begin |
3071 iterator^.dX:= iterator^.dX + signAs(cGravity * getRandom(1000),iterator^.dX); |
3298 flags := Ammo^[CurSlot, CurAmmo].Timer; |
3072 iterator^.dY:= iterator^.dY + signAs(cGravity * getRandom(1000),iterator^.dY); |
3299 |
3073 s:= _0_96 / Distance(iterator^.dX, iterator^.dY); |
3300 if destroyGear xor ((oldPortal^.Tag and 2) = 0) then |
3074 iterator^.dX:= s * iterator^.dX; |
3301 flags := flags or 1 |
3075 iterator^.dY:= s * iterator^.dX; |
3302 else |
|
3303 flags := flags and not 1; |
|
3304 |
|
3305 Ammo^[CurSlot, CurAmmo].Timer := flags and not 2; |
|
3306 // make the ball visible |
3076 end; |
3307 end; |
3077 end; |
3308 |
3078 end; |
3309 if destroyGear then deleteGear(oldPortal); |
3079 |
3310 end; |
3080 procedure doStepMovingPortal(Gear: PGear); |
3311 |
3081 var x, y, tx, ty: LongInt;//, bx, by, tangle: LongInt; |
3312 begin |
3082 s, dx, dy: hwFloat; |
3313 doPortalColorSwitch(); |
3083 |
3314 |
3084 procedure loadNewPortalBall(oldPortal: PGear; destroyGear: Boolean); |
3315 Gear^.X := Gear^.X + Gear^.dX; |
3085 var flags: LongWord; |
3316 Gear^.Y := Gear^.Y + Gear^.dY; |
3086 begin |
3317 x := hwRound(Gear^.X); |
3087 if CurrentHedgehog <> nil then |
3318 y := hwRound(Gear^.Y); |
3088 With CurrentHedgehog^ do |
3319 tx := 0; |
3089 if (Ammo^[CurSlot, CurAmmo].AmmoType = amPortalGun) then |
3320 ty := 0; |
3090 begin |
3321 // avoid compiler hints |
3091 flags:= Ammo^[CurSlot, CurAmmo].Timer; |
3322 |
3092 |
3323 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then |
3093 if destroyGear xor ((oldPortal^.Tag and 2) = 0) then |
3324 begin |
3094 flags:= flags or 1 |
3325 if not calcSlopeTangent(Gear, x, y, tx, ty, 255) |
3095 else |
3326 or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain |
3096 flags:= flags and not 1; |
3327 begin |
3097 |
|
3098 Ammo^[CurSlot, CurAmmo].Timer:= flags and not 2; // make the ball visible |
|
3099 end; |
|
3100 |
|
3101 if destroyGear then deleteGear(oldPortal); |
|
3102 end; |
|
3103 |
|
3104 begin |
|
3105 doPortalColorSwitch(); |
|
3106 |
|
3107 Gear^.X:= Gear^.X + Gear^.dX; |
|
3108 Gear^.Y:= Gear^.Y + Gear^.dY; |
|
3109 x:= hwRound(Gear^.X); |
|
3110 y:= hwRound(Gear^.Y); |
|
3111 tx:= 0; ty:= 0; // avoid compiler hints |
|
3112 |
|
3113 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then |
|
3114 begin |
|
3115 if not calcSlopeTangent(Gear, x, y, tx, ty, 255) |
|
3116 or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain |
|
3117 begin |
|
3118 loadNewPortalBall(Gear, true); |
3328 loadNewPortalBall(Gear, true); |
3119 EXIT; |
3329 EXIT; |
|
3330 end; |
|
3331 |
|
3332 // making a normalized normal vector |
|
3333 s := _1/DistanceI(tx,ty); |
|
3334 dx := -s * ty; |
|
3335 dy := s * tx; |
|
3336 |
|
3337 // make sure the vector is pointing outwards |
|
3338 if not (Gear^.dX*dx + Gear^.dY*dy).isNegative then |
|
3339 begin |
|
3340 dx := -dx; |
|
3341 dy := -dy; |
|
3342 end; |
|
3343 |
|
3344 Gear^.dX := dx; |
|
3345 Gear^.dY := dy; |
|
3346 |
|
3347 Gear^.DirAngle := DxDy2Angle(-dy,dx); |
|
3348 if not Gear^.dX.isNegative then Gear^.DirAngle := 180-Gear^.DirAngle; |
|
3349 |
|
3350 if ((Gear^.IntersectGear = nil) |
|
3351 or (hwRound(Distance(Gear^.X - Gear^.IntersectGear^.X,Gear^.Y-Gear^.IntersectGear^.Y)) >= |
|
3352 Gear^.Radius*2)) |
|
3353 then |
|
3354 begin |
|
3355 loadNewPortalBall(Gear, false); |
|
3356 inc(Gear^.Tag); |
|
3357 Gear^.doStep := @doStepPortal; |
|
3358 end |
|
3359 else |
|
3360 loadNewPortalBall(Gear, true); |
|
3361 end |
|
3362 else if (y > cWaterLine) or (y < -LAND_WIDTH) |
|
3363 or (x > 2*LAND_WIDTH) or (x < -LAND_WIDTH) then |
|
3364 loadNewPortalBall(Gear, true); |
|
3365 end; |
|
3366 |
|
3367 procedure doStepPortalShot(newPortal: PGear); |
|
3368 var |
|
3369 iterator: PGear; |
|
3370 begin |
|
3371 newPortal^.IntersectGear := nil; |
|
3372 |
|
3373 if CurrentHedgehog <> nil then |
|
3374 With CurrentHedgehog^ do |
|
3375 begin |
|
3376 // make portal gun look unloaded |
|
3377 Ammo^[CurSlot, CurAmmo].Timer := Ammo^[CurSlot, CurAmmo].Timer or 2; |
|
3378 |
|
3379 // set portal to the currently chosen color |
|
3380 if ((Ammo^[CurSlot, CurAmmo].Timer and 1) <> 0) then |
|
3381 newPortal^.Tag := newPortal^.Tag or 2; |
|
3382 |
|
3383 iterator := GearsList; |
|
3384 while iterator <> nil do |
|
3385 begin |
|
3386 if (iterator^.Kind = gtPortal) then |
|
3387 if (iterator <> newPortal) then |
|
3388 begin |
|
3389 if (iterator^.Tag and 2) = (newPortal^.Tag and 2) then |
|
3390 begin |
|
3391 iterator := iterator^.PrevGear; |
|
3392 deleteGear(iterator^.NextGear); |
|
3393 continue; |
|
3394 end |
|
3395 else |
|
3396 begin |
|
3397 // link portals with each other |
|
3398 newPortal^.IntersectGear := iterator; |
|
3399 iterator^.IntersectGear := newPortal; |
|
3400 iterator^.Health := newPortal^.Health; |
|
3401 end; |
|
3402 end; |
|
3403 iterator := iterator^.NextGear |
3120 end; |
3404 end; |
3121 |
3405 end; |
3122 // making a normalized normal vector |
3406 newPortal^.doStep := @doStepMovingPortal; |
3123 s:= _1/DistanceI(tx,ty); |
3407 end; |
3124 dx:= -s * ty; |
3408 |
3125 dy:= s * tx; |
3409 procedure doStepPiano(Gear: PGear); |
3126 |
3410 var |
3127 // make sure the vector is pointing outwards |
3411 r0, r1: LongInt; |
3128 if not (Gear^.dX*dx + Gear^.dY*dy).isNegative then |
3412 begin |
3129 begin |
3413 AllInactive := false; |
3130 dx:= -dx; |
3414 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^. |
3131 dy:= -dy; |
3415 Message and gm_Slot) <> 0) then |
3132 end; |
3416 begin |
3133 |
3417 case CurrentHedgehog^.Gear^.MsgParam of |
3134 Gear^.dX:= dx; |
3418 0: PlaySound(sndPiano0); |
3135 Gear^.dY:= dy; |
3419 1: PlaySound(sndPiano1); |
3136 |
3420 2: PlaySound(sndPiano2); |
3137 Gear^.DirAngle:= DxDy2Angle(-dy,dx); |
3421 3: PlaySound(sndPiano3); |
3138 if not Gear^.dX.isNegative then Gear^.DirAngle:= 180-Gear^.DirAngle; |
3422 4: PlaySound(sndPiano4); |
3139 |
3423 5: PlaySound(sndPiano5); |
3140 if ((Gear^.IntersectGear = nil) |
3424 6: PlaySound(sndPiano6); |
3141 or (hwRound(Distance(Gear^.X - Gear^.IntersectGear^.X,Gear^.Y-Gear^.IntersectGear^.Y)) >= Gear^.Radius*2)) |
3425 7: PlaySound(sndPiano7); |
3142 then |
3426 else PlaySound(sndPiano8); |
3143 begin |
3427 end; |
3144 loadNewPortalBall(Gear, false); |
3428 CurrentHedgehog^.Gear^.MsgParam := 0; |
3145 inc(Gear^.Tag); |
3429 CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gm_Slot; |
3146 Gear^.doStep:= @doStepPortal; |
3430 end; |
|
3431 |
|
3432 if ((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or (Gear^.Pos = 20) then |
|
3433 // bounce up to 20 times (3 times on gameflagged solid land) before dropping past landscape |
|
3434 begin |
|
3435 Gear^.dY := Gear^.dY + cGravity * 3; |
|
3436 Gear^.Y := Gear^.Y + Gear^.dY; |
|
3437 CheckGearDrowning(Gear); |
|
3438 if (Gear^.State and gstDrowning) <> 0 then |
|
3439 begin |
|
3440 if CurrentHedgehog^.Gear <> nil then |
|
3441 begin |
|
3442 // Drown the hedgehog. Could also just delete it, but hey, this gets a caption |
|
3443 CurrentHedgehog^.Gear^.Active := true; |
|
3444 CurrentHedgehog^.Gear^.X := Gear^.X; |
|
3445 CurrentHedgehog^.Gear^.Y := int2hwFloat(cWaterLine+cVisibleWater)+_128; |
|
3446 CurrentHedgehog^.Unplaced := false |
|
3447 end; |
|
3448 ResumeMusic |
|
3449 end; |
|
3450 exit |
|
3451 end; |
|
3452 |
|
3453 doStepFallingGear(Gear); |
|
3454 |
|
3455 if (Gear^.State and gstDrowning) <> 0 then |
|
3456 begin |
|
3457 if CurrentHedgehog^.Gear <> nil then |
|
3458 begin |
|
3459 // Drown the hedgehog. Could also just delete it, but hey, this gets a caption |
|
3460 CurrentHedgehog^.Gear^.Active := true; |
|
3461 CurrentHedgehog^.Gear^.X := Gear^.X; |
|
3462 CurrentHedgehog^.Gear^.Y := int2hwFloat(cWaterLine+cVisibleWater)+_128; |
|
3463 CurrentHedgehog^.Unplaced := false |
|
3464 end; |
|
3465 ResumeMusic |
|
3466 end |
|
3467 else if (Gear^.State and gstCollision) <> 0 then |
|
3468 begin |
|
3469 r0 := GetRandom(21); |
|
3470 r1 := GetRandom(21); |
|
3471 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 80 + r0, EXPLAutoSound); |
|
3472 doMakeExplosion(hwRound(Gear^.X) - 30 - r0, hwRound(Gear^.Y) + 40, 40 + r1, |
|
3473 EXPLAutoSound); |
|
3474 doMakeExplosion(hwRound(Gear^.X) + 30 + r1, hwRound(Gear^.Y) + 40, 40 + r0, |
|
3475 EXPLAutoSound); |
|
3476 Gear^.dY := -_1; |
|
3477 Gear^.Pos := Gear^.Pos + 1; |
3147 end |
3478 end |
3148 else |
3479 else |
3149 loadNewPortalBall(Gear, true); |
3480 Gear^.dY := Gear^.dY + cGravity * 2; |
3150 end |
3481 // let it fall faster so itdoesn't take too long for the whole attack |
3151 else if (y > cWaterLine) or (y < -LAND_WIDTH) |
|
3152 or (x > 2*LAND_WIDTH) or (x < -LAND_WIDTH) then |
|
3153 loadNewPortalBall(Gear, true); |
|
3154 end; |
|
3155 |
|
3156 procedure doStepPortalShot(newPortal: PGear); |
|
3157 var iterator: PGear; |
|
3158 begin |
|
3159 newPortal^.IntersectGear:= nil; |
|
3160 |
|
3161 if CurrentHedgehog <> nil then |
|
3162 With CurrentHedgehog^ do |
|
3163 begin |
|
3164 // make portal gun look unloaded |
|
3165 Ammo^[CurSlot, CurAmmo].Timer:= Ammo^[CurSlot, CurAmmo].Timer or 2; |
|
3166 |
|
3167 // set portal to the currently chosen color |
|
3168 if ((Ammo^[CurSlot, CurAmmo].Timer and 1) <> 0) then |
|
3169 newPortal^.Tag:= newPortal^.Tag or 2; |
|
3170 |
|
3171 iterator:= GearsList; |
|
3172 while iterator <> nil do |
|
3173 begin |
|
3174 if (iterator^.Kind = gtPortal) then |
|
3175 if (iterator <> newPortal) then |
|
3176 begin |
|
3177 if (iterator^.Tag and 2) = (newPortal^.Tag and 2) then |
|
3178 begin |
|
3179 iterator:= iterator^.PrevGear; |
|
3180 deleteGear(iterator^.NextGear); |
|
3181 continue; |
|
3182 end |
|
3183 else |
|
3184 begin // link portals with each other |
|
3185 newPortal^.IntersectGear:= iterator; |
|
3186 iterator^.IntersectGear:= newPortal; |
|
3187 iterator^.Health:= newPortal^.Health; |
|
3188 end; |
|
3189 end; |
|
3190 iterator:= iterator^.NextGear |
|
3191 end; |
|
3192 end; |
|
3193 newPortal^.doStep:= @doStepMovingPortal; |
|
3194 end; |
|
3195 |
|
3196 procedure doStepPiano(Gear: PGear); |
|
3197 var r0, r1: LongInt; |
|
3198 begin |
|
3199 AllInactive:= false; |
|
3200 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.Message and gm_Slot) <> 0) then |
|
3201 begin |
|
3202 case CurrentHedgehog^.Gear^.MsgParam of |
|
3203 0: PlaySound(sndPiano0); |
|
3204 1: PlaySound(sndPiano1); |
|
3205 2: PlaySound(sndPiano2); |
|
3206 3: PlaySound(sndPiano3); |
|
3207 4: PlaySound(sndPiano4); |
|
3208 5: PlaySound(sndPiano5); |
|
3209 6: PlaySound(sndPiano6); |
|
3210 7: PlaySound(sndPiano7); |
|
3211 else PlaySound(sndPiano8); |
|
3212 end; |
|
3213 CurrentHedgehog^.Gear^.MsgParam:= 0; |
|
3214 CurrentHedgehog^.Gear^.Message:= CurrentHedgehog^.Gear^.Message and not gm_Slot; |
|
3215 end; |
|
3216 |
|
3217 if ((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or (Gear^.Pos = 20) then // bounce up to 20 times (3 times on gameflagged solid land) before dropping past landscape |
|
3218 begin |
|
3219 Gear^.dY:= Gear^.dY + cGravity * 3; |
|
3220 Gear^.Y:= Gear^.Y + Gear^.dY; |
|
3221 CheckGearDrowning(Gear); |
|
3222 if (Gear^.State and gstDrowning) <> 0 then |
|
3223 begin |
|
3224 if CurrentHedgehog^.Gear <> nil then |
|
3225 begin |
|
3226 // Drown the hedgehog. Could also just delete it, but hey, this gets a caption |
|
3227 CurrentHedgehog^.Gear^.Active:= true; |
|
3228 CurrentHedgehog^.Gear^.X:= Gear^.X; |
|
3229 CurrentHedgehog^.Gear^.Y:=int2hwFloat(cWaterLine+cVisibleWater)+_128; |
|
3230 CurrentHedgehog^.Unplaced:= false |
|
3231 end; |
|
3232 ResumeMusic |
|
3233 end; |
|
3234 exit |
|
3235 end; |
|
3236 |
|
3237 doStepFallingGear(Gear); |
|
3238 |
|
3239 if (Gear^.State and gstDrowning) <> 0 then |
|
3240 begin |
|
3241 if CurrentHedgehog^.Gear <> nil then |
|
3242 begin |
|
3243 // Drown the hedgehog. Could also just delete it, but hey, this gets a caption |
|
3244 CurrentHedgehog^.Gear^.Active:= true; |
|
3245 CurrentHedgehog^.Gear^.X:= Gear^.X; |
|
3246 CurrentHedgehog^.Gear^.Y:=int2hwFloat(cWaterLine+cVisibleWater)+_128; |
|
3247 CurrentHedgehog^.Unplaced:= false |
|
3248 end; |
|
3249 ResumeMusic |
|
3250 end |
|
3251 else if (Gear^.State and gstCollision) <> 0 then |
|
3252 begin |
|
3253 r0:= GetRandom(21); |
|
3254 r1:= GetRandom(21); |
|
3255 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 80 + r0, EXPLAutoSound); |
|
3256 doMakeExplosion(hwRound(Gear^.X) - 30 - r0, hwRound(Gear^.Y) + 40, 40 + r1, EXPLAutoSound); |
|
3257 doMakeExplosion(hwRound(Gear^.X) + 30 + r1, hwRound(Gear^.Y) + 40, 40 + r0, EXPLAutoSound); |
|
3258 Gear^.dY:= -_1; |
|
3259 Gear^.Pos:= Gear^.Pos + 1; |
|
3260 end |
|
3261 else |
|
3262 Gear^.dY:= Gear^.dY + cGravity * 2; // let it fall faster so itdoesn't take too long for the whole attack |
|
3263 end; |
3482 end; |
3264 |
3483 |
3265 |
3484 |
3266 //////////////////////////////////////////////////////////////////////////////// |
3485 //////////////////////////////////////////////////////////////////////////////// |
3267 procedure doStepSineGunShotWork(Gear: PGear); |
3486 procedure doStepSineGunShotWork(Gear: PGear); |
3268 var x, y, rX, rY, t, tmp, initHealth: LongInt; |
3487 var |
|
3488 x, y, rX, rY, t, tmp, initHealth: LongInt; |
3269 oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat; |
3489 oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat; |
3270 justCollided: boolean; |
3490 justCollided: boolean; |
3271 begin |
3491 begin |
3272 AllInactive:= false; |
3492 AllInactive := false; |
3273 initHealth:= Gear^.Health; |
3493 initHealth := Gear^.Health; |
3274 lX:= Gear^.X; |
3494 lX := Gear^.X; |
3275 lY:= Gear^.Y; |
3495 lY := Gear^.Y; |
3276 ldX:= Gear^.dX; |
3496 ldX := Gear^.dX; |
3277 ldY:= Gear^.dY; |
3497 ldY := Gear^.dY; |
3278 sdy:= _0_5/Distance(Gear^.dX,Gear^.dY); |
3498 sdy := _0_5/Distance(Gear^.dX,Gear^.dY); |
3279 ldX:= ldX * sdy; |
3499 ldX := ldX * sdy; |
3280 ldY:= ldY * sdy; |
3500 ldY := ldY * sdy; |
3281 sdY:= hwAbs(ldX) + hwAbs(ldY); |
3501 sdY := hwAbs(ldX) + hwAbs(ldY); |
3282 sdX:= _1 - hwAbs(ldX/sdY); |
3502 sdX := _1 - hwAbs(ldX/sdY); |
3283 sdY:= _1 - hwAbs(ldY/sdY); |
3503 sdY := _1 - hwAbs(ldY/sdY); |
3284 if (ldX.isNegative = ldY.isNegative) then sdY:= -sdY; |
3504 if (ldX.isNegative = ldY.isNegative) then sdY := -sdY; |
3285 |
3505 |
3286 // initial angle depends on current GameTicks |
3506 // initial angle depends on current GameTicks |
3287 t:= GameTicks mod 4096; |
3507 t := GameTicks mod 4096; |
3288 |
3508 |
3289 |
3509 |
3290 // used for a work-around detection of area that is within land array, but outside borders |
3510 // used for a work-around detection of area that is within land array, but outside borders |
3291 justCollided:= false; |
3511 justCollided := false; |
3292 |
3512 |
3293 repeat |
3513 repeat |
3294 lX:= lX + ldX; |
3514 lX := lX + ldX; |
3295 lY:= lY + ldY; |
3515 lY := lY + ldY; |
3296 oX:= Gear^.X; |
3516 oX := Gear^.X; |
3297 oY:= Gear^.Y; |
3517 oY := Gear^.Y; |
3298 rX:= hwRound(oX); |
3518 rX := hwRound(oX); |
3299 rY:= hwRound(oY); |
3519 rY := hwRound(oY); |
3300 tmp:= t mod 4096; |
3520 tmp := t mod 4096; |
3301 amp:= _128 * (_1 - hwSqr(int2hwFloat(Gear^.Health)/initHealth)); |
3521 amp := _128 * (_1 - hwSqr(int2hwFloat(Gear^.Health)/initHealth)); |
3302 sine:= amp * AngleSin(tmp mod 2048); |
3522 sine := amp * AngleSin(tmp mod 2048); |
3303 sine.isNegative:= (tmp < 2048); |
3523 sine.isNegative := (tmp < 2048); |
3304 inc(t,Gear^.Health div 313); |
3524 inc(t,Gear^.Health div 313); |
3305 Gear^.X:= lX + (sine * sdX); |
3525 Gear^.X := lX + (sine * sdX); |
3306 Gear^.Y:= ly + (sine * sdY); |
3526 Gear^.Y := ly + (sine * sdY); |
3307 Gear^.dX:= Gear^.X - oX; |
3527 Gear^.dX := Gear^.X - oX; |
3308 Gear^.dY:= Gear^.Y - oY; |
3528 Gear^.dY := Gear^.Y - oY; |
3309 |
3529 |
3310 x:= hwRound(Gear^.X); |
3530 x := hwRound(Gear^.X); |
3311 y:= hwRound(Gear^.Y); |
3531 y := hwRound(Gear^.Y); |
3312 |
3532 |
3313 // if borders are on, stop outside land array |
3533 // if borders are on, stop outside land array |
3314 if hasBorder and (((x and LAND_WIDTH_MASK) <> 0) or ((y and LAND_HEIGHT_MASK) <> 0)) then |
3534 if hasBorder and (((x and LAND_WIDTH_MASK) <> 0) or ((y and LAND_HEIGHT_MASK) <> 0)) then |
|
3535 begin |
|
3536 Gear^.Damage := 0; |
|
3537 Gear^.Health := 0; |
|
3538 end |
|
3539 else |
|
3540 begin |
|
3541 if (rY <= cWaterLine) or (y <= cWaterLine) then |
3315 begin |
3542 begin |
3316 Gear^.Damage:= 0; |
3543 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
3317 Gear^.Health:= 0; |
3544 and (Land[y, x] <> 0) then |
|
3545 begin |
|
3546 if justCollided then |
|
3547 begin |
|
3548 Gear^.Damage := 0; |
|
3549 Gear^.Health := 0; |
|
3550 end |
|
3551 else |
|
3552 begin |
|
3553 inc(Gear^.Damage,3); |
|
3554 justCollided := true; |
|
3555 end; |
|
3556 end |
|
3557 else |
|
3558 justCollided := false; |
|
3559 |
|
3560 // kick nearby hogs, dig tunnel and add some fire |
|
3561 // if at least 5 collisions occured |
|
3562 if Gear^.Damage > 0 then |
|
3563 begin |
|
3564 DrawExplosion(rX,rY,Gear^.Radius); |
|
3565 |
|
3566 // kick nearby hogs |
|
3567 AmmoShove(Gear, 35, 50); |
|
3568 |
|
3569 dec(Gear^.Health, Gear^.Damage); |
|
3570 Gear^.Damage := 0; |
|
3571 |
|
3572 // add some fire to the tunnel |
|
3573 if getRandom(6) = 0 then |
|
3574 AddGear(x - Gear^.Radius + LongInt(getRandom(2 * Gear^.Radius)), y - |
|
3575 getRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0); |
|
3576 end; |
|
3577 |
|
3578 if getRandom(100) = 0 then |
|
3579 AddVisualGear(x, y, vgtSmokeTrace); |
3318 end |
3580 end |
3319 else |
3581 else dec(Gear^.Health, 5); // if underwater get additional damage |
3320 begin |
3582 end; |
3321 if (rY <= cWaterLine) or (y <= cWaterLine) then |
3583 |
3322 begin |
3584 dec(Gear^.Health); |
3323 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
3585 |
3324 and (Land[y, x] <> 0) then |
3586 // decrease bullet size towards the end |
3325 begin |
3587 if (Gear^.Radius > 4) then begin |
3326 if justCollided then |
3588 if (Gear^.Health <= (initHealth div 3)) then dec(Gear^.Radius) end |
3327 begin |
3589 else if (Gear^.Radius > 3) then begin |
3328 Gear^.Damage:= 0; |
3590 if (Gear^.Health <= (initHealth div 4)) then dec(Gear^.Radius) end |
3329 Gear^.Health:= 0; |
3591 else if (Gear^.Radius > 2) then begin |
3330 end |
3592 if (Gear^.Health <= (initHealth div 5)) then dec(Gear^.Radius) end |
3331 else |
3593 else if (Gear^.Radius > 1) then begin |
3332 begin |
3594 if (Gear^.Health <= (initHealth div 6)) then dec(Gear^.Radius) end; |
3333 inc(Gear^.Damage,3); |
3595 |
3334 justCollided:= true; |
3596 until (Gear^.Health <= 0); |
3335 end; |
3597 |
3336 end |
3598 DeleteGear(Gear); |
3337 else |
3599 AfterAttack; |
3338 justCollided:= false; |
|
3339 |
|
3340 // kick nearby hogs, dig tunnel and add some fire |
|
3341 // if at least 5 collisions occured |
|
3342 if Gear^.Damage > 0 then |
|
3343 begin |
|
3344 DrawExplosion(rX,rY,Gear^.Radius); |
|
3345 |
|
3346 // kick nearby hogs |
|
3347 AmmoShove(Gear, 35, 50); |
|
3348 |
|
3349 dec(Gear^.Health, Gear^.Damage); |
|
3350 Gear^.Damage:= 0; |
|
3351 |
|
3352 // add some fire to the tunnel |
|
3353 if getRandom(6) = 0 then |
|
3354 AddGear(x - Gear^.Radius + LongInt(getRandom(2 * Gear^.Radius)), y - getRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0); |
|
3355 end; |
|
3356 |
|
3357 if getRandom(100) = 0 then |
|
3358 AddVisualGear(x, y, vgtSmokeTrace); |
|
3359 |
|
3360 end |
|
3361 // if underwater get additional damage |
|
3362 else dec(Gear^.Health, 5); |
|
3363 end; |
|
3364 |
|
3365 dec(Gear^.Health); |
|
3366 |
|
3367 // decrease bullet size towards the end |
|
3368 if (Gear^.Radius > 4) then begin |
|
3369 if (Gear^.Health <= (initHealth div 3)) then dec(Gear^.Radius) end |
|
3370 else if (Gear^.Radius > 3) then begin |
|
3371 if (Gear^.Health <= (initHealth div 4)) then dec(Gear^.Radius) end |
|
3372 else if (Gear^.Radius > 2) then begin |
|
3373 if (Gear^.Health <= (initHealth div 5)) then dec(Gear^.Radius) end |
|
3374 else if (Gear^.Radius > 1) then begin |
|
3375 if (Gear^.Health <= (initHealth div 6)) then dec(Gear^.Radius) end; |
|
3376 |
|
3377 until (Gear^.Health <= 0); |
|
3378 |
|
3379 DeleteGear(Gear); |
|
3380 AfterAttack; |
|
3381 end; |
3600 end; |
3382 |
3601 |
3383 procedure doStepSineGunShot(Gear: PGear); |
3602 procedure doStepSineGunShot(Gear: PGear); |
3384 var HHGear: PGear; |
3603 var |
3385 begin |
3604 HHGear: PGear; |
3386 PlaySound(sndSineGun); |
3605 begin |
3387 |
3606 PlaySound(sndSineGun); |
3388 |
3607 |
3389 // push the shooting Hedgehog back |
3608 // push the shooting Hedgehog back |
3390 HHGear:= CurrentHedgehog^.Gear; |
3609 HHGear := CurrentHedgehog^.Gear; |
3391 Gear^.dX.isNegative:= not Gear^.dX.isNegative; |
3610 Gear^.dX.isNegative := not Gear^.dX.isNegative; |
3392 Gear^.dY.isNegative:= not Gear^.dY.isNegative; |
3611 Gear^.dY.isNegative := not Gear^.dY.isNegative; |
3393 HHGear^.dX:= Gear^.dX; |
3612 HHGear^.dX := Gear^.dX; |
3394 HHGear^.dY:= Gear^.dY; |
3613 HHGear^.dY := Gear^.dY; |
3395 AmmoShove(Gear, 0, 80); |
3614 AmmoShove(Gear, 0, 80); |
3396 Gear^.dX.isNegative:= not Gear^.dX.isNegative; |
3615 Gear^.dX.isNegative := not Gear^.dX.isNegative; |
3397 Gear^.dY.isNegative:= not Gear^.dY.isNegative; |
3616 Gear^.dY.isNegative := not Gear^.dY.isNegative; |
3398 |
3617 |
3399 Gear^.doStep:= @doStepSineGunShotWork |
3618 Gear^.doStep := @doStepSineGunShotWork; |
3400 |
3619 end; |
3401 end; |
|