Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * R e a d m e
- * -----------
- *
- * In this file you can include any instructions or other comments you want to have injected onto the
- * top of your final script. You can safely delete this file if you do not want any such comments.
- */
- // This file contains your actual script.
- //
- // You can either keep all your code here, or you can create separate
- // code files to make your program easier to navigate while coding.
- //
- // In order to add a new utility class, right-click on your project,
- // select 'New' then 'Add Item...'. Now find the 'Space Engineers'
- // category under 'Visual C# Items' on the left hand side, and select
- // 'Utility Class' in the main area. Name it in the box below, and
- // press OK. This utility class will be merged in with your code when
- // deploying your final script.
- //
- // You can also simply create a new utility class manually, you don't
- // have to use the template if you don't want to. Just do so the first
- // time to see what a utility class looks like.
- //
- // Go to:
- // https://github.com/malware-dev/MDK-SE/wiki/Quick-Introduction-to-Space-Engineers-Ingame-Scripts
- //
- // to learn more about ingame scripts.
- public Program()
- {
- set();
- Runtime.UpdateFrequency = UpdateFrequency.Update100;
- }
- public bool isThisShips(IMyTerminalBlock b)
- {
- return b.OwnerId == Me.OwnerId && b.IsFunctional && b.CubeGrid == Me.CubeGrid && b.IsSameConstructAs(Me);
- }
- public class Order
- {
- public static int QUANTITY_ALL = 10000000;
- public string name = "";
- public int price=0;
- public int quantity=0;
- public Order(string name, int price, int quantity)
- {
- this.name = name;
- this.price = price;
- this.quantity = quantity;
- }
- public Order(string line)
- {
- string[] lr = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
- if (lr.Length >= 4)
- {
- int p = 0;
- int.TryParse(lr[3], out p);
- if (lr[0] == "BUY") p = -p;
- string item = lr[1];
- name = item;
- price = p;
- string quant = lr[2];
- if (quant == "ALL") quantity = QUANTITY_ALL;
- else
- {
- int.TryParse(quant, out quantity);
- }
- }
- }
- }
- //Dictionary<string, int> prices = new Dictionary<string, int>();
- List<Order> orders = new List<Order>();
- Order getOrderByName(string n)
- {
- foreach (Order o in orders)
- {
- if (o.name == n) return o;
- }
- return null;
- }
- int getStock(string n, AggregateInventoryInterface inv)
- {
- foreach (var kvp in inv.items)
- {
- string iname = isyname(kvp.Key);
- if (iname == n) return kvp.Value;
- }
- return 0;
- }
- void readprices()
- {
- orders.Clear();
- string[] lines = Me.CustomData.Split('\n');
- foreach (string line in lines)
- {
- if (line.StartsWith("#")) continue;
- Order o = new Order(line);
- if (o.name != "") orders.Add(o);
- /*string[] lr = line.Split(new char[] { ' ' },StringSplitOptions.RemoveEmptyEntries);
- if (lr.Length >= 4)
- {
- int price = 0;
- int.TryParse(lr[4],out price);
- if (lr[0] == "BUY") price = -price;
- string key = lr[1];
- prices[key] = price;
- }*/
- }
- }
- string isyname(MyItemType t)
- {
- return t.TypeId + "/" + t.SubtypeId;
- }
- void writeprices()
- {
- string str = "#BUY/SELL ITEMID QUANTITY PRICE\n#\n";
- foreach (Order o in orders)
- {
- if (o.name.Trim() != "")
- {
- int price = o.price;
- if (price == 0) str += "UNSET ";
- else if (price < 0)
- {
- price = -price;
- str += "BUY ";
- }
- else str += "SELL ";
- str += o.name + " ";
- if (o.quantity >= Order.QUANTITY_ALL) str += "ALL";
- else str += o.quantity.ToString();
- str += " ";
- str += price + "\n";
- }
- }
- Me.CustomData = str;
- }
- /*MyTuple<MyItemType, int> getkvp(string n, AggregateInventoryInterface inv)
- {
- foreach(var kvp in inv.items)
- {
- string iname = isyname(kvp.Key);
- if (iname == n) return new MyTuple<MyItemType, int>(kvp.Key,kvp.Value);
- }
- return new MyTuple<MyItemType, int>(null,0);
- }*/
- public void set()
- {
- IMyTextSurface log = Me.GetSurface(0);
- log.ContentType = ContentType.TEXT_AND_IMAGE;
- log.WriteText("");
- List<IMyCargoContainer> cargo = new List<IMyCargoContainer>();
- GridTerminalSystem.GetBlocksOfType<IMyCargoContainer>(cargo, delegate (IMyCargoContainer b) { return isThisShips(b); });
- AggregateInventoryInterface inv = new AggregateInventoryInterface();
- inv.setContainers(cargo);
- inv.update(true);
- readprices();
- foreach (var k in inv.items)
- {
- string n = isyname(k.Key);
- Order o = getOrderByName(n);
- if (o == null) orders.Add(new Order(n, 0, Order.QUANTITY_ALL));
- }
- writeprices();
- List<IMyStoreBlock> s = new List<IMyStoreBlock>();
- GridTerminalSystem.GetBlocksOfType<IMyStoreBlock>(s, delegate (IMyStoreBlock b) { return isThisShips(b); });
- if (s.Count > 0)
- {
- var store = s[0];
- List<MyStoreQueryItem> cur = new List<MyStoreQueryItem>();
- store.GetPlayerStoreItems(cur);
- foreach (var i in cur)
- {
- store.CancelStoreItem(i.Id);
- }
- foreach (Order o in orders)
- {
- if (o.price != 0)
- {
- //var i = k.Key;
- MyDefinitionId definitionId;
- if (MyDefinitionId.TryParse(o.name, out definitionId))
- {
- long nid = -1;
- if (o.price > 0)
- {
- int quantity = o.quantity;
- int stock = getStock(o.name, inv);
- if (stock < quantity) quantity = stock;
- var si = new MyStoreItemDataSimple(definitionId, quantity, o.price);
- store.InsertOffer(si, out nid);
- }
- else if (o.price < 0)
- {
- var si = new MyStoreItemDataSimple(definitionId, o.quantity, -o.price);
- store.InsertOrder(si, out nid);
- }
- if (nid != -1) log.WriteText("added " + o.name + "\n", true);
- else log.WriteText("fail added " + o.name + "\n", true);
- }
- }
- else
- {
- log.WriteText("no price set for " + o.name+"\n", true);
- }
- //getStock(string n, AggregateInventoryInterface inv)
- }
- }
- }
- int lastUpdateTick = 0;
- int tick = 0;
- DateTime lastUpd = DateTime.MinValue;
- public void Main(string argument, UpdateType updateSource)
- {
- tick += 100;
- if (argument == "set")
- {
- set();
- }
- if((DateTime.Now - lastUpd).TotalMinutes > 5)
- {
- lastUpd = DateTime.Now;
- lastUpdateTick = tick;
- set();
- }
- }
- //can generate an inventory from a bunch of inventories, and can simplify programmatically sending stuff between such groupings.
- //the most immediate use here is automatically unstuffing grinders, stuffing torpedo launchers and other weapons, and sending excess garbage to connectors for ejection from the ship.
- //this interface doesn't recognize partial items, only whole units / integers.
- class AggregateInventoryInterface
- {
- int tickOffset = 0;
- static int offseti = 0;
- public AggregateInventoryInterface()
- {
- tickOffset = offseti;
- offseti += 10;
- }
- /*public void setContainers(List<IMyTerminalBlock> c)
- {
- containers = c;
- }*/
- public void setContainers<T>(List<T> c) where T : IMyTerminalBlock
- {
- containers.Clear();
- foreach (T i in c)
- {
- containers.Add(i);
- }
- }
- List<IMyTerminalBlock> containers = new List<IMyTerminalBlock>();
- public Dictionary<MyItemType, int> items = new Dictionary<MyItemType, int>();
- int updateInterval = 60 * 3;
- int lastUpdateTick = 0;
- int tick = 0;
- //if called every tick will update the inventory manifest every 3 seconds.
- //may not be necessary - a force update is best before doing anything important.
- public void update(bool force = false, int ticks = 1)
- {
- tick += ticks;
- if (tick + tickOffset - lastUpdateTick > updateInterval || force)
- {
- lastUpdateTick = tick;
- items.Clear();
- foreach (IMyTerminalBlock t in containers)
- {
- for (int i = 0; i < t.InventoryCount; i++)
- {
- var inv = t.GetInventory(i);
- List<MyInventoryItem> t_items = new List<MyInventoryItem>();
- inv.GetItems(t_items);
- foreach (MyInventoryItem item in t_items)
- {
- if (!items.ContainsKey(item.Type)) items[item.Type] = (int)Math.Floor((double)item.Amount);
- else items[item.Type] += (int)Math.Floor((double)item.Amount);
- }
- }
- }
- }
- }
- //these return the amount of items that could not be sent (unavailable, no room, whatever). Ergo, 0 means all were transferred.
- public int TransferItemTo(MyItemType type, int amount_to_transfer, IMyInventory destination)
- {
- float unit_volume = type.GetItemInfo().Volume;
- foreach (IMyTerminalBlock t in containers)
- {
- for (int i = 0; i < t.InventoryCount; i++)
- {
- var inv = t.GetInventory(i);
- List<MyInventoryItem> t_items = new List<MyInventoryItem>();
- inv.GetItems(t_items);
- foreach (MyInventoryItem item in t_items)
- {
- if (item.Type == type)
- {
- int transfer_amt = (int)Math.Floor((double)item.Amount);
- int max_room_for = (int)Math.Floor((double)(destination.MaxVolume - destination.CurrentVolume + (MyFixedPoint)0.001) / unit_volume);
- if (max_room_for < transfer_amt) transfer_amt = max_room_for;
- if (transfer_amt > amount_to_transfer) transfer_amt = amount_to_transfer;
- //log(">sending " + transfer_amt + " of " + item.Type.SubtypeId);
- if (inv.TransferItemTo(destination, item, transfer_amt)) amount_to_transfer -= transfer_amt;
- if (amount_to_transfer <= 0) return 0;
- }
- }
- }
- }
- return amount_to_transfer;
- }
- //these return the amount of items that could not be sent (unavailable, no room, whatever). Ergo, 0 means all were transferred.
- public int TransferItemTo(MyItemType type, int amount, AggregateInventoryInterface destination)
- {
- foreach (IMyTerminalBlock t in destination.containers)
- {
- for (int i = 0; i < t.InventoryCount; i++)
- {
- var inv = t.GetInventory(i);
- //log("sending " + amount + " of " + type.SubtypeId + " to " + t.DefinitionDisplayNameText);
- amount = TransferItemTo(type, amount, inv);
- if (amount <= 0) return amount;
- }
- }
- return amount;
- }
- static string[] common_ammo_identifiers = new string[]
- {
- "missile",
- "ammo",
- "magazine",
- "torpedo",
- "slug",
- "box"
- };
- static Dictionary<string, string> bulkreplace = new Dictionary<string, string>();
- static void initbulk()
- {
- var r = bulkreplace;
- if (r.Count != 0) return;
- r["AngleGrinder"] = "Grinder";
- r["CrateTomato"] = "Crate of Tomatoes";
- r["HeavyArms"] = "Heavy Armaments";
- r["GravityGenerator"] = "Gravity Comp.";
- r["RadioCommunication"] = "Radio-comm Comp.";
- r["Detector"] = "Detector Comp.";
- r["LargeTube"] = "Large Steel Tube";
- r["Construction"] = "Construction Comp.";
- }
- static public string prettyItemName(MyItemType item)
- {
- initbulk();
- string name = item.SubtypeId.Replace("MyObjectBuilder_", "").Replace("_", " ");
- var nfo = item.GetItemInfo();
- foreach (KeyValuePair<string, string> kvp in bulkreplace)
- {
- if (name == kvp.Key)
- {
- name = kvp.Value;
- break;
- }
- else if (name.StartsWith(kvp.Key))
- {
- name = name.Replace(kvp.Key, kvp.Value);
- break;
- }
- }
- if (nfo.IsAmmo)
- {
- var l = name.ToLower();
- if (name.Length > 20) name = name.Replace("Magazine", "");
- else
- {
- if (name.StartsWith("Missile"))
- {
- name = name.Substring("Missile".Length) + " Missile";
- }
- if (l.IndexOf("magazine") == -1)// && l.IndexOf(' ') == -1)
- {
- }
- }
- l = name.ToLower();
- bool id = false;
- foreach (var i in common_ammo_identifiers)
- {
- if (l.IndexOf(i) != -1)
- {
- id = true;
- break;
- }
- }
- if (!id)
- {
- name += "Ammo";
- }
- }
- if (nfo.IsTool && name.Length > 5)
- {
- string nsub = name.Substring(0, name.Length - 5);
- if (name.EndsWith("1Item")) name = nsub;
- else if (name.EndsWith("2Item")) name = nsub + " (Enhanced)";
- else if (name.EndsWith("3Item")) name = nsub + " (Proficient)";
- else if (name.EndsWith("4Item")) name = nsub + " (Elite)";
- }
- int capcount = 0;
- foreach (char c in name) if (char.IsUpper(c)) capcount += 1;
- if (capcount <= 1)
- {
- if (nfo.IsOre && name != "Stone") return name + " Ore";
- if (nfo.IsIngot)
- {
- if (name == "Stone") return "Gravel";
- return name + " Ingot";
- }
- //if (name == "Stone Ingot") name = "Gravel";
- }
- else
- {
- string rename = "";
- // bool didLast = false;
- for (int i = 0; i < name.Length; i++)
- {
- if (i > 0 && i < name.Length - 1)
- {
- bool notlast = true;
- if (rename.Length > 0) notlast = rename[rename.Length - 1] != ' ';
- if (name[i - 1] != ' ' && name[i] != ' ' && name[i + 1] != ' ' && notlast)
- {
- bool prev = char.IsUpper(name[i - 1]);
- bool cur = char.IsUpper(name[i]);
- bool next = char.IsUpper(name[i + 1]);
- bool nextLetter = char.IsLetter(name[i + 1]);
- if ((cur && !next && nextLetter && name[i - 1] != '(' && name[i] != ' ') || (!prev && name[i - 1] != '(' && cur && name[i] != ' '))// && !prev)
- {
- rename += " ";
- }
- if (prev && !char.IsLetter(name[i]) && name[i] != ' ') rename += " ";
- }
- }
- rename += name[i]; ;
- }
- name = rename;
- }
- name = name.Replace(" Adv ", " Advanced ");
- if (nfo.IsAmmo && name.Length > 4)
- {
- if (name.EndsWith("MCRN")) name = name.Substring(0, name.Length - 4) + "(MCRN)";
- if (name.EndsWith("UNN")) name = name.Substring(0, name.Length - 3) + "(UNN)";
- }
- return name;
- }
- public string listInv(Func<MyItemType,bool> filter = null)
- {
- string r = "";
- int nlen = 0;
- Dictionary<string, int> entries = new Dictionary<string, int>();
- foreach (KeyValuePair<MyItemType, int> kvp in items)
- {
- if (filter != null) if (!filter(kvp.Key)) continue;
- entries[prettyItemName(kvp.Key)] = kvp.Value;
- }
- foreach (KeyValuePair<string, int> kvp in entries)if (kvp.Key.Length > nlen) nlen = kvp.Key.Length;
- foreach (KeyValuePair<string, int> kvp in entries)
- {
- string d = kvp.Key;
- if (d.Length < nlen) d += new string('_', nlen - d.Length);
- r += d + ": " + kvp.Value + "\n";
- }
- return r;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement