Add distributed-builder.ank
This commit is contained in:
		
							parent
							
								
									11afcc4162
								
							
						
					
					
						commit
						91829b2e8e
					
				
							
								
								
									
										440
									
								
								distributed-builder.ank
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										440
									
								
								distributed-builder.ank
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,440 @@
 | 
				
			|||||||
 | 
					// =============================================================================
 | 
				
			||||||
 | 
					// OGame Ninja Multi-Planet Ship Builder Script
 | 
				
			||||||
 | 
					// =============================================================================
 | 
				
			||||||
 | 
					// This script automates building ships on multiple planets, importing resources
 | 
				
			||||||
 | 
					// from a master planet when needed, and parking ships on the main planet.
 | 
				
			||||||
 | 
					// =============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ========================= CONFIGURATION =========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Target ship quantities - using NewShipsInfos() and Set() method
 | 
				
			||||||
 | 
					TARGET_SHIPS = NewShipsInfos()
 | 
				
			||||||
 | 
					TARGET_SHIPS.Set(LIGHTFIGHTER, 20000)      // Light Fighters
 | 
				
			||||||
 | 
					TARGET_SHIPS.Set(HEAVYFIGHTER, 15000)      // Heavy Fighters
 | 
				
			||||||
 | 
					TARGET_SHIPS.Set(CRUISER, 2000)            // Cruisers
 | 
				
			||||||
 | 
					TARGET_SHIPS.Set(BATTLESHIP, 1000)         // Battleships
 | 
				
			||||||
 | 
					TARGET_SHIPS.Set(LARGECARGO, 3000)         // Large Cargo
 | 
				
			||||||
 | 
					TARGET_SHIPS.Set(SMALLCARGO, 3000)         // Small Cargo
 | 
				
			||||||
 | 
					TARGET_SHIPS.Set(RECYCLER, 500)            // Recyclers
 | 
				
			||||||
 | 
					TARGET_SHIPS.Set(ESPIONAGEPROBE, 0)        // Espionage Probes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// List of planets to build ships on
 | 
				
			||||||
 | 
					BUILDER_PLANETS = ["1:2:1", "1:2:2", "1:2:3", "1:2:4", "1:2:5", "1:2:6", "1:2:7"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// *** FIX: Manually define an array of ship IDs to iterate over ***
 | 
				
			||||||
 | 
					SHIP_IDS_TO_BUILD = [LIGHTFIGHTER, HEAVYFIGHTER, CRUISER, BATTLESHIP, LARGECARGO, SMALLCARGO, RECYCLER, ESPIONAGEPROBE]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Master planet for resource imports
 | 
				
			||||||
 | 
					MASTER_PLANET = "2:2:14"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Main planet where to park all ships
 | 
				
			||||||
 | 
					MAIN_PLANET = "2:2:14"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Resource threshold - minimum resources to keep on master planet
 | 
				
			||||||
 | 
					RESOURCE_THRESHOLD = NewResources(1000000, 500000, 100000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Minimum resources needed before attempting ship building
 | 
				
			||||||
 | 
					MIN_RESOURCES_TO_BUILD = NewResources(100000, 50000, 10000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Building check interval (milliseconds)
 | 
				
			||||||
 | 
					CHECK_INTERVAL = 5 * 60 * 1000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Fleet parking interval (milliseconds)
 | 
				
			||||||
 | 
					PARKING_INTERVAL = 30 * 60 * 1000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Transport fleet configuration
 | 
				
			||||||
 | 
					TRANSPORT_SHIPS = NewShipsInfos()
 | 
				
			||||||
 | 
					TRANSPORT_SHIPS.Set(LARGECARGO, 100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ========================= GLOBAL VARIABLES =========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lastParkingCheck = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ========================= MAIN FUNCTIONS =========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
					    LogInfo("=== Multi-Planet Ship Builder Started ===")
 | 
				
			||||||
 | 
					    LogInfof("Builder planets count: %d", len(BUILDER_PLANETS))
 | 
				
			||||||
 | 
					    LogInfof("Master planet: %s", MASTER_PLANET)
 | 
				
			||||||
 | 
					    LogInfof("Main planet: %s", MAIN_PLANET)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Main loop
 | 
				
			||||||
 | 
					    for {
 | 
				
			||||||
 | 
					        LogInfo("--- Starting build cycle ---")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Check each builder planet
 | 
				
			||||||
 | 
					        for i = 0; i < len(BUILDER_PLANETS); i++ {
 | 
				
			||||||
 | 
					            planetCoord = BUILDER_PLANETS[i]
 | 
				
			||||||
 | 
					            processPlanet(planetCoord)
 | 
				
			||||||
 | 
					            Sleep(Random(2000, 5000))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Check if it's time to park fleets
 | 
				
			||||||
 | 
					        currentTime = GetTimestamp()
 | 
				
			||||||
 | 
					        if currentTime - lastParkingCheck > PARKING_INTERVAL / 1000 {
 | 
				
			||||||
 | 
					            parkAllFleets()
 | 
				
			||||||
 | 
					            lastParkingCheck = currentTime
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Print status at the end of each cycle
 | 
				
			||||||
 | 
							printStatus()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        LogInfo("--- Build cycle complete, sleeping ---")
 | 
				
			||||||
 | 
					        Sleep(CHECK_INTERVAL)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func processPlanet(planetCoord) {
 | 
				
			||||||
 | 
					    LogInfof("Processing planet: %s", planetCoord)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    planet, _ = GetPlanet(planetCoord)
 | 
				
			||||||
 | 
					    if planet == nil {
 | 
				
			||||||
 | 
					        LogErrorf("Could not get planet %s", planetCoord)
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if planet has shipyard
 | 
				
			||||||
 | 
					    facilities, _ = planet.GetFacilities()
 | 
				
			||||||
 | 
					    if facilities.Shipyard == 0 {
 | 
				
			||||||
 | 
					        LogWarnf("Planet %s has no shipyard", planetCoord)
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if shipyard is busy with buildings or ships
 | 
				
			||||||
 | 
					    bldgID, shipsCount, _ = planet.GetProduction()
 | 
				
			||||||
 | 
					    if bldgID != 0 {
 | 
				
			||||||
 | 
					        LogInfof("Shipyard is blocked by building construction on %s", planetCoord)
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if shipsCount > 0 {
 | 
				
			||||||
 | 
					        LogInfof("Shipyard already building ships on %s", planetCoord)
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get current ships on planet
 | 
				
			||||||
 | 
					    currentShips, _ = planet.GetShips()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check what ships need to be built
 | 
				
			||||||
 | 
					    shipsToBuild = calculateShipsNeeded(currentShips)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if any ships are needed
 | 
				
			||||||
 | 
					    totalNeeded = 0
 | 
				
			||||||
 | 
					    for i = 0; i < len(SHIP_IDS_TO_BUILD); i++ {
 | 
				
			||||||
 | 
					        shipID = SHIP_IDS_TO_BUILD[i]
 | 
				
			||||||
 | 
					        totalNeeded = totalNeeded + shipsToBuild.ByID(shipID)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if totalNeeded == 0 {
 | 
				
			||||||
 | 
					        LogInfof("Planet %s - No ships needed", planetCoord)
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if we have enough resources
 | 
				
			||||||
 | 
					    resources, _ = planet.GetResources()
 | 
				
			||||||
 | 
					    requiredResources = calculateRequiredResources(shipsToBuild)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    neededMetal = 0
 | 
				
			||||||
 | 
					    neededCrystal = 0
 | 
				
			||||||
 | 
					    neededDeut = 0
 | 
				
			||||||
 | 
					    if requiredResources.Metal > resources.Metal { neededMetal = requiredResources.Metal - resources.Metal }
 | 
				
			||||||
 | 
					    if requiredResources.Crystal > resources.Crystal { neededCrystal = requiredResources.Crystal - resources.Crystal }
 | 
				
			||||||
 | 
					    if requiredResources.Deuterium > resources.Deuterium { neededDeut = requiredResources.Deuterium - resources.Deuterium }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If we need resources, our only job this cycle is to try and get them.
 | 
				
			||||||
 | 
					    if neededMetal > 0 || neededCrystal > 0 || neededDeut > 0 {
 | 
				
			||||||
 | 
					        LogInfof("Planet %s needs resources. Required: M:%d C:%d D:%d", planetCoord, neededMetal, neededCrystal, neededDeut)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        fleets, slots = GetFleets()
 | 
				
			||||||
 | 
					        isReceivingTransport = false
 | 
				
			||||||
 | 
					        for i = 0; i < len(fleets); i++ {
 | 
				
			||||||
 | 
					            f = fleets[i]
 | 
				
			||||||
 | 
					            if f.Mission == TRANSPORT && f.Destination.String() == planetCoord {
 | 
				
			||||||
 | 
					                isReceivingTransport = true
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if isReceivingTransport {
 | 
				
			||||||
 | 
					            LogInfof("Waiting for incoming resources on %s.", planetCoord)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            if len(fleets) >= slots.Total {
 | 
				
			||||||
 | 
					                LogWarnf("No free fleet slot to import resources to %s.", planetCoord)
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                missingResources = NewResources(neededMetal, neededCrystal, neededDeut)
 | 
				
			||||||
 | 
					                LogInfo("Requesting resource import from master planet.")
 | 
				
			||||||
 | 
					                importResources(planetCoord, missingResources)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return // End this planet's turn. We either sent res, are waiting, or couldn't send.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If we've reached this point, we have enough resources and can try to build.
 | 
				
			||||||
 | 
					    LogInfo("Sufficient resources found. Attempting to build ships.")
 | 
				
			||||||
 | 
					    buildShips(planet, shipsToBuild, resources)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func calculateShipsNeeded(currentShips) {
 | 
				
			||||||
 | 
					    needed = NewShipsInfos()
 | 
				
			||||||
 | 
					    for i = 0; i < len(SHIP_IDS_TO_BUILD); i++ {
 | 
				
			||||||
 | 
					        shipID = SHIP_IDS_TO_BUILD[i]
 | 
				
			||||||
 | 
					        targetAmount = TARGET_SHIPS.ByID(shipID)
 | 
				
			||||||
 | 
					        currentAmount = currentShips.ByID(shipID)
 | 
				
			||||||
 | 
					        if currentAmount < targetAmount {
 | 
				
			||||||
 | 
					            stillNeeded = targetAmount - currentAmount
 | 
				
			||||||
 | 
					            buildBatch = getBuildBatchSize(shipID, stillNeeded)
 | 
				
			||||||
 | 
					            if buildBatch > 0 {
 | 
				
			||||||
 | 
					                needed.Set(shipID, buildBatch)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return needed
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getBuildBatchSize(shipID, stillNeeded) {
 | 
				
			||||||
 | 
					    batchSize = 0
 | 
				
			||||||
 | 
					    switch shipID {
 | 
				
			||||||
 | 
					    case LIGHTFIGHTER:
 | 
				
			||||||
 | 
					        batchSize = 200
 | 
				
			||||||
 | 
					    case HEAVYFIGHTER:
 | 
				
			||||||
 | 
					        batchSize = 150
 | 
				
			||||||
 | 
					    case CRUISER:
 | 
				
			||||||
 | 
					        batchSize = 50
 | 
				
			||||||
 | 
					    case BATTLESHIP:
 | 
				
			||||||
 | 
					        batchSize = 25
 | 
				
			||||||
 | 
					    case LARGECARGO:
 | 
				
			||||||
 | 
					        batchSize = 100
 | 
				
			||||||
 | 
					    case SMALLCARGO:
 | 
				
			||||||
 | 
					        batchSize = 100
 | 
				
			||||||
 | 
					    case RECYCLER:
 | 
				
			||||||
 | 
					        batchSize = 20
 | 
				
			||||||
 | 
					    case ESPIONAGEPROBE:
 | 
				
			||||||
 | 
					        batchSize = 0
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        batchSize = 10
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if stillNeeded < batchSize {
 | 
				
			||||||
 | 
					        return stillNeeded
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return batchSize
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func calculateRequiredResources(ships) {
 | 
				
			||||||
 | 
					    totalMetal = 0
 | 
				
			||||||
 | 
					    totalCrystal = 0
 | 
				
			||||||
 | 
					    totalDeut = 0
 | 
				
			||||||
 | 
					    for i = 0; i < len(SHIP_IDS_TO_BUILD); i++ {
 | 
				
			||||||
 | 
					        shipID = SHIP_IDS_TO_BUILD[i]
 | 
				
			||||||
 | 
					        quantity = ships.ByID(shipID)
 | 
				
			||||||
 | 
					        if quantity > 0 {
 | 
				
			||||||
 | 
					            cost = GetPrice(shipID, quantity)
 | 
				
			||||||
 | 
					            totalMetal += cost.Metal
 | 
				
			||||||
 | 
					            totalCrystal += cost.Crystal
 | 
				
			||||||
 | 
					            totalDeut += cost.Deuterium
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return NewResources(totalMetal, totalCrystal, totalDeut)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func importResources(targetPlanetCoord, neededResources) {
 | 
				
			||||||
 | 
					    LogInfof("Importing resources to %s", targetPlanetCoord)
 | 
				
			||||||
 | 
					    masterPlanet, _ = GetPlanet(MASTER_PLANET)
 | 
				
			||||||
 | 
					    if masterPlanet == nil {
 | 
				
			||||||
 | 
					        LogErrorf("Could not get master planet %s", MASTER_PLANET)
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    masterResources, _ = masterPlanet.GetResources()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    availableMetal = 0
 | 
				
			||||||
 | 
					    availableCrystal = 0
 | 
				
			||||||
 | 
					    availableDeut = 0
 | 
				
			||||||
 | 
					    if masterResources.Metal > RESOURCE_THRESHOLD.Metal { availableMetal = masterResources.Metal - RESOURCE_THRESHOLD.Metal }
 | 
				
			||||||
 | 
					    if masterResources.Crystal > RESOURCE_THRESHOLD.Crystal { availableCrystal = masterResources.Crystal - RESOURCE_THRESHOLD.Crystal }
 | 
				
			||||||
 | 
					    if masterResources.Deuterium > RESOURCE_THRESHOLD.Deuterium { availableDeut = masterResources.Deuterium - RESOURCE_THRESHOLD.Deuterium }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    toSendMetal = neededResources.Metal
 | 
				
			||||||
 | 
					    toSendCrystal = neededResources.Crystal
 | 
				
			||||||
 | 
					    toSendDeut = neededResources.Deuterium
 | 
				
			||||||
 | 
					    if toSendMetal > availableMetal { toSendMetal = availableMetal }
 | 
				
			||||||
 | 
					    if toSendCrystal > availableCrystal { toSendCrystal = availableCrystal }
 | 
				
			||||||
 | 
					    if toSendDeut > availableDeut { toSendDeut = availableDeut }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if toSendMetal <= 0 && toSendCrystal <= 0 && toSendDeut <= 0 {
 | 
				
			||||||
 | 
					        LogInfo("Master planet doesn't have enough resources to send")
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LogInfof("Sending: M:%d C:%d D:%d", toSendMetal, toSendCrystal, toSendDeut)
 | 
				
			||||||
 | 
					    fleet = NewFleet()
 | 
				
			||||||
 | 
					    fleet.SetOrigin(MASTER_PLANET)
 | 
				
			||||||
 | 
					    fleet.SetDestination(targetPlanetCoord)
 | 
				
			||||||
 | 
					    fleet.SetSpeed(HUNDRED_PERCENT)
 | 
				
			||||||
 | 
					    fleet.SetMission(TRANSPORT)
 | 
				
			||||||
 | 
					    fleet.SetShips(*TRANSPORT_SHIPS)
 | 
				
			||||||
 | 
					    fleet.SetResources(NewResources(toSendMetal, toSendCrystal, toSendDeut))
 | 
				
			||||||
 | 
					    _, err = fleet.SendNow()
 | 
				
			||||||
 | 
					    if err != nil {
 | 
				
			||||||
 | 
					        LogErrorf("Failed to send transport: %s", err)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        LogInfof("Transport sent to %s", targetPlanetCoord)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func buildShips(planet, shipsToBuild, resources) {
 | 
				
			||||||
 | 
					    coordinate, _ = planet.GetCoordinate()
 | 
				
			||||||
 | 
					    LogInfof("Building ships on %s", coordinate)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    availableMetal = resources.Metal
 | 
				
			||||||
 | 
					    availableCrystal = resources.Crystal
 | 
				
			||||||
 | 
					    availableDeuterium = resources.Deuterium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priorityOrder = [LARGECARGO, LIGHTFIGHTER, HEAVYFIGHTER, CRUISER, BATTLESHIP, SMALLCARGO, RECYCLER]
 | 
				
			||||||
 | 
					    for i = 0; i < len(priorityOrder); i++ {
 | 
				
			||||||
 | 
					        shipID = priorityOrder[i]
 | 
				
			||||||
 | 
					        quantity = shipsToBuild.ByID(shipID)
 | 
				
			||||||
 | 
					        if quantity > 0 {
 | 
				
			||||||
 | 
					            cost = GetPrice(shipID, quantity)
 | 
				
			||||||
 | 
					            if availableMetal >= cost.Metal && availableCrystal >= cost.Crystal && availableDeuterium >= cost.Deuterium {
 | 
				
			||||||
 | 
					                err = planet.BuildShips(shipID, quantity)
 | 
				
			||||||
 | 
					                if err != nil {
 | 
				
			||||||
 | 
					                    LogErrorf("Failed to build ships: %s", err)
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    LogInfof("Building %d %s", quantity, ID2Str(shipID))
 | 
				
			||||||
 | 
					                    availableMetal -= cost.Metal
 | 
				
			||||||
 | 
					                    availableCrystal -= cost.Crystal
 | 
				
			||||||
 | 
					                    availableDeuterium -= cost.Deuterium
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                LogInfof("Not enough resources for %d %s", quantity, ID2Str(shipID))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parkAllFleets() {
 | 
				
			||||||
 | 
					    LogInfo("=== Parking fleets on main planet ===")
 | 
				
			||||||
 | 
					    for i = 0; i < len(BUILDER_PLANETS); i++ {
 | 
				
			||||||
 | 
					        planetCoord = BUILDER_PLANETS[i]
 | 
				
			||||||
 | 
					        if planetCoord == MAIN_PLANET { continue }
 | 
				
			||||||
 | 
					        planet, _ = GetPlanet(planetCoord)
 | 
				
			||||||
 | 
					        if planet == nil { continue }
 | 
				
			||||||
 | 
					        ships, _ = planet.GetShips()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        shipsToPark = NewShipsInfos()
 | 
				
			||||||
 | 
					        if ships.ByID(LIGHTFIGHTER) > 100 { shipsToPark.Set(LIGHTFIGHTER, ships.ByID(LIGHTFIGHTER) - 100) }
 | 
				
			||||||
 | 
					        if ships.ByID(HEAVYFIGHTER) > 50 { shipsToPark.Set(HEAVYFIGHTER, ships.ByID(HEAVYFIGHTER) - 50) }
 | 
				
			||||||
 | 
					        if ships.ByID(CRUISER) > 0 { shipsToPark.Set(CRUISER, ships.ByID(CRUISER)) }
 | 
				
			||||||
 | 
					        if ships.ByID(BATTLESHIP) > 0 { shipsToPark.Set(BATTLESHIP, ships.ByID(BATTLESHIP)) }
 | 
				
			||||||
 | 
					        if ships.ByID(LARGECARGO) > 20 { shipsToPark.Set(LARGECARGO, ships.ByID(LARGECARGO) - 20) }
 | 
				
			||||||
 | 
					        if ships.ByID(SMALLCARGO) > 20 { shipsToPark.Set(SMALLCARGO, ships.ByID(SMALLCARGO) - 20) }
 | 
				
			||||||
 | 
					        if ships.ByID(RECYCLER) > 5 { shipsToPark.Set(RECYCLER, ships.ByID(RECYCLER) - 5) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        totalToPark = 0
 | 
				
			||||||
 | 
					        for j = 0; j < len(SHIP_IDS_TO_BUILD); j++ {
 | 
				
			||||||
 | 
					            shipID = SHIP_IDS_TO_BUILD[j]
 | 
				
			||||||
 | 
					            totalToPark += shipsToPark.ByID(shipID)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if totalToPark > 0 {
 | 
				
			||||||
 | 
					            fleets, slots = GetFleets()
 | 
				
			||||||
 | 
					            if len(fleets) >= slots.Total {
 | 
				
			||||||
 | 
					                LogWarnf("No free fleet slots to park ships from %s. Skipping.", planetCoord)
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            LogInfof("Parking %d ships from %s", totalToPark, planetCoord)
 | 
				
			||||||
 | 
					            fleet = NewFleet()
 | 
				
			||||||
 | 
					            fleet.SetOrigin(planetCoord)
 | 
				
			||||||
 | 
					            fleet.SetDestination(MAIN_PLANET)
 | 
				
			||||||
 | 
					            fleet.SetSpeed(HUNDRED_PERCENT)
 | 
				
			||||||
 | 
					            fleet.SetMission(PARK)
 | 
				
			||||||
 | 
					            fleet.SetShips(*shipsToPark)
 | 
				
			||||||
 | 
					            _, err = fleet.SendNow()
 | 
				
			||||||
 | 
					            if err != nil {
 | 
				
			||||||
 | 
					                LogErrorf("Failed to park fleet: %s", err)
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                LogInfof("Fleet sent to main planet from %s", planetCoord)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            LogInfof("No ships to park from %s", planetCoord)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Sleep(Random(2000, 5000))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ========================= MONITORING FUNCTIONS =========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func printStatus() {
 | 
				
			||||||
 | 
					    LogInfo("=== Current Status ===")
 | 
				
			||||||
 | 
					    totalShips = NewShipsInfos()
 | 
				
			||||||
 | 
					    uniquePlanets = []
 | 
				
			||||||
 | 
					    uniquePlanets = uniquePlanets + [MAIN_PLANET] // FIX: Use + operator instead of append
 | 
				
			||||||
 | 
					    for i = 0; i < len(BUILDER_PLANETS); i++ {
 | 
				
			||||||
 | 
					        planetCoord = BUILDER_PLANETS[i]
 | 
				
			||||||
 | 
					        isAlreadyInList = false
 | 
				
			||||||
 | 
					        for j = 0; j < len(uniquePlanets); j++ {
 | 
				
			||||||
 | 
					            if planetCoord == uniquePlanets[j] {
 | 
				
			||||||
 | 
					                isAlreadyInList = true
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if !isAlreadyInList {
 | 
				
			||||||
 | 
					            uniquePlanets = uniquePlanets + [planetCoord] // FIX: Use + operator instead of append
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for i = 0; i < len(uniquePlanets); i++ {
 | 
				
			||||||
 | 
					        planetCoord = uniquePlanets[i]
 | 
				
			||||||
 | 
					        planet, _ = GetPlanet(planetCoord)
 | 
				
			||||||
 | 
					        if planet == nil { continue }
 | 
				
			||||||
 | 
					        ships, _ = planet.GetShips()
 | 
				
			||||||
 | 
					        LogInfof("Planet %s: LF:%d HF:%d CR:%d BS:%d LC:%d SC:%d Rec:%d",
 | 
				
			||||||
 | 
					            planetCoord, ships.ByID(LIGHTFIGHTER), ships.ByID(HEAVYFIGHTER),
 | 
				
			||||||
 | 
					            ships.ByID(CRUISER), ships.ByID(BATTLESHIP), ships.ByID(LARGECARGO),
 | 
				
			||||||
 | 
					            ships.ByID(SMALLCARGO), ships.ByID(RECYCLER))
 | 
				
			||||||
 | 
					        totalShips.Add(ships)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LogInfo("---")
 | 
				
			||||||
 | 
					    LogInfo("Total ships across all planets:")
 | 
				
			||||||
 | 
					    LogInfof("Light Fighters: %d/%d", totalShips.ByID(LIGHTFIGHTER), TARGET_SHIPS.ByID(LIGHTFIGHTER))
 | 
				
			||||||
 | 
					    LogInfof("Heavy Fighters: %d/%d", totalShips.ByID(HEAVYFIGHTER), TARGET_SHIPS.ByID(HEAVYFIGHTER))
 | 
				
			||||||
 | 
					    LogInfof("Cruisers: %d/%d", totalShips.ByID(CRUISER), TARGET_SHIPS.ByID(CRUISER))
 | 
				
			||||||
 | 
					    LogInfof("Battleships: %d/%d", totalShips.ByID(BATTLESHIP), TARGET_SHIPS.ByID(BATTLESHIP))
 | 
				
			||||||
 | 
					    LogInfof("Large Cargo: %d/%d", totalShips.ByID(LARGECARGO), TARGET_SHIPS.ByID(LARGECARGO))
 | 
				
			||||||
 | 
					    LogInfof("Small Cargo: %d/%d", totalShips.ByID(SMALLCARGO), TARGET_SHIPS.ByID(SMALLCARGO))
 | 
				
			||||||
 | 
					    LogInfof("Recyclers: %d/%d", totalShips.ByID(RECYCLER), TARGET_SHIPS.ByID(RECYCLER))
 | 
				
			||||||
 | 
					    LogInfo("---")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func forceResourceImport() {
 | 
				
			||||||
 | 
					    LogInfo("=== Forcing resource import to all planets ===")
 | 
				
			||||||
 | 
					    for i = 0; i < len(BUILDER_PLANETS); i++ {
 | 
				
			||||||
 | 
					        planetCoord = BUILDER_PLANETS[i]
 | 
				
			||||||
 | 
					        if planetCoord != MASTER_PLANET {
 | 
				
			||||||
 | 
					            importResources(planetCoord, NewResources(500000, 250000, 50000))
 | 
				
			||||||
 | 
					            Sleep(5000)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func forceParkAll() {
 | 
				
			||||||
 | 
					    LogInfo("=== Forcing fleet parking ===")
 | 
				
			||||||
 | 
					    parkAllFleets()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func showProgress() {
 | 
				
			||||||
 | 
					    printStatus()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ========================= STARTUP =========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CronExec("0 0 * * * *", func() { printStatus() })
 | 
				
			||||||
 | 
					CronExec("0 0 */2 * * *", func() { parkAllFleets() })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LogInfo("Starting Multi-Planet Ship Builder...")
 | 
				
			||||||
 | 
					LogInfo("Commands available:")
 | 
				
			||||||
 | 
					LogInfo("  showProgress() - Display current status")
 | 
				
			||||||
 | 
					LogInfo("  forceResourceImport() - Manually import resources")
 | 
				
			||||||
 | 
					LogInfo("  forceParkAll() - Manually park all fleets")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user