hedgewars/GSHandlers.inc
changeset 7442 9bb6abdb5675
parent 7426 55b49cc1f33a
child 7468 1333ca7554dc
equal deleted inserted replaced
7392:bc3306c59a08 7442:9bb6abdb5675
   114     if FollowGear = HH^.Gear then
   114     if FollowGear = HH^.Gear then
   115         FollowGear:= nil;
   115         FollowGear:= nil;
   116         
   116         
   117     if lastGearByUID = HH^.Gear then
   117     if lastGearByUID = HH^.Gear then
   118         lastGearByUID := nil;
   118         lastGearByUID := nil;
   119         
   119     
   120     RemoveGearFromList(HH^.Gear);
   120     HH^.Gear^.Message:= HH^.Gear^.Message or gmRemoveFromList;
   121     with HH^.Gear^ do
   121     with HH^.Gear^ do
   122         begin
   122         begin
   123         Z := cHHZ;
   123         Z := cHHZ;
   124         Active := false;
   124         HH^.Gear^.Active:= false;
   125         State:= State and (not (gstHHDriven or gstAttacking or gstAttacked));
   125         State:= State and (not (gstHHDriven or gstAttacking or gstAttacked));
   126         Message := Message and (not gmAttack);
   126         Message := Message and (not gmAttack);
   127     end;
   127     end;
   128     HH^.GearHidden:= HH^.Gear;
   128     HH^.GearHidden:= HH^.Gear;
   129     HH^.Gear:= nil
   129     HH^.Gear:= nil
   731 end;
   731 end;
   732 
   732 
   733 ////////////////////////////////////////////////////////////////////////////////
   733 ////////////////////////////////////////////////////////////////////////////////
   734 procedure doStepGrave(Gear: PGear);
   734 procedure doStepGrave(Gear: PGear);
   735 begin
   735 begin
       
   736     if (Gear^.Message and gmDestroy) <> 0 then
       
   737         begin
       
   738         DeleteGear(Gear);
       
   739         exit
       
   740         end;
       
   741 
   736     AllInactive := false;
   742     AllInactive := false;
       
   743 
   737     if Gear^.dY.isNegative then
   744     if Gear^.dY.isNegative then
   738         if TestCollisionY(Gear, -1) then
   745         if TestCollisionY(Gear, -1) then
   739             Gear^.dY := _0;
   746             Gear^.dY := _0;
   740 
   747 
   741     if not Gear^.dY.isNegative then
   748     if not Gear^.dY.isNegative then
  2078     k: TGearType;
  2085     k: TGearType;
  2079     exBoom: boolean;
  2086     exBoom: boolean;
  2080     dX, dY: HWFloat;
  2087     dX, dY: HWFloat;
  2081     hog: PHedgehog;
  2088     hog: PHedgehog;
  2082     sparkles: PVisualGear;
  2089     sparkles: PVisualGear;
       
  2090     gi: PGear;
  2083 begin
  2091 begin
  2084     k := Gear^.Kind;
  2092     k := Gear^.Kind;
  2085     exBoom := false;
  2093     exBoom := false;
  2086 
  2094 
  2087     if (Gear^.Message and gmDestroy) > 0 then
  2095     if (Gear^.Message and gmDestroy) > 0 then
  2112         if Gear^.Health <= 0 then
  2120         if Gear^.Health <= 0 then
  2113             exBoom := true;
  2121             exBoom := true;
  2114         end
  2122         end
  2115     else
  2123     else
  2116         begin 
  2124         begin 
       
  2125         if (Gear^.Pos <> posCaseHealth) and (GameTicks and $3FF = 0) then // stir it up every second or so
       
  2126             begin
       
  2127             gi := GearsList;
       
  2128             while gi <> nil do
       
  2129                 begin
       
  2130                 if gi^.Kind = gtGenericFaller then
       
  2131                     begin
       
  2132                     gi^.Active:= true;
       
  2133                     gi^.X:=  int2hwFloat(GetRandom(rightX-leftX)+leftX);
       
  2134                     gi^.Y:=  int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY);
       
  2135                     gi^.dX:= _90-(GetRandomf*_360);
       
  2136                     gi^.dY:= _90-(GetRandomf*_360)
       
  2137                     end;
       
  2138                 gi := gi^.NextGear
       
  2139                 end
       
  2140             end;
       
  2141 
  2117         if Gear^.Timer = 500 then
  2142         if Gear^.Timer = 500 then
  2118             begin
  2143             begin
  2119 (* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up
  2144 (* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up
  2120    voices. Reinforcements voices is heard for active team, not team-to-be.  Either that or change crate spawn from end of turn to start, although that
  2145    voices. Reinforcements voices is heard for active team, not team-to-be.  Either that or change crate spawn from end of turn to start, although that
  2121    has its own complexities. *)
  2146    has its own complexities. *)
  2379                 else if ((GameTicks and $3) = 3) then
  2404                 else if ((GameTicks and $3) = 3) then
  2380                     doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage); 
  2405                     doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage); 
  2381                 //DrawExplosion(gX, gY, 4);
  2406                 //DrawExplosion(gX, gY, 4);
  2382                 
  2407                 
  2383                 if ((GameTicks and $7) = 0) and (Random(2) = 0) then
  2408                 if ((GameTicks and $7) = 0) and (Random(2) = 0) then
  2384                     for i:= 1 to Random(2)+1 do
  2409                     for i:= Random(2) downto 0 do
  2385                         AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  2410                         AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  2386                         
  2411                         
  2387                 if Gear^.Health > 0 then
  2412                 if Gear^.Health > 0 then
  2388                     dec(Gear^.Health);
  2413                     dec(Gear^.Health);
  2389                 Gear^.Timer := 450 - Gear^.Tag * 8
  2414                 Gear^.Timer := 450 - Gear^.Tag * 8
  2393                 // Modified fire
  2418                 // Modified fire
  2394                 if ((GameTicks and $7FF) = 0) and ((GameFlags and gfSolidLand) = 0) then
  2419                 if ((GameTicks and $7FF) = 0) and ((GameFlags and gfSolidLand) = 0) then
  2395                     begin
  2420                     begin
  2396                     DrawExplosion(gX, gY, 4);
  2421                     DrawExplosion(gX, gY, 4);
  2397 
  2422 
  2398                     for i:= 0 to Random(3) do
  2423                     for i:= Random(3) downto 0 do
  2399                         AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  2424                         AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  2400                     end;
  2425                     end;
  2401 
  2426 
  2402 // This one is interesting.  I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom.
  2427 // This one is interesting.  I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom.
  2403                 Gear^.Timer := 100 - Gear^.Tag * 3;
  2428                 Gear^.Timer := 100 - Gear^.Tag * 3;
  2411         gX := hwRound(Gear^.X);
  2436         gX := hwRound(Gear^.X);
  2412         gY := hwRound(Gear^.Y);
  2437         gY := hwRound(Gear^.Y);
  2413         if not sticky then
  2438         if not sticky then
  2414             begin
  2439             begin
  2415             if ((GameTicks and $3) = 0) and (Random(1) = 0) then
  2440             if ((GameTicks and $3) = 0) and (Random(1) = 0) then
  2416                 begin
  2441                 for i:= Random(2) downto 0 do
  2417                 for i:= 1 to Random(2)+1 do
       
  2418                     begin
       
  2419                     AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  2442                     AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  2420                     end;
       
  2421                 end;
       
  2422             end
  2443             end
  2423         else
  2444         else
  2424             begin
  2445             for i:= Random(3) downto 0 do
  2425             for i:= 0 to Random(3) do
       
  2426                 begin
       
  2427                 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  2446                 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  2428                 end;
       
  2429             end;
       
  2430 
  2447 
  2431         DeleteGear(Gear)
  2448         DeleteGear(Gear)
  2432         end;
  2449         end;
  2433 end;
  2450 end;
  2434 
  2451 
  2773         HHGear := CurrentHedgehog^.Gear;
  2790         HHGear := CurrentHedgehog^.Gear;
  2774         HHGear^.Message := HHGear^.Message and (not gmSwitch);
  2791         HHGear^.Message := HHGear^.Message and (not gmSwitch);
  2775         Gear^.Message := Gear^.Message and (not gmSwitch);
  2792         Gear^.Message := Gear^.Message and (not gmSwitch);
  2776         State := HHGear^.State;
  2793         State := HHGear^.State;
  2777         HHGear^.State := 0;
  2794         HHGear^.State := 0;
       
  2795         HHGear^.Z := cHHZ;
  2778         HHGear^.Active := false;
  2796         HHGear^.Active := false;
  2779         HHGear^.Z := cHHZ;
  2797         HHGear^.Message:= HHGear^.Message or gmRemoveFromList or gmAddToList;
  2780         RemoveGearFromList(HHGear);
       
  2781         InsertGearToList(HHGear);
       
  2782 
  2798 
  2783         PlaySound(sndSwitchHog);
  2799         PlaySound(sndSwitchHog);
  2784 
  2800 
  2785         repeat
  2801         repeat
  2786             CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
  2802             CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
  2792         HHGear := CurrentHedgehog^.Gear;
  2808         HHGear := CurrentHedgehog^.Gear;
  2793         HHGear^.State := State;
  2809         HHGear^.State := State;
  2794         HHGear^.Active := true;
  2810         HHGear^.Active := true;
  2795         FollowGear := HHGear;
  2811         FollowGear := HHGear;
  2796         HHGear^.Z := cCurrHHZ;
  2812         HHGear^.Z := cCurrHHZ;
  2797         RemoveGearFromList(HHGear);
  2813         HHGear^.Message:= HHGear^.Message or gmRemoveFromList or gmAddToList;
  2798         InsertGearToList(HHGear);
       
  2799         Gear^.X := HHGear^.X;
  2814         Gear^.X := HHGear^.X;
  2800         Gear^.Y := HHGear^.Y
  2815         Gear^.Y := HHGear^.Y
  2801         end;
  2816         end;
  2802 end;
  2817 end;
  2803 
  2818 
  2938                             dy := -dy;
  2953                             dy := -dy;
  2939                         FrameTicks:= random(400) + 250
  2954                         FrameTicks:= random(400) + 250
  2940                         end
  2955                         end
  2941                 end;
  2956                 end;
  2942         AfterAttack;
  2957         AfterAttack;
  2943         DeleteGear(HHGear);
  2958         HHGear^.Message:= HHGear^.Message or gmDestroy;
  2944         DeleteGear(Gear);
  2959         DeleteGear(Gear);
  2945     end
  2960     end
  2946     else
  2961     else
  2947         begin
  2962         begin
  2948         dec(Gear^.Health, Gear^.Damage);
  2963         dec(Gear^.Health, Gear^.Damage);
  2982 end;
  2997 end;
  2983 
  2998 
  2984 ////////////////////////////////////////////////////////////////////////////////
  2999 ////////////////////////////////////////////////////////////////////////////////
  2985 
  3000 
  2986 const cakeh =   27;
  3001 const cakeh =   27;
  2987     cakeDmg =   75;
       
  2988 var 
  3002 var 
  2989     CakePoints: array[0..Pred(cakeh)] of record
  3003     CakePoints: array[0..Pred(cakeh)] of record
  2990         x, y: hwFloat;
  3004         x, y: hwFloat;
  2991     end;
  3005     end;
  2992     CakeI: Longword;
  3006     CakeI: Longword;
  3066 
  3080 
  3067     inc(Gear^.Tag);
  3081     inc(Gear^.Tag);
  3068     if Gear^.Tag < 7 then
  3082     if Gear^.Tag < 7 then
  3069         exit;
  3083         exit;
  3070 
  3084 
       
  3085     dec(Gear^.Health);
       
  3086     Gear^.Timer := Gear^.Health*10;
       
  3087     if Gear^.Health mod 100 = 0 then
       
  3088         Gear^.PortalCounter:= 0;
       
  3089     // This is not seconds, but at least it is *some* feedback
       
  3090     if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then
       
  3091         begin
       
  3092         FollowGear := Gear;
       
  3093         Gear^.RenderTimer := false;
       
  3094         Gear^.doStep := @doStepCakeDown;
       
  3095         exit
       
  3096         end;
       
  3097 
  3071     cakeStep(Gear);
  3098     cakeStep(Gear);
  3072 
  3099 
  3073     if Gear^.Tag = 0 then
  3100     if Gear^.Tag = 0 then
  3074         begin
  3101         begin
  3075         CakeI := (CakeI + 1) mod cakeh;
  3102         CakeI := (CakeI + 1) mod cakeh;
  3077         tdy := - CakePoints[CakeI].y + Gear^.Y;
  3104         tdy := - CakePoints[CakeI].y + Gear^.Y;
  3078         CakePoints[CakeI].x := Gear^.X;
  3105         CakePoints[CakeI].x := Gear^.X;
  3079         CakePoints[CakeI].y := Gear^.Y;
  3106         CakePoints[CakeI].y := Gear^.Y;
  3080         Gear^.DirAngle := DxDy2Angle(tdx, tdy);
  3107         Gear^.DirAngle := DxDy2Angle(tdx, tdy);
  3081         end;
  3108         end;
  3082 
       
  3083     dec(Gear^.Health);
       
  3084     Gear^.Timer := Gear^.Health*10;
       
  3085     if Gear^.Health mod 100 = 0 then
       
  3086         Gear^.PortalCounter:= 0;
       
  3087     // This is not seconds, but at least it is *some* feedback
       
  3088     if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then
       
  3089         begin
       
  3090         FollowGear := Gear;
       
  3091         Gear^.RenderTimer := false;
       
  3092         Gear^.doStep := @doStepCakeDown
       
  3093         end
       
  3094 end;
  3109 end;
  3095 
  3110 
  3096 procedure doStepCakeUp(Gear: PGear);
  3111 procedure doStepCakeUp(Gear: PGear);
  3097 var 
  3112 var 
  3098     i: Longword;
  3113     i: Longword;
  4294         and (iterator = CurrentHedgehog^.Gear)
  4309         and (iterator = CurrentHedgehog^.Gear)
  4295         and (CurAmmoGear <> nil)
  4310         and (CurAmmoGear <> nil)
  4296         and (CurAmmoGear^.Kind =gtRope) then
  4311         and (CurAmmoGear^.Kind =gtRope) then
  4297                CurAmmoGear^.PortalCounter:= 1;
  4312                CurAmmoGear^.PortalCounter:= 1;
  4298 
  4313 
  4299         if not isbullet
  4314         if not isbullet and (iterator^.State and gstInvisible = 0) 
  4300         and (iterator^.Kind <> gtFlake) then
  4315         and (iterator^.Kind <> gtFlake) then
  4301             FollowGear := iterator;
  4316             FollowGear := iterator;
  4302 
  4317 
  4303         // store X/Y values of exit for net bullet trail
  4318         // store X/Y values of exit for net bullet trail
  4304         if isbullet then
  4319         if isbullet then
  4373         begin
  4388         begin
  4374         Gear^.State := Gear^.State or gstCollision;
  4389         Gear^.State := Gear^.State or gstCollision;
  4375         Gear^.State := Gear^.State and (not gstMoving);
  4390         Gear^.State := Gear^.State and (not gstMoving);
  4376         
  4391         
  4377         if (Land[y, x] and lfBouncy <> 0)
  4392         if (Land[y, x] and lfBouncy <> 0)
  4378         or not CalcSlopeTangent(Gear, x, y, tx, ty, 255)
  4393         or (not CalcSlopeTangent(Gear, x, y, tx, ty, 255))
  4379         or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
  4394         or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
  4380             begin
  4395             begin
  4381             loadNewPortalBall(Gear, true);
  4396             loadNewPortalBall(Gear, true);
  4382             EXIT;
  4397             EXIT;
  4383             end;
  4398             end;
  4653                     dec(Gear^.Health, Gear^.Damage);
  4668                     dec(Gear^.Health, Gear^.Damage);
  4654                     Gear^.Damage := 0;
  4669                     Gear^.Damage := 0;
  4655 
  4670 
  4656                     // add some fire to the tunnel
  4671                     // add some fire to the tunnel
  4657                     if getRandom(6) = 0 then
  4672                     if getRandom(6) = 0 then
  4658                         AddGear(x - Gear^.Radius + LongInt(getRandom(2 * Gear^.Radius)), y -
  4673                         begin
  4659                         getRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0);
  4674                         tmp:= GetRandom(2 * Gear^.Radius);
       
  4675                         AddGear(x - Gear^.Radius + tmp, y - GetRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0)
       
  4676                         end
  4660                     end;
  4677                     end;
  4661 
  4678 
  4662                 if getRandom(100) = 0 then
  4679                 if random(100) = 0 then
  4663                     AddVisualGear(x, y, vgtSmokeTrace); 
  4680                     AddVisualGear(x, y, vgtSmokeTrace); 
  4664                 end
  4681                 end
  4665                 else dec(Gear^.Health, 5); // if underwater get additional damage
  4682                 else dec(Gear^.Health, 5); // if underwater get additional damage
  4666             end;
  4683             end;
  4667 
  4684 
  5067         if graves.size <= Gear^.Tag then Gear^.Tag:= 0;
  5084         if graves.size <= Gear^.Tag then Gear^.Tag:= 0;
  5068         dec(hh^.Gear^.Health);
  5085         dec(hh^.Gear^.Health);
  5069         if (hh^.Gear^.Health = 0) and (hh^.Gear^.Damage = 0) then
  5086         if (hh^.Gear^.Health = 0) and (hh^.Gear^.Damage = 0) then
  5070             hh^.Gear^.Damage:= 1;
  5087             hh^.Gear^.Damage:= 1;
  5071         RenderHealth(hh^);
  5088         RenderHealth(hh^);
       
  5089         RecountTeamHealth(hh^.Team);
  5072         inc(graves.ar^[Gear^.Tag]^.Health);
  5090         inc(graves.ar^[Gear^.Tag]^.Health);
  5073         inc(Gear^.Tag)
  5091         inc(Gear^.Tag)
  5074 {-for i:= 0 to High(graves) do begin
  5092 {-for i:= 0 to High(graves) do begin
  5075             if hh^.Gear^.Health > 0 then begin
  5093             if hh^.Gear^.Health > 0 then begin
  5076                 dec(hh^.Gear^.Health);
  5094                 dec(hh^.Gear^.Health);
  5086                 begin
  5104                 begin
  5087                 resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0);
  5105                 resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0);
  5088                 resgear^.Hedgehog := graves.ar^[i]^.Hedgehog;
  5106                 resgear^.Hedgehog := graves.ar^[i]^.Hedgehog;
  5089                 resgear^.Health := graves.ar^[i]^.Health;
  5107                 resgear^.Health := graves.ar^[i]^.Health;
  5090                 PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := resgear;
  5108                 PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := resgear;
  5091                 DeleteGear(graves.ar^[i]);
  5109                 graves.ar^[i]^.Message:= graves.ar^[i]^.Message or gmDestroy;
       
  5110                 graves.ar^[i]^.Active:= true;
  5092                 RenderHealth(resgear^.Hedgehog^);
  5111                 RenderHealth(resgear^.Hedgehog^);
  5093                 RecountTeamHealth(resgear^.Hedgehog^.Team);
  5112                 RecountTeamHealth(resgear^.Hedgehog^.Team);
  5094                 resgear^.Hedgehog^.Effects[heResurrected]:= 1;
  5113                 resgear^.Hedgehog^.Effects[heResurrected]:= 1;
  5095                 // only make hat-less hedgehogs look like zombies, preserve existing hats
  5114                 // only make hat-less hedgehogs look like zombies, preserve existing hats
  5096                 
  5115 
  5097                 if resgear^.Hedgehog^.Hat = 'NoHat' then
  5116                 if resgear^.Hedgehog^.Hat = 'NoHat' then
  5098                     LoadHedgehogHat(resgear, 'Reserved/Zombie');
  5117                     LoadHedgehogHat(resgear, 'Reserved/Zombie');
  5099                 end;
  5118                 end;
  5100 
  5119 
  5101         hh^.Gear^.dY := _0;
  5120         hh^.Gear^.dY := _0;
  5530                 Y:= HHGear^.Y
  5549                 Y:= HHGear^.Y
  5531                 end
  5550                 end
  5532         end
  5551         end
  5533     end;
  5552     end;
  5534 end;
  5553 end;
       
  5554 
       
  5555 procedure doStepAddAmmo(Gear: PGear);
       
  5556 var a: TAmmoType;
       
  5557     gi: PGear;
       
  5558 begin
       
  5559 if Gear^.Timer > 0 then dec(Gear^.Timer)
       
  5560 else
       
  5561     begin
       
  5562     if Gear^.Pos = posCaseUtility then
       
  5563         a:= GetUtility(Gear^.Hedgehog)
       
  5564     else
       
  5565         a:= GetAmmo(Gear^.Hedgehog);
       
  5566     CheckSum:= CheckSum xor GameTicks;
       
  5567     gi := GearsList;
       
  5568     while gi <> nil do
       
  5569         begin
       
  5570         with gi^ do CheckSum:= CheckSum xor X.round xor X.frac xor dX.round xor dX.frac xor Y.round xor Y.frac xor dY.round xor dY.frac;
       
  5571         AddRandomness(CheckSum);
       
  5572         gi := gi^.NextGear
       
  5573         end;
       
  5574     AddPickup(Gear^.Hedgehog^, a, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
       
  5575     DeleteGear(Gear)
       
  5576     end;
       
  5577 end;
       
  5578 
       
  5579 procedure doStepGenericFaller(Gear: PGear);
       
  5580 begin
       
  5581 if Gear^.Timer < $FFFFFFFF then
       
  5582     if Gear^.Timer > 0 then
       
  5583         dec(Gear^.Timer)
       
  5584     else
       
  5585         begin
       
  5586         DeleteGear(Gear);
       
  5587         exit
       
  5588         end;
       
  5589     
       
  5590 doStepFallingGear(Gear);
       
  5591 end;