

function GetHouseWares(aHouse : Integer) : array of Integer;
var aType : Integer;
begin
	aType := S.HouseType(aHouse);
	Result := [];
	case aType of 
		0: Result := [2];
		1: Result := [3,5,6];
		2: Result := [5,6,23,21,25];
		3: Result := [5];
		4: Result := [3];
		5: Result := [4];
		6: Result := [27];
		7: Result := [10,11];
		8: Result := [9];
		9: Result := [0];
		10: Result := [5,6,17,19];
		11: Result := [];
		12: Result := [9,26];
		13: Result := [7];
		14: Result := [1];
		15: Result := [5,3,7];
		16: Result := [9,14,15];
		17: Result := [1];
		18: Result := [7];
		19: Result := [2,20,22,24];
		20: Result := [2,12,16,18];
		21: Result := [];
		22: Result := [9,11];
		23: Result := [];
		24: Result := [13,14];
		25: Result := [15,12];
		26: Result := [];
		27: Result := [8,10,13,27];
		28: Result := [8];
		29: Result := [];
	end;
end;

Procedure FillHouse(aHouse :Integer;  isRandom : Boolean);
var K : Integer;
	WaresToAdd : array of Integer;
begin
	WaresToAdd := GetHouseWares(aHouse);
	If length(WaresToAdd) > 0 then 
		for K := 0 to high(WaresToAdd) do 
			If isRandom then 
				A.HouseAddWaresTo(aHouse, WaresToAdd[K], S.KamRandomI(5) + 1)
			else
				A.HouseAddWaresTo(aHouse, WaresToAdd[K], 5);
end;


Procedure AddUnitToHouse(aHouse :Integer;  withServant : Boolean);
var aType, aUType, aOwner : Integer;
	aPos : TKMPoint;
begin
	aType := S.HouseType(aHouse);
	aUType := S.HouseTypeToOccupantType(aType);
	aPos := S.HousePosition(aHouse);
	aOwner := S.HouseOwner(aHouse);
	If not S.HouseHasWorker(aHouse) then 
		A.GiveUnit(aOwner, aUType, aPos.X, aPos.Y + 1, 4);
	
	If withServant then 
		A.GiveUnit(aOwner, 0, aPos.X, aPos.Y + 1, 4);
	
end;

procedure AddWaresToHouse(aHouse : Integer; aWares, aCountFrom, aCountTo : array of Integer);
var I, WI, RR : Integer;
begin
	for I := 0 to high(aWares) do 
	begin
		WI := Maximum(I, high(aCountFrom));
		RR := aCountFrom[WI] + S.KamRandomI(aCountTo[WI] - aCountFrom[WI] );
		A.HouseAddWaresTo(aHouse, aWares[I], RR);
	end;
end;

procedure AddWaresToPlStores(aPlayer : Integer; aWares, aCountFrom, aCountTo : array of Integer);
var I : Integer;
begin
	With HKS_Players[aPlayer].Houses[11] do 
		If Length(IDs) > 0 then 			
			for I := 0 to high(IDs) do 
				AddWaresToHouse(IDs[I], aWares, aCountFrom, aCountTo);
end;

procedure AddWaresToPlBarracks(aPlayer : Integer; aWares, aCountFrom, aCountTo : array of Integer);
var I : Integer;
begin
	With HKS_Players[aPlayer].Houses[21] do 
		If Length(IDs) > 0 then 			
			for I := 0 to high(IDs) do 
				AddWaresToHouse(IDs[I], aWares, aCountFrom, aCountTo);
end;


Procedure FillPlayerHouses(aPlayers : array of Integer;  isRandom : Boolean);
var I, J : Integer;
	anArray : array of Integer;
begin
	If Length(aPlayers) = 0 then 
		Exit;


	for I := 0 to high(aPlayers) do
	begin
		anArray := States.PlayerGetAllHouses(aPlayers[I]);
		If length(anArray) > 0 then 
			for J := 0 to high(anArray) do
				FillHouse(anArray[J], isRandom);
	
	end;
end;

