96 end; |
96 end; |
97 |
97 |
98 procedure doStepRopeWork(Gear: PGear); |
98 procedure doStepRopeWork(Gear: PGear); |
99 var |
99 var |
100 HHGear: PGear; |
100 HHGear: PGear; |
101 len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY, sDx, sDy: hwFloat; |
101 len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; |
102 i, lx, ly, cd: LongInt; |
102 lx, ly, cd: LongInt; |
103 haveCollision, |
103 haveCollision, |
104 haveDivided: boolean; |
104 haveDivided: boolean; |
105 |
105 |
106 begin |
106 begin |
107 if GameTicks mod 8 <> 0 then exit; |
107 if GameTicks mod 4 <> 0 then exit; |
108 |
108 |
109 HHGear := Gear^.Hedgehog^.Gear; |
109 HHGear := Gear^.Hedgehog^.Gear; |
110 |
110 |
111 if ((HHGear^.State and gstHHDriven) = 0) |
111 if ((HHGear^.State and gstHHDriven) = 0) |
112 or (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then |
112 or (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then |
113 begin |
113 begin |
|
114 HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue shr 2; |
|
115 HHGear^.dY.QWordValue:= HHGear^.dY.QWordValue shr 2; |
114 PlaySound(sndRopeRelease); |
116 PlaySound(sndRopeRelease); |
115 RopeDeleteMe(Gear, HHGear); |
117 RopeDeleteMe(Gear, HHGear); |
116 exit |
118 exit |
117 end; |
119 end; |
118 |
120 |
119 HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue shl 3; |
|
120 HHGear^.dY.QWordValue:= HHGear^.dY.QWordValue shl 3; |
|
121 |
|
122 if (Gear^.Message and gmLeft <> 0) and (not TestCollisionXwithGear(HHGear, -1)) then |
121 if (Gear^.Message and gmLeft <> 0) and (not TestCollisionXwithGear(HHGear, -1)) then |
123 HHGear^.dX := HHGear^.dX - _0_0128; |
122 HHGear^.dX := HHGear^.dX - _0_0032; |
124 |
123 |
125 if (Gear^.Message and gmRight <> 0) and (not TestCollisionXwithGear(HHGear, 1)) then |
124 if (Gear^.Message and gmRight <> 0) and (not TestCollisionXwithGear(HHGear, 1)) then |
126 HHGear^.dX := HHGear^.dX + _0_0128; |
125 HHGear^.dX := HHGear^.dX + _0_0032; |
127 |
126 |
128 // vector between hedgehog and rope attaching point |
127 // vector between hedgehog and rope attaching point |
129 ropeDx := HHGear^.X - Gear^.X; |
128 ropeDx := HHGear^.X - Gear^.X; |
130 ropeDy := HHGear^.Y - Gear^.Y; |
129 ropeDy := HHGear^.Y - Gear^.Y; |
131 |
130 |
139 else |
138 else |
140 cd:= 1; |
139 cd:= 1; |
141 |
140 |
142 // apply gravity if there is no obstacle |
141 // apply gravity if there is no obstacle |
143 if not TestCollisionXwithGear(HHGear, cd) then |
142 if not TestCollisionXwithGear(HHGear, cd) then |
144 HHGear^.dY := HHGear^.dY + cGravity * 64; |
143 HHGear^.dY := HHGear^.dY + cGravity * 16; |
145 |
144 |
146 if (GameFlags and gfMoreWind) <> 0 then |
145 if (GameFlags and gfMoreWind) <> 0 then |
147 // apply wind if there's no obstacle |
146 // apply wind if there's no obstacle |
148 if not TestCollisionXwithGear(HHGear, hwSign(cWindSpeed)) then |
147 if not TestCollisionXwithGear(HHGear, hwSign(cWindSpeed)) then |
149 HHGear^.dX := HHGear^.dX + cWindSpeed * 64 / HHGear^.Density; |
148 HHGear^.dX := HHGear^.dX + cWindSpeed * 16 / HHGear^.Density; |
150 end; |
149 end; |
151 |
150 |
152 mdX := ropeDx + HHGear^.dX; |
151 mdX := ropeDx + HHGear^.dX; |
153 mdY := ropeDy + HHGear^.dY; |
152 mdY := ropeDy + HHGear^.dY; |
154 len := _1 / Distance(mdX, mdY); |
153 len := _1 / Distance(mdX, mdY); |
165 ty := HHGear^.Y; |
164 ty := HHGear^.Y; |
166 |
165 |
167 if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then |
166 if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then |
168 if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx)) |
167 if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx)) |
169 or (TestCollisionYwithGear(HHGear, hwSign(ropeDy)) <> 0)) then |
168 or (TestCollisionYwithGear(HHGear, hwSign(ropeDy)) <> 0)) then |
170 Gear^.Elasticity := Gear^.Elasticity + _2_4; |
169 Gear^.Elasticity := Gear^.Elasticity + _1_2; |
171 |
170 |
172 if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then |
171 if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then |
173 if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx)) |
172 if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx)) |
174 or (TestCollisionYwithGear(HHGear, -hwSign(ropeDy)) <> 0)) then |
173 or (TestCollisionYwithGear(HHGear, -hwSign(ropeDy)) <> 0)) then |
175 Gear^.Elasticity := Gear^.Elasticity - _2_4; |
174 Gear^.Elasticity := Gear^.Elasticity - _1_2; |
176 |
175 |
177 HHGear^.X := Gear^.X + mdX * Gear^.Elasticity; |
176 HHGear^.X := Gear^.X + mdX * Gear^.Elasticity; |
178 HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity; |
177 HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity; |
179 |
178 |
180 HHGear^.dX := Gear^.X + mdX * Gear^.Elasticity - tx; |
179 HHGear^.dX := HHGear^.X - tx; |
181 HHGear^.dY := Gear^.Y + mdY * Gear^.Elasticity - ty; |
180 HHGear^.dY := HHGear^.Y - ty; |
182 |
|
183 sDx:= HHGear^.dX / 8; |
|
184 sDy:= HHGear^.dY / 8; |
|
185 |
|
186 HHGear^.X:= tx; |
|
187 HHGear^.Y:= ty; |
|
188 |
|
189 i:= 0; |
|
190 while not ((i = 8) |
|
191 or TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) |
|
192 or (TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) <> 0)) do |
|
193 begin |
|
194 inc(i); |
|
195 HHGear^.X:= HHGear^.X + sDx; |
|
196 HHGear^.Y:= HHGear^.Y + sDy; |
|
197 end; |
|
198 //// |
181 //// |
199 |
182 |
200 |
183 |
201 haveDivided := false; |
184 haveDivided := false; |
202 // check whether rope needs dividing |
185 // check whether rope needs dividing |
203 |
186 |
204 len := Gear^.Elasticity - _5; |
187 len := Gear^.Elasticity - _5; |
205 nx := Gear^.X + mdX * len; |
188 nx := Gear^.X + mdX * len; |
206 ny := Gear^.Y + mdY * len; |
189 ny := Gear^.Y + mdY * len; |
207 tx := mdX * _2_4; // should be the same as increase step |
190 tx := mdX * _1_2; // should be the same as increase step |
208 ty := mdY * _2_4; |
191 ty := mdY * _1_2; |
209 |
192 |
210 while len > _3 do |
193 while len > _3 do |
211 begin |
194 begin |
212 lx := hwRound(nx); |
195 lx := hwRound(nx); |
213 ly := hwRound(ny); |
196 ly := hwRound(ny); |
287 haveCollision := true |
270 haveCollision := true |
288 end; |
271 end; |
289 |
272 |
290 if haveCollision and (Gear^.Message and (gmLeft or gmRight) <> 0) and (Gear^.Message and (gmUp or gmDown) <> 0) then |
273 if haveCollision and (Gear^.Message and (gmLeft or gmRight) <> 0) and (Gear^.Message and (gmUp or gmDown) <> 0) then |
291 begin |
274 begin |
292 HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _1_6, HHGear^.dX); |
275 HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _0_8, HHGear^.dX); |
293 HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _1_6, HHGear^.dY) |
276 HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _0_8, HHGear^.dY) |
294 end; |
277 end; |
295 |
278 |
296 len := hwSqr(HHGear^.dX) + hwSqr(HHGear^.dY); |
279 len := hwSqr(HHGear^.dX) + hwSqr(HHGear^.dY); |
297 if len > _49 then |
280 if len > _10 then |
298 begin |
281 begin |
299 len := _7 / hwSqrt(len); |
282 len := _3_2 / hwSqrt(len); |
300 HHGear^.dX := HHGear^.dX * len; |
283 HHGear^.dX := HHGear^.dX * len; |
301 HHGear^.dY := HHGear^.dY * len; |
284 HHGear^.dY := HHGear^.dY * len; |
302 end; |
285 end; |
303 |
286 |
304 haveCollision:= ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)]) <> 0); |
287 haveCollision:= ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)]) <> 0); |
340 |
323 |
341 if not haveCollision then |
324 if not haveCollision then |
342 begin |
325 begin |
343 if (Gear^.State and gsttmpFlag) <> 0 then |
326 if (Gear^.State and gsttmpFlag) <> 0 then |
344 begin |
327 begin |
|
328 HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue shr 2; |
|
329 HHGear^.dY.QWordValue:= HHGear^.dY.QWordValue shr 2; |
|
330 |
345 PlaySound(sndRopeRelease); |
331 PlaySound(sndRopeRelease); |
346 if Gear^.Hedgehog^.CurAmmoType <> amParachute then |
332 if Gear^.Hedgehog^.CurAmmoType <> amParachute then |
347 RopeWaitCollision(Gear, HHGear) |
333 RopeWaitCollision(Gear, HHGear) |
348 else |
334 else |
349 RopeDeleteMe(Gear, HHGear) |
335 RopeDeleteMe(Gear, HHGear) |
350 end |
336 end |
351 end |
337 end |
352 else |
338 else |
353 if (Gear^.State and gsttmpFlag) = 0 then |
339 if (Gear^.State and gsttmpFlag) = 0 then |
354 Gear^.State := Gear^.State or gsttmpFlag; |
340 Gear^.State := Gear^.State or gsttmpFlag; |
355 |
|
356 HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue shr 3; |
|
357 HHGear^.dY.QWordValue:= HHGear^.dY.QWordValue shr 3; |
|
358 end; |
341 end; |
359 |
342 |
360 procedure RopeRemoveFromAmmo(Gear, HHGear: PGear); |
343 procedure RopeRemoveFromAmmo(Gear, HHGear: PGear); |
361 begin |
344 begin |
362 if (Gear^.State and gstAttacked) = 0 then |
345 if (Gear^.State and gstAttacked) = 0 then |
416 Gear^.Elasticity := tt; |
399 Gear^.Elasticity := tt; |
417 Gear^.doStep := @doStepRopeWork; |
400 Gear^.doStep := @doStepRopeWork; |
418 PlaySound(sndRopeAttach); |
401 PlaySound(sndRopeAttach); |
419 with HHGear^ do |
402 with HHGear^ do |
420 begin |
403 begin |
|
404 dX.QWordValue:= dX.QWordValue shl 2; |
|
405 dY.QWordValue:= dY.QWordValue shl 2; |
421 State := State and (not (gstAttacking or gstHHJumping or gstHHHJump)); |
406 State := State and (not (gstAttacking or gstHHJumping or gstHHHJump)); |
422 Message := Message and (not gmAttack) |
407 Message := Message and (not gmAttack) |
423 end; |
408 end; |
424 |
409 |
425 RopeRemoveFromAmmo(Gear, HHGear); |
410 RopeRemoveFromAmmo(Gear, HHGear); |
442 begin |
427 begin |
443 Gear^.doStep := @doStepRopeWork; |
428 Gear^.doStep := @doStepRopeWork; |
444 PlaySound(sndRopeAttach); |
429 PlaySound(sndRopeAttach); |
445 with HHGear^ do |
430 with HHGear^ do |
446 begin |
431 begin |
|
432 dX.QWordValue:= dX.QWordValue shl 2; |
|
433 dY.QWordValue:= dY.QWordValue shl 2; |
447 State := State and (not (gstAttacking or gstHHJumping or gstHHHJump)); |
434 State := State and (not (gstAttacking or gstHHJumping or gstHHHJump)); |
448 Message := Message and (not gmAttack) |
435 Message := Message and (not gmAttack) |
449 end; |
436 end; |
450 |
437 |
451 RopeRemoveFromAmmo(Gear, HHGear); |
438 RopeRemoveFromAmmo(Gear, HHGear); |