hedgewars/uGears.pas
changeset 1505 3a96e93572cb
parent 1503 a40b871d506b
child 1506 a4ab75470ce1
equal deleted inserted replaced
1504:1603a796f42a 1505:3a96e93572cb
    95 procedure AfterAttack; forward;
    95 procedure AfterAttack; forward;
    96 procedure FindPlace(Gear: PGear; withFall: boolean; Left, Right: LongInt); forward;
    96 procedure FindPlace(Gear: PGear; withFall: boolean; Left, Right: LongInt); forward;
    97 procedure HedgehogStep(Gear: PGear); forward;
    97 procedure HedgehogStep(Gear: PGear); forward;
    98 procedure HedgehogChAngle(Gear: PGear); forward;
    98 procedure HedgehogChAngle(Gear: PGear); forward;
    99 procedure ShotgunShot(Gear: PGear); forward;
    99 procedure ShotgunShot(Gear: PGear); forward;
   100 procedure AddDamageTag(X, Y, Damage: LongWord; Gear: PGear); forward;
       
   101 
   100 
   102 {$INCLUDE GSHandlers.inc}
   101 {$INCLUDE GSHandlers.inc}
   103 {$INCLUDE HHHandlers.inc}
   102 {$INCLUDE HHHandlers.inc}
   104 
   103 
   105 const doStepHandlers: array[TGearType] of TGearStepProcedure = (
   104 const doStepHandlers: array[TGearType] of TGearStepProcedure = (
   131 			@doStepAirAttack,
   130 			@doStepAirAttack,
   132 			@doStepAirBomb,
   131 			@doStepAirBomb,
   133 			@doStepBlowTorch,
   132 			@doStepBlowTorch,
   134 			@doStepGirder,
   133 			@doStepGirder,
   135 			@doStepTeleport,
   134 			@doStepTeleport,
   136 			@doStepHealthTag,
       
   137 			@doStepSwitcher,
   135 			@doStepSwitcher,
   138 			@doStepCase,
   136 			@doStepCase,
   139 			@doStepMortar,
   137 			@doStepMortar,
   140 			@doStepWhip,
   138 			@doStepWhip,
   141 			@doStepKamikaze,
   139 			@doStepKamikaze,
   150 
   148 
   151 procedure InsertGearToList(Gear: PGear);
   149 procedure InsertGearToList(Gear: PGear);
   152 var tmp, ptmp: PGear;
   150 var tmp, ptmp: PGear;
   153 begin
   151 begin
   154 if GearsList = nil then
   152 if GearsList = nil then
   155    GearsList:= Gear
   153 	GearsList:= Gear
   156    else begin
   154 	else begin
   157    tmp:= GearsList;
   155 	tmp:= GearsList;
   158    ptmp:= GearsList;
   156 	ptmp:= GearsList;
   159    while (tmp <> nil) and (tmp^.Z <= Gear^.Z) do
   157 	while (tmp <> nil) and (tmp^.Z <= Gear^.Z) do
   160           begin
   158 		begin
   161           ptmp:= tmp;
   159 		ptmp:= tmp;
   162           tmp:= tmp^.NextGear
   160 		tmp:= tmp^.NextGear
   163           end;
   161 		end;
   164 
   162 
   165    if ptmp <> nil then
   163 	if ptmp <> nil then
   166       begin
   164 		begin
   167       Gear^.NextGear:= ptmp^.NextGear;
   165 		Gear^.NextGear:= ptmp^.NextGear;
   168       Gear^.PrevGear:= ptmp;
   166 		Gear^.PrevGear:= ptmp;
   169       if ptmp^.NextGear <> nil then ptmp^.NextGear^.PrevGear:= Gear;
   167 		if ptmp^.NextGear <> nil then ptmp^.NextGear^.PrevGear:= Gear;
   170       ptmp^.NextGear:= Gear
   168 		ptmp^.NextGear:= Gear
   171       end
   169 		end
   172    else GearsList:= Gear
   170 	else GearsList:= Gear
   173    end
   171 	end
   174 end;
   172 end;
   175 
   173 
   176 procedure RemoveGearFromList(Gear: PGear);
   174 procedure RemoveGearFromList(Gear: PGear);
   177 begin
   175 begin
   178 if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
   176 if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
   179 if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear
   177 if Gear^.PrevGear <> nil then
   180    else GearsList:= Gear^.NextGear
   178 	Gear^.PrevGear^.NextGear:= Gear^.NextGear
       
   179 else
       
   180 	GearsList:= Gear^.NextGear
   181 end;
   181 end;
   182 
   182 
   183 function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
   183 function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
   184 const Counter: Longword = 0;
   184 const Counter: Longword = 0;
   185 var Result: PGear;
   185 var Result: PGear;
   203 Result^.Timer:= Timer;
   203 Result^.Timer:= Timer;
   204 Result^.Z:= cUsualZ;
   204 Result^.Z:= cUsualZ;
   205 Result^.uid:= Counter;
   205 Result^.uid:= Counter;
   206 
   206 
   207 if CurrentTeam <> nil then
   207 if CurrentTeam <> nil then
   208    begin
   208 	begin
   209    Result^.Hedgehog:= CurrentHedgehog;
   209 	Result^.Hedgehog:= CurrentHedgehog;
   210    Result^.IntersectGear:= CurrentHedgehog^.Gear
   210 	Result^.IntersectGear:= CurrentHedgehog^.Gear
   211    end;
   211 	end;
   212 
   212 
   213 case Kind of
   213 case Kind of
   214    gtAmmo_Bomb,
   214    gtAmmo_Bomb,
   215  gtClusterBomb: begin
   215  gtClusterBomb: begin
   216                 Result^.Radius:= 4;
   216                 Result^.Radius:= 4;
   307                 Result^.Radius:= 5;
   307                 Result^.Radius:= 5;
   308                 end;
   308                 end;
   309    gtBlowTorch: begin
   309    gtBlowTorch: begin
   310                 Result^.Radius:= cHHRadius + cBlowTorchC;
   310                 Result^.Radius:= cHHRadius + cBlowTorchC;
   311                 Result^.Timer:= 7500;
   311                 Result^.Timer:= 7500;
   312                 end;
       
   313  gtSmallDamage: begin
       
   314                 Result^.Timer:= 1100;
       
   315                 Result^.Z:= 2000;
       
   316                 end;
   312                 end;
   317     gtSwitcher: begin
   313     gtSwitcher: begin
   318                 Result^.Z:= cCurrHHZ
   314                 Result^.Z:= cCurrHHZ
   319                 end;
   315                 end;
   320       gtTarget: begin
   316       gtTarget: begin
   415 		else
   411 		else
   416 			dec(Gear^.Health, Gear^.Damage);
   412 			dec(Gear^.Health, Gear^.Damage);
   417 
   413 
   418 		AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) - cHHRadius - 12,
   414 		AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) - cHHRadius - 12,
   419 				gtHealthTag, Gear^.Damage, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
   415 				gtHealthTag, Gear^.Damage, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
       
   416 
   420 		RenderHealth(PHedgehog(Gear^.Hedgehog)^);
   417 		RenderHealth(PHedgehog(Gear^.Hedgehog)^);
   421 		RecountTeamHealth(PHedgehog(Gear^.Hedgehog)^.Team);
   418 		RecountTeamHealth(PHedgehog(Gear^.Hedgehog)^.Team);
   422 
   419 
   423 		Gear^.Damage:= 0
   420 		Gear^.Damage:= 0
   424 		end;
   421 		end;
   436 	if Gear^.Kind = gtHedgehog then
   433 	if Gear^.Kind = gtHedgehog then
   437 		Gear^.Damage:= min(cHealthDecrease, Gear^.Health - 1);
   434 		Gear^.Damage:= min(cHealthDecrease, Gear^.Health - 1);
   438 
   435 
   439 	Gear:= Gear^.NextGear
   436 	Gear:= Gear^.NextGear
   440 	end;
   437 	end;
   441 end;
       
   442 
       
   443 procedure AddDamageTag(X, Y, Damage: LongWord; Gear: PGear);
       
   444 begin
       
   445 if cAltDamage then
       
   446 	AddGear(X, Y, gtSmallDamage, Damage, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
       
   447 end;
   438 end;
   448 
   439 
   449 procedure ProcessGears;
   440 procedure ProcessGears;
   450 const delay: LongWord = 0;
   441 const delay: LongWord = 0;
   451 	step: (stDelay, stChDmg, stTurnReact,
   442 	step: (stDelay, stChDmg, stTurnReact,
   572 var t: PGear;
   563 var t: PGear;
   573 begin
   564 begin
   574 AllInactive:= false;
   565 AllInactive:= false;
   575 t:= GearsList;
   566 t:= GearsList;
   576 while t <> nil do
   567 while t <> nil do
   577       begin
   568 	begin
   578       t^.Active:= true;
   569 	t^.Active:= true;
   579       t:= t^.NextGear
   570 	t:= t^.NextGear
   580       end
   571 	end
   581 end;
   572 end;
   582 
   573 
   583 procedure SetAllHHToActive;
   574 procedure SetAllHHToActive;
   584 var t: PGear;
   575 var t: PGear;
   585 begin
   576 begin
   586 AllInactive:= false;
   577 AllInactive:= false;
   587 t:= GearsList;
   578 t:= GearsList;
   588 while t <> nil do
   579 while t <> nil do
   589       begin
   580 	begin
   590       if t^.Kind = gtHedgehog then t^.Active:= true;
   581 	if t^.Kind = gtHedgehog then t^.Active:= true;
   591       t:= t^.NextGear
   582 	t:= t^.NextGear
   592       end
   583 	end
   593 end;
   584 end;
   594 
   585 
   595 procedure DrawHH(Gear: PGear);
   586 procedure DrawHH(Gear: PGear);
   596 var t: LongInt;
   587 var t: LongInt;
   597 	amt: TAmmoType;
   588 	amt: TAmmoType;
  1039       begin
  1030       begin
  1040       case Gear^.Kind of
  1031       case Gear^.Kind of
  1041        gtAmmo_Bomb: DrawRotated(sprBomb, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, Gear^.DirAngle);
  1032        gtAmmo_Bomb: DrawRotated(sprBomb, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, Gear^.DirAngle);
  1042         gtHedgehog: DrawHH(Gear);
  1033         gtHedgehog: DrawHH(Gear);
  1043     gtAmmo_Grenade: DrawRotated(sprGrenade, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1034     gtAmmo_Grenade: DrawRotated(sprGrenade, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1044        gtHealthTag,
  1035        gtHealthTag: if Gear^.Tex <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex);
  1045      gtSmallDamage: if Gear^.Tex <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex);
       
  1046            gtGrave: DrawSurfSprite(hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 32, (GameTicks shr 7) and 7, PHedgehog(Gear^.Hedgehog)^.Team^.GraveTex);
  1036            gtGrave: DrawSurfSprite(hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 32, (GameTicks shr 7) and 7, PHedgehog(Gear^.Hedgehog)^.Team^.GraveTex);
  1047              gtUFO: DrawSprite(sprUFO, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 16 + WorldDy, (GameTicks shr 7) mod 4);
  1037              gtUFO: DrawSprite(sprUFO, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 16 + WorldDy, (GameTicks shr 7) mod 4);
  1048       gtPickHammer: DrawSprite(sprPHammer, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 50 + LongInt(((GameTicks shr 5) and 1) * 2) + WorldDy, 0);
  1038       gtPickHammer: DrawSprite(sprPHammer, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 50 + LongInt(((GameTicks shr 5) and 1) * 2) + WorldDy, 0);
  1049             gtRope: begin
  1039             gtRope: begin
  1050                     roplen:= 0;
  1040                     roplen:= 0;
  1115 procedure FreeGearsList;
  1105 procedure FreeGearsList;
  1116 var t, tt: PGear;
  1106 var t, tt: PGear;
  1117 begin
  1107 begin
  1118 tt:= GearsList;
  1108 tt:= GearsList;
  1119 GearsList:= nil;
  1109 GearsList:= nil;
  1120 while tt<>nil do
  1110 while tt <> nil do
  1121       begin
  1111 	begin
  1122       t:= tt;
  1112 	t:= tt;
  1123       tt:= tt^.NextGear;
  1113 	tt:= tt^.NextGear;
  1124       Dispose(t)
  1114 	Dispose(t)
  1125       end;
  1115 	end;
  1126 end;
  1116 end;
  1127 
  1117 
  1128 procedure AddMiscGears;
  1118 procedure AddMiscGears;
  1129 var i: LongInt;
  1119 var i: LongInt;
  1130 begin
  1120 begin
  1166 						//{$IFDEF DEBUGFILE}AddFileLog('Damage: ' + inttostr(dmg));{$ENDIF}
  1156 						//{$IFDEF DEBUGFILE}AddFileLog('Damage: ' + inttostr(dmg));{$ENDIF}
  1167 						if (Mask and EXPLNoDamage) = 0 then
  1157 						if (Mask and EXPLNoDamage) = 0 then
  1168 							begin
  1158 							begin
  1169 							inc(Gear^.Damage, dmg);
  1159 							inc(Gear^.Damage, dmg);
  1170 							if Gear^.Kind = gtHedgehog then
  1160 							if Gear^.Kind = gtHedgehog then
  1171 								AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), dmg, Gear)
  1161 								AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), dmg, PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.Color)
  1172 							end;
  1162 							end;
  1173 						if ((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog) then
  1163 						if ((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog) then
  1174 							begin
  1164 							begin
  1175 							DeleteCI(Gear);
  1165 							DeleteCI(Gear);
  1176 							Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - int2hwFloat(X));
  1166 							Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - int2hwFloat(X));
  1211 			gtCase,
  1201 			gtCase,
  1212 			gtTarget: begin
  1202 			gtTarget: begin
  1213 					inc(t^.Damage, dmg);
  1203 					inc(t^.Damage, dmg);
  1214 
  1204 
  1215 					if t^.Kind = gtHedgehog then
  1205 					if t^.Kind = gtHedgehog then
  1216 							AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), dmg, t);
  1206 						AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), dmg, PHedgehog(t^.Hedgehog)^.Team^.Clan^.Color);
  1217 
  1207 
  1218 					DeleteCI(t);
  1208 					DeleteCI(t);
  1219 					t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX);
  1209 					t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX);
  1220 					t^.dY:= t^.dY + Gear^.dY * dmg * _0_01;
  1210 					t^.dY:= t^.dY + Gear^.dY * dmg * _0_01;
  1221 					t^.State:= t^.State or gstMoving;
  1211 					t^.State:= t^.State or gstMoving;
  1248 			gtTarget,
  1238 			gtTarget,
  1249 			gtCase: begin
  1239 			gtCase: begin
  1250 					inc(t^.ar[i]^.Damage, Damage);
  1240 					inc(t^.ar[i]^.Damage, Damage);
  1251 
  1241 
  1252 					if (t^.ar[i]^.Kind = gtHedgehog) and (Damage > 0) then
  1242 					if (t^.ar[i]^.Kind = gtHedgehog) and (Damage > 0) then
  1253 						AddDamageTag(hwRound(t^.ar[i]^.X), hwRound(t^.ar[i]^.Y), Damage, t^.ar[i]);
  1243 						AddDamageTag(hwRound(t^.ar[i]^.X), hwRound(t^.ar[i]^.Y), Damage, PHedgehog(t^.ar[i]^.Hedgehog)^.Team^.Clan^.Color);
  1254 
  1244 
  1255 					DeleteCI(t^.ar[i]);
  1245 					DeleteCI(t^.ar[i]);
  1256 					t^.ar[i]^.dX:= Ammo^.dX * Power * _0_01;
  1246 					t^.ar[i]^.dX:= Ammo^.dX * Power * _0_01;
  1257 					t^.ar[i]^.dY:= Ammo^.dY * Power * _0_01;
  1247 					t^.ar[i]^.dY:= Ammo^.dY * Power * _0_01;
  1258 					t^.ar[i]^.Active:= true;
  1248 					t^.ar[i]^.Active:= true;