Created
November 10, 2018 11:30
-
-
Save ChuckSavage/fd5777417b802bf59a07a60688f84a94 to your computer and use it in GitHub Desktop.
Space Engineers - Stone Duster mod, script to control stone amounts
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
// Written by steam handle "Dune__" aka Chuck Savage | |
// - Gist link: https://gist.github.com/ChuckSavage/fd5777417b802bf59a07a60688f84a94 | |
// Feel free to use and modify. It'd be great if you list any | |
// changes here on this gist page so I can keep this up to date if they are important changes. | |
// Todo: handle multiple stone dusters. I'm not sure how to go about finding the type "Stone Duster" that | |
// the mod has listed for itself. | |
// Some code borrowed from the Space Engineers Visual Script Builder - http://dco.pe/vsb/ | |
// Set name of Stone Duster to this name, or change this name to your stone duster's name | |
const string StoneDusterName = "StoneDuster"; | |
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 IsIngot { get { return (bool)(_IsIngot ?? (_IsIngot = TypeId.EndsWith("Ingot"))); } } | |
bool? _IsIngot; | |
public bool IsOre { get { return (bool)(_IsOre ?? (_IsOre = TypeId.EndsWith("Ore"))); } } | |
bool? _IsOre; | |
public string ItemType { get { return _ItemType ?? (_ItemType = _this.Content.SubtypeId.ToString()); } } | |
string _ItemType; | |
public string TypeId { get { return _TypeId ?? (_TypeId = _this.Content.TypeId.ToString()); } } | |
string _TypeId; | |
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 float MaxVolume { get { return ((float)_this.MaxVolume); } } | |
public IMyInventory This { get { return _this; } } | |
} | |
public class CargoContainer | |
{ | |
private readonly IMyTerminalBlock _this; | |
public CargoContainer(IMyTerminalBlock cargoBlock) | |
{ | |
_this = cargoBlock; | |
} | |
public Inventory Inventory { get { return _Inventory ?? (_Inventory = new Inventory((_this as IMyEntity).GetInventory(0))); } } | |
Inventory _Inventory; | |
//Refineries and Assemblers have In and Out inventories, have yet to figure out which is which and if they | |
//are different to each other (refineries to assemblers). | |
//public Inventory InventoryIN { get { return _InventoryIN ?? (_InventoryIN = new Inventory((_this as IMyEntity).GetInventory(0))); } } | |
//Inventory _InventoryIN; | |
//public Inventory InventoryOUT { get { return _InventoryOUT ?? (_InventoryOUT = new Inventory((_this as IMyEntity).GetInventory(1))); } } | |
//Inventory _InventoryOUT; | |
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; } } | |
/// <summary> | |
/// Is the block a cargo container? | |
/// </summary> | |
/// <param name="block"></param> | |
/// <returns></returns> | |
public static bool IsCargoContainer(IMyTerminalBlock block) | |
{ | |
return (block as IMyEntity)?.HasInventory ?? false; | |
/* simplified version of | |
IMyEntity entity = block as IMyEntity; | |
if (null == entity) | |
return false; | |
return entity.HasInventory; | |
*/ | |
} | |
} | |
void Main(string argument) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>(); | |
GridTerminalSystem.GetBlocksOfType<IMyTerminalBlock>(blocks, filterThis); | |
List<CargoContainer> cargos = blocks | |
.Where(block => CargoContainer.IsCargoContainer(block)) | |
.Select(block => new CargoContainer(block)) | |
.ToList(); | |
if (cargos.Count == 0) | |
sb.AppendLine("No Cargo Containers found."); | |
//List<MyRefinery> stoneDusters = new List<MyRefinery>(); | |
//GridTerminalSystem.GetBlocksOfType<IMyRefinery>(stoneDusters, filterThis); | |
IMyRefinery stoneduster = (IMyRefinery)GridTerminalSystem.GetBlockWithName(StoneDusterName); | |
//Echo(stoneduster.GetType().ToString()); //Sandbox.Game.Entities.Cube.MyRefinery | |
//Echo(stoneduster.GetType().FullName); //Sandbox.Game.Entities.Cube.MyRefinery | |
if (null == stoneduster) | |
sb.AppendLine("No Stone Duster by name '" + StoneDusterName + "' found."); | |
string customData = stoneduster?.CustomData ?? "0"; // if stoneduster is null don't bomb here | |
int stoneLimit = 100000; | |
if (string.IsNullOrWhiteSpace(customData)) | |
sb.AppendLine("No CustomData found for " + StoneDusterName + ", use a number."); | |
else if (!int.TryParse(customData, out stoneLimit)) | |
sb.AppendLine("Invalid stone limit. Set " + StoneDusterName + "'s CustomData to a whole number only."); | |
if (stoneLimit < 0) | |
stoneLimit = 0; | |
if (sb.Length > 0) | |
{ | |
Echo("Script Errors:\n" + sb.ToString() + "(make sure block ownership is set correctly)"); | |
return; | |
} | |
Echo("Stone Limit: " + stoneLimit.ToString()); | |
var stone = cargos.SelectMany(c => c.Inventory.Items()) | |
.Where(item => item.ItemType == "Stone"); | |
float oreAmount = stone.Where(item => item.IsOre) | |
.Sum(item => item.Amount); | |
float gravelAmount = stone.Where(item => item.IsIngot) | |
.Sum(item => item.Amount); | |
float totalStone = oreAmount + gravelAmount; | |
//List<InventoryItem> items = cargos.SelectMany(c => c.Inventory.Items()).ToList(); | |
//items | |
// .Where(item => item.ItemType.ToLower().Contains("stone")) | |
// .ToList() | |
// .ForEach(item => Echo(item.TypeId + " : " + item.ItemType)); | |
//List<InventoryItem> ores = cargos.SelectMany(c => c.Inventory.Items()) | |
// .Where(item => item.IsOre) | |
// .ToList(); | |
//Echo("Ore Count: " + ores.Count.ToString()); | |
Echo("Stone: " + oreAmount.ToString()); | |
Echo("Gravel: " + gravelAmount.ToString()); | |
Echo("Total: " + totalStone.ToString()); | |
// since duster doesn't differentiate between gravel and stone(ore), we use total | |
if (totalStone > stoneLimit) | |
stoneduster.ApplyAction("OnOff_On"); | |
else | |
stoneduster.ApplyAction("OnOff_Off"); | |
} | |
bool filterThis(IMyTerminalBlock block) | |
{ | |
return block.CubeGrid == Me.CubeGrid; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment