hedgewars/uGearsHedgehog.pas
changeset 8492 67d2ad3b3ce9
parent 8414 c1ac0b64315e
child 8493 1a84f8b08ca7
equal deleted inserted replaced
8491:f0f167f7a4a6 8492:67d2ad3b3ce9
   209         ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0))
   209         ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0))
   210         or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
   210         or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
   211         and ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
   211         and ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
   212             begin
   212             begin
   213             State:= State or gstAttacking;
   213             State:= State or gstAttacking;
   214             if Power = cMaxPower then
   214             if (Power = cMaxPower) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0) then
   215                 Message:= Message and (not gmAttack)
       
   216             else if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0 then
       
   217                 Message:= Message and (not gmAttack)
   215                 Message:= Message and (not gmAttack)
   218             else
   216             else
   219                 begin
   217                 begin
   220                 if Power = 0 then
   218                 if Power = 0 then
   221                     begin
   219                     begin
   222                     AttackBar:= CurrentTeam^.AttackBar;
   220                     AttackBar:= CurrentTeam^.AttackBar;
   223                     PlaySound(sndThrowPowerUp)
   221                     PlaySound(sndThrowPowerUp)
   224                     end;
   222                     end;
   225                 inc(Power)
   223                 inc(Power)
   226                 end;
   224                 end;
   227         if ((Message and gmAttack) <> 0) then
   225             if ((Message and gmAttack) <> 0) then
   228             exit;
   226                 exit;
   229 
   227 
   230         if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
   228             if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
   231             begin
   229                 begin
   232             StopSound(sndThrowPowerUp);
   230                 StopSound(sndThrowPowerUp);
   233             PlaySound(sndThrowRelease);
   231                 PlaySound(sndThrowRelease);
   234             end;
   232                 end;
   235 
   233 
   236         xx:= SignAs(AngleSin(Angle), dX);
   234             xx:= SignAs(AngleSin(Angle), dX);
   237         yy:= -AngleCos(Angle);
   235             yy:= -AngleCos(Angle);
   238 
   236 
   239         lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
   237             lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
   240         ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
   238             ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
   241 
   239 
   242         if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
   240             if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
   243             xx:= - xx;
   241                 xx:= - xx;
   244         if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
   242             if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
   245             AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
   243                 AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
   246 
   244 
   247 // Initiating alt attack
   245 // Initiating alt attack
   248         if  (CurAmmoGear <> nil)
   246             if  (CurAmmoGear <> nil)
   249         and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
   247             and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
   250         and ((Gear^.Message and gmLJump) <> 0)
   248             and ((Gear^.Message and gmLJump) <> 0)
   251         and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   249             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   252             begin
   250                 begin
   253             newDx:= dX; 
   251                 newDx:= dX; 
   254             newDy:= dY;
   252                 newDy:= dY;
   255             altUse:= true
   253                 altUse:= true
   256             end
   254                 end
   257         else
   255             else
   258             begin
   256                 begin
   259             newDx:= xx*Power/cPowerDivisor;
   257                 newDx:= xx*Power/cPowerDivisor;
   260             newDy:= yy*Power/cPowerDivisor;
   258                 newDy:= yy*Power/cPowerDivisor;
   261             altUse:= false
   259                 altUse:= false
   262             end;
   260                 end;
   263 
   261 
   264              case CurAmmoType of
   262             case CurAmmoType of
   265                       amGrenade: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGrenade,         0, newDx, newDy, CurWeapon^.Timer);
   263                       amGrenade: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGrenade,         0, newDx, newDy, CurWeapon^.Timer);
   266                       amMolotov: newGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov,      0, newDx, newDy, 0);
   264                       amMolotov: newGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov,      0, newDx, newDy, 0);
   267                   amClusterBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb,  0, newDx, newDy, CurWeapon^.Timer);
   265                   amClusterBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb,  0, newDx, newDy, CurWeapon^.Timer);
   268                       amGasBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb,      0, newDx, newDy, CurWeapon^.Timer);
   266                       amGasBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb,      0, newDx, newDy, CurWeapon^.Timer);
   269                       amBazooka: newGear:= AddGear(hwRound(lx), hwRound(ly), gtShell,        0, newDx, newDy, 0);
   267                       amBazooka: newGear:= AddGear(hwRound(lx), hwRound(ly), gtShell,        0, newDx, newDy, 0);
   375                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   373                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   376                                  end;
   374                                  end;
   377                     //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
   375                     //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
   378                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
   376                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
   379                        amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
   377                        amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
   380              end;
   378             end;
   381              if altUse and (newGear <> nil) then
   379             if altUse and (newGear <> nil) then
   382                 begin
   380                begin
   383                 newGear^.dX:= newDx / newGear^.Density;
   381                newGear^.dX:= newDx / newGear^.Density;
   384                 newGear^.dY:= newDY / newGear^.Density
   382                newGear^.dY:= newDY / newGear^.Density
   385                 end;
   383                end;
   386              
   384              
   387              case CurAmmoType of
   385             case CurAmmoType of
   388                       amGrenade, amMolotov, 
   386                      amGrenade, amMolotov, 
   389                   amClusterBomb, amGasBomb, 
   387                  amClusterBomb, amGasBomb, 
   390                       amBazooka, amSnowball, 
   388                      amBazooka, amSnowball, 
   391                           amBee, amSMine,
   389                          amBee, amSMine,
   392                        amMortar, amWatermelon,
   390                       amMortar, amWatermelon,
   393                   amHellishBomb, amDrill: FollowGear:= newGear;
   391                  amHellishBomb, amDrill: FollowGear:= newGear;
   394 
   392 
   395                       amShotgun, amPickHammer,
   393                      amShotgun, amPickHammer,
   396                          amRope, amDEagle,
   394                         amRope, amDEagle,
   397                       amSineGun, amSniperRifle,
   395                      amSineGun, amSniperRifle,
   398                     amFirePunch, amWhip,
   396                    amFirePunch, amWhip,
   399                        amHammer, amBaseballBat,
   397                       amHammer, amBaseballBat,
   400                     amParachute, amBlowTorch,
   398                    amParachute, amBlowTorch,
   401                        amGirder, amTeleport,
   399                       amGirder, amTeleport,
   402                        amSwitch, amRCPlane,
   400                       amSwitch, amRCPlane,
   403                      amKamikaze, amCake,
   401                     amKamikaze, amCake,
   404                     amSeduction, amBallgun,
   402                    amSeduction, amBallgun,
   405                       amJetpack, amBirdy,
   403                      amJetpack, amBirdy,
   406                  amFlamethrower, amLandGun,
   404                 amFlamethrower, amLandGun,
   407                   amResurrector, //amStructure,
   405                  amResurrector, //amStructure,
   408                        amTardis, amPiano,
   406                       amTardis, amPiano,
   409                        amIceGun: CurAmmoGear:= newGear;
   407                       amIceGun: CurAmmoGear:= newGear;
   410              end;
   408             end;
   411              
   409              
   412             if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
   410             if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
   413                 newGear^.FlightTime:= GameTicks + 1000
   411                 newGear^.FlightTime:= GameTicks + 1000
   414             else if CurAmmoType = amDrill then
   412             else if CurAmmoType = amDrill then
   415                 newGear^.FlightTime:= GameTicks + 250;
   413                 newGear^.FlightTime:= GameTicks + 250;
   416         if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
   414             if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
   417             begin
   415                 begin
   418             newGear^.Target.X:= TargetPoint.X;
   416                 newGear^.Target.X:= TargetPoint.X;
   419             newGear^.Target.Y:= TargetPoint.Y
   417                 newGear^.Target.Y:= TargetPoint.Y
   420             end;
       
   421         if (newGear <> nil) and (newGear^.CollisionMask and $80 <> 0) then newGear^.CollisionMask:= newGear^.CollisionMask and (not $80);
       
   422 
       
   423         // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
       
   424         if altUse then
       
   425             FollowGear:= nil;
       
   426 
       
   427         if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
       
   428             begin
       
   429             elastic:=  int2hwfloat(CurWeapon^.Bounciness) / _1000;
       
   430 
       
   431             if elastic < _1 then
       
   432                 newGear^.Elasticity:= newGear^.Elasticity * elastic
       
   433             else if elastic > _1 then
       
   434                 newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
       
   435 (* Experimented with friction modifier. Didn't seem helpful 
       
   436             fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
       
   437             if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
       
   438             else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
       
   439             end;
       
   440 
       
   441 
       
   442         uStats.AmmoUsed(CurAmmoType);
       
   443 
       
   444         if not (SpeechText = '') then
       
   445             begin
       
   446             speech:= AddVisualGear(0, 0, vgtSpeechBubble);
       
   447             if speech <> nil then
       
   448                 begin
       
   449                 speech^.Text:= SpeechText;
       
   450                 speech^.Hedgehog:= Gear^.Hedgehog;
       
   451                 speech^.FrameTicks:= SpeechType;
       
   452                 end;
   418                 end;
   453             SpeechText:= ''
   419             if (newGear <> nil) and (newGear^.CollisionMask and $80 <> 0) then newGear^.CollisionMask:= newGear^.CollisionMask and (not $80);
   454             end;
   420 
   455 
   421             // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
   456         Power:= 0;
   422             if altUse then
   457         if (CurAmmoGear <> nil)
   423                 FollowGear:= nil;
   458             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
   424 
   459             begin
   425             if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
   460             Message:= Message or gmAttack;
   426                 begin
   461             CurAmmoGear^.Message:= Message
   427                 elastic:=  int2hwfloat(CurWeapon^.Bounciness) / _1000;
       
   428 
       
   429                 if elastic < _1 then
       
   430                     newGear^.Elasticity:= newGear^.Elasticity * elastic
       
   431                 else if elastic > _1 then
       
   432                     newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
       
   433     (* Experimented with friction modifier. Didn't seem helpful 
       
   434                 fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
       
   435                 if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
       
   436                 else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
       
   437                 end;
       
   438 
       
   439 
       
   440             uStats.AmmoUsed(CurAmmoType);
       
   441 
       
   442             if not (SpeechText = '') then
       
   443                 begin
       
   444                 speech:= AddVisualGear(0, 0, vgtSpeechBubble);
       
   445                 if speech <> nil then
       
   446                     begin
       
   447                     speech^.Text:= SpeechText;
       
   448                     speech^.Hedgehog:= Gear^.Hedgehog;
       
   449                     speech^.FrameTicks:= SpeechType;
       
   450                     end;
       
   451                 SpeechText:= ''
       
   452                 end;
       
   453 
       
   454             Power:= 0;
       
   455             if (CurAmmoGear <> nil)
       
   456                 and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
       
   457                 begin
       
   458                 //Message:= Message or gmAttack;
       
   459                 CurAmmoGear^.Message:= Message
       
   460                 end
       
   461             else
       
   462                 begin
       
   463                 if not CurrentTeam^.ExtDriven
       
   464                 and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
       
   465                     SendIPC(_S'a');
       
   466                 AfterAttack;
       
   467                 end
   462             end
   468             end
   463         else
   469         else 
   464             begin
   470             Message:= Message and (not gmAttack);
   465             if not CurrentTeam^.ExtDriven
       
   466             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
       
   467                 SendIPC(_S'a');
       
   468             AfterAttack;
       
   469             end
       
   470         end
       
   471     else 
       
   472         Message:= Message and (not gmAttack);
       
   473     end;
   471     end;
   474     TargetPoint.X := NoPointX;
   472     TargetPoint.X := NoPointX;
   475     ScriptCall('onHogAttack');
   473     ScriptCall('onHogAttack');
   476 end;
   474 end;
   477 
   475 
   998 var t: PGear;
   996 var t: PGear;
   999     wasJumping: boolean;
   997     wasJumping: boolean;
  1000     Hedgehog: PHedgehog;
   998     Hedgehog: PHedgehog;
  1001 begin
   999 begin
  1002 Hedgehog:= HHGear^.Hedgehog;
  1000 Hedgehog:= HHGear^.Hedgehog;
       
  1001 // Some weapons, deagle in particular, wouldn't play so nice in infinite attack mode if hogs were still moving.  Most likely scenario
       
  1002 // is trying to shoot them twice while rolling.  This is mostly about not wasting ammo, but shouldn't apply to gears not using AmmoShove (portal
       
  1003 // Should we rethink AmmoShove? Presumably we'd need a way of knowing if current gear had already attacked a gear
       
  1004 if isInMultiShoot and not AllInactive and (Hedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle]) then HHGear^.Message:= HHGear^.Message and not gmAttack;
       
  1005 (*
  1003 if isInMultiShoot then
  1006 if isInMultiShoot then
  1004     HHGear^.Message:= 0;
  1007     HHGear^.Message:= 0;
  1005 
  1008 *)
  1006 if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then 
  1009 
       
  1010 (*if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then 
  1007     AllInactive:= true
  1011     AllInactive:= true
  1008 else if not isInMultiShoot then
  1012 else if not isInMultiShoot then
  1009     AllInactive:= false;
  1013    AllInactive:= false;*)
       
  1014  AllInactive:= false;
  1010 
  1015 
  1011 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
  1016 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
  1012     begin
  1017     begin
  1013     if TagTurnTimeLeft = 0 then
  1018     if TagTurnTimeLeft = 0 then
  1014         TagTurnTimeLeft:= TurnTimeLeft;
  1019         TagTurnTimeLeft:= TurnTimeLeft;
  1084     begin
  1089     begin
  1085     CurAmmoGear^.Message:= HHGear^.Message;
  1090     CurAmmoGear^.Message:= HHGear^.Message;
  1086     exit
  1091     exit
  1087     end;
  1092     end;
  1088 
  1093 
  1089 if not isInMultiShoot then
       
  1090     HedgehogChAngle(HHGear);
  1094     HedgehogChAngle(HHGear);
  1091 
  1095 
  1092 if (HHGear^.State and gstMoving) <> 0 then
  1096 if (HHGear^.State and gstMoving) <> 0 then
  1093     begin
  1097     begin
  1094     wasJumping:= ((HHGear^.State and gstHHJumping) <> 0);
  1098     wasJumping:= ((HHGear^.State and gstHHJumping) <> 0);
  1120             GHStepTicks:= 95
  1124             GHStepTicks:= 95
  1121         end;
  1125         end;
  1122     exit
  1126     exit
  1123     end;
  1127     end;
  1124 
  1128 
  1125     if not isInMultiShoot and (Hedgehog^.Gear <> nil) then
  1129     if Hedgehog^.Gear <> nil then
  1126         begin
  1130         begin
  1127         if GHStepTicks > 0 then
  1131         if GHStepTicks > 0 then
  1128             dec(GHStepTicks);
  1132             dec(GHStepTicks);
  1129         if (GHStepTicks = 0) then
  1133         if (GHStepTicks = 0) then
  1130             HedgehogStep(HHGear)
  1134             HedgehogStep(HHGear)