Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
e6597b2
fix(test): Use custom server mock to prevent skipping tests
Tisawesomeness Dec 30, 2025
50e18b0
fix(test): Fix failing tests
Tisawesomeness Dec 31, 2025
ff321f8
feat(track-brewer): Add brewers to BrewingStep
Tisawesomeness Dec 31, 2025
0158dc9
Fix(BrewingStepPdcType): Reader always assuming encrypted brew
Mitality Dec 31, 2025
b0fe029
fix(distillery): Change how particle effect is processed
Jan 1, 2026
7adf727
fix(debugging): Completely stop ticking TBP when server is frozen
Jan 1, 2026
585667b
fix(distillery): Issue when destroying distillery
Jan 2, 2026
d2446f2
fix(distillery): Timing issue
Jan 2, 2026
4567c6f
fix(display): Only display modifiers that were actually changed
Tisawesomeness Dec 24, 2025
2b6b304
fix(display): Minor code adjustments
Tisawesomeness Dec 31, 2025
e37971a
fix(cauldron): Null pointer exception
Jan 2, 2026
0508735
version: 2.6.0
Jan 2, 2026
f2212a0
fix(barrel): Barrel inventory issues as well
Jan 2, 2026
b628fad
version: 2.6.1
Jan 2, 2026
159b70c
fix(paper-versions): Bump supported versions (included in 2.6.1)
Jan 2, 2026
b20d13b
fix(registry): Fix concurrency issue in recipe registry
Tisawesomeness Jan 2, 2026
326db08
feat(api): Add event classes
Nov 13, 2025
02610df
fix(brewery-events): Event system changes
Dec 4, 2025
4ea730a
fix(brewery-events): Rework events
Dec 4, 2025
9d2e84e
temp
Dec 5, 2025
ee0e18b
fix(events): Preset logic to track item transactions
Dec 5, 2025
7a4ac76
temp
Dec 7, 2025
1501371
fix(brew-events): Shift clicking issue
Dec 22, 2025
4156ade
fix(brew-events): Cancel non brew transactions by default
Dec 22, 2025
e15fd7f
fix(brew-events): Hotswap issues
Dec 22, 2025
a3d5e25
fix(brew-events): Double check the right item is being modified
Dec 22, 2025
2a66f93
fix(brew-events): Add another permission check
Dec 23, 2025
a9eef98
fix(brew-events): Add cauldron event triggers
Dec 24, 2025
b2a9aee
fix(brew-events): Store event cancel state differently
Dec 25, 2025
95db0da
fix(api-events): Clone item stack before saving it
Dec 31, 2025
a241966
fix(api): Better distillery/barrel api access
Dec 31, 2025
a108877
fix(api): Better cauldron api access
Dec 31, 2025
be6d524
fix(api-events): Avoid using non API classes in API
Dec 31, 2025
e6da9d4
fix(api-events): Add hopper and drag event tracking (untested)
Dec 31, 2025
5668f93
fix(brew-events): Fix Paper not recognizing handler list
Tisawesomeness Dec 31, 2025
858ca8e
fix(api-breweries): Prefer CancelState return type over boolean
Jan 1, 2026
0bd8145
fix(brew-events): Update brew lore on barrel insert/extract
Tisawesomeness Jan 2, 2026
ff8a230
fix(brew-events): Fire CauldronExtractEvent and tweak API
Tisawesomeness Jan 3, 2026
1111cda
fix(brew-events): Clone items on API boundary
Tisawesomeness Jan 3, 2026
74639df
fix(brew-events): Setters on cauldron events
Tisawesomeness Jan 3, 2026
19e88e2
fix(events-api): Invert statement - Bug for drag event
Jan 4, 2026
0822cc5
feat(events-api): Add drunken event initiate event
Jan 4, 2026
e99de30
feat(brew-events): Add destroy events
Tisawesomeness Jan 5, 2026
41f973a
feat(brew-events): Allow editing drops in destroy events
Tisawesomeness Jan 6, 2026
961bdf9
fix(api-events): Simplify code
Jan 6, 2026
51e8557
fix(api-events): Only trigger events once for each structure
Jan 6, 2026
6b64c23
fix(api-events): Avoid unnecessary addition of element into set
Jan 6, 2026
a3c8d64
fix(track-brewer): Fix rebase fail
Tisawesomeness Jan 7, 2026
0de422f
feat(brewer): /brew brewer
Tisawesomeness Jan 7, 2026
c00d934
feat(brewer): Add brewers to /brew info
Tisawesomeness Jan 7, 2026
4f214f8
fix(brewer): Fix /brew brewer not removing brewers
Tisawesomeness Jan 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions api/src/main/java/dev/jsinco/brewery/api/brew/Brew.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;

