maozs3946 发表于 2019-11-2 22:57

求助如何将建筑修改为自动运作

如题,比如碎石机这样需要复制人操作的建筑如何能用dnspy修改为像窑炉那样加好材料自动就会运行的呢?
窑炉的代码
string id = "Kiln";
      int width = 2;
      int height = 2;
      string anim = "kiln_kanim";
      int hitpoints = 100;
      float construction_time = 30f;
      float[] tier = TUNING.BUILDINGS.CONSTRUCTION_MASS_KG.TIER3;
      string[] all_METALS = MATERIALS.ALL_METALS;
      float melting_point = 800f;
      BuildLocationRule build_location_rule = BuildLocationRule.OnFloor;
      EffectorValues tier2 = NOISE_POLLUTION.NOISY.TIER5;
      BuildingDef buildingDef = BuildingTemplates.CreateBuildingDef(id, width, height, anim, hitpoints, construction_time, tier, all_METALS, melting_point, build_location_rule, TUNING.BUILDINGS.DECOR.PENALTY.TIER1, tier2, 0.2f);
      buildingDef.Overheatable = false;
      buildingDef.RequiresPowerInput = false;
      buildingDef.ExhaustKilowattsWhenActive = 16f;
      buildingDef.SelfHeatKilowattsWhenActive = 4f;
      buildingDef.AudioCategory = "HollowMetal";
      return buildingDef;
    }
    // Token: 0x060062ED RID: 25325 RVA: 0x001D9E90 File Offset: 0x001D8090
    public override void ConfigureBuildingTemplate(GameObject go, Tag prefab_tag)
    {
      go.GetComponent<KPrefabID>().AddTag(RoomConstraints.ConstraintTags.IndustrialMachinery, false);
      go.AddOrGet<DropAllWorkable>();
      go.AddOrGet<BuildingComplete>().isManuallyOperated = false;
      ComplexFabricator complexFabricator = go.AddOrGet<ComplexFabricator>();
      complexFabricator.resultState = ComplexFabricator.ResultState.Heated;
      complexFabricator.heatedTemperature = 353.15f;
      complexFabricator.duplicantOperated = false;
      complexFabricator.sideScreenStyle = ComplexFabricatorSideScreen.StyleSetting.ListQueueHybrid;
      go.AddOrGet<FabricatorIngredientStatusManager>();
      go.AddOrGet<CopyBuildingSettings>();
      BuildingTemplates.CreateComplexFabricatorStorage(go, complexFabricator);
      this.ConfgiureRecipes();
      Prioritizable.AddRef(go);
碎石机的代码
string id = "RockCrusher";
      int width = 4;
      int height = 4;
      string anim = "rockrefinery_kanim";
      int hitpoints = 30;
      float construction_time = 60f;
      float[] tier = TUNING.BUILDINGS.CONSTRUCTION_MASS_KG.TIER5;
      string[] all_METALS = MATERIALS.ALL_METALS;
      float melting_point = 2400f;
      BuildLocationRule build_location_rule = BuildLocationRule.OnFloor;
      EffectorValues tier2 = NOISE_POLLUTION.NOISY.TIER6;
      BuildingDef buildingDef = BuildingTemplates.CreateBuildingDef(id, width, height, anim, hitpoints, construction_time, tier, all_METALS, melting_point, build_location_rule, TUNING.BUILDINGS.DECOR.PENALTY.TIER2, tier2, 0.2f);
      buildingDef.RequiresPowerInput = true;
      buildingDef.EnergyConsumptionWhenActive = 120f;
      buildingDef.SelfHeatKilowattsWhenActive = 4f;
      buildingDef.ViewMode = OverlayModes.Power.ID;
      buildingDef.AudioCategory = "HollowMetal";
      buildingDef.AudioSize = "large";
      return buildingDef;
    }
    // Token: 0x060066B0 RID: 26288 RVA: 0x001EC2AC File Offset: 0x001EA4AC
    public override void ConfigureBuildingTemplate(GameObject go, Tag prefab_tag)
    {
      go.AddOrGet<DropAllWorkable>();
      go.AddOrGet<BuildingComplete>().isManuallyOperated = true;
      ComplexFabricator complexFabricator = go.AddOrGet<ComplexFabricator>();
      complexFabricator.sideScreenStyle = ComplexFabricatorSideScreen.StyleSetting.ListQueueHybrid;
      complexFabricator.duplicantOperated = true;
      go.AddOrGet<FabricatorIngredientStatusManager>();
      go.AddOrGet<CopyBuildingSettings>();
      ComplexFabricatorWorkable complexFabricatorWorkable = go.AddOrGet<ComplexFabricatorWorkable>();
      BuildingTemplates.CreateComplexFabricatorStorage(go, complexFabricator);
      complexFabricatorWorkable.overrideAnims = new KAnimFile[]
      {
            Assets.GetAnim("anim_interacts_rockrefinery_kanim")
      };
      complexFabricatorWorkable.workingPstComplete = "working_pst_complete";
      Tag tag = SimHashes.Sand.CreateTag();
      foreach (Element element in ElementLoader.elements.FindAll((Element e) => e.HasTag(GameTags.Crushable)))
      {
            ComplexRecipe.RecipeElement[] array = new ComplexRecipe.RecipeElement[]
            {
                new ComplexRecipe.RecipeElement(element.tag, 100f)
            };
            ComplexRecipe.RecipeElement[] array2 = new ComplexRecipe.RecipeElement[]
            {
                new ComplexRecipe.RecipeElement(ElementLoader.FindElementByHash(SimHashes.Niobium).tag, 5f),
                new ComplexRecipe.RecipeElement(tag, 95f)
            };
对比了一下代码并没有发现有自动和须人操作的概念呢,
有大神指导吗

耕耘gareth 发表于 2019-11-3 07:30

本帖最后由 耕耘gareth 于 2019-11-3 08:23 编辑

public static void Postfix(GameObject go)
                {
                        if (!NoDupeHelper.CheckConfig("Rock Crusher"))
                        {
                              return;
                        }
                        NoDupeHelper.SetAutomatic(go, go.GetComponent<ComplexFabricator>());
                }
      }
}



