hedgewars/uGears.pas
changeset 1515 0cf2edcfdd8f
parent 1506 a4ab75470ce1
child 1528 3fee15104c1d
equal deleted inserted replaced
1514:c4170faf7b0a 1515:0cf2edcfdd8f
    84                                   dLen: hwFloat;
    84                                   dLen: hwFloat;
    85                                   b: boolean;
    85                                   b: boolean;
    86                                   end;
    86                                   end;
    87                  end;
    87                  end;
    88 
    88 
    89 procedure DeleteGear(var Gear: PGear); forward;
    89 procedure DeleteGear(Gear: PGear); forward;
    90 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord); forward;
    90 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord); forward;
    91 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward;
    91 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward;
    92 //procedure AmmoFlameWork(Ammo: PGear); forward;
    92 //procedure AmmoFlameWork(Ammo: PGear); forward;
    93 function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; forward;
    93 function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; forward;
    94 procedure SpawnBoxOfSmth; forward;
    94 procedure SpawnBoxOfSmth; forward;
    95 procedure AfterAttack; forward;
    95 procedure AfterAttack; forward;
    96 procedure FindPlace(Gear: PGear; withFall: boolean; Left, Right: LongInt); forward;
    96 procedure FindPlace(var 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 
   100 
   101 {$INCLUDE GSHandlers.inc}
   101 {$INCLUDE GSHandlers.inc}
   341      end;
   341      end;
   342 InsertGearToList(Result);
   342 InsertGearToList(Result);
   343 AddGear:= Result
   343 AddGear:= Result
   344 end;
   344 end;
   345 
   345 
   346 procedure DeleteGear(var Gear: PGear);
   346 procedure DeleteGear(Gear: PGear);
   347 var team: PTeam;
   347 var team: PTeam;
   348     t: Longword;
   348 	t: Longword;
   349 begin
   349 begin
   350 DeleteCI(Gear);
   350 DeleteCI(Gear);
   351 
   351 
   352 if Gear^.Tex <> nil then
   352 if Gear^.Tex <> nil then
   353 	begin
   353 	begin
   369 			t:= max(Gear^.Damage, Gear^.Health);
   369 			t:= max(Gear^.Damage, Gear^.Health);
   370 			Gear^.Damage:= t;
   370 			Gear^.Damage:= t;
   371 			AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtHealthTag, t, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
   371 			AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtHealthTag, t, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
   372 			uStats.HedgehogDamaged(Gear)
   372 			uStats.HedgehogDamaged(Gear)
   373 			end;
   373 			end;
       
   374 	
   374 		team:= PHedgehog(Gear^.Hedgehog)^.Team;
   375 		team:= PHedgehog(Gear^.Hedgehog)^.Team;
   375 		if CurrentHedgehog^.Gear = Gear then
   376 		if CurrentHedgehog^.Gear = Gear then
   376 			FreeActionsList; // to avoid ThinkThread on drawned gear
   377 			FreeActionsList; // to avoid ThinkThread on drawned gear
       
   378 		
   377 		PHedgehog(Gear^.Hedgehog)^.Gear:= nil;
   379 		PHedgehog(Gear^.Hedgehog)^.Gear:= nil;
   378 		inc(KilledHHs);
   380 		inc(KilledHHs);
   379 		RecountTeamHealth(team);
   381 		RecountTeamHealth(team)
   380 		end;
   382 		end;
   381 
       
   382 {$IFDEF DEBUGFILE}
   383 {$IFDEF DEBUGFILE}
   383 with Gear^ do AddFileLog('Delete: #' + inttostr(uid) + ' (' + inttostr(hwRound(x)) + ',' + inttostr(hwRound(y)) + '), d(' + floattostr(dX) + ',' + floattostr(dY) + ') type = ' + inttostr(ord(Kind)));
   384 with Gear^ do AddFileLog('Delete: #' + inttostr(uid) + ' (' + inttostr(hwRound(x)) + ',' + inttostr(hwRound(y)) + '), d(' + floattostr(dX) + ',' + floattostr(dY) + ') type = ' + inttostr(ord(Kind)));
   384 {$ENDIF}
   385 {$ENDIF}
   385 
   386 
   386 if Gear^.TriggerId <> 0 then TickTrigger(Gear^.TriggerId);
   387 if Gear^.TriggerId <> 0 then TickTrigger(Gear^.TriggerId);
   387 if CurAmmoGear = Gear then CurAmmoGear:= nil;
   388 if CurAmmoGear = Gear then CurAmmoGear:= nil;
   388 if FollowGear = Gear then FollowGear:= nil;
   389 if FollowGear = Gear then FollowGear:= nil;
   389 RemoveGearFromList(Gear);
   390 RemoveGearFromList(Gear);
   390 
   391 
   391 Dispose(Gear);
   392 Dispose(Gear)
   392 
       
   393 Gear:= nil
       
   394 end;
   393 end;
   395 
   394 
   396 function CheckNoDamage: boolean; // returns TRUE in case of no damaged hhs
   395 function CheckNoDamage: boolean; // returns TRUE in case of no damaged hhs
   397 var Gear: PGear;
   396 var Gear: PGear;
   398 begin
   397 begin
  1115 	end;
  1114 	end;
  1116 end;
  1115 end;
  1117 
  1116 
  1118 procedure AddMiscGears;
  1117 procedure AddMiscGears;
  1119 var i: LongInt;
  1118 var i: LongInt;
       
  1119 	Gear: PGear;
  1120 begin
  1120 begin
  1121 AddGear(0, 0, gtATStartGame, 0, _0, _0, 2000);
  1121 AddGear(0, 0, gtATStartGame, 0, _0, _0, 2000);
  1122 
  1122 
  1123 if (GameFlags and gfForts) = 0 then
  1123 if (GameFlags and gfForts) = 0 then
  1124 	for i:= 0 to Pred(cLandAdditions) do
  1124 	for i:= 0 to Pred(cLandAdditions) do
  1125 		FindPlace(AddGear(0, 0, gtMine, 0, _0, _0, 0), false, 0, 2048);
  1125 		begin
       
  1126 		Gear:= AddGear(0, 0, gtMine, 0, _0, _0, 0);
       
  1127 		FindPlace(Gear, false, 0, 2048)
       
  1128 		end
  1126 end;
  1129 end;
  1127 
  1130 
  1128 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord);
  1131 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord);
  1129 var Gear: PGear;
  1132 var Gear: PGear;
  1130     dmg, dmgRadius: LongInt;
  1133     dmg, dmgRadius: LongInt;
  1266 SetAllToActive
  1269 SetAllToActive
  1267 end;
  1270 end;
  1268 
  1271 
  1269 procedure AssignHHCoords;
  1272 procedure AssignHHCoords;
  1270 var i, t, p, j: LongInt;
  1273 var i, t, p, j: LongInt;
  1271     ar: array[0..Pred(cMaxHHs)] of PGear;
  1274     ar: array[0..Pred(cMaxHHs)] of PHedgehog;
  1272     Count: Longword;
  1275     Count: Longword;
  1273 begin
  1276 begin
  1274 if (GameFlags and (gfForts or gfDivideTeams)) <> 0 then
  1277 if (GameFlags and (gfForts or gfDivideTeams)) <> 0 then
  1275 	begin
  1278 	begin
  1276 	t:= 0;
  1279 	t:= 0;
  1282 				with Teams[j]^ do
  1285 				with Teams[j]^ do
  1283 					for i:= 0 to cMaxHHIndex do
  1286 					for i:= 0 to cMaxHHIndex do
  1284 						with Hedgehogs[i] do
  1287 						with Hedgehogs[i] do
  1285 							if (Gear <> nil) and (Gear^.X.QWordValue = 0) then
  1288 							if (Gear <> nil) and (Gear^.X.QWordValue = 0) then
  1286 								begin
  1289 								begin
  1287 								FindPlace(Gear, false, t, t + 1024);
  1290 								FindPlace(Gear, false, t, t + 1024);// could make Gear == nil
  1288 								Gear^.Pos:= GetRandom(19);
  1291 								if Gear <> nil then
  1289 								Gear^.dX.isNegative:= p = 1;
  1292 									begin
       
  1293 									Gear^.Pos:= GetRandom(19);
       
  1294 									Gear^.dX.isNegative:= p = 1;
       
  1295 									end
  1290 								end;
  1296 								end;
  1291 		inc(t, 1024)
  1297 		inc(t, 1024)
  1292 		end
  1298 		end
  1293 	end else // mix hedgehogs
  1299 	end else // mix hedgehogs
  1294 	begin
  1300 	begin
  1298 		begin
  1304 		begin
  1299 		for i:= 0 to cMaxHHIndex do
  1305 		for i:= 0 to cMaxHHIndex do
  1300 			with Hedgehogs[i] do
  1306 			with Hedgehogs[i] do
  1301 				if (Gear <> nil) and (Gear^.X.QWordValue = 0) then
  1307 				if (Gear <> nil) and (Gear^.X.QWordValue = 0) then
  1302 					begin
  1308 					begin
  1303 					ar[Count]:= Gear;
  1309 					ar[Count]:= @Hedgehogs[i];
  1304 					inc(Count)
  1310 					inc(Count)
  1305 					end;
  1311 					end;
  1306 		end;
  1312 		end;
  1307 
  1313 
  1308 	while (Count > 0) do
  1314 	while (Count > 0) do
  1309 		begin
  1315 		begin
  1310 		i:= GetRandom(Count);
  1316 		i:= GetRandom(Count);
  1311 		FindPlace(ar[i], false, 0, 2048);
  1317 		FindPlace(ar[i]^.Gear, false, 0, 2048);
  1312 		ar[i]^.dX.isNegative:= ar[i]^.X > _1024;
  1318 		if ar[i]^.Gear <> nil then
  1313 		ar[i]^.Pos:= GetRandom(19);
  1319 			begin
  1314 		ar[i]:= ar[Count - 1];
  1320 			ar[i]^.Gear^.dX.isNegative:= ar[i]^.Gear^.X > _1024;
       
  1321 			ar[i]^.Gear^.Pos:= GetRandom(19);
       
  1322 			ar[i]:= ar[Count - 1]
       
  1323 			end;
  1315 		dec(Count)
  1324 		dec(Count)
  1316 		end
  1325 		end
  1317 	end
  1326 	end
  1318 end;
  1327 end;
  1319 
  1328 
  1360 begin
  1369 begin
  1361 t:= GearsList;
  1370 t:= GearsList;
  1362 rX:= sqr(rX);
  1371 rX:= sqr(rX);
  1363 rY:= sqr(rY);
  1372 rY:= sqr(rY);
  1364 while t <> nil do
  1373 while t <> nil do
  1365       begin
  1374 	begin
  1366       if t^.Kind in Kind then
  1375 	if t^.Kind in Kind then
  1367          if not (hwSqr(int2hwFloat(mX) - t^.X) / rX + hwSqr(int2hwFloat(mY) - t^.Y) / rY > _1) then
  1376 		if not (hwSqr(int2hwFloat(mX) - t^.X) / rX + hwSqr(int2hwFloat(mY) - t^.Y) / rY > _1) then
  1368             exit(t);
  1377 			exit(t);
  1369       t:= t^.NextGear
  1378 	t:= t^.NextGear
  1370       end;
  1379 	end;
  1371 CheckGearsNear:= nil
  1380 CheckGearsNear:= nil
  1372 end;
  1381 end;
  1373 
  1382 
  1374 function CountGears(Kind: TGearType): Longword;
  1383 function CountGears(Kind: TGearType): Longword;
  1375 var t: PGear;
  1384 var t: PGear;
  1376     Result: Longword;
  1385     Result: Longword;
  1377 begin
  1386 begin
  1378 Result:= 0;
  1387 Result:= 0;
  1379 t:= GearsList;
  1388 t:= GearsList;
  1380 while t <> nil do
  1389 while t <> nil do
  1381       begin
  1390 	begin
  1382       if t^.Kind = Kind then inc(Result);
  1391 	if t^.Kind = Kind then inc(Result);
  1383       t:= t^.NextGear
  1392 	t:= t^.NextGear
  1384       end;
  1393 	end;
  1385 CountGears:= Result
  1394 CountGears:= Result
  1386 end;
  1395 end;
  1387 
  1396 
  1388 procedure SpawnBoxOfSmth;
  1397 procedure SpawnBoxOfSmth;
  1389 var t: LongInt;
  1398 var t: LongInt;
  1417         end;
  1426         end;
  1418      end;
  1427      end;
  1419 FindPlace(FollowGear, true, 0, 2048)
  1428 FindPlace(FollowGear, true, 0, 2048)
  1420 end;
  1429 end;
  1421 
  1430 
  1422 procedure FindPlace(Gear: PGear; withFall: boolean; Left, Right: LongInt);
  1431 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt);
  1423 
  1432 
  1424     function CountNonZeroz(x, y, r: LongInt): LongInt;
  1433 	function CountNonZeroz(x, y, r: LongInt): LongInt;
  1425     var i: LongInt;
  1434 	var i: LongInt;
  1426         Result: LongInt;
  1435 		Result: LongInt;
  1427     begin
  1436 	begin
  1428     Result:= 0;
  1437 	Result:= 0;
  1429     if (y and $FFFFFC00) = 0 then
  1438 	if (y and $FFFFFC00) = 0 then
  1430       for i:= max(x - r, 0) to min(x + r, 2043) do
  1439 		for i:= max(x - r, 0) to min(x + r, 2043) do
  1431         if Land[y, i] <> 0 then inc(Result);
  1440 			if Land[y, i] <> 0 then inc(Result);
  1432     CountNonZeroz:= Result
  1441 	CountNonZeroz:= Result
  1433     end;
  1442 	end;
  1434 
  1443 
  1435 var x: LongInt;
  1444 var x: LongInt;
  1436     y, sy: LongInt;
  1445 	y, sy: LongInt;
  1437     ar: array[0..511] of TPoint;
  1446 	ar: array[0..511] of TPoint;
  1438     ar2: array[0..1023] of TPoint;
  1447 	ar2: array[0..1023] of TPoint;
  1439     cnt, cnt2: Longword;
  1448 	cnt, cnt2: Longword;
  1440     delta: LongInt;
  1449 	delta: LongInt;
  1441 begin
  1450 begin
  1442 delta:= 250;
  1451 delta:= 250;
  1443 cnt2:= 0;
  1452 cnt2:= 0;
  1444 repeat
  1453 repeat
  1445   x:= Left + LongInt(GetRandom(Delta));
  1454 	x:= Left + LongInt(GetRandom(Delta));
  1446   repeat
  1455 	repeat
  1447      inc(x, Delta);
  1456 		inc(x, Delta);
  1448      cnt:= 0;
  1457 		cnt:= 0;
  1449      y:= -Gear^.Radius * 2;
  1458 		y:= -Gear^.Radius * 2;
  1450      while y < 1023 do
  1459 		while y < 1023 do
  1451         begin
  1460 			begin
  1452         repeat
  1461 			repeat
  1453          inc(y, 2);
  1462 				inc(y, 2);
  1454         until (y > 1023) or (CountNonZeroz(x, y, Gear^.Radius - 1) = 0);
  1463 			until (y > 1023) or (CountNonZeroz(x, y, Gear^.Radius - 1) = 0);
  1455         sy:= y;
  1464 			
  1456         repeat
  1465 			sy:= y;
  1457           inc(y);
  1466 
  1458         until (y > 1023) or (CountNonZeroz(x, y, Gear^.Radius - 1) <> 0);
  1467 			repeat
  1459         if (y - sy > Gear^.Radius * 2)
  1468 				inc(y);
  1460         and (y < 1023)
  1469 			until (y > 1023) or (CountNonZeroz(x, y, Gear^.Radius - 1) <> 0);
  1461         and (CheckGearsNear(x, y - Gear^.Radius, [gtHedgehog, gtMine, gtCase], 110, 110) = nil) then
  1470 			
  1462            begin
  1471 			if (y - sy > Gear^.Radius * 2)
  1463            ar[cnt].X:= x;
  1472 				and (y < 1023)
  1464            if withFall then ar[cnt].Y:= sy + Gear^.Radius
  1473 				and (CheckGearsNear(x, y - Gear^.Radius, [gtHedgehog, gtMine, gtCase], 110, 110) = nil) then
  1465                        else ar[cnt].Y:= y - Gear^.Radius;
  1474 				begin
  1466            inc(cnt)
  1475 				ar[cnt].X:= x;
  1467            end;
  1476 				if withFall then ar[cnt].Y:= sy + Gear^.Radius
  1468         inc(y, 45)
  1477 							else ar[cnt].Y:= y - Gear^.Radius;
  1469         end;
  1478 				inc(cnt)
  1470      if cnt > 0 then
  1479 				end;
  1471         with ar[GetRandom(cnt)] do
  1480 			
  1472           begin
  1481 			inc(y, 45)
  1473           ar2[cnt2].x:= x;
  1482 			end;
  1474           ar2[cnt2].y:= y;
  1483 		
  1475           inc(cnt2)
  1484 		if cnt > 0 then
  1476           end
  1485 			with ar[GetRandom(cnt)] do
  1477   until (x + Delta > Right);
  1486 				begin
  1478 dec(Delta, 60)
  1487 				ar2[cnt2].x:= x;
       
  1488 				ar2[cnt2].y:= y;
       
  1489 				inc(cnt2)
       
  1490 				end
       
  1491 	until (x + Delta > Right);
       
  1492 	dec(Delta, 60)
  1479 until (cnt2 > 0) or (Delta < 70);
  1493 until (cnt2 > 0) or (Delta < 70);
       
  1494 
  1480 if cnt2 > 0 then
  1495 if cnt2 > 0 then
  1481    with ar2[GetRandom(cnt2)] do
  1496 	with ar2[GetRandom(cnt2)] do
  1482       begin
  1497 		begin
  1483       Gear^.X:= int2hwFloat(x);
  1498 		Gear^.X:= int2hwFloat(x);
  1484       Gear^.Y:= int2hwFloat(y);
  1499 		Gear^.Y:= int2hwFloat(y);
  1485       {$IFDEF DEBUGFILE}
  1500 		{$IFDEF DEBUGFILE}
  1486       AddFileLog('Assigned Gear coordinates (' + inttostr(x) + ',' + inttostr(y) + ')');
  1501 		AddFileLog('Assigned Gear coordinates (' + inttostr(x) + ',' + inttostr(y) + ')');
  1487       {$ENDIF}
  1502 		{$ENDIF}
  1488       end
  1503 		end
  1489    else
  1504 	else
  1490    begin
  1505 	begin
  1491    OutError('Can''t find place for Gear', false);
  1506 	OutError('Can''t find place for Gear', false);
  1492    DeleteGear(Gear)
  1507 	DeleteGear(Gear);
  1493    end
  1508 	Gear:= nil
       
  1509 	end
  1494 end;
  1510 end;
  1495 
  1511 
  1496 initialization
  1512 initialization
  1497 
  1513 
  1498 finalization
  1514 finalization