Skip to content

Commit

Permalink
Work on cleaning up some smells
Browse files Browse the repository at this point in the history
Wrapping functions is a little silly when the wrapped functions could just be methods (and not have 5 constructor parameters).
May want to move VanillaAnvil.BEHAVIOR to a more clear constant, add defaults to AnvilBehavior methods.
Not sure how I feel about extracting implementations out of AnvilFunction to AnvilFunctions. A little inconsistent with other areas.

In general, needs tweaks.
  • Loading branch information
Jikoo committed Dec 20, 2024
1 parent 4e5534f commit 7003e5e
Show file tree
Hide file tree
Showing 13 changed files with 671 additions and 730 deletions.
40 changes: 20 additions & 20 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,50 @@ systems and divide them up into readable, manageable, customizable segments.
### Anvil Enchanting

Anvil enchanting is primarily accessed via the
[`AnvilOperation`](src/main/java/com/github/jikoo/planarenchanting/anvil/AnvilOperation.java).
[`VanillaAnvil`](src/main/java/com/github/jikoo/planarenchanting/anvil/VanillaAnvil.java).
This is a class containing several simple ways to modify anvil behaviors.

For basic vanilla-style combination, all you need is an ordinary `AnvilOperation`.
For basic vanilla-style combination, all you need is an ordinary `VanillaAnvil`.

```java
class MyAnvilHandler implements Listener {
@EventHandler
private void onPrepareAnvil(PrepareAnvilEvent event) {
AnvilView view = event.getView();
AnvilOperation operation = new AnvilOperation();
AnvilResult result = operation.apply(view);
VanillaAnvil anvil = new VanillaAnvil();
AnvilResult result = anvil.getResult(event.getView());

event.setResult(result.item());
inventory.setRepairCostAmount(result.materialCost());

// Note: depending on how anvil actually functions, may need to update cost on a 0-tick delay.
// May also need to set relevant window property for client.
inventory.setRepairCost(result.levelCost());
}
}
```

For specific use cases (i.e. removing or changing enchantment level cap) you can provide the
`AnvilOperation` with different functions which will be used by the default `AnvilFunction`
implementations.
For specific tweaks (i.e. removing or changing enchantment level cap) you can provide the
`VanillaAnvil` with a different `AnvilBehavior` implementation.

Allowing conflicting enchantments to be added:

```java
AnvilOperation operation = new AnvilOperation();
operation.setEnchantsConflict((enchant1, enchant2) -> false);
VanillaAnvil anvil = new VanillaAnvil(new AnvilBehavior() {
@Override
public boolean getEnchantsConflict(Enchantment enchant1, Enchantment enchant2) {
return false;
}
});
```

If you have even more specific needs but still want to leverage certain vanilla-style functionality,
you can write your own `AnvilOperation` and override `AnvilOperation#apply` to set your own
operation order.
you can write your own anvil functionality.

A custom `AnvilOperation` that only performs rename operations:
An implementation that only allows the input to be renamed:

```java
class RenameOperation extends AnvilOperation {
@Override
public void apply(@NotNull AnvilView view) {
AnvilOperationState state = new AnvilOperationState(this, view);
class RenameOnlyAnvil {
public void getResult(@NotNull AnvilView view) {
AnvilState state = new AnvilState(VanillaAnvil.BEHAVIOR, view);

// Require first item to be set, second item to be unset.
if (ItemUtil.isEmpty(state.getBase().getItem())
Expand All @@ -69,9 +69,9 @@ class RenameOperation extends AnvilOperation {
}

// Apply base cost.
state.apply(AnvilFunction.PRIOR_WORK_LEVEL_COST);
state.apply(AnvilFunctions.PRIOR_WORK_LEVEL_COST);
// Apply rename.
state.apply(AnvilFunction.RENAME);
state.apply(AnvilFunctions.RENAME);

return state.forge();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.github.jikoo.planarenchanting.anvil;

import com.github.jikoo.planarenchanting.util.MetaCachedStack;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;

public interface AnvilBehavior {

/**
* Get whether an {@link Enchantment} is applicable for a wrapped {@link ItemStack}.
*
* @param enchantment the {@code Enchantment} to check for applicability
* @param base the item that may be enchanted
* @return whether the {@code Enchantment} can be applied
*/
boolean enchantApplies(@NotNull Enchantment enchantment, @NotNull MetaCachedStack base);

/**
* Get whether two {@link Enchantment Enchantments} conflict.
*
* @return whether the {@code Enchantments} conflict
*/
boolean enchantsConflict(@NotNull Enchantment enchant1, @NotNull Enchantment enchant2);

/**
* Get the maximum level for an {@link Enchantment}.
*
* @return the maximum level for an {@code Enchantment}
*/
int getEnchantMaxLevel(@NotNull Enchantment enchantment);

/**
* Get whether an item should combine its {@link Enchantment Enchantments} with another item.
*
* @param base the base item
* @param addition the item added
* @return whether items should combine {@code Enchantments}
*/
boolean itemsCombineEnchants(@NotNull MetaCachedStack base, @NotNull MetaCachedStack addition);

/**
* Get whether an item is repaired by another item. This is not the same as a repair via
* combination of like items! Like items always attempt to combine durability. If you require
* different behavior, override {@link VanillaAnvil#getResult(org.bukkit.inventory.view.AnvilView)}
* and do not call {@link AnvilFunctions#REPAIR_WITH_COMBINATION}.
*
* @param repaired the item repaired
* @param repairMat the item used to repair
* @return the method determining whether an item is repaired by another item
*/
public boolean itemRepairedBy(@NotNull MetaCachedStack repaired, @NotNull MetaCachedStack repairMat);

}
Loading

0 comments on commit 7003e5e

Please sign in to comment.