Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- include("CitySupport");
- include("ProductionHelper");
- include("SupportFunctions"); --Split
- -- When there aren't any more buildings to build, Cities will do a project
- local Idle_AddProject:boolean = true;
- -- Once the first project has been added, nomore projects will be added to the queue, prevents all the other list entries from being picked
- local Idle_SingleProjectLimit:boolean = false;
- -- Should we be able to repair buildings?
- local Repairs:boolean = true;
- -- Should Repairing be prioritize above the QueueList?
- local Repairs_Prioritize:boolean = true;
- local SortedQueue_Buildings:table = {{}};
- -- Projects will be attempted to be added in the following order, projects not in the list will not be picked
- local SortedQueue_Projects:table = {{}};
- local Debugging:boolean = false;
- local CurrentCity:table;
- function debugPrint(Message:string)
- if (Debugging) then
- print(Message);
- end
- end
- function AddToTable(List)
- local Result:table = {};
- for Item in List do
- table.insert(Result, Item);
- end
- return Result;
- end
- -- Copied and modified from ProductionPanel.lua
- function IsBuildQueueFull(City:table)
- if City then
- local BuildQueue = City:GetBuildQueue();
- if (BuildQueue ~= nil) then
- local iQueueSize:number = BuildQueue:GetSize();
- if ((iQueueSize - 1) >= MAX_QUEUE_SIZE) then
- return true;
- end
- end
- end
- return false;
- end
- function IsBuildQueueEmpty(City:table)
- if City then
- local BuildQueue = City:GetBuildQueue();
- if (BuildQueue ~= nil) then
- local iQueueSize:number = BuildQueue:GetSize();
- if (iQueueSize > 0) then
- return false;
- end
- end
- end
- return true;
- end
- function BuildBuilding(City:table, Building:table)
- local tParameters = {};
- tParameters[CityOperationTypes.PARAM_BUILDING_TYPE] = Building.Hash;
- tParameters[CityOperationTypes.PARAM_INSERT_MODE] = CityOperationTypes.VALUE_APPEND;
- CityManager.RequestOperation(City, CityOperationTypes.BUILD, tParameters);
- end
- function BuildProject(City:table, Project:table)
- local tParameters = {};
- tParameters[CityOperationTypes.PARAM_PROJECT_TYPE] = Project.Hash;
- tParameters[CityOperationTypes.PARAM_INSERT_MODE] = CityOperationTypes.VALUE_APPEND;
- CityManager.RequestOperation(City, CityOperationTypes.BUILD, tParameters);
- end
- function BuildDistrict(City:table, District:table)
- local tParameters = {};
- tParameters[CityOperationTypes.PARAM_DISTRICT_TYPE] = District.Hash;
- tParameters[CityOperationTypes.PARAM_INSERT_MODE] = CityOperationTypes.VALUE_APPEND;
- CityManager.RequestOperation(City, CityOperationTypes.BUILD, tParameters);
- end
- function OnProductionPanelOpen()
- CurrentCity = UI.GetHeadSelectedCity();
- if (CurrentCity == nil) then
- return;
- end
- local ProductionPanel:table = ContextPtr:LookUpControl("/InGame/ProductionPanel");
- Controls.ButtonContainer:ChangeParent(ProductionPanel);
- Controls.Button:RegisterCallback(Mouse.eLClick, ToggleActive);
- UpdateToggle();
- ContextPtr:SetHide(false);
- end
- function ExistsInTable(Source:table, Find:string)
- for _, Value in ipairs(Source) do
- if (Value == Find) then
- return true;
- end
- end
- return false;
- end
- function CityExists(CityID:number)
- for _, ID in ipairs(ExposedMembers.AutoQueue.Cities) do
- if (ID == CityID) then
- return true;
- end
- end
- return false;
- end
- function RemoveCity(CityID:number)
- for Key, Value in pairs(ExposedMembers.AutoQueue.Cities) do
- if (Value == CityID) then
- table.remove(ExposedMembers.AutoQueue.Cities, Key);
- ExposedMembers.AutoQueue.Save();
- break;
- end
- end
- end
- function ToggleActive()
- local CityID = CurrentCity:GetID();
- if CityExists(CityID) then
- RemoveCity(CityID);
- else
- table.insert(ExposedMembers.AutoQueue.Cities, CityID);
- ExposedMembers.AutoQueue.Save();
- CheckCity(Game.GetLocalPlayer(), CityID);
- end
- UpdateToggle();
- end
- function UpdateToggle()
- local CityID = CurrentCity:GetID();
- if CityExists(CityID) then
- Controls.ToggleLabel:SetText(Locale.Lookup("LOC_AUTOQUEUE_ON"));
- Controls.ToggleLabel:SetColorByName("StatGoodCS");
- else
- Controls.ToggleLabel:SetText(Locale.Lookup("LOC_AUTOQUEUE_OFF"));
- Controls.ToggleLabel:SetColorByName("White");
- end
- end
- function GetQueueTypeNames(City:table)
- local TypeNames:table = {};
- local BuildQueue:table = City:GetBuildQueue();
- -- The current Production is at 0, there are 8 Queue slot in total, 1 more than what's described in MAX_QUEUE_SIZE
- for i = 0, (MAX_QUEUE_SIZE + 1) do
- local Entry:table = BuildQueue:GetAt(i);
- if Entry then
- local TypeName:string = nil;
- if (Entry.Directive == CityProductionDirectives.TRAIN) then
- TypeName = GameInfo.Units[Entry.UnitType].UnitType;
- elseif (Entry.Directive == CityProductionDirectives.CONSTRUCT) then
- TypeName = GameInfo.Buildings[Entry.BuildingType].BuildingType;
- elseif (Entry.Directive == CityProductionDirectives.ZONE) then
- TypeName = GameInfo.Districts[Entry.DistrictType].DistrictType;
- elseif (Entry.Directive == CityProductionDirectives.PROJECT) then
- TypeName = GameInfo.Projects[Entry.ProjectType].ProjectType;
- end
- -- TypeName isn't Nil and the TypeName hasn't been added yet
- if (TypeName and (not ExistsInTable(TypeNames, TypeName))) then
- table.insert(TypeNames, TypeName);
- end
- end
- end
- return TypeNames;
- end
- function CheckRepairs(City:table)
- if Repairs then
- local CityDistricts:table = City:GetDistricts();
- local BuildQueue:table = City:GetBuildQueue();
- local QueuedTypeNames:table = GetQueueTypeNames(City);
- local Project:table = GameInfo.Projects["PROJECT_REPAIR_OUTER_DEFENSES"];
- if (not IsBuildQueueFull(City)) then
- if (not ExistsInTable(QueuedTypeNames, Project.ProjectType)) then
- table.insert(QueuedTypeNames, Project.ProjectType);
- BuildProject(City, Project);
- end
- end
- for i, District in CityDistricts:Members() do
- local Plot:table = Map.GetPlot(District:GetX(), District:GetY());
- if CityDistricts:IsPillaged(District:GetType(), Plot) then
- local DistrictInfo:table = GameInfo.Districts[District:GetType()];
- if (not IsBuildQueueFull(City)) then
- -- Don't add it if it exists in the Queue
- if (not ExistsInTable(QueuedTypeNames, District.DistrictType)) then
- table.insert(QueuedTypeNames, District.DistrictType);
- BuildDistrict(City, DistrictInfo);
- end
- else
- -- Build Queue is full, don't add more to it
- break;
- end
- end
- end
- local Buildings:table = City:GetBuildings();
- for Building in GameInfo.Buildings() do
- if Buildings:HasBuilding(Building.Index) then
- if Buildings:IsPillaged(Building.BuildingType) then
- if (not IsBuildQueueFull(City)) then
- -- Don't add it if it exists in the Queue
- if (not ExistsInTable(QueuedTypeNames, Building.BuildingType)) then
- table.insert(QueuedTypeNames, Building.BuildingType);
- BuildBuilding(City, Building);
- end
- else
- -- Build Queue is full, don't add more to it
- break;
- end
- end
- end
- end
- end
- end
- function CheckCity(PlayerID:number, CityID:number)
- local City:table = CityManager.GetCity(PlayerID, CityID);
- if (City == nil) then
- return;
- end
- if IsBuildQueueFull(City) then
- -- Queue is full, do nothing
- return;
- end
- local BuildQueue:table = City:GetBuildQueue();
- local CanProduceAnything:boolean = false;
- local Buildings:table = City:GetBuildings();
- local QueuedTypeNames:table = GetQueueTypeNames(City);
- if Repairs_Prioritize then
- CheckRepairs(City);
- end
- debugPrint("CheckCity");
- for _, Item in ipairs(ExposedMembers.AutoQueue.SortedQueue_Buildings) do
- local Building:table = GameInfo.Buildings[Item.ObjectID];
- local CanProduce = BuildQueue:CanProduce(Building.Hash, true);
- if CanProduce then
- CanProduceAnything = true;
- if (not IsBuildQueueFull(City)) then
- -- Don't add it if it exists in the Queue
- if (not ExistsInTable(QueuedTypeNames, Building.BuildingType)) then
- table.insert(QueuedTypeNames, Building.BuildingType);
- BuildBuilding(City, Building);
- end
- else
- -- Build Queue is full, don't add more to it
- break;
- end
- end
- end
- -- There is nothing queued right now, look for an available project
- if (IsBuildQueueEmpty(City) and Idle_AddProject) then
- debugPrint("Queue is empty");
- local NoCurrentProject:boolean = true;
- if Idle_SingleProjectLimit then
- for row in GameInfo.Projects() do
- if ExistsInTable(QueuedTypeNames, row.ProjectType) then
- -- There's already a Project running, do not add more
- NoCurrentProject = false;
- break;
- end
- end
- end
- if NoCurrentProject then
- debugPrint("No current project");
- for _, Item in ipairs(ExposedMembers.AutoQueue.SortedQueue_Projects) do
- local Project:table = GameInfo.Projects[Item.ObjectID];
- if (Project ~= nil) then
- local CanProduce = BuildQueue:CanProduce(Project.Hash, true);
- if CanProduce then
- debugPrint("Can product project");
- if (not IsBuildQueueFull(City)) then
- -- Don't add it if it exists in the Queue
- debugPrint("Build queue is not full");
- if (not ExistsInTable(QueuedTypeNames, Project.ProjectType)) then
- debugPrint("Build the project");
- table.insert(QueuedTypeNames, Project.ProjectType);
- BuildProject(City, Project);
- end
- if Idle_SingleProjectLimit then
- break;
- end
- else
- -- Build Queue is full, don't add more to it
- break;
- end
- end
- end
- end
- end
- end
- CheckRepairs(City);
- end
- function OnCitySelectionChanged(PlayerID:number, CityID:number, i, j, k, isSelected:boolean, isEditable:boolean)
- CurrentCity = UI.GetHeadSelectedCity();
- if (CurrentCity == nil) then
- return;
- end
- UpdateToggle();
- end
- function UpdateCities(PlayerID:number)
- for Key, Value in pairs(ExposedMembers.AutoQueue.Cities) do
- if (Value ~= nil) then
- local City = CityManager.GetCity(PlayerID, Value);
- if (City ~= nil) then
- CheckCity(PlayerID, Value);
- else
- -- City is either destroyed or captured by another player
- RemoveCity(Value);
- end
- end
- end
- end
- function Save()
- local PlayerConfig = PlayerConfigurations[Game.GetLocalPlayer()];
- if PlayerConfig then
- -- SetValue only supports string values
- PlayerConfig:SetValue("ExposedMembers_AutoQueue_Cities", Serialize(ExposedMembers.AutoQueue.Cities));
- end
- end
- function OnLoadComplete(Result, Type, Options, FileType)
- local PlayerConfig = PlayerConfigurations[Game.GetLocalPlayer()];
- if PlayerConfig then
- local Cities = Deserialize(PlayerConfig:GetValue("ExposedMembers_AutoQueue_Cities"));
- if Cities then
- ExposedMembers.AutoQueue.Cities = Cities;
- end
- end
- end
- function Serialize(Input:table)
- local Output:string = "";
- for Key, Value in ipairs(Input) do
- Output = Output .. tostring(Value) .. ",";
- end
- return Output;
- end
- function Deserialize(Input:string)
- local Output:table = {};
- for Key, Value in ipairs(Split(Input, ",")) do
- table.insert(Output, tonumber(Value));
- end
- return Output;
- end
- function Initialize()
- if (not ExposedMembers.AutoQueue) then
- ExposedMembers.AutoQueue = {};
- end
- LuaEvents.ProductionPanel_Open.Add(OnProductionPanelOpen);
- Events.CitySelectionChanged.Add(OnCitySelectionChanged);
- Events.LoadComplete.Add(OnLoadComplete);
- SortedQueue_Buildings = AddToTable(GameInfo.QueueOrder_Buildings());
- table.sort(SortedQueue_Buildings, function(a, b) return (a.Priority < b.Priority); end);
- SortedQueue_Projects = AddToTable(GameInfo.QueueOrder_Projects());
- table.sort(SortedQueue_Projects, function(a, b) return (a.Priority < b.Priority); end);
- ExposedMembers.AutoQueue.SortedQueue_Buildings = SortedQueue_Buildings;
- ExposedMembers.AutoQueue.SortedQueue_Projects = SortedQueue_Projects;
- ExposedMembers.AutoQueue.Cities = {};
- ExposedMembers.AutoQueue.CheckCity = CheckCity;
- ExposedMembers.AutoQueue.CityExists = CityExists;
- ExposedMembers.AutoQueue.RemoveCity = RemoveCity;
- ExposedMembers.AutoQueue.Save = Save;
- end
- Initialize();
Add Comment
Please, Sign In to add comment