public override void InitializeStates(out BaseState default_state) { if (waitingForCoolantStatus == null) { waitingForCoolantStatus = new StatusItem("waitingForCoolantStatus", BUILDING.STATUSITEMS.ENOUGH_COOLANT.NAME, BUILDING.STATUSITEMS.ENOUGH_COOLANT.TOOLTIP, "status_item_no_liquid_to_pump", StatusItem.IconType.Custom, NotificationType.BadMinor, false, OverlayModes.None.ID) { resolveStringCallback = delegate(string str, object obj) { var lcfr = (LiquidCooledFueledRefinery)obj; return(string.Format(str, lcfr.coolantTag.ProperName(), GameUtil.GetFormattedMass(lcfr.minCoolantMass, GameUtil.TimeSlice.None, GameUtil.MetricMassFormat.UseThreshold, true, "{0:0.#}"))); } }; } if (waitingForFuelStatus == null) { waitingForFuelStatus = new StatusItem("waitingForFuelStatus", BUILDING.STATUSITEMS.ENOUGH_FUEL.NAME, BUILDING.STATUSITEMS.ENOUGH_FUEL.TOOLTIP, "status_item_resource_unavailable", StatusItem.IconType.Custom, NotificationType.BadMinor, false, OverlayModes.None.ID) { resolveStringCallback = delegate(string str, object obj) { var lcfr = (LiquidCooledFueledRefinery)obj; return(string.Format(str, lcfr.fuelTag.ProperName(), GameUtil.GetFormattedMass(SmelterConfig.START_FUEL_MASS, GameUtil.TimeSlice.None, GameUtil.MetricMassFormat.UseThreshold, true, "{0:0.#}"))); } }; } if (waitingForEmptyingStatus == null) { waitingForEmptyingStatus = new StatusItem("waitingForEmptying", STRINGS.BUILDINGS.STATUSITEMS.SMELTERNEEDSEMPTYING.NAME, STRINGS.BUILDINGS.STATUSITEMS.SMELTERNEEDSEMPTYING.TOOLTIP, "status_item_empty_pipe", StatusItem.IconType.Custom, NotificationType.BadMinor, false, OverlayModes.None.ID); } default_state = waiting; // у нас нет выходной трубы, однако воспользуемся готовым флагом для обработки нехватки топлива // внимание! если событие OnStorageChange (или иное событие) // прилетело из глубины недр ComplexFabricator в процессе выполнения рецепта // то попытка манипулировать флагами operational.SetFlag // приводит к хитровыебанному вылету в недрах ComplexFabricator // поэтому выключать флаг нужно только в проверке IsOutOfFuel (прилетает от ElementConverter) // или в проверках выполняемых не во время выполнения рецепта root .OnSignal(coolant_too_hot, needsEmptying); waiting .Enter((StatesInstance smi) => smi.UpdateStates()) .EventHandler(GameHashes.OnStorageChange, (StatesInstance smi) => smi.UpdateStates()); waiting.for_coolant .ToggleStatusItem(waitingForCoolantStatus, (StatesInstance smi) => smi.master); waiting.for_fuel .ToggleStatusItem(waitingForFuelStatus, (StatesInstance smi) => smi.master); waiting.for_coolant_and_fuel .ToggleStatusItem(waitingForCoolantStatus, (StatesInstance smi) => smi.master) .ToggleStatusItem(waitingForFuelStatus, (StatesInstance smi) => smi.master); ready .Enter((StatesInstance smi) => { smi.master.SetQueueDirty(); smi.master.operational.SetFlag(coolantOutputPipeEmpty, true); }) .EventTransition(GameHashes.OnStorageChange, waiting, (StatesInstance smi) => !smi.master.HasEnoughCoolant() || smi.master.IsOutOfFuel()); needsEmptying .Enter((StatesInstance smi) => { smi.master.operational.SetFlag(coolantOutputPipeEmpty, false); smi.master.SetQueueDirty(); smi.Trigger((int)GameHashes.DroppedAll); // обработчик в ComplexFabricator очищает и обновляет очередь задач. должно помочь предотвратить сбои smi.CreateEmptyChore(); }) .Exit((StatesInstance smi) => smi.CancelEmptyChore()) .EventTransition(GameHashes.OnStorageChange, waiting, (StatesInstance smi) => smi.master.IsHotCoolantIsRemoved()) .ToggleStatusItem(waitingForEmptyingStatus); }