private static void OnFuelChanged(
            IStaticWorldObject objectManufacturer,
            FuelBurningState state,
            CraftingQueue byproductsCraftQueue,
            ManufacturingConfig config)
        {
            if (!config.IsProduceByproducts)
            {
                return;
            }

            var currentByproductRecipe = byproductsCraftQueue.QueueItems.FirstOrDefault()?.Recipe
                                         as Recipe.RecipeForManufacturingByproduct;
            var newByproductRecipe = config.MatchRecipeForByproduct(state.CurrentFuelItemType);

            if (currentByproductRecipe == newByproductRecipe)
            {
                return;
            }

            byproductsCraftQueue.Clear();

            if (newByproductRecipe != null)
            {
                CraftingMechanics.ServerStartCrafting(
                    objectManufacturer,
                    null,
                    byproductsCraftQueue,
                    newByproductRecipe,
                    // unlimited count
                    countToCraft: ushort.MaxValue);
            }
        }
Exemple #2
0
        /// <summary>
        /// Refreshes best matching recipe, auto-select it if needed by config.
        /// </summary>
        private static void RefreshRecipe(
            ManufacturingState state,
            ManufacturingConfig config,
            IStaticWorldObject objectManufacturer)
        {
            var selectedRecipe = state.SelectedRecipe;
            var bestRecipe     = SharedMatchBestRecipe(state,
                                                       config,
                                                       objectManufacturer);

            if (bestRecipe is not null &&
                config.IsAutoSelectRecipe)
            {
                // auto-select the best recipe
                selectedRecipe = state.SelectedRecipe = bestRecipe;
                bestRecipe     = null;
                state.CraftingQueue.Clear();
            }

            if (selectedRecipe is null)
            {
                return;
            }

            // refresh selected recipe
            var isSelectedRecipeCanBeCrafted = selectedRecipe.CanBeCrafted(
                character: null,
                objectManufacturer,
                state.CraftingQueue,
                countToCraft: 1);

            if (isSelectedRecipeCanBeCrafted)
            {
                var currentCraftingRecipe = state.CraftingQueue.QueueItems.FirstOrDefault();
                if (currentCraftingRecipe is null ||
                    currentCraftingRecipe.RecipeEntry?.Recipe != selectedRecipe)
                {
                    // there is nothing crafting or something different is crafting - start crafting the new selected recipe
                    Logger.Info($"Manufacturing of recipe {selectedRecipe} started at {objectManufacturer}");
                    CraftingMechanics.ServerStartCrafting(
                        objectManufacturer,
                        null,
                        state.CraftingQueue,
                        new RecipeWithSkin(selectedRecipe),
                        countToCraft: ushort.MaxValue);
                }
            }
            else if (state.CraftingQueue.QueueItems.Count > 0)
            {
                // the selected recipe cannot be crafted
                // clear current queue (progress is lost!)
                // nothing will be crafted now
                Logger.Info($"Manufacturing stopped at {objectManufacturer} - the recipe cannot be crafted anymore");
                state.CraftingQueue.Clear();
            }
        }