Procedure AddUnitsToPlayer(aPlayers : array of Integer;  withServant : Boolean);
var I, J : Integer;
	anArray : array of Integer;
begin
	If Length(aPlayers) = 0 then 
		Exit;


	for I := 0 to high(aPlayers) do
	begin
		anArray := States.PlayerGetAllHouses(aPlayers[I]);
		If length(anArray) > 0 then 
			for J := 0 to high(anArray) do
				AddUnitToHouse(anArray[J], withServant);
	
	end;
end;

procedure ChangeHouseOwner(aHouse, newOwner : Integer; rememberHeight, WithWares : Boolean);
var aX, aY, I: Integer;
	HH : KD_HouseStats;
	WW : KD_UnitStats;
	aHeight : array[0..8] of array[0..8] of Integer;
begin
	HH := SetHouse(aHouse, true);
	If HH.aOwner = newOwner then 
		Exit;
	If rememberHeight then 
	begin
		for aX := -4 to 4 do 
			for aY := -4 to 4 do 
				aHeight[aX + 4][aY + 4] := S.MapTileHeight(aX + HH.aPos.X,aY + HH.aPos.Y);
	end;
	A.HouseDestroy(aHouse, true);
	
	HH.aID := A.GiveHouse(newOwner, HH.aType, HH.aPos.X, HH.aPos.Y);
	
	If rememberHeight then 
	begin
		for aX := -4 to 4 do 
			for aY := -4 to 4 do 
				A.MapTileHeightSet(aX + HH.aPos.X,aY + HH.aPos.Y,aHeight[aX + 4][aY + 4]);
	end;
	If HH.aType in [11, 21, 27] then 
		If WithWares then 
			for I := 0 to 27 do 
				A.HouseAddWaresTo(HH.aID, I, HH.Wares[I]);
	If HH.aWorker > 0 then 
	begin
		SetUnit(HH.aWorker, WW);
		A.UnitKill(HH.aWorker, true);
		A.GiveUnit(newOwner, WW.aType, HH.aPos.X, HH.aPos.Y + 1, 4);
	end;
end;

procedure ChangeHousesOwner(aHouse : array of Integer; newOwner : Integer; rememberHeight, WithWares : Boolean);
var I : Integer;
begin
	If length(aHouse) = 0 then 
		Exit;
	for I := 0 to high(aHouse) do 
		ChangeHouseOwner(aHouse[I], newOwner, rememberHeight, WithWares);
end;

function ChangeGroupOwner(aGroup, aNewOwner : Integer) : Integer;
var GG : KD_GroupStats;
begin
	GG := SetGroup(aGroup);
	GG.aOwner := aNewOwner;
	A.GroupKillAll(aGroup, true);
	Result := GiveKDGroup(GG);
	A.GroupOrderHalt(Result);
end;

procedure ChangeGroupsOwner(aGroups : array of Integer; newOwner : Integer);
var I : Integer;
begin
	If length(aGroups) = 0 then 
		Exit;
	for I := 0 to high(aGroups) do 
		ChangeGroupOwner(aGroups[I], newOwner);
end;

function ChangeUnitOwner(aUnit, aNewOwner : Integer) : Integer;
var UU : KD_UnitStats;
begin
	SetUnit(aUnit, UU);
	If UU.aType >= 14 then 
		Exit;
		
	UU.Owner := aNewOwner;
	A.UnitKill(aUnit, true);
	
	result := GiveKDUnit(UU);
end;

procedure ChangeUnitsOwner(aUnits : array of Integer; newOwner : Integer);
var I : Integer;
begin
	If length(aUnits) = 0 then 
		Exit;
		
	for I := 0 to high(aUnits) do 
		ChangeUnitOwner(aUnits[I], newOwner);
end;

procedure ChangePlayerOwner(aPlayer, newPlayer : Integer; withWares : Boolean);
begin
	ChangeGroupsOwner(S.PlayerGetAllGroups(aPlayer), newPlayer);
	ChangeHousesOwner(S.PlayerGetAllHouses(aPlayer), newPlayer, false, withWares);
	ChangeUnitsOwner(S.PlayerGetAllUnits(aPlayer), newPlayer);
	
end;