1 (* |
1 (* |
2 * Hedgewars, a free turn based strategy game |
2 * Hedgewars, a free turn based strategy game |
3 * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com> |
3 * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com> |
4 * |
4 * |
5 * This program is free software; you can redistribute it and/or modify |
5 * This program is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License as published by |
6 * it under the terms of the GNU General Public License as published by |
7 * the Free Software Foundation; version 2 of the License |
7 * the Free Software Foundation; version 2 of the License |
8 * |
8 * |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. |
12 * GNU General Public License for more details. |
13 * |
13 * |
14 * You should have received a copy of the GNU General Public License |
14 * You should have received a copy of the GNU General Public License |
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 *) |
17 *) |
18 |
18 |
19 {$INCLUDE "options.inc"} |
19 {$INCLUDE "options.inc"} |
20 unit uGearsHandlersRope; |
20 unit uGearsHandlersRope; |
21 interface |
21 interface |
26 |
26 |
27 implementation |
27 implementation |
28 uses uConsts, uFloat, uCollisions, uVariables, uGearsList, uSound, uGearsUtils, |
28 uses uConsts, uFloat, uCollisions, uVariables, uGearsList, uSound, uGearsUtils, |
29 uAmmos, uDebug, uUtils, uGearsHedgehog, uGearsRender; |
29 uAmmos, uDebug, uUtils, uGearsHedgehog, uGearsRender; |
30 |
30 |
|
31 const |
|
32 IsNilHHFatal = false; |
|
33 |
31 procedure doStepRopeAfterAttack(Gear: PGear); |
34 procedure doStepRopeAfterAttack(Gear: PGear); |
32 var |
35 var |
33 HHGear: PGear; |
36 HHGear: PGear; |
34 tX: hwFloat; |
37 tX: hwFloat; |
35 begin |
38 begin |
36 HHGear := Gear^.Hedgehog^.Gear; |
39 HHGear := Gear^.Hedgehog^.Gear; |
|
40 if HHGear = nil then |
|
41 begin |
|
42 OutError('ERROR: doStepRopeAfterAttack called while HHGear = nil', IsNilHHFatal); |
|
43 DeleteGear(Gear); |
|
44 exit() |
|
45 end |
|
46 else if not CurrentTeam^.ExtDriven and (FollowGear <> nil) then FollowGear := HHGear; |
|
47 |
37 tX:= HHGear^.X; |
48 tX:= HHGear^.X; |
38 if WorldWrap(HHGear) and (WorldEdge = weWrap) and |
49 if WorldWrap(HHGear) and (WorldEdge = weWrap) and |
39 ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0)) then |
50 ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0)) then |
40 begin |
51 begin |
41 HHGear^.X:= tX; |
52 HHGear^.X:= tX; |
42 HHGear^.dX.isNegative:= (hwRound(tX) > leftX+HHGear^.Radius*2) |
53 HHGear^.dX.isNegative:= hwRound(tX) > LongInt(leftX) + HHGear^.Radius * 2 |
43 end; |
54 end; |
44 |
55 |
45 if (HHGear^.Hedgehog^.CurAmmoType = amParachute) and (HHGear^.dY > _0_39) then |
56 if (HHGear^.Hedgehog^.CurAmmoType = amParachute) and (HHGear^.dY > _0_39) then |
46 begin |
57 begin |
47 DeleteGear(Gear); |
58 DeleteGear(Gear); |
68 if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then |
79 if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then |
69 HHGear^.dY := _0; |
80 HHGear^.dY := _0; |
70 HHGear^.X := HHGear^.X + HHGear^.dX; |
81 HHGear^.X := HHGear^.X + HHGear^.dX; |
71 HHGear^.Y := HHGear^.Y + HHGear^.dY; |
82 HHGear^.Y := HHGear^.Y + HHGear^.dY; |
72 HHGear^.dY := HHGear^.dY + cGravity; |
83 HHGear^.dY := HHGear^.dY + cGravity; |
73 |
84 |
74 if (GameFlags and gfMoreWind) <> 0 then |
85 if (GameFlags and gfMoreWind) <> 0 then |
75 HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density; |
86 HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density; |
76 |
87 |
77 if (Gear^.Message and gmAttack) <> 0 then |
88 if (Gear^.Message and gmAttack) <> 0 then |
78 begin |
89 begin |
111 Gear^.Elasticity := _0; |
122 Gear^.Elasticity := _0; |
112 Gear^.doStep := @doStepRopeAfterAttack |
123 Gear^.doStep := @doStepRopeAfterAttack |
113 end; |
124 end; |
114 |
125 |
115 procedure doStepRopeWork(Gear: PGear); |
126 procedure doStepRopeWork(Gear: PGear); |
116 var |
127 var |
117 HHGear: PGear; |
128 HHGear: PGear; |
118 len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; |
129 len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; |
119 lx, ly, cd: LongInt; |
130 lx, ly, cd: LongInt; |
120 haveCollision, |
131 haveCollision, |
121 haveDivided: boolean; |
132 haveDivided: boolean; |
122 wrongSide: boolean; |
133 wrongSide: boolean; |
123 begin |
134 begin |
|
135 HHGear := Gear^.Hedgehog^.Gear; |
|
136 if HHGear = nil then |
|
137 begin |
|
138 OutError('ERROR: doStepRopeWork called while HHGear = nil', IsNilHHFatal); |
|
139 DeleteGear(Gear); |
|
140 exit() |
|
141 end |
|
142 else if not CurrentTeam^.ExtDriven and (FollowGear <> nil) then FollowGear := HHGear; |
|
143 |
|
144 if ((HHGear^.State and gstHHDriven) = 0) or |
|
145 (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then |
|
146 begin |
|
147 PlaySound(sndRopeRelease); |
|
148 RopeDeleteMe(Gear, HHGear); |
|
149 exit |
|
150 end; |
|
151 |
124 if GameTicks mod 4 <> 0 then exit; |
152 if GameTicks mod 4 <> 0 then exit; |
125 |
153 |
126 HHGear := Gear^.Hedgehog^.Gear; |
|
127 |
|
128 tX:= HHGear^.X; |
154 tX:= HHGear^.X; |
129 if WorldWrap(HHGear) and (WorldEdge = weWrap) and |
155 if WorldWrap(HHGear) and (WorldEdge = weWrap) and |
130 ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0)) then |
156 ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0)) then |
131 begin |
157 begin |
132 PlaySound(sndRopeRelease); |
158 PlaySound(sndRopeRelease); |
133 RopeDeleteMe(Gear, HHGear); |
159 RopeDeleteMe(Gear, HHGear); |
134 HHGear^.X:= tX; |
160 HHGear^.X:= tX; |
135 HHGear^.dX.isNegative:= (hwRound(tX) > leftX+HHGear^.Radius*2); |
161 HHGear^.dX.isNegative:= hwRound(tX) > LongInt(leftX) + HHGear^.Radius * 2; |
136 exit |
162 exit |
137 end; |
163 end; |
138 |
164 |
139 tX:= HHGear^.X; |
165 tX:= HHGear^.X; |
140 if ((HHGear^.State and gstHHDriven) = 0) or |
|
141 (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then |
|
142 begin |
|
143 PlaySound(sndRopeRelease); |
|
144 RopeDeleteMe(Gear, HHGear); |
|
145 exit |
|
146 end; |
|
147 |
|
148 HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue shl 2; |
166 HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue shl 2; |
149 HHGear^.dY.QWordValue:= HHGear^.dY.QWordValue shl 2; |
167 HHGear^.dY.QWordValue:= HHGear^.dY.QWordValue shl 2; |
150 if (Gear^.Message and gmLeft <> 0) and (TestCollisionXwithGear(HHGear, -1) = 0) then |
168 if (Gear^.Message and gmLeft <> 0) and (TestCollisionXwithGear(HHGear, -1) = 0) then |
151 HHGear^.dX := HHGear^.dX - _0_0032; |
169 HHGear^.dX := HHGear^.dX - _0_0032; |
152 |
170 |
403 end; |
421 end; |
404 ApplyAmmoChanges(HHGear^.Hedgehog^) |
422 ApplyAmmoChanges(HHGear^.Hedgehog^) |
405 end; |
423 end; |
406 |
424 |
407 procedure doStepRopeAttach(Gear: PGear); |
425 procedure doStepRopeAttach(Gear: PGear); |
408 var |
426 var |
409 HHGear: PGear; |
427 HHGear: PGear; |
410 tx, ty, tt: hwFloat; |
428 tx, ty, tt: hwFloat; |
411 begin |
429 begin |
|
430 |
412 Gear^.X := Gear^.X - Gear^.dX; |
431 Gear^.X := Gear^.X - Gear^.dX; |
413 Gear^.Y := Gear^.Y - Gear^.dY; |
432 Gear^.Y := Gear^.Y - Gear^.dY; |
414 Gear^.Elasticity := Gear^.Elasticity + _1; |
433 Gear^.Elasticity := Gear^.Elasticity + _1; |
415 |
434 |
416 HHGear := Gear^.Hedgehog^.Gear; |
435 HHGear := Gear^.Hedgehog^.Gear; |
|
436 if HHGear = nil then |
|
437 begin |
|
438 OutError('ERROR: doStepRopeAttach called while HHGear = nil', IsNilHHFatal); |
|
439 DeleteGear(Gear); |
|
440 exit() |
|
441 end |
|
442 else if not CurrentTeam^.ExtDriven and (FollowGear <> nil) then FollowGear := HHGear; |
|
443 |
417 DeleteCI(HHGear); |
444 DeleteCI(HHGear); |
418 |
445 |
419 if (HHGear^.State and gstMoving) <> 0 then |
446 if (HHGear^.State and gstMoving) <> 0 then |
420 begin |
447 begin |
421 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) <> 0 then |
448 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) <> 0 then |