Expand Down Expand Up @@ -51,6 +50,26 @@ public interface Brew {
*/
Brew withStep(BrewingStep step);

/**
* @param steps A collection brewing steps
* @return A new brew instance with the brewing step added in the chain
*/
Brew withSteps(Collection<BrewingStep> steps);

/**
* @param steps A collection of brewing steps
* @return A new brew instance with the brewing steps replacing the existing steps
*/
Brew withStepsReplaced(Collection<BrewingStep> steps);

/**
* @param index Index of the step in {@link #getSteps()}
* @param modifier Function that modifies the step
* @return A new brew instance with the modified step
* @throws IndexOutOfBoundsException If the index is out of bounds
*/
Brew withModifiedStep(int index, Function<BrewingStep, BrewingStep> modifier);

/**
* @param modifier Function that modifies the last step
* @return A new brew instance with the modified last step
Expand Down Expand Up @@ -78,6 +97,13 @@ public interface Brew {
*/
List<BrewingStep> getSteps();

/**
* All players who contributed to this brew, in their order of contribution.
*
* @return All brewers, may be empty
*/
SequencedSet<UUID> getBrewers();

/**
* A state of a brew, mainly indicates how the data should be written when converting into an item
*/
Expand Down
38 changes: 30 additions & 8 deletions api/src/main/java/dev/jsinco/brewery/api/brew/BrewingStep.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.minimessage.translation.Argument;

import java.util.Locale;
import java.util.Map;
import java.util.*;

public interface BrewingStep {

Expand Down Expand Up @@ -37,6 +36,12 @@ public interface BrewingStep {
*/
Map<ScoreType, PartialBrewScore> failedScores();

/**
* All players who contributed to this brewing step, in their order of contribution.
* @return All brewers, may be empty
*/
SequencedSet<UUID> brewers();

/**
* @param state The state of the brew
* @param resolver A tag resolver for this step
Expand All @@ -50,21 +55,38 @@ default Component infoDisplay(Brew.State state, TagResolver resolver) {
}, Argument.tagResolver(resolver));
}

interface TimedStep {
interface TimedStep extends BrewingStep {
/**
* @return The time for this step (ticks)
*/
Moment time();
}

interface IngredientsStep {
interface IngredientsStep extends BrewingStep {
/**
* @return The ingredients for this step
*/
Map<? extends Ingredient, Integer> ingredients();
}

interface Cook extends BrewingStep, TimedStep, IngredientsStep {
interface AuthoredStep<SELF extends AuthoredStep<SELF>> extends BrewingStep {

/**
* @param brewer A brewer's UUID
* @return A new instance of this step with the specified brewer
*/
SELF withBrewer(UUID brewer);

/**
* @param brewers A collection of brewer UUIDs
* @return A new instance of this step with the specified brewers
*/
SELF withBrewers(SequencedCollection<UUID> brewers);

SELF withBrewersReplaced(SequencedCollection<UUID> brewers);
}

interface Cook extends TimedStep, IngredientsStep, AuthoredStep<Cook> {

/**
* @return The type of the cauldron
Expand All @@ -84,7 +106,7 @@ interface Cook extends BrewingStep, TimedStep, IngredientsStep {
Cook withIngredients(Map<Ingredient, Integer> ingredients);
}

interface Distill extends BrewingStep {
interface Distill extends AuthoredStep<Distill> {

/**
* @return The amount of distill runs for this step
Expand All @@ -97,7 +119,7 @@ interface Distill extends BrewingStep {
Distill incrementRuns();
}

interface Age extends BrewingStep, TimedStep {
interface Age extends TimedStep, AuthoredStep<Age> {

/**
* @return The type of the barrel
Expand All @@ -111,7 +133,7 @@ interface Age extends BrewingStep, TimedStep {
Age withAge(Moment age);
}

interface Mix extends BrewingStep, TimedStep, IngredientsStep {
interface Mix extends TimedStep, IngredientsStep, AuthoredStep<Mix> {

/**
* @param ingredients A map of ingredients with amount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

import dev.jsinco.brewery.api.structure.StructureType;

/**
* Due to using too much generics complexity, replaced with {@link BarrelAccess}
* @param <B> Self
* @param <IS> ItemStack
* @param <I> Inventory
*/
@Deprecated(forRemoval = true)
public interface Barrel<B extends Barrel<B, IS, I>, IS, I> extends StructureHolder<B>, InventoryAccessible<IS, I> {

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package dev.jsinco.brewery.api.breweries;

import dev.jsinco.brewery.api.structure.MultiblockStructure;
import dev.jsinco.brewery.api.util.CancelState;
import dev.jsinco.brewery.api.util.Holder;
import dev.jsinco.brewery.api.vector.BreweryLocation;
import org.jetbrains.annotations.NotNull;

import java.util.UUID;

public interface BarrelAccess {

/**
* Open this barrels inventory for the player with the specified UUID
* @param location The location to open from
* @param player The player
* @return The resulting state
*/
CancelState open(@NotNull BreweryLocation location, @NotNull Holder.Player player);

/**
* Closes the barrel inventory for all viewers
* @param silent Whether to play a barrel sound or not
*/
void close(boolean silent);

/**
* Destroy the barrel, dropping all contained items
* @param breweryLocation The location to destroy from
*/
void destroy(BreweryLocation breweryLocation);

/**
* @return The barrels inventory
*/
BrewInventory getBrewInventory();

/**
* @return The underlying barrel structure
*/
MultiblockStructure<? extends BarrelAccess> getStructure();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package dev.jsinco.brewery.api.breweries;

import dev.jsinco.brewery.api.brew.Brew;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public interface BrewInventory {

/**
* Gets a view of brews in the inventory, where each index of the array corresponds to a position in the inventory.
* Empty slots are represented by null.
*
* @return All brews in this inventory
*/
Brew[] getBrews();

/**
* Gets a snapshot of all brews currently in the inventory. The list does not update as the inventory updates.
*
* @return All brews in this inventory
*/
default List<Brew> getBrewSnapshot() {
return Arrays.stream(getBrews())
.filter(Objects::nonNull)
.toList();
}

/**
* Set an item in the inventory without changing the database
*
* @param brew The brew to set
* @param position The position of the brew to set
*/
void set(@Nullable Brew brew, int position);

/**
* Update the inventory GUI from brew inventory
*/
void updateInventoryFromBrews();

/**
* Update the brew inventory from inventory GUI
* @return True if inventory GUI had any changes
*/
boolean updateBrewsFromInventory();

/**
* Store an item in the inventory, also modify the database
* @param brew The brew to store
* @param position The position to store the brew
*/
void store(Brew brew, int position);

/**
* @return True if inventory is empty
*/
boolean isEmpty();

/**
* @return True if inventory is full
*/
boolean isFull();

/**
* @return The amount of brews in this inventory
*/
int brewAmount();
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package dev.jsinco.brewery.api.breweries;

import dev.jsinco.brewery.api.brew.Brew;
import dev.jsinco.brewery.api.structure.SinglePositionStructure;
import org.jetbrains.annotations.NotNull;

public interface Cauldron extends Tickable, SinglePositionStructure {

long getTime();

boolean isHot();

@NotNull Brew getBrew();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import dev.jsinco.brewery.api.structure.StructureType;

@Deprecated(forRemoval = true)
public interface Distillery<D extends Distillery<D, IS, I>, IS, I> extends StructureHolder<D>, InventoryAccessible<IS, I>, Tickable {

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package dev.jsinco.brewery.api.breweries;

import dev.jsinco.brewery.api.structure.MultiblockStructure;
import dev.jsinco.brewery.api.util.CancelState;
import dev.jsinco.brewery.api.util.Holder;
import dev.jsinco.brewery.api.vector.BreweryLocation;
import org.jetbrains.annotations.NotNull;

import java.util.UUID;

public interface DistilleryAccess {
/**
* Open this distillery inventory for the player with the specified UUID
* @param location The location to open from
* @param player The player UUID
* @return True if canceled
*/
CancelState open(@NotNull BreweryLocation location, @NotNull Holder.Player player);

/**
* Closes the distillery inventory for all viewers
* @param silent Whether to play a close sound or not
*/
void close(boolean silent);

/**
* Destroy the distillery, dropping all contained items
* @param breweryLocation The location to destroy from
*/
void destroy(BreweryLocation breweryLocation);

/**
* @return This distillery mixture inventory
*/
BrewInventory getMixture();

/**
* @return This distillery distillate inventory
*/
BrewInventory getDistillate();

/**
* @return The underlying distillery structure
*/
MultiblockStructure<? extends DistilleryAccess> getStructure();

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public interface StructureHolder<H extends StructureHolder<H>> {
MultiblockStructure<H> getStructure();

/**
* Persistently destroy the structure
* Persistently destroy the structure, dropping all contained items
*
* @param breweryLocation The location to destroy from
*/
Expand Down
24 changes: 24 additions & 0 deletions api/src/main/java/dev/jsinco/brewery/api/util/CancelState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package dev.jsinco.brewery.api.util;

import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;

public sealed interface CancelState {

record Cancelled() implements CancelState {
}

record PermissionDenied(Component message) implements CancelState {

public void sendMessage(@Nullable Audience audience) {
if(audience == null) {
return;
}
audience.sendMessage(message);
}
}

record Allowed() implements CancelState {
}
}
Loading