hedgewars/HHHandlers.inc
changeset 37 2b7f2a43b999
parent 32 78bff13b11c0
child 38 c1ec4b15d70e
equal deleted inserted replaced
36:a803a00a3272 37:2b7f2a43b999
    29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    32  *)
    32  *)
    33 
    33 
       
    34 procedure AddIntersectorsCR(Gear: PGear);
       
    35 var t: PGear;
       
    36     x, xw, y, yh: real;
       
    37     ar: array[0..Pred(cMaxHHs)] of PGear;
       
    38     cnt: Longword;
       
    39     b: boolean;
       
    40 begin
       
    41 x:= Gear.X - Gear.HalfWidth;
       
    42 xw:= Gear.X + Gear.HalfWidth;
       
    43 y:= Gear.Y - Gear.HalfHeight;
       
    44 yh:= Gear.Y + Gear.HalfHeight;
       
    45 t:= GearsList;
       
    46 b:= false;
       
    47 cnt:= 0;
       
    48 while (t <> nil) do
       
    49       begin
       
    50       if (t <> Gear) then
       
    51          if (x < t.X + t.HalfWidth ) and (t.X - t.HalfWidth  < xw) and
       
    52             (y < t.Y + t.HalfHeight) and (t.Y - t.HalfHeight < yh) then
       
    53             if t.Kind = gtHedgehog then
       
    54                begin
       
    55                ar[cnt]:= t;
       
    56                inc(cnt)
       
    57                end else b:= true;
       
    58       t:= t.NextGear
       
    59       end;
       
    60 ar[cnt]:= Gear;
       
    61 inc(cnt);
       
    62 if b then
       
    63    begin
       
    64    repeat
       
    65      dec(cnt);
       
    66      if ar[cnt].CollIndex < High(Longword) then DeleteCR(ar[cnt])
       
    67    until cnt = 0;
       
    68    end else
       
    69    begin
       
    70    repeat
       
    71      dec(cnt);
       
    72      if ar[cnt].CollIndex = High(Longword) then AddGearCR(ar[cnt])
       
    73    until cnt = 0
       
    74    end
       
    75 end;
       
    76 
       
    77 procedure RemoveIntersectorsCR(Gear: PGear);
       
    78 var t: PGear;
       
    79     x, xw, y, yh: real;
       
    80 begin
       
    81 x:= Gear.X - Gear.HalfWidth;
       
    82 xw:= Gear.X + Gear.HalfWidth;
       
    83 y:= Gear.Y - Gear.HalfHeight;
       
    84 yh:= Gear.Y + Gear.HalfHeight;
       
    85 t:= GearsList;
       
    86 while (t <> nil) do
       
    87       begin
       
    88       if (t <> Gear) then
       
    89          if (x < t.X + t.HalfWidth ) and (t.X - t.HalfWidth  < xw) and
       
    90             (y < t.Y + t.HalfHeight) and (t.Y - t.HalfHeight < yh) then
       
    91                if t.CollIndex < High(Longword) then DeleteCR(t);
       
    92       t:= t.NextGear
       
    93       end;
       
    94 if Gear.CollIndex < High(Longword) then DeleteCR(Gear);
       
    95 end;
       
    96 
       
    97 ////////////////////////////////////////////////////////////////////////////////
    34 procedure Attack(Gear: PGear);
    98 procedure Attack(Gear: PGear);
    35 var xx, yy: real;
    99 var xx, yy: real;
    36 begin
   100 begin
    37 with Gear^,
   101 with Gear^,
    38      CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
   102      CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
    62                           amUFO: FollowGear:= AddGear(round(X), round(Y), gtUFO,          0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor);
   126                           amUFO: FollowGear:= AddGear(round(X), round(Y), gtUFO,          0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor);
    63                       amShotgun: begin
   127                       amShotgun: begin
    64                                  PlaySound(sndShotgunReload);
   128                                  PlaySound(sndShotgunReload);
    65                                  FollowGear:= AddGear(round(X + xx*20), round(Y + yy*20), gtShotgunShot,  0, xx * 0.5, 0.5 * yy);
   129                                  FollowGear:= AddGear(round(X + xx*20), round(Y + yy*20), gtShotgunShot,  0, xx * 0.5, 0.5 * yy);
    66                                  end;
   130                                  end;
       
   131                        amDEagle: begin
       
   132                                  FollowGear:= AddGear(round(X + xx*20), round(Y + yy*20), gtDEagleShot,  0, xx * 0.5, 0.5 * yy);
       
   133                                  end;
    67                          amSkip: TurnTimeLeft:= 0;
   134                          amSkip: TurnTimeLeft:= 0;
    68                    amPickHammer: CurAmmoGear:= AddGear(round(Gear.X), round(Gear.Y) + cHHHalfHeight, gtPickHammer, 0);
   135                    amPickHammer: CurAmmoGear:= AddGear(round(Gear.X), round(Gear.Y) + cHHHalfHeight, gtPickHammer, 0);
    69                          amRope: CurAmmoGear:= AddGear(round(Gear.X), round(Gear.Y), gtRope, 0, xx, yy);
   136                          amRope: CurAmmoGear:= AddGear(round(Gear.X), round(Gear.Y), gtRope, 0, xx, yy);
    70                          amMine: AddGear(round(X) + Sign(dX) * 7, round(Y), gtMine, 0, Sign(dX) * 0.01, 0, 3000);
   137                          amMine: AddGear(round(X) + Sign(dX) * 7, round(Y), gtMine, 0, Sign(dX) * 0.01, 0, 3000);
    71                   end;
   138                   end;
   118    Gear.State:= Gear.State and not gstHHDriven;
   185    Gear.State:= Gear.State and not gstHHDriven;
   119    if Gear.Damage > 0 then
   186    if Gear.Damage > 0 then
   120       Gear.State:= Gear.State and not gstHHJumping;
   187       Gear.State:= Gear.State and not gstHHJumping;
   121    exit
   188    exit
   122    end;
   189    end;
   123    
   190 
   124 // check for case with ammo
   191 // check for case with ammo
   125 t:= CheckGearNear(Gear, gtCase, 30, 30);
   192 t:= CheckGearNear(Gear, gtCase, 30, 30);
   126 if t <> nil then
   193 if t <> nil then
   127    begin
   194    begin
   128    t.Message:= gm_Destroy;
   195    t.Message:= gm_Destroy;
   139    if (Gear.State and (gstAttacked or gstHHChooseTarget) = 0) then
   206    if (Gear.State and (gstAttacked or gstHHChooseTarget) = 0) then
   140       with PHedgehog(Gear.Hedgehog)^ do
   207       with PHedgehog(Gear.Hedgehog)^ do
   141             begin
   208             begin
   142             Gear.State:= Gear.State or gstAttacking;
   209             Gear.State:= Gear.State or gstAttacking;
   143             if Gear.Power = cMaxPower then Gear.Message:= Gear.Message and not gm_Attack
   210             if Gear.Power = cMaxPower then Gear.Message:= Gear.Message and not gm_Attack
   144                else begin
   211                else
   145                if (Ammo[CurSlot, CurAmmo].Propz and ammoprop_Power) = 0 then Attack(Gear)
   212                if (Ammo[CurSlot, CurAmmo].Propz and ammoprop_Power) = 0 then Attack(Gear)
   146                   else begin
   213                   else begin
   147                   if Gear.Power = 0 then
   214                   if Gear.Power = 0 then
   148                      begin
   215                      begin
   149                      AttackBar:= CurrentTeam.AttackBar;
   216                      AttackBar:= CurrentTeam.AttackBar;
   150                      PlaySound(sndThrowPowerUp)
   217                      PlaySound(sndThrowPowerUp)
   151                      end;
   218                      end;
   152                   inc(Gear.Power)
   219                   inc(Gear.Power)
   153                   end
   220                   end
   154                end;
   221             end
   155             end else Gear.Message:= Gear.Message and not gm_Attack;
   222       else Gear.Message:= Gear.Message and not gm_Attack;
   156 
   223 
   157 if ((Gear.State and gstAttacking) <> 0) and ((Gear.Message and gm_Attack) = 0) then Attack(Gear);
   224 if ((Gear.State and gstAttacking) <> 0) and ((Gear.Message and gm_Attack) = 0) then
       
   225    begin
       
   226    RemoveIntersectorsCR(Gear);
       
   227    Attack(Gear);
       
   228    end;
   158 
   229 
   159 if (Gear.State and gstFalling) <> 0 then
   230 if (Gear.State and gstFalling) <> 0 then
   160    begin
   231    begin
   161    // it could be the source to trick: double-backspace jump -> vertical wall
   232    // it could be the source to trick: double-backspace jump -> vertical wall
   162    // collision - > (abs(Gear.dX) < 0.0000002) -> backspace -> even more high jump
   233    // collision - > (abs(Gear.dX) < 0.0000002) -> backspace -> even more high jump
   176       begin
   247       begin
   177       CheckHHDamage(Gear);
   248       CheckHHDamage(Gear);
   178       if ((abs(Gear.dX) + abs(Gear.dY)) < 0.55)
   249       if ((abs(Gear.dX) + abs(Gear.dY)) < 0.55)
   179          and ((Gear.State and gstHHJumping) <> 0) then Gear.dX:= 0.0000001 * Sign(Gear.dX);
   250          and ((Gear.State and gstHHJumping) <> 0) then Gear.dX:= 0.0000001 * Sign(Gear.dX);
   180       Gear.State:= Gear.State and not (gstFalling or gstHHJumping);
   251       Gear.State:= Gear.State and not (gstFalling or gstHHJumping);
   181       StepTicks:= 200;
   252       StepTicks:= 300;   writelntoconsole(inttostr(gameticks)+'ooo');
   182       Gear.dY:= 0
   253       Gear.dY:= 0
   183       end;
   254       end;
   184    CheckGearDrowning(Gear);
   255    CheckGearDrowning(Gear);
   185    exit
   256    exit
   186    end;
   257    end else if Gear.CollIndex = High(Longword) then AddIntersectorsCR(Gear);
   187 
   258 
   188 if StepTicks > 0 then dec(StepTicks);
   259 if StepTicks > 0 then dec(StepTicks);
   189 
   260 
   190 if ((Gear.State and (gstMoving or gstFalling)) = 0) then
   261 if ((Gear.State and (gstMoving or gstFalling)) = 0) then
   191    if (Gear.Message and gm_Up    )<>0 then if Gear.Angle > 0         then dec(Gear.Angle)
   262    if (Gear.Message and gm_Up    )<>0 then if Gear.Angle > 0         then dec(Gear.Angle)
   195 if ((Gear.State and (gstAttacking or gstMoving or gstFalling)) = 0)and(StepTicks = 0) then
   266 if ((Gear.State and (gstAttacking or gstMoving or gstFalling)) = 0)and(StepTicks = 0) then
   196    begin
   267    begin
   197    if ((Gear.Message and gm_LJump )<>0) then
   268    if ((Gear.Message and gm_LJump )<>0) then
   198       begin
   269       begin
   199       Gear.Message:= 0;
   270       Gear.Message:= 0;
       
   271       RemoveIntersectorsCR(Gear);
   200       if not HHTestCollisionYwithGear(Gear, -1) then
   272       if not HHTestCollisionYwithGear(Gear, -1) then
   201          if not TestCollisionXwithXYShift(Gear, 0, -2, Sign(Gear.dX)) then Gear.Y:= Gear.Y - 2 else
   273          if not TestCollisionXwithXYShift(Gear, 0, -2, Sign(Gear.dX)) then Gear.Y:= Gear.Y - 2 else
   202          if not TestCollisionXwithXYShift(Gear, 0, -1, Sign(Gear.dX)) then Gear.Y:= Gear.Y - 1;
   274          if not TestCollisionXwithXYShift(Gear, 0, -1, Sign(Gear.dX)) then Gear.Y:= Gear.Y - 1;
   203       if not (TestCollisionXwithGear(Gear, Sign(Gear.dX))
   275       if not (TestCollisionXwithGear(Gear, Sign(Gear.dX))
   204          or   HHTestCollisionYwithGear(Gear, -1)) then
   276          or   HHTestCollisionYwithGear(Gear, -1)) then
   210          end;
   282          end;
   211       end;
   283       end;
   212    if ((Gear.Message and gm_HJump )<>0) then
   284    if ((Gear.Message and gm_HJump )<>0) then
   213       begin
   285       begin
   214       Gear.Message:= 0;
   286       Gear.Message:= 0;
       
   287       RemoveIntersectorsCR(Gear);
   215       if not HHTestCollisionYwithGear(Gear, -1) then
   288       if not HHTestCollisionYwithGear(Gear, -1) then
   216          begin
   289          begin
   217          Gear.dY:= -0.20;
   290          Gear.dY:= -0.20;
   218          Gear.dX:= 0.0000001 * Sign(Gear.dX);
   291          Gear.dX:= 0.0000001 * Sign(Gear.dX);
   219          Gear.X:= Gear.X - Sign(Gear.dX)*0.00008; // компенсация сдвига %)
   292          Gear.X:= Gear.X - Sign(Gear.dX)*0.00008; // компенсация сдвига %)
   223       end;
   296       end;
   224    if (Gear.Message and gm_Left  )<>0 then Gear.dX:= -1.0 else
   297    if (Gear.Message and gm_Left  )<>0 then Gear.dX:= -1.0 else
   225    if (Gear.Message and gm_Right )<>0 then Gear.dX:=  1.0 else exit;
   298    if (Gear.Message and gm_Right )<>0 then Gear.dX:=  1.0 else exit;
   226    PHedgehog(Gear.Hedgehog).visStepPos:= (PHedgehog(Gear.Hedgehog).visStepPos + 1) and 7;
   299    PHedgehog(Gear.Hedgehog).visStepPos:= (PHedgehog(Gear.Hedgehog).visStepPos + 1) and 7;
   227    StepTicks:= 40;
   300    StepTicks:= 40;
       
   301    RemoveIntersectorsCR(Gear);
   228    if TestCollisionXwithGear(Gear, Sign(Gear.dX)) then
   302    if TestCollisionXwithGear(Gear, Sign(Gear.dX)) then
   229       begin
   303       begin
   230       if not (TestCollisionXwithXYShift(Gear, 0, -6, Sign(Gear.dX))
   304       if not (TestCollisionXwithXYShift(Gear, 0, -6, Sign(Gear.dX))
   231          or HHTestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1;
   305          or HHTestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1;
   232       if not (TestCollisionXwithXYShift(Gear, 0, -5, Sign(Gear.dX))
   306       if not (TestCollisionXwithXYShift(Gear, 0, -5, Sign(Gear.dX))
   239          or HHTestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1;
   313          or HHTestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1;
   240       if not (TestCollisionXwithXYShift(Gear, 0, -1, Sign(Gear.dX))
   314       if not (TestCollisionXwithXYShift(Gear, 0, -1, Sign(Gear.dX))
   241          or HHTestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1;
   315          or HHTestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1;
   242       end;
   316       end;
   243    if not TestCollisionXwithGear(Gear, Sign(Gear.dX)) then Gear.X:= Gear.X + Gear.dX;
   317    if not TestCollisionXwithGear(Gear, Sign(Gear.dX)) then Gear.X:= Gear.X + Gear.dX;
   244    
   318 
   245    if not HHTestCollisionYwithGear(Gear, 1) then
   319    if not HHTestCollisionYwithGear(Gear, 1) then
   246    begin
   320    begin
   247    Gear.Y:= Gear.Y + 1;
   321    Gear.Y:= Gear.Y + 1;
   248    if not HHTestCollisionYwithGear(Gear, 1) then
   322    if not HHTestCollisionYwithGear(Gear, 1) then
   249    begin
   323    begin
   265       Gear.Y:= Gear.Y - 6;
   339       Gear.Y:= Gear.Y - 6;
   266       Gear.dY:= 0;
   340       Gear.dY:= 0;
   267       Gear.dX:= 0.0000001 * Sign(Gear.dX);
   341       Gear.dX:= 0.0000001 * Sign(Gear.dX);
   268       Gear.State:= Gear.State or gstFalling
   342       Gear.State:= Gear.State or gstFalling
   269       end;
   343       end;
       
   344    end
       
   345    end
       
   346    end
       
   347    end
       
   348    end
       
   349    end;
       
   350    AddIntersectorsCR(Gear);
   270    SetAllHHToActive
   351    SetAllHHToActive
   271    end
       
   272    end
       
   273    end
       
   274    end
       
   275    end
       
   276    end
       
   277    end
   352    end
   278 end;
   353 end;
   279 
   354 
   280 ////////////////////////////////////////////////////////////////////////////////
   355 ////////////////////////////////////////////////////////////////////////////////
   281 procedure doStepHedgehogFree(Gear: PGear);
   356 procedure doStepHedgehogFree(Gear: PGear);
   282 begin
   357 begin
       
   358 if Gear.CollIndex < High(Longword) then DeleteCR(Gear);
   283 if not HHTestCollisionYwithGear(Gear, 1) then
   359 if not HHTestCollisionYwithGear(Gear, 1) then
   284    begin
   360    begin
   285    if (Gear.dY < 0) and HHTestCollisionYwithGear(Gear, -1) then Gear.dY:= 0;
   361    if (Gear.dY < 0) and HHTestCollisionYwithGear(Gear, -1) then Gear.dY:= 0;
   286    Gear.State:= Gear.State or gstFalling or gstMoving;
   362    Gear.State:= Gear.State or gstFalling or gstMoving;
   287    Gear.dY:= Gear.dY + cGravity
   363    Gear.dY:= Gear.dY + cGravity
   346 if (not CheckGearDrowning(Gear)) and
   422 if (not CheckGearDrowning(Gear)) and
   347    ((Gear.State and gstMoving) = 0) then
   423    ((Gear.State and gstMoving) = 0) then
   348       begin
   424       begin
   349       Gear.State:= 0;
   425       Gear.State:= 0;
   350       Gear.Active:= false;
   426       Gear.Active:= false;
   351       AddGearCR(Gear);
   427       AddIntersectorsCR(Gear);
   352       exit
   428       exit
   353       end
   429       end
   354 end;
   430 end;
   355 
   431 
   356 ////////////////////////////////////////////////////////////////////////////////
   432 ////////////////////////////////////////////////////////////////////////////////
   359 if (Gear.Message and gm_Destroy) <> 0 then
   435 if (Gear.Message and gm_Destroy) <> 0 then
   360    begin
   436    begin
   361    DeleteGear(Gear);
   437    DeleteGear(Gear);
   362    exit
   438    exit
   363    end;
   439    end;
   364 if Gear.CollIndex < High(Longword) then DeleteCR(Gear);
       
   365 if (Gear.State and gstHHDriven) = 0 then doStepHedgehogFree(Gear)
   440 if (Gear.State and gstHHDriven) = 0 then doStepHedgehogFree(Gear)
   366                                     else doStepHedgehogDriven(Gear)
   441                                     else doStepHedgehogDriven(Gear)
   367 end;
   442 end;