hedgewars/GSHandlers.inc
changeset 3384 7eb4707d43f0
parent 3382 633046fa040c
child 3388 ab9352a4ddcc
equal deleted inserted replaced
3383:45a73be4d8c1 3384:7eb4707d43f0
    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;