Skip to content

Commit

Permalink
Fix Recipe Remainder API (#366)
Browse files Browse the repository at this point in the history
* Initial Fix

Fixes #251

* Add a way to get locations with the ID

* Support more default and an all location
  • Loading branch information
OroArmor committed Apr 3, 2024
1 parent dcf6b4e commit 2f729d5
Show file tree
Hide file tree
Showing 18 changed files with 363 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package org.quiltmc.qsl.item.setting.api;

import java.util.Map;

import org.quiltmc.qsl.item.setting.impl.CustomItemSettingImpl;

/**
Expand All @@ -36,17 +38,20 @@ private QuiltCustomItemSettings() {}

/**
* The {@link CustomItemSetting} in charge of handing {@link RecipeRemainderProvider}s. This setting should be used when implementing custom crafting systems to properly handle remainders.
*
* <p>
* The setting is currently used in the following places:
* <ul>
* <li>Crafting Table</li>
* <li>Crafting</li>
* <li>Furnace Fuel</li>
* <li>Furnace Ingredient</li>
* <li>Loom Dye Input</li>
* <li>Brewing Stand Ingredient</li>
* <li>Smithing Table Addition</li>
* <li>Stone Cutter Ingredient</li>
* <li>Loom Dye</li>
* <li>Brewing Ingredient</li>
* <li>Smithing Template</li>
* <li>Smithing Base</li>
* <li>Smithing Ingredient</li>
* <li>Stonecutter Input</li>
* </ul>
*/
public static final CustomItemSetting<RecipeRemainderProvider> RECIPE_REMAINDER_PROVIDER = CustomItemSettingImpl.RECIPE_REMAINDER_PROVIDER;
public static final CustomItemSetting<Map<RecipeRemainderLocation, RecipeRemainderProvider>> RECIPE_REMAINDER_PROVIDER = CustomItemSettingImpl.RECIPE_REMAINDER_PROVIDER;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package org.quiltmc.qsl.item.setting.api;

import java.util.Map;

import org.jetbrains.annotations.Contract;

import net.minecraft.entity.EquipmentSlot;
Expand All @@ -31,6 +33,7 @@
/**
* Quilt's version of {@link Item.Settings}.
* Adds additional methods and hooks not found in the original class.
*
* <p>
* To use it, simply replace {@code new Item.Settings()} with {@code new QuiltItemSettings()}.
*/
Expand Down Expand Up @@ -69,33 +72,83 @@ public QuiltItemSettings customDamage(CustomDamageHandler handler) {

/**
* Sets the stack-aware recipe remainder provider of the item.
* Defaults to setting both crafting and furnace fuel remainder, like vanilla.
*
* @param provider the {@link RecipeRemainderProvider} for the item
*/
public QuiltItemSettings recipeRemainder(RecipeRemainderProvider provider) {
return this.customSetting(QuiltCustomItemSettings.RECIPE_REMAINDER_PROVIDER, provider);
return this.recipeRemainder(provider, RecipeRemainderLocation.DEFAULT_LOCATIONS);
}

/**
* Sets the stack-aware recipe remainder to damage the item by 1 every time it is used in crafting.
* Defaults to setting both crafting and furnace fuel remainder, like vanilla.
*/
public QuiltItemSettings recipeDamageRemainder() {
return this.recipeDamageRemainder(1);
return this.recipeDamageRemainder(1, RecipeRemainderLocation.DEFAULT_LOCATIONS);
}

/**
* Sets the stack-aware recipe remainder to return the item itself.
* Defaults to setting both crafting and furnace fuel remainder, like vanilla.
*/
public QuiltItemSettings recipeSelfRemainder() {
return this.recipeDamageRemainder(0);
return this.recipeDamageRemainder(0, RecipeRemainderLocation.DEFAULT_LOCATIONS);
}

/**
* Sets the stack-aware recipe remainder to damage the item by a certain amount every time it is used in crafting.
* Defaults to setting both crafting and furnace fuel remainder, like vanilla.
*
* @param by the amount
*/
public QuiltItemSettings recipeDamageRemainder(int by) {
return this.recipeDamageRemainder(by, RecipeRemainderLocation.DEFAULT_LOCATIONS);
}

/**
* Sets the stack-aware recipe remainder provider of the item.
*
* @param provider the {@link RecipeRemainderProvider} for the item
* @param locations the {@link RecipeRemainderLocation locations} for the remainder
*/
public QuiltItemSettings recipeRemainder(RecipeRemainderProvider provider, RecipeRemainderLocation... locations) {
for (var location : locations) {
((CustomItemSettingImpl<Map<RecipeRemainderLocation, RecipeRemainderProvider>>) QuiltCustomItemSettings.RECIPE_REMAINDER_PROVIDER)
.get(this)
.put(location, provider);
}

return this;
}

/**
* Sets the stack-aware recipe remainder to damage the item by 1 every time it is used in crafting.
*
* @param locations the {@link RecipeRemainderLocation locations} for the remainder
*/
public QuiltItemSettings recipeDamageRemainder(RecipeRemainderLocation... locations) {
return this.recipeDamageRemainder(1, locations);
}

/**
* Sets the stack-aware recipe remainder to return the item itself.
*
* @param locations the {@link RecipeRemainderLocation locations} for the remainder
*/
public QuiltItemSettings recipeSelfRemainder(RecipeRemainderLocation... locations) {
return this.recipeDamageRemainder(0, locations);
}

/**
* Sets the stack-aware recipe remainder to damage the item by a certain amount every time it is used in crafting.
*
* @param by the amount
* @param locations the {@link RecipeRemainderLocation location} for the remainder
*/
public QuiltItemSettings recipeDamageRemainder(int by, RecipeRemainderLocation... locations) {
if (by == 0) {
return this.recipeRemainder((original, recipe) -> original.copy());
return this.recipeRemainder((original, recipe) -> original.copy(), locations);
}

return this.recipeRemainder((original, recipe) -> {
Expand All @@ -113,7 +166,7 @@ public QuiltItemSettings recipeDamageRemainder(int by) {
}

return copy;
});
}, locations);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright 2024 The Quilt Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.quiltmc.qsl.item.setting.api;

import java.util.Objects;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;

import net.minecraft.util.Identifier;

import org.quiltmc.qsl.item.setting.impl.RecipeRemainderLogicHandlerImpl;

/**
* Contains the different recipe remainder locations that QSL supports.
* Calling {@link #getOrCreate(Identifier)} allows mods to create their own remainder locations or get remainder locations without needing to compile against the other mod.
* The hierarchy of recipe remainder locations is: {@link #DEFAULT_LOCATIONS} &lt; any location &lt; {@link #ALL_LOCATIONS}.
*
* <p> This class should not be extended.
*/
@ApiStatus.NonExtendable
public interface RecipeRemainderLocation {
/**
* Remainder location for Vanilla crafting. Used in Crafting Tables and the inventory crafting screen.
*/
RecipeRemainderLocation CRAFTING = addToDefaultLocations(getOrCreate(new Identifier("minecraft:crafting")));

/**
* Remainder location for the furnace fuel slot in the different furnace types.
*/
RecipeRemainderLocation FURNACE_FUEL = addToDefaultLocations(getOrCreate(new Identifier("minecraft:furnace_fuel")));

/**
* Remainder location for the furnace ingredient slot in the different furnace types.
*/
RecipeRemainderLocation FURNACE_INGREDIENT = getOrCreate(new Identifier("minecraft:furnace_ingredient"));

/**
* Remainder location for the dye slot in looms.
*/
RecipeRemainderLocation LOOM_DYE = getOrCreate(new Identifier("minecraft:loom_dye"));

/**
* Remainder location for the potion addition in brewing stands.
*/
RecipeRemainderLocation POTION_ADDITION = getOrCreate(new Identifier("minecraft:potion_addition"));

/**
* Remainder location for the input to the stonecutter.
*/
RecipeRemainderLocation STONECUTTER_INPUT = getOrCreate(new Identifier("minecraft:stonecutter_input"));

/**
* Remainder location for the smithing template slot.
*/
RecipeRemainderLocation SMITHING_TEMPLATE = getOrCreate(new Identifier("minecraft:smithing_template"));

/**
* Remainder location for the smithing base slot.
*/
RecipeRemainderLocation SMITHING_BASE = getOrCreate(new Identifier("minecraft:smithing_base"));

/**
* Remainder location for the smithing ingredient slot.
*/
RecipeRemainderLocation SMITHING_INGREDIENT = getOrCreate(new Identifier("minecraft:smithing_ingredient"));

/**
* Remainder location for the default locations. This starts with {@link #CRAFTING} and {@link #FURNACE_FUEL}.
*/
RecipeRemainderLocation DEFAULT_LOCATIONS = getOrCreate(new Identifier("quilt:default"));

/**
* Remainder location for all locations. Using this will override any other locations that is specified.
*/
RecipeRemainderLocation ALL_LOCATIONS = getOrCreate(new Identifier("quilt:all"));

/**
* Gets a new remainder location if it already exists, creating it otherwise.
* @param id the id for the location
* @return the remainder location
*/
@Contract("null -> fail; _ -> new")
static RecipeRemainderLocation getOrCreate(Identifier id) {
record RecipeRemainderLocationImpl(Identifier id) implements RecipeRemainderLocation {
}

Objects.requireNonNull(id, "`id` must not be null.");

return RecipeRemainderLogicHandlerImpl.LOCATIONS.computeIfAbsent(id, RecipeRemainderLocationImpl::new);
}

/**
* @param location the location to add to the default locations
*/
@Contract("null -> fail")
static RecipeRemainderLocation addToDefaultLocations(RecipeRemainderLocation location) {
Objects.requireNonNull(location, "`location` must not be null");

RecipeRemainderLogicHandlerImpl.DEFAULT_LOCATIONS.add(location);
return location;
}

/**
*
* @return the id for the location.
*/
Identifier id();
}
Loading

0 comments on commit 2f729d5

Please sign in to comment.