public class NoDupeHelper
      {
                // Token: 0x0600007C RID: 124 RVA: 0x00003DA8 File Offset: 0x00001FA8
                public static void SetAutomatic(GameObject go, object fabricatorObject)
                {
                        Object arg_0E_0 = go.GetComponent<BuildingComplete>();
                        ComplexFabricator complexFabricator = (ComplexFabricator)fabricatorObject;
                        if (arg_0E_0 == null)
                        {
                              Debug.LogWarning("SetAutomatic bc was null");
                              return;
                        }
                        if (complexFabricator == null)
                        {
                              Debug.LogWarning("SetAutomatic fabricator was null");
                              return;
                        }
                        go.AddOrGet<BuildingComplete>().isManuallyOperated = false;
                        complexFabricator.duplicantOperated = false;
                }

                // Token: 0x0600007D RID: 125 RVA: 0x00003DFC File Offset: 0x00001FFC
                public static bool CheckConfig(Dictionary<string, bool> state, string key)
                {
                        try
                        {
                              bool result = state;
                              Debug.Log("CheckConfig " + key + " resulted in " + result.ToString());
                              return result;
                        }
                        catch (Exception)
                        {
                              Debug.LogWarning("CheckSetting could not resolve: " + key);
                        }
                        return false;
                }

                // Token: 0x0600007E RID: 126 RVA: 0x00003E58 File Offset: 0x00002058
                public static bool CheckConfig(string key)
                {
                        if (!CustomizeBuildingsState.StateManager.State.NoDupeBuildingsGlobal)
                        {
                              return false;
                        }
                        try
                        {
                              bool result = CustomizeBuildingsState.StateManager.State.NoDupeBuildings;
                              Debug.Log("CheckConfig " + key + " resulted in " + result.ToString());
                              return result;
                        }
                        catch (Exception)
                        {
                              Debug.LogWarning("CheckConfig could not resolve: " + key);
                        }
                        return false;
                }
      }
}

其中prifix,postfix是mod向游戏中插入代码的专用函数
这里有详细说明https://github.com/pardeike/Harmony/wiki/Patching
NoDupeHelper是他自定义的函数
这是别人做的mod 的代码,你有兴趣可以研究一下

耕耘gareth 发表于 2019-11-3 07:41


这是他的mod,里面包括很多内容,什么改箱子的容量,电线的电压等,但我觉得最值得研究的代码是他把所有的需要人操作的机器改成自动的
我给的这个是老版本,不建议直接在游戏里用

maozs3946 发表于 2019-11-3 14:36

耕耘gareth 发表于 2019-11-3 07:41
这是他的mod,里面包括很多内容,什么改箱子的容量,电线的电压等,但我觉得最值得研究的代码是他把所有的 ...

谢谢,研究一项修改了那个建筑参数

42422315 发表于 2019-11-5 21:29

订阅Customize Buildings (more capacity, less dupes)
MOD

windvchina 发表于 2020-2-5 00:01

      go.GetComponent<KPrefabID>().AddTag(RoomConstraints.ConstraintTags.IndustrialMachinery, false);
      go.AddOrGet<DropAllWorkable>();
      go.AddOrGet<BuildingComplete>().isManuallyOperated = false;
      ComplexFabricator complexFabricator = go.AddOrGet<ComplexFabricator>();
      complexFabricator.resultState = ComplexFabricator.ResultState.Heated;
      complexFabricator.heatedTemperature = 353.15f;
      complexFabricator.duplicantOperated = false;
      complexFabricator.sideScreenStyle = ComplexFabricatorSideScreen.StyleSetting.ListQueueHybrid;

窑炉的代码里这一段 看懂或贴进去就行了。

windvchina 发表于 2020-2-5 15:05

      go.AddOrGet<BuildingComplete>().isManuallyOperated = false;
      complexFabricator.duplicantOperated = false;

再确认了一下只要有这俩参数 就够了。无论是自动制造食物,炼钢,玻璃或是碎石。都可以自动完成。
页: [1]
查看完整版本: 求助如何将建筑修改为自动运作