public static async Task ClientStartCrafting(RecipeWithSkin recipeEntry, ushort countToCraft) { recipeEntry.Validate(); if (recipeEntry.ProtoItemSkinOverride is IProtoItemWithSkinData protoItemSkin) { if (!Client.Microtransactions.IsSkinOwned((ushort)protoItemSkin.SkinId)) { throw new Exception("The skin is not owned: " + protoItemSkin); } } if (SharedValidateQueueIsNotFull(Client.Characters.CurrentPlayerCharacter, recipeEntry, countToCraft, maxCraftingQueueEntriesCount: ClientCurrentMaxCraftingQueueEntriesCount)) { await Instance.CallServer(_ => _.ServerRemote_CraftRecipe(recipeEntry, countToCraft)); } }
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); }