71 else |
71 else |
72 begin |
72 begin |
73 CheckGearDrowning:= true; |
73 CheckGearDrowning:= true; |
74 Gear^.State:= gstDrowning; |
74 Gear^.State:= gstDrowning; |
75 Gear^.RenderTimer:= false; |
75 Gear^.RenderTimer:= false; |
76 if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and (Gear^.Kind <> gtDEagleShot) then |
76 if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then |
77 Gear^.doStep:= @doStepDrowningGear; |
77 Gear^.doStep:= @doStepDrowningGear; |
78 if Gear^.Kind = gtHedgehog then |
78 if Gear^.Kind = gtHedgehog then |
79 begin |
79 begin |
80 Gear^.State:= Gear^.State and (not gstHHDriven); |
80 Gear^.State:= Gear^.State and (not gstHHDriven); |
81 AddCaption(Format(GetEventString(eidDrowned), PHedgehog(Gear^.Hedgehog)^.Name), cWhiteColor, capgrpMessage); |
81 AddCaption(Format(GetEventString(eidDrowned), PHedgehog(Gear^.Hedgehog)^.Name), cWhiteColor, capgrpMessage); |
3107 Gear^.Pos:= Gear^.Pos + 1; |
3107 Gear^.Pos:= Gear^.Pos + 1; |
3108 end |
3108 end |
3109 else |
3109 else |
3110 Gear^.dY:= Gear^.dY + cGravity * 2; // let it fall faster so itdoesn't take too long for the whole attack |
3110 Gear^.dY:= Gear^.dY + cGravity * 2; // let it fall faster so itdoesn't take too long for the whole attack |
3111 end; |
3111 end; |
|
3112 |
|
3113 |
|
3114 //////////////////////////////////////////////////////////////////////////////// |
|
3115 procedure doStepSineGunShotWork(Gear: PGear); |
|
3116 var x, y, rX, rY, t, tmp, initHealth: LongWord; |
|
3117 oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat; |
|
3118 justCollided: boolean; |
|
3119 begin |
|
3120 AllInactive:= false; |
|
3121 initHealth:= Gear^.Health; |
|
3122 lX:= Gear^.X; |
|
3123 lY:= Gear^.Y; |
|
3124 ldX:= Gear^.dX; |
|
3125 ldY:= Gear^.dY; |
|
3126 sdy:= _0_5/Distance(Gear^.dX,Gear^.dY); |
|
3127 ldX:= ldX * sdy; |
|
3128 ldY:= ldY * sdy; |
|
3129 sdY:= hwAbs(ldX) + hwAbs(ldY); |
|
3130 sdX:= _1 - hwAbs(ldX/sdY); |
|
3131 sdY:= _1 - hwAbs(ldY/sdY); |
|
3132 if (ldX.isNegative = ldY.isNegative) then sdY:= -sdY; |
|
3133 |
|
3134 // initial angle depends on current GameTicks |
|
3135 t:= GameTicks mod 4096; |
|
3136 |
|
3137 |
|
3138 // used for a work-around detection of area that is within land array, but outside borders |
|
3139 justCollided:= false; |
|
3140 |
|
3141 repeat |
|
3142 lX:= lX + ldX; |
|
3143 lY:= lY + ldY; |
|
3144 oX:= Gear^.X; |
|
3145 oY:= Gear^.Y; |
|
3146 rX:= hwRound(oX); |
|
3147 rY:= hwRound(oY); |
|
3148 tmp:= t mod 4096; |
|
3149 amp:= _128 * (_1 - hwSqr(int2hwFloat(Gear^.Health)/initHealth)); |
|
3150 sine:= amp * AngleSin(tmp mod 2048); |
|
3151 sine.isNegative:= (tmp < 2048); |
|
3152 inc(t,Gear^.Health div 313); |
|
3153 Gear^.X:= lX + (sine * sdX); |
|
3154 Gear^.Y:= ly + (sine * sdY); |
|
3155 Gear^.dX:= Gear^.X - oX; |
|
3156 Gear^.dY:= Gear^.Y - oY; |
|
3157 |
|
3158 x:= hwRound(Gear^.X); |
|
3159 y:= hwRound(Gear^.Y); |
|
3160 |
|
3161 // if borders are on, stop outside land array |
|
3162 if hasBorder and (((x and LAND_WIDTH_MASK) <> 0) or ((y and LAND_HEIGHT_MASK) <> 0)) then |
|
3163 begin |
|
3164 Gear^.Damage:= 0; |
|
3165 Gear^.Health:= 0; |
|
3166 end |
|
3167 else |
|
3168 begin |
|
3169 if (rY <= cWaterLine) or (y <= cWaterLine) then |
|
3170 begin |
|
3171 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
|
3172 and (Land[y, x] <> 0) then |
|
3173 begin |
|
3174 if justCollided then |
|
3175 begin |
|
3176 Gear^.Damage:= 0; |
|
3177 Gear^.Health:= 0; |
|
3178 end |
|
3179 else |
|
3180 begin |
|
3181 inc(Gear^.Damage,3); |
|
3182 justCollided:= true; |
|
3183 end; |
|
3184 end |
|
3185 else |
|
3186 justCollided:= false; |
|
3187 |
|
3188 // kick nearby hogs, dig tunnel and add some fire |
|
3189 // if at least 5 collisions occured |
|
3190 if Gear^.Damage > 0 then |
|
3191 begin |
|
3192 DrawExplosion(rX,rY,Gear^.Radius); |
|
3193 |
|
3194 // kick nearby hogs |
|
3195 AmmoShove(Gear, 35, 50); |
|
3196 |
|
3197 dec(Gear^.Health, Gear^.Damage); |
|
3198 Gear^.Damage:= 0; |
|
3199 |
|
3200 // add some fire to the tunnel |
|
3201 if getRandom(6) = 0 then |
|
3202 AddGear(x-Gear^.Radius+getRandom(2*Gear^.Radius), y-getRandom(Gear^.Radius+1), gtFlame, gsttmpFlag, _0, _0, 0); |
|
3203 end; |
|
3204 |
|
3205 if getRandom(100) = 0 then |
|
3206 AddGear(x, y, gtSmokeTrace, 0, _0, _0, 0); |
|
3207 |
|
3208 end |
|
3209 // if underwater get additional damage |
|
3210 else dec(Gear^.Health, 5); |
|
3211 end; |
|
3212 |
|
3213 dec(Gear^.Health); |
|
3214 |
|
3215 // decrease bullet size towards the end |
|
3216 if (Gear^.Radius > 4) then begin |
|
3217 if (Gear^.Health <= (initHealth div 3)) then dec(Gear^.Radius) end |
|
3218 else if (Gear^.Radius > 3) then begin |
|
3219 if (Gear^.Health <= (initHealth div 4)) then dec(Gear^.Radius) end |
|
3220 else if (Gear^.Radius > 2) then begin |
|
3221 if (Gear^.Health <= (initHealth div 5)) then dec(Gear^.Radius) end |
|
3222 else if (Gear^.Radius > 1) then begin |
|
3223 if (Gear^.Health <= (initHealth div 6)) then dec(Gear^.Radius) end; |
|
3224 |
|
3225 until (Gear^.Health <= 0); |
|
3226 |
|
3227 DeleteGear(Gear); |
|
3228 AfterAttack; |
|
3229 end; |
|
3230 |
|
3231 procedure doStepSineGunShot(Gear: PGear); |
|
3232 var HHGear: PGear; |
|
3233 begin |
|
3234 PlaySound(sndSineGun); |
|
3235 |
|
3236 |
|
3237 // push the shooting Hedgehog back |
|
3238 HHGear:= CurrentHedgehog^.Gear; |
|
3239 Gear^.dX.isNegative:= not Gear^.dX.isNegative; |
|
3240 Gear^.dY.isNegative:= not Gear^.dY.isNegative; |
|
3241 HHGear^.dX:= Gear^.dX; |
|
3242 HHGear^.dY:= Gear^.dY; |
|
3243 AmmoShove(Gear, 0, 80); |
|
3244 Gear^.dX.isNegative:= not Gear^.dX.isNegative; |
|
3245 Gear^.dY.isNegative:= not Gear^.dY.isNegative; |
|
3246 |
|
3247 Gear^.doStep:= @doStepSineGunShotWork |
|
3248 |
|
3249 end; |