## 太空工程师编程笔记3 - 物流与生产
### 物流与生产相关功能
物流与生产是管理基地或者大型飞船的基础,也是官方编程手册中没有说得太清楚的地方。
利用API,其实可以做到这么几件事情:
1、物体的统计调度,及管道联通性检查。
2、控制组装机组装或拆装,将组件添加到队列或从队列中删除。
3、控制精炼厂精炼。
4、控制筛选器的筛选。
#### API
存储接口,各类有存储能力的块都继承了此接口。功能可以看接口,比较明白。
~~~csharp
public interface IMyInventory
{
// Methods
bool CanItemsBeAdded(MyFixedPoint amount, SerializableDefinitionId contentId);
bool ContainItems(MyFixedPoint amount, MyObjectBuilder_PhysicalObject ob);
IMyInventoryItem FindItem(SerializableDefinitionId contentId);
MyFixedPoint GetItemAmount(SerializableDefinitionId contentId, MyItemFlags flags = 0);
IMyInventoryItem GetItemByID(uint id);
List<IMyInventoryItem> GetItems();
bool IsConnectedTo(IMyInventory dst);
bool IsItemAt(int position);
bool TransferItemFrom(IMyInventory sourceInventory, int sourceItemIndex, int? targetItemIndex = new int?(), bool? stackIfPossible = new bool?(), MyFixedPoint? amount = new MyFixedPoint?());
bool TransferItemTo(IMyInventory dst, int sourceItemIndex, int? targetItemIndex = new int?(), bool? stackIfPossible = new bool?(), MyFixedPoint? amount = new MyFixedPoint?());
// Properties
bool IsFull { get; }
Vector3 Size { get; }
MyFixedPoint CurrentMass { get; }
MyFixedPoint MaxVolume { get; }
MyFixedPoint CurrentVolume { get; }
IMyInventoryOwner Owner { get; }
}
~~~
存储Item,即每个存储项,比如一坨矿石。
~~~csharp
public interface IMyInventoryItem
{
// Properties
MyFixedPoint Amount { get; set; }
float Scale { get; set; }
MyObjectBuilder_Base Content { get; set; }
uint ItemId { get; set; }
}
~~~
组装机
~~~csharp
public interface IMyAssembler : IMyProductionBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
{
// Properties
[Obsolete("Use the Mode property")]
bool DisassembleEnabled { get; }
float CurrentProgress { get; }
MyAssemblerMode Mode { get; set; }
bool CooperativeMode { get; set; }
bool Repeating { get; set; }
}
~~~
精炼厂其实没有特殊接口
~~~csharp
public interface IMyRefinery : IMyProductionBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
{
}
~~~
组装机和精炼厂共同继承的IMyProductionBlock才是生产队列的关键所在
~~~csharp
public interface IMyProductionBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
{
// Methods
void AddQueueItem(MyDefinitionId blueprint, decimal amount);
void AddQueueItem(MyDefinitionId blueprint, double amount);
void AddQueueItem(MyDefinitionId blueprint, MyFixedPoint amount);
bool CanUseBlueprint(MyDefinitionId blueprint);
void ClearQueue();
void GetQueue(List<MyProductionItem> items);
void InsertQueueItem(int idx, MyDefinitionId blueprint, decimal amount);
void InsertQueueItem(int idx, MyDefinitionId blueprint, double amount);
void InsertQueueItem(int idx, MyDefinitionId blueprint, MyFixedPoint amount);
void MoveQueueItemRequest(uint queueItemId, int targetIdx);
void RemoveQueueItem(int idx, decimal amount);
void RemoveQueueItem(int idx, double amount);
void RemoveQueueItem(int idx, MyFixedPoint amount);
// Properties
IMyInventory InputInventory { get; }
IMyInventory OutputInventory { get; }
bool IsProducing { get; }
bool IsQueueEmpty { get; }
uint NextItemId { get; }
bool UseConveyorSystem { get; set; }
}
~~~
筛选器
~~~csharp
public interface IMyConveyorSorter : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
{
// Methods
void AddItem(MyInventoryItemFilter item);
void GetFilterList(List<MyInventoryItemFilter> items);
bool IsAllowed(MyDefinitionId id);
void RemoveItem(MyInventoryItemFilter item);
void SetFilter(MyConveyorSorterMode mode, List<MyInventoryItemFilter> items);
// Properties
bool DrainAll { get; set; }
MyConveyorSorterMode Mode { get; }
}
~~~
以及他们用到的MyDefinitionId
~~~csharp
public struct MyDefinitionId : IEquatable<MyDefinitionId>
{
public static readonly DefinitionIdComparerType Comparer;
public readonly MyObjectBuilderType TypeId;
public readonly MyStringHash SubtypeId;
public static MyDefinitionId FromContent(MyObjectBuilder_Base content);
public static MyDefinitionId Parse(string id);
public static bool TryParse(string id, out MyDefinitionId definitionId);
public static bool TryParse(string type, string subtype, out MyDefinitionId definitionId);
public string SubtypeName { get; }
public MyDefinitionId(MyObjectBuilderType type);
public MyDefinitionId(MyObjectBuilderType type, string subtypeName);
public MyDefinitionId(MyObjectBuilderType type, MyStringHash subtypeId);
public MyDefinitionId(MyRuntimeObjectBuilderId type, MyStringHash subtypeId);
public override int GetHashCode();
public long GetHashCodeLong();
public override bool Equals(object obj);
public override string ToString();
public bool Equals(MyDefinitionId other);
public static bool operator ==(MyDefinitionId l, MyDefinitionId r);
public static bool operator !=(MyDefinitionId l, MyDefinitionId r);
public static implicit operator MyDefinitionId(SerializableDefinitionId v);
public static implicit operator SerializableDefinitionId(MyDefinitionId v);
static MyDefinitionId();
// Nested Types
public class DefinitionIdComparerType : IEqualityComparer<MyDefinitionId>
{
// Methods
public DefinitionIdComparerType();
public bool Equals(MyDefinitionId x, MyDefinitionId y);
public int GetHashCode(MyDefinitionId obj);
}
}
~~~
### 编程
#### 物品统计
统计当前网格所有的物品,并输出汇总数量
~~~csharp
Dictionary<string,int> list=new Dictionary<string,int>();
public void Main(string argument, UpdateType updateSource)
{
//先获取所有块
List<IMyTerminalBlock> blocks=new List<IMyTerminalBlock>();
GridTerminalSystem.GetBlocksOfType<IMyTerminalBlock>(blocks,block=>block.HasInventory);
Echo("共有存储个数:"+blocks.Count);
//统计物品数量
foreach (IMyTerminalBlock block in blocks)
{
foreach (IMyInventoryItem item in block.GetInventory().GetItems())
{
//Echo(item.Amount.ToString());
//Echo(item.Scale.ToString());
//Echo(item.Content.TypeId.ToString());
//Echo(item.ItemId.ToString());
string itemName=item.Content.TypeId.ToString()+"-"+item.Content.SubtypeId.ToString();
int itemCount=(int)item.Amount;
if(list.ContainsKey(itemName)){
list[itemName]+=itemCount;
}else{
list.Add(itemName,itemCount);
}
}
}
//在终端输出
Echo("共有以下物体:");
foreach (var item in list)
{
Echo(item.Key+":"+item.Value);
}
}
~~~
#### 物品归集
将所有可以转移到第一个存储的物体,转移到第一个存储。
这里要注意的是,组装机和精炼厂存储并非通过GetInventory获得,应通过IMyProductionBlock的InputInventory和OutputInventory操作。
~~~csharp
public void Main(string argument, UpdateType updateSource)
{
//先获取所有块
List<IMyTerminalBlock> blocks=new List<IMyTerminalBlock>();
GridTerminalSystem.GetBlocksOfType<IMyTerminalBlock>(blocks,block=>block.HasInventory);
Echo("共有存储个数:"+blocks.Count);
if(blocks.Count<1)return;
//取第一个
IMyTerminalBlock first=blocks[0];
Echo("第一块是:"+first.CustomName);
//进行转运
foreach (IMyTerminalBlock block in blocks)
{
if(block!=first&&block.GetInventory()!=null)
foreach (IMyInventoryItem item in block.GetInventory().GetItems())
{
if(block.GetInventory().IsConnectedTo(first.GetInventory())){
Echo("正在从"+block.CustomName+"运输"+item.ToString());
if(block.GetInventory().IsItemAt(0))block.GetInventory().TransferItemTo(first.GetInventory(),0);
}
}
}
}
~~~
#### 控制组装机生产队列
打印组装机任务队列,并向任务队列里添加任务。
~~~csharp
public void Main(string argument, UpdateType updateSource)
{
//先获取一个组装机
List<IMyAssembler> assemblers=new List<IMyAssembler>();
GridTerminalSystem.GetBlocksOfType<IMyAssembler>(assemblers);
if(assemblers.Count<1)return;
IMyAssembler assembler=assemblers[0];
Echo("目标组装机:"+assembler.CustomName);
Echo("工作状态:"+assembler.Mode);
Echo("当前任务队列:");
List<MyProductionItem> items=new List<MyProductionItem>();
assembler.GetQueue(items);
foreach (var item in items)
{
Echo(item.BlueprintId+":"+item.Amount);
}
//设定组装机工作状态,不管其之前如何
assembler.Mode=MyAssemblerMode.Assembly;
//assembler.Mode=MyAssemblerMode.Disassembly;
//创建一个物品蓝图
MyDefinitionId blueprint=MyDefinitionId.Parse("MyObjectBuilder_BlueprintDefinition/BulletproofGlass");
//确认并添加到组装机队列
if(assembler.CanUseBlueprint(blueprint))assembler.AddQueueItem(blueprint,5.0);
}
~~~
- 序言
- 写在前面的话
- 太空工程师
- MEA小组
- 一、入门
- 1.1 基础概念
- 1.2 编程工具
- 1.3 变量
- 1.4 函数 Function
- 1.5 基本语法
- 1.5.1 运算符
- 1.5.2 if
- 1.5.3 for
- 1.5.4 其他语法
- 1.3 类 Class
- 二、编程块
- 2.1 方块的概念
- 2.2 List<T>结构
- 2.3 获取方块
- 2.4 方块的使用
- 三、Ship 类
- 3.1 简介
- Ship v0.5
- 代码
- 手册(待更新)
- 例子(待更新)
- Ship v1.0
- 代码
- 例子
- 文档
- 实例化
- 内置变量
- 内置方法
- Target类
- 四、运动控制算法在SE中的应用
- 4.1 运动控制介绍
- 4.2 过程控制
- 4.3 震荡和动态误差
- 4.4 误差累加方案
- 4.5 PID算法
- 4.6 对PID算法的一点点简化
- 4.7 一阶惯性系统的PID算法优化的研究
- 五、MEA方块类
- 5.0 核心代码目录
- v1.0核心代码
- v1.1 核心代码
- v2.0 核心代码
- 5.1 类的概念
- 5.2 MEA的方块类(Block)
- 5.3 方块类文档
- 5.4 方块类2.0 全教程
- 5.4.1 安装和使用
- 5.4.2 方块类(Block)
- 5.4.3 显示屏类(DisplayScreen)
- 5.4.4 LCD类(LCD)
- 5.4.5 主控座椅类(Cockpit)
- 六、疯猴的编程笔记
- 第一个程序
- 获取和控制其他块
- 物流与生产
- 界面与通信
- 运动与姿态
- 侦测与导航
- 七、SteamZhou的笔记
- 有趣而花里胡哨的IDEA
- 八、质子对撞炮的笔记
- 属性 Property
- 接口 interface