hedgewars/uGears.pas
changeset 2017 7845c77c8d31
parent 2005 aa79f631711b
child 2020 f8cd566204ef
equal deleted inserted replaced
2016:73b0bcc4396d 2017:7845c77c8d31
    52 			Tex: PTexture;
    52 			Tex: PTexture;
    53 			Z: Longword;
    53 			Z: Longword;
    54 			IntersectGear: PGear;
    54 			IntersectGear: PGear;
    55 			TriggerId: Longword;
    55 			TriggerId: Longword;
    56 			uid: Longword;
    56 			uid: Longword;
       
    57             Text: shortstring;
    57 			end;
    58 			end;
    58 
    59 
    59 function  AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
    60 function  AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
    60 procedure ProcessGears;
    61 procedure ProcessGears;
    61 procedure ResetUtilities;
    62 procedure ResetUtilities;
       
    63 procedure ApplyDamage(Gear: PGear; Damage: Longword);
    62 procedure SetAllToActive;
    64 procedure SetAllToActive;
    63 procedure SetAllHHToActive;
    65 procedure SetAllHHToActive;
    64 procedure DrawGears;
    66 procedure DrawGears;
    65 procedure FreeGearsList;
    67 procedure FreeGearsList;
    66 procedure AddMiscGears;
    68 procedure AddMiscGears;
    69 procedure RemoveGearFromList(Gear: PGear);
    71 procedure RemoveGearFromList(Gear: PGear);
    70 
    72 
    71 var CurAmmoGear: PGear = nil;
    73 var CurAmmoGear: PGear = nil;
    72     GearsList: PGear = nil;
    74     GearsList: PGear = nil;
    73     KilledHHs: Longword = 0;
    75     KilledHHs: Longword = 0;
       
    76     SuddenDeathDmg: Boolean = false;
       
    77     SpeechType: Longword = 1;
       
    78     SpeechText: shortstring;
    74 
    79 
    75 implementation
    80 implementation
    76 uses uWorld, uMisc, uStore, uConsole, uSound, uTeams, uRandom, uCollisions,
    81 uses uWorld, uMisc, uStore, uConsole, uSound, uTeams, uRandom, uCollisions,
    77 	uLand, uIO, uLandGraphics, uAIMisc, uLocale, uAI, uAmmos, uTriggers, 
    82 	uLand, uIO, uLandGraphics, uAIMisc, uLocale, uAI, uAmmos, uTriggers, 
    78 {$IFDEF IPHONE}
    83 {$IFDEF IPHONE}
   155 			@doStepSmokeTrace,
   160 			@doStepSmokeTrace,
   156 			@doStepWaterUp,
   161 			@doStepWaterUp,
   157 			@doStepDrill,
   162 			@doStepDrill,
   158 			@doStepBallgun,
   163 			@doStepBallgun,
   159 			@doStepBomb,
   164 			@doStepBomb,
   160 			@doStepRCPlane
   165 			@doStepRCPlane,
       
   166 			@doStepSpeechBubble
   161 			);
   167 			);
   162 
   168 
   163 procedure InsertGearToList(Gear: PGear);
   169 procedure InsertGearToList(Gear: PGear);
   164 var tmp, ptmp: PGear;
   170 var tmp, ptmp: PGear;
   165 begin
   171 begin
   246 gtAmmo_Grenade: begin
   252 gtAmmo_Grenade: begin
   247                 Result^.Radius:= 4;
   253                 Result^.Radius:= 4;
   248                 end;
   254                 end;
   249    gtHealthTag: begin
   255    gtHealthTag: begin
   250                 Result^.Timer:= 1500;
   256                 Result^.Timer:= 1500;
   251                 Result^.Z:= 2001;
   257                 Result^.Z:= 2002;
       
   258                 end;
       
   259    gtSpeechBubble: begin
       
   260                 Result^.Z:= 2003;
   252                 end;
   261                 end;
   253        gtGrave: begin
   262        gtGrave: begin
   254                 Result^.Radius:= 10;
   263                 Result^.Radius:= 10;
   255                 Result^.Elasticity:= _0_6;
   264                 Result^.Elasticity:= _0_6;
   256                 end;
   265                 end;
   438 	if Gear^.Kind = gtHedgehog then
   447 	if Gear^.Kind = gtHedgehog then
   439 		begin
   448 		begin
   440 		if (Gear^.Damage <> 0) and
   449 		if (Gear^.Damage <> 0) and
   441 		(not Gear^.Invulnerable) then
   450 		(not Gear^.Invulnerable) then
   442 			begin
   451 			begin
   443             if (PHedgehog(Gear^.Hedgehog)^.Team = CurrentTeam) and
       
   444                (Gear^.Damage <> int(cHealthDecrease)) then
       
   445                 Gear^.State:= Gear^.State or gstLoser;
       
   446 			CheckNoDamage:= false;
   452 			CheckNoDamage:= false;
   447 			uStats.HedgehogDamaged(Gear);
   453 			uStats.HedgehogDamaged(Gear);
   448 			dmg:= Gear^.Damage;
   454 			dmg:= Gear^.Damage;
   449 			if Gear^.Health < dmg then
   455 			if Gear^.Health < dmg then
   450 				Gear^.Health:= 0
   456 				Gear^.Health:= 0
   451 			else
   457 			else
   452 				dec(Gear^.Health, dmg);
   458 				dec(Gear^.Health, dmg);
   453 
   459 
       
   460             if (PHedgehog(Gear^.Hedgehog)^.Team = CurrentTeam) and
       
   461                 not SuddenDeathDmg then
       
   462                 Gear^.State:= Gear^.State or gstLoser;
       
   463 
   454 			AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) - cHHRadius - 12,
   464 			AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) - cHHRadius - 12,
   455 					gtHealthTag, dmg, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
   465 					gtHealthTag, dmg, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
   456 
   466 
   457 			RenderHealth(PHedgehog(Gear^.Hedgehog)^);
   467 			RenderHealth(PHedgehog(Gear^.Hedgehog)^);
   458 			RecountTeamHealth(PHedgehog(Gear^.Hedgehog)^.Team);
   468 			RecountTeamHealth(PHedgehog(Gear^.Hedgehog)^.Team);
   460 			end;
   470 			end;
   461 		Gear^.Damage:= 0;
   471 		Gear^.Damage:= 0;
   462 		end;
   472 		end;
   463 	Gear:= Gear^.NextGear
   473 	Gear:= Gear^.NextGear
   464 	end;
   474 	end;
       
   475 SuddenDeathDmg:= false;
   465 end;
   476 end;
   466 
   477 
   467 procedure HealthMachine;
   478 procedure HealthMachine;
   468 var Gear: PGear;
   479 var Gear: PGear;
   469 begin
   480 begin
   560 				or isInMultiShoot
   571 				or isInMultiShoot
   561 				or (TotalRounds = 0) then inc(step)
   572 				or (TotalRounds = 0) then inc(step)
   562 			else begin
   573 			else begin
   563 				bBetweenTurns:= true;
   574 				bBetweenTurns:= true;
   564 				HealthMachine;
   575 				HealthMachine;
       
   576                 SuddenDeathDmg:= true;
   565 				step:= stChDmg
   577 				step:= stChDmg
   566 				end
   578 				end
   567 			end;
   579 			end;
   568 	stSpawn: begin
   580 	stSpawn: begin
   569 			if not isInMultiShoot then SpawnBoxOfSmth;
   581 			if not isInMultiShoot then SpawnBoxOfSmth;
   610 //Purpose, to reset all transient attributes toggled by a utility.
   622 //Purpose, to reset all transient attributes toggled by a utility.
   611 //If any of these are set as permanent toggles in the frontend, that needs to be checked and skipped here.
   623 //If any of these are set as permanent toggles in the frontend, that needs to be checked and skipped here.
   612 procedure ResetUtilities;
   624 procedure ResetUtilities;
   613 var  i: LongInt;
   625 var  i: LongInt;
   614 begin
   626 begin
       
   627     SpeechText:= ''; // in case it hasn't been consumed
       
   628 
   615     if (GameFlags and gfLowGravity) = 0 then
   629     if (GameFlags and gfLowGravity) = 0 then
   616         cGravity:= cMaxWindSpeed;
   630         cGravity:= cMaxWindSpeed;
       
   631 
       
   632     if (GameFlags and gfVampiric) = 0 then
       
   633         cVampiric:= false;
   617 
   634 
   618     cDamageModifier:= _1;
   635     cDamageModifier:= _1;
   619 
   636 
   620     if (GameFlags and gfLaserSight) = 0 then
   637     if (GameFlags and gfLaserSight) = 0 then
   621         cLaserSighting:= false;
   638         cLaserSighting:= false;
   626           with CurrentTeam^ do
   643           with CurrentTeam^ do
   627              for i:= 0 to cMaxHHIndex do
   644              for i:= 0 to cMaxHHIndex do
   628                  with Hedgehogs[i] do
   645                  with Hedgehogs[i] do
   629                      if (Gear <> nil) then
   646                      if (Gear <> nil) then
   630                          Gear^.Invulnerable:= false;
   647                          Gear^.Invulnerable:= false;
       
   648 end;
       
   649 procedure ApplyDamage(Gear: PGear; Damage: Longword);
       
   650 var s: shortstring;
       
   651     vampDmg: Longword;
       
   652 begin
       
   653 	inc(Gear^.Damage, Damage);
       
   654 	if Gear^.Kind = gtHedgehog then
       
   655     begin
       
   656 	AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), Damage, PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.Color);
       
   657     Damage:= min(Damage, Gear^.Health);
       
   658     if (Gear <> CurrentHedgehog^.Gear) and (CurrentHedgehog^.Gear <> nil) and (Damage >= 1) then
       
   659         begin
       
   660         if cVampiric then
       
   661             begin
       
   662             vampDmg:= hwRound(int2hwFloat(Damage)*_0_8);
       
   663             // was considering pulsing on attack, Tiy thinks it should be permanent while in play
       
   664             //CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstVampiric;
       
   665             inc(CurrentHedgehog^.Gear^.Health,vampDmg);
       
   666             str(vampDmg, s);
       
   667             s:= '+' + s;
       
   668             AddCaption(s, CurrentHedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
       
   669             RenderHealth(CurrentHedgehog^);
       
   670             RecountTeamHealth(CurrentHedgehog^.Team);
       
   671             end;
       
   672         if ((GameFlags and gfKarma) <> 0) and 
       
   673            ((GameFlags and gfInvulnerable) = 0) and
       
   674            not CurrentHedgehog^.Gear^.Invulnerable then
       
   675            begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid
       
   676            if CurrentHedgehog^.Gear^.Health < int(Damage) then
       
   677            begin
       
   678                // Add damage to trigger normal resolution
       
   679                CurrentHedgehog^.Gear^.Health := 0;
       
   680                inc(CurrentHedgehog^.Gear^.Damage);
       
   681            end
       
   682            else
       
   683                dec(CurrentHedgehog^.Gear^.Health, Damage);
       
   684            AddGear(hwRound(Gear^.X), 
       
   685                    hwRound(Gear^.Y), 
       
   686                    gtHealthTag, Damage, _0, _0, 0)^.Hedgehog:= CurrentHedgehog;
       
   687            RenderHealth(CurrentHedgehog^);
       
   688            RecountTeamHealth(CurrentHedgehog^.Team);
       
   689            end;
       
   690         end;
       
   691     end;
   631 end;
   692 end;
   632 
   693 
   633 procedure SetAllToActive;
   694 procedure SetAllToActive;
   634 var t: PGear;
   695 var t: PGear;
   635 begin
   696 begin
   839 		DrawHedgehog(sx, sy,
   900 		DrawHedgehog(sx, sy,
   840 			hwSign(Gear^.dX),
   901 			hwSign(Gear^.dX),
   841 			1,
   902 			1,
   842 			1,
   903 			1,
   843 			0);
   904 			0);
       
   905 	HatVisible:= true;
   844 	defaultPos:= false
   906 	defaultPos:= false
   845 	end else
   907 	end else
   846 
   908 
   847 	if (Gear^.Message and (gm_Left or gm_Right) <> 0) and (not isCursorVisible) then
   909 	if (Gear^.Message and (gm_Left or gm_Right) <> 0) and (not isCursorVisible) then
   848 		begin
   910 		begin
   948 		defaultPos:= false
  1010 		defaultPos:= false
   949 	end
  1011 	end
   950 end else // not gstHHDriven
  1012 end else // not gstHHDriven
   951 	begin
  1013 	begin
   952 	if (Gear^.Damage > 0)
  1014 	if (Gear^.Damage > 0)
   953 	and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
  1015 	and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) 
       
  1016 // ARTILLERY
       
  1017 //and (1=0)
       
  1018 then
   954 		begin
  1019 		begin
   955 		DrawHedgehog(sx, sy,
  1020 		DrawHedgehog(sx, sy,
   956 			hwSign(Gear^.dX),
  1021 			hwSign(Gear^.dX),
   957 			2,
  1022 			2,
   958 			1,
  1023 			1,
  1121 					end
  1186 					end
  1122 			end
  1187 			end
  1123 	end;
  1188 	end;
  1124 
  1189 
  1125 if Gear^.Invulnerable then
  1190 if Gear^.Invulnerable then
  1126      begin
  1191     begin
  1127      DrawSprite(sprInvulnerable, sx - 24, sy - 24, 0);
  1192     DrawSprite(sprInvulnerable, sx - 24, sy - 24, 0);
  1128      end;
  1193     end;
       
  1194 if cVampiric and
       
  1195    (CurrentHedgehog^.Gear <> nil) and 
       
  1196    (CurrentHedgehog^.Gear = Gear) then
       
  1197     begin
       
  1198     DrawSprite(sprVampiric, sx - 24, sy - 24, 0);
       
  1199     end;
  1129 end;
  1200 end;
  1130 
  1201 
  1131 procedure DrawGears;
  1202 procedure DrawGears;
  1132 var Gear, HHGear: PGear;
  1203 var Gear, HHGear: PGear;
  1133     i: Longword;
  1204     i: Longword;
  1214         gtHedgehog: DrawHH(Gear);
  1285         gtHedgehog: DrawHH(Gear);
  1215     
  1286     
  1216     gtAmmo_Grenade: DrawRotated(sprGrenade, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1287     gtAmmo_Grenade: DrawRotated(sprGrenade, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1217        
  1288        
  1218        gtHealthTag: if Gear^.Tex <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex);
  1289        gtHealthTag: if Gear^.Tex <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex);
       
  1290 
       
  1291        gtSpeechBubble: if Gear^.Tex <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex);
  1219            
  1292            
  1220            gtGrave: DrawSurfSprite(hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 32, (GameTicks shr 7) and 7, PHedgehog(Gear^.Hedgehog)^.Team^.GraveTex);
  1293            gtGrave: DrawSurfSprite(hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 32, (GameTicks shr 7) and 7, PHedgehog(Gear^.Hedgehog)^.Team^.GraveTex);
  1221              
  1294              
  1222              gtUFO: DrawSprite(sprUFO, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 16 + WorldDy, (GameTicks shr 7) mod 4);
  1295              gtUFO: DrawSprite(sprUFO, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 16 + WorldDy, (GameTicks shr 7) mod 4);
  1223       
  1296       
  1326 		end;
  1399 		end;
  1327 
  1400 
  1328 if (GameFlags and gfLowGravity) <> 0 then
  1401 if (GameFlags and gfLowGravity) <> 0 then
  1329     cGravity:= cMaxWindSpeed / 2;
  1402     cGravity:= cMaxWindSpeed / 2;
  1330 
  1403 
       
  1404 if (GameFlags and gfVampiric) <> 0 then
       
  1405     cVampiric:= true;
       
  1406 
  1331 Gear:= GearsList;
  1407 Gear:= GearsList;
  1332 if (GameFlags and gfInvulnerable) <> 0 then
  1408 if (GameFlags and gfInvulnerable) <> 0 then
  1333    while Gear <> nil do
  1409    while Gear <> nil do
  1334        begin
  1410        begin
  1335        Gear^.Invulnerable:= true;  // this is only checked on hogs right now, so no need for gear type check
  1411        Gear^.Invulnerable:= true;  // this is only checked on hogs right now, so no need for gear type check
  1370 				gtFlame: begin
  1446 				gtFlame: begin
  1371 						//{$IFDEF DEBUGFILE}AddFileLog('Damage: ' + inttostr(dmg));{$ENDIF}
  1447 						//{$IFDEF DEBUGFILE}AddFileLog('Damage: ' + inttostr(dmg));{$ENDIF}
  1372 						if (Mask and EXPLNoDamage) = 0 then
  1448 						if (Mask and EXPLNoDamage) = 0 then
  1373 							begin
  1449 							begin
  1374 							if not Gear^.Invulnerable then
  1450 							if not Gear^.Invulnerable then
  1375 								begin
  1451                                 ApplyDamage(Gear, dmg)
  1376 							    inc(Gear^.Damage, dmg);
       
  1377 							    if Gear^.Kind = gtHedgehog then
       
  1378 								    AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), dmg, PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.Color);
       
  1379                                 end
       
  1380                             else
  1452                             else
  1381                                 Gear^.State:= Gear^.State or gstWinner;
  1453                                 Gear^.State:= Gear^.State or gstWinner;
  1382 							end;
  1454 							end;
  1383 						if ((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog) then
  1455 						if ((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog) then
  1384 							begin
  1456 							begin
  1421 		gtHedgehog,
  1493 		gtHedgehog,
  1422 			gtMine,
  1494 			gtMine,
  1423 			gtCase,
  1495 			gtCase,
  1424 			gtTarget: begin
  1496 			gtTarget: begin
  1425                     if (not t^.Invulnerable) then
  1497                     if (not t^.Invulnerable) then
  1426                         begin
  1498                         ApplyDamage(t, dmg)
  1427 					    inc(t^.Damage, dmg);
       
  1428 					    if t^.Kind = gtHedgehog then
       
  1429 						    AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y), dmg, PHedgehog(t^.Hedgehog)^.Team^.Clan^.Color);
       
  1430                         end
       
  1431                     else
  1499                     else
  1432                         Gear^.State:= Gear^.State or gstWinner;
  1500                         Gear^.State:= Gear^.State or gstWinner;
  1433 
  1501 
  1434 					DeleteCI(t);
  1502 					DeleteCI(t);
  1435 					t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX);
  1503 					t^.dX:= t^.dX + Gear^.dX * dmg * _0_01 + SignAs(cHHKick, Gear^.dX);
  1466 			gtMine,
  1534 			gtMine,
  1467 			gtTarget,
  1535 			gtTarget,
  1468 			gtCase: begin
  1536 			gtCase: begin
  1469 					if (Ammo^.Kind = gtDrill) then begin Ammo^.Timer:= 0; exit; end;
  1537 					if (Ammo^.Kind = gtDrill) then begin Ammo^.Timer:= 0; exit; end;
  1470                     if (not t^.ar[i]^.Invulnerable) then
  1538                     if (not t^.ar[i]^.Invulnerable) then
  1471                         begin
  1539                         ApplyDamage(t^.ar[i], Damage)
  1472 					    inc(t^.ar[i]^.Damage, Damage);
       
  1473 
       
  1474                         if (t^.ar[i]^.Kind = gtHedgehog) and (Damage > 0) then
       
  1475                             AddDamageTag(hwRound(t^.ar[i]^.X), hwRound(t^.ar[i]^.Y), Damage, PHedgehog(t^.ar[i]^.Hedgehog)^.Team^.Clan^.Color);
       
  1476                         end
       
  1477                     else
  1540                     else
  1478                         t^.ar[i]^.State:= t^.ar[i]^.State or gstWinner;
  1541                         t^.ar[i]^.State:= t^.ar[i]^.State or gstWinner;
  1479 
  1542 
  1480 					DeleteCI(t^.ar[i]);
  1543 					DeleteCI(t^.ar[i]);
  1481 					t^.ar[i]^.dX:= Ammo^.dX * Power * _0_01;
  1544 					t^.ar[i]^.dX:= Ammo^.dX * Power * _0_01;
  1585 while t <> nil do
  1648 while t <> nil do
  1586 	begin
  1649 	begin
  1587 	if (t^.Kind = gtHedgehog) and (t^.Y < Ammo^.Y) then
  1650 	if (t^.Kind = gtHedgehog) and (t^.Y < Ammo^.Y) then
  1588 		if not (hwSqr(Ammo^.X - t^.X) + hwSqr(Ammo^.Y - t^.Y - int2hwFloat(cHHRadius)) * 2 > _2) then
  1651 		if not (hwSqr(Ammo^.X - t^.X) + hwSqr(Ammo^.Y - t^.Y - int2hwFloat(cHHRadius)) * 2 > _2) then
  1589 			begin
  1652 			begin
  1590 			inc(t^.Damage, 5);
  1653             ApplyDamage(t, 5);
  1591 			t^.dX:= t^.dX + (t^.X - Ammo^.X) * _0_02;
  1654 			t^.dX:= t^.dX + (t^.X - Ammo^.X) * _0_02;
  1592 			t^.dY:= - _0_25;
  1655 			t^.dY:= - _0_25;
  1593 			t^.Active:= true;
  1656 			t^.Active:= true;
  1594 			DeleteCI(t);
  1657 			DeleteCI(t);
  1595 			FollowGear:= t
  1658 			FollowGear:= t
  1636    (CountGears(gtCase) >= 5) or
  1699    (CountGears(gtCase) >= 5) or
  1637    (getrandom(cCaseFactor) <> 0) then exit;
  1700    (getrandom(cCaseFactor) <> 0) then exit;
  1638 
  1701 
  1639 FollowGear:= nil;
  1702 FollowGear:= nil;
  1640 
  1703 
  1641 t:= getrandom(20);  // TEMPORARY  REMOVE WHEN CRATE PROBABILITY IS ADDED
  1704 if shoppa then  // TEMPORARY  REMOVE WHEN CRATE PROBABILITY IS ADDED
  1642 if shoppa then
       
  1643     t:= 7
  1705     t:= 7
  1644 else
  1706 else
  1645     t:= getrandom(20);
  1707     t:= getrandom(20);
  1646 
  1708 
  1647 //case getrandom(20) of
  1709 //case getrandom(20) of