hedgewars/GSHandlers.inc
changeset 6468 da1e7fe7cff7
parent 6453 11c578d30bd3
child 6472 bced12412f94
equal deleted inserted replaced
6467:090269e528df 6468:da1e7fe7cff7
   131 HH^.Gear^.Active:= true;
   131 HH^.Gear^.Active:= true;
   132 ScriptCall('onHogRestore', HH^.Gear^.Uid)
   132 ScriptCall('onHogRestore', HH^.Gear^.Uid)
   133 end;
   133 end;
   134 
   134 
   135 ////////////////////////////////////////////////////////////////////////////////
   135 ////////////////////////////////////////////////////////////////////////////////
   136 procedure doStepDrowningGear(Gear: PGear);
       
   137 forward;
       
   138 
       
   139 function CheckGearDrowning(Gear: PGear): boolean;
       
   140 var 
       
   141     skipSpeed, skipAngle, skipDecay: hwFloat;
       
   142     i, maxDrops, X, Y: LongInt;
       
   143     vdX, vdY: real;
       
   144     particle: PVisualGear;
       
   145     isSubmersible: boolean;
       
   146 begin
       
   147     isSubmersible:= (Gear = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amJetpack);
       
   148     // probably needs tweaking. might need to be in a case statement based upon gear type
       
   149     Y:= hwRound(Gear^.Y);
       
   150     if cWaterLine < Y + Gear^.Radius then
       
   151         begin
       
   152         skipSpeed := _0_25;
       
   153         skipAngle := _1_9;
       
   154         skipDecay := _0_87;
       
   155         X:= hwRound(Gear^.X);
       
   156         vdX:= hwFloat2Float(Gear^.dX);
       
   157         vdY:= hwFloat2Float(Gear^.dY);
       
   158         // this could perhaps be a tiny bit higher.
       
   159         if  (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed) and
       
   160            (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then
       
   161             begin
       
   162             Gear^.dY.isNegative := true;
       
   163             Gear^.dY := Gear^.dY * skipDecay;
       
   164             Gear^.dX := Gear^.dX * skipDecay;
       
   165             CheckGearDrowning := false;
       
   166             PlaySound(sndSkip)
       
   167             end
       
   168         else
       
   169             begin
       
   170             if not isSubmersible then
       
   171                 begin
       
   172                 CheckGearDrowning := true;
       
   173                 Gear^.State := gstDrowning;
       
   174                 Gear^.RenderTimer := false;
       
   175                 if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and 
       
   176                    (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then
       
   177                     if Gear^.Kind = gtHedgehog then
       
   178                         begin
       
   179                         if Gear^.Hedgehog^.Effects[heResurrectable] then
       
   180                             ResurrectHedgehog(Gear)
       
   181                         else
       
   182                             begin
       
   183                             Gear^.doStep := @doStepDrowningGear;
       
   184                             Gear^.State := Gear^.State and (not gstHHDriven);
       
   185                             AddCaption(Format(GetEventString(eidDrowned), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
       
   186                             end
       
   187                         end
       
   188                     else Gear^.doStep := @doStepDrowningGear;
       
   189                     if Gear^.Kind = gtFlake then exit // skip splashes 
       
   190                 end;
       
   191             if ((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) or
       
   192                (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) and (CurAmmoGear^.dY < _0_01))) then
       
   193                 // don't play splash if they are already way past the surface
       
   194                 PlaySound(sndSplash)
       
   195             end;
       
   196 
       
   197         if ((cReducedQuality and rqPlainSplash) = 0) and 
       
   198            (((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius)) or
       
   199              (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) and (CurAmmoGear^.dY < _0_01)))) then
       
   200             begin
       
   201             AddVisualGear(X, cWaterLine, vgtSplash);
       
   202 
       
   203             maxDrops := (Gear^.Radius div 2) + round(vdX * Gear^.Radius * 2) + round(vdY * Gear^.Radius * 2);
       
   204             for i:= max(maxDrops div 3, min(32, Random(maxDrops))) downto 0 do
       
   205                 begin
       
   206                 particle := AddVisualGear(X - 3 + Random(6), cWaterLine, vgtDroplet);
       
   207                 if particle <> nil then
       
   208                     begin
       
   209                     particle^.dX := particle^.dX - vdX / 10;
       
   210                     particle^.dY := particle^.dY - vdY / 5;
       
   211                     end
       
   212                 end
       
   213             end;
       
   214         if isSubmersible and (CurAmmoGear^.Pos = 0) then CurAmmoGear^.Pos := 1000
       
   215         end
       
   216     else
       
   217         CheckGearDrowning := false;
       
   218 end;
       
   219 
       
   220 procedure CheckCollision(Gear: PGear); inline;
   136 procedure CheckCollision(Gear: PGear); inline;
   221 begin
   137 begin
   222     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then
   138     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then
   223         Gear^.State := Gear^.State or gstCollision
   139         Gear^.State := Gear^.State or gstCollision
   224     else Gear^.State := Gear^.State and (not gstCollision)
   140     else Gear^.State := Gear^.State and (not gstCollision)
   230        )
   146        )
   231         then Gear^.State := Gear^.State or      gstCollision
   147         then Gear^.State := Gear^.State or      gstCollision
   232     else Gear^.State := Gear^.State and (not gstCollision)
   148     else Gear^.State := Gear^.State and (not gstCollision)
   233 end;
   149 end;
   234 
   150 
   235 procedure CheckHHDamage(Gear: PGear);
   151 
   236 var 
   152 ////////////////////////////////////////////////////////////////////////////////
   237     dmg: Longword;
   153 
   238     i: LongInt;
       
   239     particle: PVisualGear;
       
   240 begin
       
   241     if _0_4 < Gear^.dY then
       
   242         begin
       
   243         dmg := ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear);
       
   244         PlaySound(sndBump);
       
   245         if dmg < 1 then exit;
       
   246 
       
   247         for i:= min(12, (3 + dmg div 10)) downto 0 do
       
   248             begin
       
   249             particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
       
   250             if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480);
       
   251             end;
       
   252 
       
   253         if (Gear^.Invulnerable) then exit;
       
   254 
       
   255         //if _0_6 < Gear^.dY then
       
   256         //    PlaySound(sndOw4, Gear^.Hedgehog^.Team^.voicepack)
       
   257         //else
       
   258         //    PlaySound(sndOw1, Gear^.Hedgehog^.Team^.voicepack);
       
   259 
       
   260         if Gear^.LastDamage <> nil then
       
   261             ApplyDamage(Gear, Gear^.LastDamage, dmg, dsFall)
       
   262             else
       
   263             ApplyDamage(Gear, CurrentHedgehog, dmg, dsFall);
       
   264     end
       
   265 end;
       
   266 
       
   267 ////////////////////////////////////////////////////////////////////////////////
       
   268 procedure CalcRotationDirAngle(Gear: PGear);
       
   269 var 
       
   270     dAngle: real;
       
   271 begin
       
   272     dAngle := (Gear^.dX.QWordValue + Gear^.dY.QWordValue) / $80000000;
       
   273     if not Gear^.dX.isNegative then
       
   274         Gear^.DirAngle := Gear^.DirAngle + dAngle
       
   275     else
       
   276         Gear^.DirAngle := Gear^.DirAngle - dAngle;
       
   277 
       
   278     if Gear^.DirAngle < 0 then Gear^.DirAngle := Gear^.DirAngle + 360
       
   279     else if 360 < Gear^.DirAngle then Gear^.DirAngle := Gear^.DirAngle - 360
       
   280 end;
       
   281 
   154 
   282 ////////////////////////////////////////////////////////////////////////////////
   155 ////////////////////////////////////////////////////////////////////////////////
   283 procedure doStepDrowningGear(Gear: PGear);
   156 procedure doStepDrowningGear(Gear: PGear);
   284 begin
   157 begin
   285     AllInactive := false;
   158     AllInactive := false;