Created
November 3, 2018 08:35
-
-
Save ChuckSavage/e5e26a0b3764c679a100481bf74c97ad to your computer and use it in GitHub Desktop.
Space Engineers Game - Battery Charge and Drill (miner) load level and balancer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// dco.pe/vsb | |
const float MinValueToActivateRedLights = 5000f; | |
const float VolumeOfDrills = 33750f; // small ship drill (large is 234375f) | |
public Program() | |
{ | |
Runtime.UpdateFrequency = UpdateFrequency.Update100; | |
} | |
public class InventoryItem | |
{ | |
private readonly IMyInventoryItem _this; | |
public InventoryItem(IMyInventoryItem item) | |
{ | |
_this = item; | |
} | |
public float Amount { get { return (float)_this.Amount; } } | |
public bool IsOre { get { return (bool)(_IsOre ?? (_IsOre = _this.Content.TypeId.ToString().EndsWith("Ore"))); } } | |
bool? _IsOre; | |
public string ItemType { get { return _ItemType ?? (_ItemType = _this.Content.SubtypeId.ToString()); } } | |
string _ItemType; | |
public IMyInventoryItem This { get { return _this; } } | |
} | |
public class Inventory | |
{ | |
private readonly IMyInventory _this; | |
public Inventory(IMyInventory inventory) | |
{ | |
_this = inventory; | |
} | |
public float CurrentMass { get { return (float)_this.CurrentMass; } } | |
/// <summary> | |
/// Multiplied by 1000 to get the value you see in game | |
/// </summary> | |
public float CurrentVolume { get { return ((float)_this.CurrentVolume) * 1000f; } } | |
public List<InventoryItem> Items() { return _this.GetItems().Select(item => new InventoryItem(item)).ToList(); } | |
//public List<VRage.Game.Entity.MyPhysicalInventoryItem> Items2() { return _this.GetItems(); } | |
public float MaxVolume { get { return ((float)_this.MaxVolume); } } | |
public IMyInventory This { get { return _this; } } | |
} | |
public class CargoContainers | |
{ | |
private readonly IMyTerminalBlock _this; | |
public CargoContainers(IMyTerminalBlock cargoBlock) | |
{ | |
_this = cargoBlock; | |
} | |
//IMyInventory inventoryB = (containerB as IMyInventoryOwner).GetInventory(0) | |
public Inventory Inventory { get { return _Inventory ?? (_Inventory = new Inventory((_this as IMyInventoryOwner).GetInventory(0))); } } | |
Inventory _Inventory; | |
public bool IsDrill { get { return IsType<IMyShipDrill>(); } } | |
public bool IsType<T>() where T : IMyTerminalBlock | |
{ | |
try | |
{ | |
var t = (T)_this; | |
return true; | |
} | |
catch { return false; } | |
//return null != _this as T; | |
} | |
public string Name { get { return _this.CustomName; } } | |
public IMyTerminalBlock This { get { return _this; } } | |
} | |
void Main(string argument) | |
{ | |
// block declarations | |
string ERR_TXT = ""; | |
List<IMyTerminalBlock> v0 = new List<IMyTerminalBlock>(); | |
GridTerminalSystem.GetBlocksOfType<IMyBatteryBlock>(v0, filterThis); | |
if (v0.Count == 0) | |
{ | |
ERR_TXT += "no Battery blocks found\n"; | |
} | |
List<IMyTerminalBlock> v1 = new List<IMyTerminalBlock>(); | |
GridTerminalSystem.GetBlocksOfType<IMyInteriorLight>(v1, filterThis); | |
if (v1.Count == 0) | |
{ | |
ERR_TXT += "no Interior Light blocks found\n"; | |
} | |
List<IMyTerminalBlock> v2 = new List<IMyTerminalBlock>(); | |
GridTerminalSystem.GetBlocksOfType<IMyShipDrill>(v2, filterThis); | |
if (v2.Count == 0) | |
{ | |
ERR_TXT += "no Drill blocks found\n"; | |
} | |
// display errors | |
if (ERR_TXT != "") | |
{ | |
Echo("Script Errors:\n" + ERR_TXT + "(make sure block ownership is set correctly)"); | |
if (ERR_TXT.Contains("Drill")) | |
return; | |
} | |
if (v0.Count > 0) | |
{ | |
// battery logic | |
bool result0v0 = true; | |
for (int i = 0; i < v0.Count; i++) | |
{ | |
if (!(getExtraFieldFloat(v0[i], "Max Stored Power:.*Stored power: (\\d+\\.?\\d*) (\\w?)Wh") >= 1050000 && v0[i].GetValueBool("Recharge") == true)) | |
{ | |
//Echo("break power loop"); | |
result0v0 = false; | |
break; | |
} | |
} | |
if (result0v0) | |
SetInteriorLightsColor(v1, 0, 255, 0); // set green | |
else | |
SetInteriorLightsColor(v1, 255, 255, 255); // set white | |
} | |
else | |
SetInteriorLightsColor(v1, 255, 255, 255); // set white | |
// Balance the drills inventories | |
//List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>(); | |
//GridTerminalSystem.GetBlocksOfType<IMyCargoContainer>(blocks); // get all cargo container type blocks | |
List<CargoContainers> drills = v2.Select(block => new CargoContainers(block)).ToList(); | |
//Echo("CargoContainers : " + cargos.Count.ToString()); | |
//cargos.ForEach(cargo => Echo("Container : " + cargo.Name)); | |
//var drills = cargos.Where(cargo => cargo.IsDrill).ToList(); | |
//Echo("Drills : " + drills.Count.ToString()); | |
//var d = drills.First(); | |
//var firstItem = d.Inventory.GetItems().FirstOrDefault(); | |
//Echo(firstItem.GetType().FullName); | |
// Balance the drills if there are more than one drill | |
if (drills.Count > 1) | |
{ | |
drills = drills.OrderBy(drill => drill.Inventory.CurrentMass).ToList(); | |
var maxDrill = drills.Last(); | |
// balance if volume would trigger red lights if not balanced | |
if (maxDrill.Inventory.CurrentVolume >= MinValueToActivateRedLights) | |
{ | |
var minDrill = drills.First(); // was already sorted getting the maxDrill | |
float diff = maxDrill.Inventory.CurrentMass - minDrill.Inventory.CurrentMass; | |
diff /= 2; // diff = diff / 2; | |
Echo("MaxDrill:" + maxDrill.Inventory.CurrentMass.ToString()); | |
Echo("MinDrill:" + minDrill.Inventory.CurrentMass.ToString()); | |
Echo("Half Diff:" + diff.ToString()); | |
if (diff >= 1f) | |
{ | |
float max = 0; | |
int maxIndex = 0; | |
var maxItems = maxDrill.Inventory.Items(); | |
InventoryItem maxItem = null; | |
for (int i = 0; i < maxItems.Count; i++) | |
{ | |
maxItem = maxItems[i]; | |
if (maxItem.Amount > max) | |
{ | |
max = maxItem.Amount; | |
maxIndex = i; | |
} | |
} | |
//Echo("MaxItemAmount:" + max.ToString()); | |
//Echo("MaxItemIndex:" + maxIndex.ToString()); | |
// amount = lesser of item.Amount and diff | |
var amount = (VRage.MyFixedPoint)Math.Min(diff, maxItem.Amount); | |
// parameters for this are: TransferItemTo(IMyInventory destination, int itemIndex, Nullable<int> targetItemIndex, Nullable<bool> tryToStack, Nullable<MyFixedPoint> amount); | |
maxDrill.Inventory.This.TransferItemTo(minDrill.Inventory.This, maxIndex, null, true, amount); | |
} | |
} | |
//var firstItem = maxDrill.Inventory.This.GetItems().FirstOrDefault(); | |
//Echo(firstItem?.Content.SubtypeId.ToString() ?? "No Items"); | |
//Echo(firstItem.GetType().FullName); | |
} | |
//float maxDrillVolume = v2 | |
// .Select(d => (IMyShipDrill)d) | |
// .Select(I => I.GetInventory(0)) | |
// .Select(inv => ((float)inv.CurrentVolume) * 1000) | |
// .Max(); | |
float maxDrillVolume = v2.Max(drill => (float)((IMyShipDrill)drill).GetInventory(0).CurrentVolume * 1000); | |
//Echo(fs(maxDrillVolume)); | |
if (maxDrillVolume >= MinValueToActivateRedLights) | |
{ | |
float percentInDrill = maxDrillVolume / VolumeOfDrills; | |
float sumDrillVolume = 255 * percentInDrill; // to get percent value of 255 not 100 | |
//Echo("sumDrillVolume : "+ fs(sumDrillVolume)); | |
float nonRed = sumDrillVolume % 255; // 0 to 255 color | |
nonRed = 255 - nonRed; // flip the value to be 255 to 0 | |
//Echo(fs(nonRed)); | |
SetInteriorLightsColor(v1, 255, (int)nonRed, (int)nonRed); // set steadily increasing red color | |
} | |
else | |
Echo("Drills empty"); | |
// This used to sum the value in the drills. | |
// Not as effective, since drills don't share their volumes. One could fill up, and you'd | |
// then be wasting that ore it continued to mine. | |
//bool result2v2 = false; | |
//float drillVolume, sumDrillVolume; | |
//sumDrillVolume = 0; | |
// for (int i = 0; i < v2.Count; i++) { | |
//drillVolume = (float)((IMyShipDrill)v2[i]).GetInventory(0).CurrentVolume; | |
// // maxDrillVolume = Math.Max(maxDrillVolume, ) | |
// drillVolume *= 1000; | |
////Echo("Drill "+v2[i].CustomName +" : "+ fs(drillVolume)); | |
////drillVolume = 5001; // 1/6th full | |
////drillVolume = 11250; // 1/3rd full | |
////drillVolume = 16875; // 1/2 full | |
////drillVolume = 25312; // 3/4th full | |
//sumDrillVolume += drillVolume; | |
////Echo("sumDrillVolume : "+ fs(sumDrillVolume)); | |
//if(!result2v2 && (drillVolume > 5000f)) | |
// result2v2 = true; | |
// } | |
// if(result2v2) { | |
////Echo("Drills : "+ v2.Count.ToString()); | |
////Echo("sumDrillVolume : "+ fs(sumDrillVolume)); | |
//float totalVolume = 33750f * v2.Count; | |
////Echo("totalVolume : "+fs(totalVolume)); | |
//sumDrillVolume /= totalVolume; | |
//sumDrillVolume *= 255; // to get percent value of 255 not 100 | |
////Echo("sumDrillVolume : "+ fs(sumDrillVolume)); | |
//float nonRed = sumDrillVolume % 255; // 0 to 255 color | |
//nonRed = 255 - nonRed; // flip the value to be 255 to 0 | |
////Echo(fs(nonRed)); | |
//for(int i = 0; i < v1.Count; i++) { | |
// v1[i].SetValueColor("Color", new Color(255, (int)nonRed, (int)nonRed)); | |
//} | |
// } | |
// else | |
//Echo("Drills empty"); | |
} | |
void SetInteriorLightsColor(List<IMyTerminalBlock> list, int red, int green, int blue) | |
{ | |
list.ForEach(light => light.SetValueColor("Color", new Color(red, green, blue))); | |
} | |
string fs(float f) | |
{ | |
int i = (int)f; | |
return i.ToString(); | |
} | |
const string MULTIPLIERS = ".kMGTPEZY"; | |
bool filterThis(IMyTerminalBlock block) | |
{ | |
return block.CubeGrid == Me.CubeGrid; | |
} | |
float getExtraFieldFloat(IMyTerminalBlock block, string regexString) | |
{ | |
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(regexString, System.Text.RegularExpressions.RegexOptions.Singleline); | |
float result = 0.0f; | |
double parsedDouble; | |
System.Text.RegularExpressions.Match match = regex.Match(block.DetailedInfo); | |
if (match.Success) | |
{ | |
if (Double.TryParse(match.Groups[1].Value, out parsedDouble)) | |
{ | |
result = (float)parsedDouble; | |
} | |
if (MULTIPLIERS.IndexOf(match.Groups[2].Value) > -1) | |
{ | |
result = result * (float)Math.Pow(1000.0, MULTIPLIERS.IndexOf(match.Groups[2].Value)); | |
} | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment