private void Update() { if (Time.unscaledTime > lastConnectionUpdate + 10) { lastConnectionUpdate = Time.unscaledTime; // Only update in the editor, since that's the only place where we need to actively track the inventory. if (HighLogic.LoadedScene == GameScenes.EDITOR) { string bodyName; if (FlightGlobals.ActiveVessel != null) { bodyName = FlightGlobals.ActiveVessel.mainBody.bodyName; } else { bodyName = "Kerbin"; } if (XenoIndustrySignpost.IsConnected(bodyName)) { StartCoroutine(XenoIndustrySignpost.GetClusterioInventory(bodyName, clusterioInventory)); } } } }
// TODO // // - XenoIndustryLaunchCosts // --- loading from config files using a rule system // - ClusterioConnector // --- ability to connect to multiple masters and hold multiple connections open // --- only acts on external commands, no "smart" behaviour of its own // // - a single class // // ADD // - XenoIndustryCargo - dedicated cargo tanks (separate for solids and liquids) than can be loaded and unloaded using an interface when on the launchpad // - XenoIndustrySignpost // --- class handling the Clusterio connections based on planets (planetName => urlAddress dictionary) // --- loading from signpost.json file (later from a signpost server?) // --- other classes should route their requests through the XenoIndustrySignpost one, which then in turn sends the proper url address to ClusterioConnector // --- should even decide which connections to keep open and how long // public void Awake() { instance = this; DontDestroyOnLoad(this); GameEvents.onGUIApplicationLauncherReady.Add(OnGUIAppLauncherReady); GameEvents.onGUIApplicationLauncherDestroyed.Add(OnGUIApplicationLauncherDestroyed); StreamReader reader = new StreamReader(MOD_PATH + "config.json"); if (reader != null) { JSONNode modConfig = JSON.Parse(reader.ReadToEnd()); if (modConfig["debug"] != null) { Debug.Log(String.Format("ClusterioTest: sciencePerSciencePack is {0}", modConfig["sciencePerSciencePack"])); debug = modConfig["debug"]; } } XenoIndustrySignpost.LoadSignpost(); windowRect = new Rect(Screen.width / 2 - 150, Screen.height / 2 - 150, 300, 100); clusterioInventory = new Dictionary <string, int>(); }
private void Update() { if (Time.unscaledTime > lastConnectionUpdate + 10) { lastConnectionUpdate = Time.unscaledTime; // Periodically update Clusterio inventory if not ingame if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.EDITOR || HighLogic.LoadedScene == GameScenes.TRACKSTATION) { string bodyName; if (FlightGlobals.ActiveVessel != null) { bodyName = FlightGlobals.ActiveVessel.mainBody.bodyName; } else { bodyName = "Kerbin"; } if (XenoIndustrySignpost.IsConnected(bodyName)) { StartCoroutine(XenoIndustrySignpost.GetClusterioInventory(bodyName, clusterioInventory)); } else { XenoIndustrySignpost.RefreshConnection(bodyName); } } } }
private void DeductLaunchPrice() { string bodyName = "Kerbin"; // Only launches from Kerbin are possible at this point foreach (KeyValuePair <string, int> kvPair in latestLaunchCosts) { StartCoroutine(XenoIndustrySignpost.RemoveItemsFromClusterio(bodyName, clusterioInventory, kvPair.Key, kvPair.Value)); } }
public static IEnumerator RemoveItemsFromClusterio(string bodyName, Dictionary <string, int> clusterioInventory, string itemName, int count, Action <bool> onFinished = null) { if (!BodyHasServer(bodyName)) { Debug.Log(String.Format("XenoIndustrySignpost: Sending a RemoveItemsFromClusterio request to a celestial {0} which has no assigned server!", bodyName)); yield break; } XenoIndustrySignpostBodyAddress address = bodyAddresses[bodyName]; // Connect to the server if we aren't connected yet if (!ClusterioConnector.IsConnected(address.masterIP, address.masterPort)) { ClusterioConnector.ConntectToMaster(address.masterIP, address.masterPort, address.masterAuthToken); } // First, we need to see what items are stored in the Clusterio server, and wait for that request to be finished yield return(XenoIndustryCore.instance.StartCoroutine(XenoIndustrySignpost.GetClusterioInventory(bodyName, clusterioInventory))); // Don't do a remove request if there's not enough items, or if the item isn't there at all if (!clusterioInventory.ContainsKey(itemName) || clusterioInventory[itemName] < count) { yield break; } Dictionary <string, string> sendValues = new Dictionary <string, string>(); sendValues["name"] = itemName; sendValues["count"] = count.ToString(); Debug.Log(String.Format("ClusterioUtil: removing {0} of {1} from item repository", count, itemName)); string apiCommand = "/api/remove"; ClusterioMessage resultMessage = new ClusterioMessage(); yield return(ClusterioConnector.SendPostRequest(address.masterIP, address.masterPort, apiCommand, resultMessage, sendValues)); if (resultMessage.result == ClusterioMessageResult.SUCCESS) { if (onFinished != null) { onFinished(true); } } else { if (onFinished != null) { onFinished(false); } } }
/*public void Start() * { * Debug.Log("ClusterioTest: Start"); * }*/ private void OnGameSceneSwitchRequested(GameEvents.FromToAction <GameScenes, GameScenes> sceneSwitch) { if (HighLogic.CurrentGame.Parameters.CustomParams <XenoIndustryCoreGameParameters>().enabled) { if (toolbarButton != null) { toolbarButton.SetFalse(); } // If the player has reverted to VAB or SPH, refund the spent items if (sceneSwitch.from == GameScenes.FLIGHT && sceneSwitch.to == GameScenes.EDITOR) { string bodyName = "Kerbin"; // Only launches from Kerbin are possible at this point foreach (KeyValuePair <string, int> kvPair in latestLaunchCosts) { StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, kvPair.Key, kvPair.Value)); } } } }
IEnumerator TransferScienceToClusterio() { int scienceTransferAmount = (int)(ResearchAndDevelopment.Instance.Science - (ResearchAndDevelopment.Instance.Science % sciencePerSciencePack)); int sciencePackTransferAmount = (int)(scienceTransferAmount / sciencePerSciencePack); ClusterioMessage resultMessage = new ClusterioMessage(); string bodyName = "Kerbin"; // Science packs can only be converted at Kerbin for now yield return(StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "space-science-pack", sciencePackTransferAmount, (success) => { if (success) { // Show results as text Debug.Log("TransferScienceToClusterio: science sent successfully"); // Only subtract science in KSP if the request successfuly reached the Clusterio master server ResearchAndDevelopment.Instance.AddScience(-scienceTransferAmount, TransactionReasons.ScienceTransmission); } } ))); }
private void OnVesselRecovered(ProtoVessel recoveredVessel, bool quick) { if (HighLogic.CurrentGame.Parameters.CustomParams <XenoIndustryCoreGameParameters>().enabled) { Dictionary <string, int> recoveredResources = new Dictionary <string, int>(); CalculateLaunchCosts(ref recoveredResources, recoveredVessel); if (recoveredResources.Count > 0) { string message = "Following resources have been recovered: \n"; string bodyName = "Kerbin"; // Recovery is only possible on Kerbin for now foreach (KeyValuePair <string, int> kvPair in recoveredResources) { message += String.Format("\n {0} {1}", kvPair.Value, kvPair.Key); StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, kvPair.Key, kvPair.Value)); } message += "\n"; if (!quick) { MultiOptionDialog dialog = new MultiOptionDialog("ClusterioResourceRecovery", message, "Recovery successful", UISkinManager.GetSkin("KSP window 7"), new DialogGUIBase[] { new DialogGUIButton("Continue", null) }); PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), dialog, false, null); } } } }
private void OnCargoWindowInternal(int id) { GUILayout.BeginVertical(); string bodyName; if (FlightGlobals.ActiveVessel != null) { bodyName = FlightGlobals.ActiveVessel.mainBody.bodyName; } else { bodyName = "Kerbin"; } if (!XenoIndustrySignpost.BodyHasServer(bodyName)) { GUILayout.Label("This celestial body has no associated master server."); } else if (!XenoIndustrySignpost.IsConnected(bodyName)) { GUILayout.Label("Cannot connect to Clusterio master server!"); GUILayout.Label("Error: " + XenoIndustrySignpost.GetConnectionError(bodyName)); if (GUILayout.Button("Refresh connection")) { XenoIndustrySignpost.RefreshConnection(bodyName); } } else if (FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.situation != Vessel.Situations.LANDED && FlightGlobals.ActiveVessel.situation != Vessel.Situations.PRELAUNCH && FlightGlobals.ActiveVessel.situation != Vessel.Situations.SPLASHED) { GUILayout.Label("Cannot transfer cargo until vessel is landed"); } else { // Clusterio inventory handling if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.EDITOR || HighLogic.LoadedScene == GameScenes.TRACKSTATION || HighLogic.LoadedScene == GameScenes.FLIGHT) { GUILayout.Label("Available inventory:"); if (clusterioInventory.Count > 0) { int spaceRemaining = (int)(windowActivePart.cargoResource.maxAmount - windowActivePart.cargoResource.amount); int netTransfer = 0; // Item names GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); GUILayout.Label("Resource"); GUILayout.Space(8); foreach (KeyValuePair <string, int> kvPair in clusterioInventory) { GUILayout.Label(kvPair.Key + ":"); } GUILayout.EndVertical(); // Loaded cargo GUILayout.BeginVertical(); GUILayout.Label("Loaded"); GUILayout.Space(8); foreach (KeyValuePair <string, int> kvPair in clusterioInventory) { if (windowActivePart.carriedCargo.ContainsKey(kvPair.Key)) { GUILayout.Label(windowActivePart.carriedCargo[kvPair.Key].ToString()); } else { GUILayout.Label("0"); } } GUILayout.EndVertical(); // Item amount to transfer GUILayout.BeginVertical(); GUILayout.Label("Transfer"); GUILayout.Space(8); foreach (KeyValuePair <string, int> kvPair in clusterioInventory) { if (!cargoSelected.ContainsKey(kvPair.Key)) { cargoSelected[kvPair.Key] = 0; } int result; int.TryParse(GUILayout.TextField(cargoSelected[kvPair.Key].ToString()), out result); cargoSelected[kvPair.Key] = result; spaceRemaining -= result; netTransfer += result; } GUILayout.EndVertical(); // Items stocks GUILayout.BeginVertical(); GUILayout.Label("Available"); GUILayout.Space(8); foreach (KeyValuePair <string, int> kvPair in clusterioInventory) { GUILayout.Label(kvPair.Value.ToString()); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.Space(8); // Remaining space GUILayout.BeginHorizontal(); GUILayout.Label("Space remaining:"); GUILayout.Label(spaceRemaining.ToString() + " / " + ((int)windowActivePart.cargoResource.maxAmount).ToString()); GUILayout.EndHorizontal(); // Net amount of items transferred to part GUILayout.BeginHorizontal(); GUILayout.Label("Net items transferred:"); GUILayout.Label(netTransfer.ToString()); GUILayout.EndHorizontal(); GUILayout.Space(8); GUILayout.Label(windowResponse); if (GUILayout.Button("Transfer cargo")) { // Check if we aren't trying to load more than the module can actually hold if (spaceRemaining < 0) { windowResponse = "Cannot load more cargo than the module can hold"; } else { bool success = true; // Check if we aren't trying to more cargo than the the server actually has foreach (KeyValuePair <string, int> kvPair in cargoSelected) { if (clusterioInventory.ContainsKey(kvPair.Key)) { if (kvPair.Value > clusterioInventory[kvPair.Key]) { windowResponse = String.Format("Cannot load {0} of item {1}, only {2} is available", kvPair.Value, kvPair.Key, clusterioInventory[kvPair.Key]); success = false; break; } } } // Check if we aren't trying to unload more cargo than the module has foreach (KeyValuePair <string, int> kvPair in cargoSelected) { if (kvPair.Value < 0) { if (!windowActivePart.carriedCargo.ContainsKey(kvPair.Key)) { windowResponse = String.Format("Cannot unload {0} item {1}, none currently loaded", kvPair.Value, kvPair.Key); success = false; break; } if (-kvPair.Value > windowActivePart.carriedCargo[kvPair.Key]) { windowResponse = String.Format("Cannot unload {0} of item {1}, only {2} currently loaded", kvPair.Value, kvPair.Key, windowActivePart.carriedCargo[kvPair.Key]); success = false; break; } } } if (success) { windowResponse = "Cargo transfer successful"; foreach (KeyValuePair <string, int> kvPair in cargoSelected) { // Sanity check if (kvPair.Value == 0) { continue; } Action <bool> cargoCallback = delegate(bool requestSuccessful) { if (requestSuccessful) { if (windowActivePart.carriedCargo.ContainsKey(kvPair.Key)) { windowActivePart.carriedCargo[kvPair.Key] += kvPair.Value; } else { windowActivePart.carriedCargo[kvPair.Key] = kvPair.Value; } } }; if (kvPair.Value > 0) { StartCoroutine(XenoIndustrySignpost.RemoveItemsFromClusterio(bodyName, clusterioInventory, kvPair.Key, kvPair.Value, cargoCallback)); } else { StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, kvPair.Key, -kvPair.Value, cargoCallback)); } } windowActivePart.cargoResource.amount += netTransfer; cargoSelected.Clear(); } } } } else { GUILayout.Label("No cargo available for transfer."); } GUILayout.Space(16); if (GUILayout.Button("Refresh Clusterio inventory")) { StartCoroutine(XenoIndustrySignpost.GetClusterioInventory(bodyName, clusterioInventory)); } } } GUILayout.EndVertical(); // --- GUI.DragWindow(); }
private void OnWindowInternal(int id) { GUILayout.BeginVertical(); string bodyName = "Kerbin"; // Since this is for launching, only Kerbin is possible for now if (!XenoIndustrySignpost.BodyHasServer(bodyName)) { GUILayout.Label("This celestial body has no associated master server."); } else if (!XenoIndustrySignpost.IsConnected(bodyName)) { GUILayout.Label("Cannot connect to Clusterio master server!"); GUILayout.Label("Error: " + XenoIndustrySignpost.GetConnectionError(bodyName)); if (GUILayout.Button("Refresh connection")) { XenoIndustrySignpost.RefreshConnection(bodyName); } } else { // Show ship costs in editor if (HighLogic.LoadedScene == GameScenes.EDITOR) { //GUILayout.Space(16); //GUILayout.Label("", GUI.skin.horizontalSlider); //GUILayout.Space(8); if (latestLaunchCosts.Count > 0) { // Item names GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); GUILayout.Label("Resource"); GUILayout.Space(8); foreach (KeyValuePair <string, int> kvPair in latestLaunchCosts) { GUILayout.Label(kvPair.Key + ":"); } GUILayout.EndVertical(); // Item costs GUILayout.BeginVertical(); GUILayout.Label("Required"); GUILayout.Space(8); foreach (KeyValuePair <string, int> kvPair in latestLaunchCosts) { GUILayout.Label(kvPair.Value.ToString()); } GUILayout.EndVertical(); // Items stocks GUILayout.BeginVertical(); GUILayout.Label("Available"); GUILayout.Space(8); foreach (KeyValuePair <string, int> kvPair in latestLaunchCosts) { GUILayout.Label((clusterioInventory.ContainsKey(kvPair.Key)) ? clusterioInventory[kvPair.Key].ToString() : 0.ToString()); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.Space(8); if (GUILayout.Button("Refresh Clusterio inventory")) { StartCoroutine(XenoIndustrySignpost.GetClusterioInventory(bodyName, clusterioInventory)); } } else { GUILayout.Label("None"); } } } GUILayout.EndVertical(); // --- GUI.DragWindow(); }
IEnumerator ClusterioPreflightResourceCheck() { Debug.Log("XenoIndustryLaunchCosts: PreflightResourceCheck"); string bodyName = "Kerbin"; // Launching only works on Kerbin for now yield return(StartCoroutine(XenoIndustrySignpost.GetClusterioInventory(bodyName, clusterioInventory))); CalculateLaunchCosts(ref latestLaunchCosts); bool pass = true; foreach (KeyValuePair <string, int> kvPair in latestLaunchCosts) { if (!clusterioInventory.ContainsKey(kvPair.Key) || clusterioInventory[kvPair.Key] < kvPair.Value) { pass = false; break; } } if (!pass) { // Insufficient resources to launch string message = "You do not have enough resources to launch this vessel! This vessel needs: \n"; foreach (KeyValuePair <string, int> kvPair in latestLaunchCosts) { message += String.Format("\n {0} {1} (you have {2})", kvPair.Value, kvPair.Key, (clusterioInventory.ContainsKey(kvPair.Key)) ? clusterioInventory[kvPair.Key] : 0); } message += "\n"; MultiOptionDialog dialog = new MultiOptionDialog("InsufficientClusterioResources", message, "Insufficient resources!", UISkinManager.GetSkin("KSP window 7"), new DialogGUIBase[] { new DialogGUIButton("Unable to Launch", null) }); PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), dialog, false, null); } else { // Launch can proceed string message = "Launching this vessel will require: \n"; foreach (KeyValuePair <string, int> kvPair in latestLaunchCosts) { message += String.Format("\n {0} {1} (you have {2})", kvPair.Value, kvPair.Key, (clusterioInventory.ContainsKey(kvPair.Key)) ? clusterioInventory[kvPair.Key] : 0); } message += "\n"; MultiOptionDialog dialog = new MultiOptionDialog("ClusterioLaunchConfirmation", message, "Launch Possible", UISkinManager.GetSkin("KSP window 7"), new DialogGUIBase[] { new DialogGUIButton("Launch", new Callback(ProceedToLaunch)), new DialogGUIButton("Cancel", null) }); PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), dialog, false, null); } }
private void OnCoreWindowInternal(int id) { GUILayout.BeginVertical(); string bodyName; if (FlightGlobals.ActiveVessel != null) { bodyName = FlightGlobals.ActiveVessel.mainBody.bodyName; } else { bodyName = "Kerbin"; } if (!XenoIndustrySignpost.BodyHasServer(bodyName)) { GUILayout.Label("This celestial body has no associated master server."); } else if (!XenoIndustrySignpost.IsConnected(bodyName)) { GUILayout.Label("Cannot connect to Clusterio master server!"); GUILayout.Label("Error: " + XenoIndustrySignpost.GetConnectionError(bodyName)); if (GUILayout.Button("Refresh connection")) { XenoIndustrySignpost.RefreshConnection(bodyName); } } else { // Clusterio inventory handling if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.EDITOR || HighLogic.LoadedScene == GameScenes.TRACKSTATION || HighLogic.LoadedScene == GameScenes.FLIGHT) { GUILayout.Label("Clusterio inventory:"); if (clusterioInventory.Count > 0) { GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); foreach (KeyValuePair <string, int> kvPair in clusterioInventory) { GUILayout.Label(kvPair.Key + ":"); } GUILayout.EndVertical(); GUILayout.BeginVertical(); foreach (KeyValuePair <string, int> kvPair in clusterioInventory) { GUILayout.Label(kvPair.Value.ToString()); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); } else { GUILayout.Label("Clusterio inventory is empty."); } GUILayout.Space(8); if (GUILayout.Button("Refresh Clusterio inventory")) { StartCoroutine(XenoIndustrySignpost.GetClusterioInventory(bodyName, clusterioInventory)); } } if (debug) { if (GUILayout.Button("Add 1000 rocket component items")) { StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "low-density-structure", 1000)); StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "rocket-control-unit", 1000)); StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "solar-panel", 1000)); StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "uranium-238", 1000)); StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "accumulator", 1000)); StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "electric-mining-drill", 1000)); StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "electric-furnace", 1000)); StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "radar", 1000)); StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "processing-unit", 1000)); } if (GUILayout.Button("Add 1000 rocket fuel items")) { StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "rocket-fuel", 1000)); StartCoroutine(XenoIndustrySignpost.AddItemsToClusterio(bodyName, "explosives", 1000)); } if (GUILayout.Button("Write out CelestialBody names")) { XenoIndustrySignpost.WriteOutCelestialBodies(); } } } GUILayout.EndVertical(); // --- GUI.DragWindow(); }
private void OnClusterioWindowInternal(int id) { GUILayout.BeginVertical(); string bodyName = "Kerbin"; // Science transfer can only be done on Kerbin right now if (!XenoIndustrySignpost.BodyHasServer(bodyName)) { GUILayout.Label("This celestial body has no associated master server."); } else if (!XenoIndustrySignpost.IsConnected(bodyName)) { GUILayout.Label("Cannot connect to Clusterio master server!"); GUILayout.Label("Error: " + XenoIndustrySignpost.GetConnectionError(bodyName)); if (GUILayout.Button("Refresh connection")) { XenoIndustrySignpost.RefreshConnection(bodyName); } } else if (ResearchAndDevelopment.Instance == null) { GUILayout.Label("Cannot transfer science in sandbox mode!"); } else { // Science transfer to Factorio //if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.EDITOR || HighLogic.LoadedScene == GameScenes.TRACKSTATION || HighLogic.LoadedScene == GameScenes.FLIGHT) if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.TRACKSTATION || HighLogic.LoadedScene == GameScenes.FLIGHT) { /*GUILayout.Space(16); * GUILayout.Label("", GUI.skin.horizontalSlider); * GUILayout.Space(8);*/ int scienceTransferAmount = (int)(ResearchAndDevelopment.Instance.Science - (ResearchAndDevelopment.Instance.Science % sciencePerSciencePack)); GUILayout.Label(String.Format("Can use {0} science to transfer {1} science packs to Factorio.", scienceTransferAmount, (scienceTransferAmount / sciencePerSciencePack).ToString())); GUILayout.Space(8); if (GUILayout.Button("Transfer Science to Clusterio") && ResearchAndDevelopment.Instance != null) { Debug.Log("ClusterioTest: transferring science to Factorio"); StartCoroutine(TransferScienceToClusterio()); } GUILayout.Space(8); if (GUILayout.Button("Refresh Clusterio inventory")) { StartCoroutine(XenoIndustrySignpost.GetClusterioInventory(bodyName, clusterioInventory)); } } } GUILayout.EndVertical(); // --- GUI.DragWindow(); }