Exemple #3
0
        public bool ServerRemote_CraftRecipe(RecipeWithSkin recipeEntry, ushort countToCraft)
        {
            recipeEntry.Validate();
            var character            = ServerRemoteContext.Character;
            var characterServerState = PlayerCharacter.GetPrivateState(character);

            if (recipeEntry.ProtoItemSkinOverride is IProtoItemWithSkinData protoItemSkin)
            {
                if (!Server.Items.IsSkinOwned(character, (ushort)protoItemSkin.SkinId))
                {
                    throw new Exception("The skin is not owned: " + protoItemSkin + " for " + character);
                }
            }

            IStaticWorldObject station;
            var craftingQueue = characterServerState.CraftingQueue;

            switch (recipeEntry.Recipe)
            {
            case Recipe.RecipeForHandCrafting:
                // simply craft by character
                station = null;
                break;

            case Recipe.RecipeForStationCrafting recipeForStation:
                station = SharedFindNearbyStationOfTypes(recipeForStation.StationTypes, character);
                if (station is null)
                {
                    Logger.Error(
                        $"No crafting stations of types {recipeForStation.StationTypes.GetJoinedString()} found nearby character {character} at position {character.Position}");
                    return(false);
                }

                break;

            default:
                throw new Exception("Incorrect recipe for in-hand or station crafting: " + recipeEntry);
            }

            // extra check (it's also done in the recipe itself)
            if (!recipeEntry.Recipe.SharedIsTechUnlocked(character))
            {
                // locked recipe
                return(false);
            }

            var maxCraftingQueueEntriesCount = SharedGetMaxCraftingQueueEntriesCount(character);

            if (recipeEntry.Recipe.OutputItems.Items[0].ProtoItem.IsStackable)
            {
                // stackable items
                if (!SharedValidateQueueIsNotFull(character, recipeEntry, countToCraft, maxCraftingQueueEntriesCount))
                {
                    return(false);
                }

                CraftingMechanics.ServerStartCrafting(station,
                                                      character,
                                                      craftingQueue,
                                                      recipeEntry,
                                                      countToCraft,
                                                      maxQueueSize: maxCraftingQueueEntriesCount);
            }
            else
            {
                // non-stackable items
                countToCraft = MathHelper.Clamp(countToCraft,
                                                min: (ushort)1,
                                                max: maxCraftingQueueEntriesCount);
                for (var i = 0; i < countToCraft; i++)
                {
                    if (!SharedValidateQueueIsNotFull(character,
                                                      recipeEntry,
                                                      countToCraft: 1,
                                                      maxCraftingQueueEntriesCount))
                    {
                        return(false);
                    }

                    CraftingMechanics.ServerStartCrafting(station,
                                                          character,
                                                          craftingQueue,
                                                          recipeEntry,
                                                          countToCraft: 1,
                                                          maxQueueSize: maxCraftingQueueEntriesCount);
                }
            }

            return(true);
        }
        public bool ServerRemote_CraftRecipe(Recipe recipe, ushort countToCraft)
        {
            var character            = ServerRemoteContext.Character;
            var characterServerState = PlayerCharacter.GetPrivateState(character);

            IStaticWorldObject station;
            var craftingQueue = characterServerState.CraftingQueue;

            if (recipe.RecipeType == RecipeType.Hand)
            {
                // simply craft by character
                station = null;
            }
            else
            {
                var recipeForStation = (Recipe.BaseRecipeForStation)recipe;
                station = SharedFindNearbyStationOfTypes(recipeForStation.StationTypes, character);
                if (station == null)
                {
                    Logger.Error(
                        $"No crafting stations of types {recipeForStation.StationTypes.GetJoinedString()} found nearby character {character} at position {character.Position}");
                    return(false);
                }

                if (recipeForStation is Recipe.RecipeForManufacturing)
                {
                    // manufacture on station
                    throw new Exception("Cannot craft in hand recipe for station manufacturing");
                }
            }

            var maxCraftingQueueEntriesCount = SharedGetMaxCraftingQueueEntriesCount(character);

            if (recipe.OutputItems.Items[0].ProtoItem.IsStackable)
            {
                // stackable items
                if (!SharedValidateQueueIsNotFull(character, recipe, countToCraft, maxCraftingQueueEntriesCount))
                {
                    return(false);
                }

                CraftingMechanics.ServerStartCrafting(station,
                                                      character,
                                                      craftingQueue,
                                                      recipe,
                                                      countToCraft,
                                                      maxQueueSize: maxCraftingQueueEntriesCount);
            }
            else
            {
                // non-stackable items
                countToCraft = MathHelper.Clamp(countToCraft,
                                                min: (ushort)1,
                                                max: maxCraftingQueueEntriesCount);
                for (var i = 0; i < countToCraft; i++)
                {
                    if (!SharedValidateQueueIsNotFull(character,
                                                      recipe,
                                                      countToCraft: 1,
                                                      maxCraftingQueueEntriesCount))
                    {
                        return(false);
                    }

                    CraftingMechanics.ServerStartCrafting(station,
                                                          character,
                                                          craftingQueue,
                                                          recipe,
                                                          countToCraft: 1,
                                                          maxQueueSize: maxCraftingQueueEntriesCount);
                }
            }

            return(true);
        }