-
-
Notifications
You must be signed in to change notification settings - Fork 377
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add Loot Tables * Optimize Imports * Fix docs and add a registry class info * Changes * remove license thing * Add converter for LootTables - LootTable, Change toString for LootTable class info, Change syntax * add tests ? unsure if theyre correct and add expressions to get luck/killer/entity of context * Replace current implementation to module, add NameSpacedUtils class from the Recipe pull request, and changes * Add docs, optimize imports and changes * Change syntax and add some tests * Fix docs, fix tests, replace paper methods to bukkit ones and changes * one silly thing hehe * Add JUnit tests, fix tests and changes * Fix JUnit test * ok junit test * fix tests * Optimize imports and fix description of EffGenerateLoot and ExprLootItems * Clean up LootTableUtils and update docs * update tests * add loot table type in the default.lang file * Fix the seed expression not actually updating the state * optimize imports * change exampled for loot table seed * Add default event value for LootTable in LootGenerate event * Add escape character for colons * Add LootContext event value in LootGenerateEvent * Make cached loot context transient * changes * tests and fix docs * alot of things * fix toString * remove consumer * fix tests * optimize imports * Fix exception in Java 17 * hopefully one last thing * move LootGenerateEvent and event values to module class because idk why i didn't have it there * optimize imports and another one * pickel era changes * update tests * more pickel era changes * uh oh * more uh ohs * even more uh ohs * we dont talk about it * small changes * optimize le importos * even more pickel era changes * wow pickel has alot of changes * Move ExprLoot to module and clean it up * changes --------- Co-authored-by: Moderocky <admin@moderocky.com> Co-authored-by: Efnilite <35348263+Efnilite@users.noreply.github.com>
- Loading branch information
1 parent
b0be357
commit b123b88
Showing
30 changed files
with
1,492 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
src/main/java/org/skriptlang/skript/bukkit/loottables/LootContextCreateEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package org.skriptlang.skript.bukkit.loottables; | ||
|
||
import org.bukkit.event.Event; | ||
import org.bukkit.event.HandlerList; | ||
import org.skriptlang.skript.bukkit.loottables.elements.expressions.ExprSecCreateLootContext; | ||
|
||
/** | ||
* The event used in the {@link ExprSecCreateLootContext} section. | ||
*/ | ||
public class LootContextCreateEvent extends Event { | ||
|
||
private final LootContextWrapper contextWrapper; | ||
|
||
public LootContextCreateEvent(LootContextWrapper context) { | ||
this.contextWrapper = context; | ||
} | ||
|
||
public LootContextWrapper getContextWrapper() { | ||
return contextWrapper; | ||
} | ||
|
||
@Override | ||
public HandlerList getHandlers() { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
} |
112 changes: 112 additions & 0 deletions
112
src/main/java/org/skriptlang/skript/bukkit/loottables/LootContextWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package org.skriptlang.skript.bukkit.loottables; | ||
|
||
import org.bukkit.Location; | ||
import org.bukkit.entity.Entity; | ||
import org.bukkit.entity.Player; | ||
import org.bukkit.loot.LootContext; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
/** | ||
* Wrapper for a LootContext.Builder to allow easier creation of LootContexts. | ||
*/ | ||
public class LootContextWrapper { | ||
|
||
private @NotNull Location location; | ||
private transient @Nullable LootContext cachedLootContext; | ||
private @Nullable Player killer; | ||
private @Nullable Entity entity; | ||
private float luck; | ||
|
||
/** | ||
* Creates a new LootContextWrapper at the given location. | ||
* @param location the location of the LootContext. | ||
*/ | ||
public LootContextWrapper(@NotNull Location location) { | ||
this.location = location; | ||
} | ||
|
||
/** | ||
* Gets the LootContext from the wrapper. | ||
* @return the LootContext. | ||
*/ | ||
public LootContext getContext() { | ||
if (cachedLootContext == null) | ||
cachedLootContext = new LootContext.Builder(location) | ||
.killer(killer) | ||
.lootedEntity(entity) | ||
.luck(luck) | ||
.build(); | ||
|
||
return cachedLootContext; | ||
} | ||
|
||
/** | ||
* Sets the location of the LootContext. | ||
* @param location the location. | ||
*/ | ||
public void setLocation(@NotNull Location location) { | ||
this.location = location; | ||
cachedLootContext = null; | ||
} | ||
|
||
/** | ||
* Sets the killer of the LootContext. | ||
* @param killer the killer. | ||
*/ | ||
public void setKiller(@Nullable Player killer) { | ||
this.killer = killer; | ||
cachedLootContext = null; | ||
} | ||
|
||
/** | ||
* Sets the entity of the LootContext. | ||
* @param entity the entity. | ||
*/ | ||
public void setEntity(@Nullable Entity entity) { | ||
this.entity = entity; | ||
cachedLootContext = null; | ||
} | ||
|
||
/** | ||
* Sets the luck of the LootContext. | ||
* @param luck the luck value. | ||
*/ | ||
public void setLuck(float luck) { | ||
this.luck = luck; | ||
cachedLootContext = null; | ||
} | ||
|
||
/** | ||
* Gets the location of the LootContext. | ||
* @return the location. | ||
*/ | ||
public Location getLocation() { | ||
return location; | ||
} | ||
|
||
/** | ||
* Gets the killer of the LootContext. | ||
* @return the killer. | ||
*/ | ||
public @Nullable Player getKiller() { | ||
return killer; | ||
} | ||
|
||
/** | ||
* Gets the entity of the LootContext. | ||
* @return the entity. | ||
*/ | ||
public @Nullable Entity getEntity() { | ||
return entity; | ||
} | ||
|
||
/** | ||
* Gets the luck of the LootContext. | ||
* @return the luck value. | ||
*/ | ||
public float getLuck() { | ||
return luck; | ||
} | ||
|
||
} |
127 changes: 127 additions & 0 deletions
127
src/main/java/org/skriptlang/skript/bukkit/loottables/LootTableModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package org.skriptlang.skript.bukkit.loottables; | ||
|
||
import ch.njol.skript.Skript; | ||
import ch.njol.skript.classes.ClassInfo; | ||
import ch.njol.skript.classes.Parser; | ||
import ch.njol.skript.expressions.base.EventValueExpression; | ||
import ch.njol.skript.lang.ParseContext; | ||
import ch.njol.skript.lang.util.SimpleEvent; | ||
import ch.njol.skript.registrations.Classes; | ||
import ch.njol.skript.registrations.EventValues; | ||
import org.bukkit.Bukkit; | ||
import org.bukkit.Location; | ||
import org.bukkit.NamespacedKey; | ||
import org.bukkit.entity.Entity; | ||
import org.bukkit.event.world.LootGenerateEvent; | ||
import org.bukkit.loot.LootContext; | ||
import org.bukkit.loot.LootTable; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.io.IOException; | ||
|
||
public class LootTableModule { | ||
|
||
public static void load() throws IOException { | ||
|
||
// --- CLASSES --- // | ||
|
||
Classes.registerClass(new ClassInfo<>(LootTable.class, "loottable") | ||
.user("loot ?tables?") | ||
.name("Loot Table") | ||
.description( | ||
"Loot tables represent what items should be in naturally generated containers, " | ||
+ "what items should be dropped when killing a mob, or what items can be fished.", | ||
"You can find more information about this in https://minecraft.wiki/w/Loot_table" | ||
) | ||
.since("INSERT VERSION") | ||
.parser(new Parser<>() { | ||
@Override | ||
public @Nullable LootTable parse(String key, ParseContext context) { | ||
NamespacedKey namespacedKey = NamespacedKey.fromString(key); | ||
if (namespacedKey == null) | ||
return null; | ||
return Bukkit.getLootTable(namespacedKey); | ||
} | ||
|
||
@Override | ||
public String toString(LootTable o, int flags) { | ||
return "loot table \"" + o.getKey() + '\"'; | ||
} | ||
|
||
@Override | ||
public String toVariableNameString(LootTable o) { | ||
return "loot table:" + o.getKey(); | ||
} | ||
}) | ||
); | ||
|
||
Classes.registerClass(new ClassInfo<>(LootContext.class, "lootcontext") | ||
.user("loot ?contexts?") | ||
.name("Loot Context") | ||
.description( | ||
"Represents additional information a loot table can use to modify its generated loot.", | ||
"", | ||
"Some loot tables will require some values (i.e. looter, location, looted entity) " | ||
+ "in a loot context when generating loot whereas others may not.", | ||
"For example, the loot table of a simple dungeon chest will only require a location, " | ||
+ "whereas the loot table of a cow will require a looting player, looted entity, and location.", | ||
"You can find more information about this in https://minecraft.wiki/w/Loot_context" | ||
) | ||
.since("INSERT VERSION") | ||
.defaultExpression(new EventValueExpression<>(LootContext.class)) | ||
.parser(new Parser<>() { | ||
@Override | ||
public boolean canParse(ParseContext context) { | ||
return false; | ||
} | ||
|
||
@Override | ||
public String toString(LootContext context, int flags) { | ||
StringBuilder builder = new StringBuilder("loot context at ") | ||
.append(Classes.toString(context.getLocation())); | ||
|
||
if (context.getLootedEntity() != null) | ||
builder.append(" with entity ").append(Classes.toString(context.getLootedEntity())); | ||
if (context.getKiller() != null) | ||
builder.append(" with killer ").append(Classes.toString(context.getKiller())); | ||
if (context.getLuck() != 0) | ||
builder.append(" with luck ").append(context.getLuck()); | ||
|
||
return builder.toString(); | ||
} | ||
|
||
@Override | ||
public String toVariableNameString(LootContext context) { | ||
return "loot context:" + context.hashCode(); | ||
} | ||
}) | ||
); | ||
|
||
Skript.getAddonInstance().loadClasses("org.skriptlang.skript.bukkit.loottables", "elements"); | ||
|
||
// --- SIMPLE EVENTS --- // | ||
|
||
Skript.registerEvent("Loot Generate", SimpleEvent.class, LootGenerateEvent.class, "loot generat(e|ing)") | ||
.description( | ||
"Called when a loot table of an inventory is generated in the world.", | ||
"For example, when opening a shipwreck chest." | ||
) | ||
.examples( | ||
"on loot generate:", | ||
"\tchance of 10%", | ||
"\tadd 64 diamonds to the loot", | ||
"\tsend \"You hit the jackpot at %event-location%!\"" | ||
) | ||
.since("2.7") | ||
.requiredPlugins("MC 1.16+"); | ||
|
||
// --- EVENT VALUES --- // | ||
|
||
// LootGenerateEvent | ||
EventValues.registerEventValue(LootGenerateEvent.class, Entity.class, LootGenerateEvent::getEntity); | ||
EventValues.registerEventValue(LootGenerateEvent.class, Location.class, event -> event.getLootContext().getLocation()); | ||
EventValues.registerEventValue(LootGenerateEvent.class, LootTable.class, LootGenerateEvent::getLootTable); | ||
EventValues.registerEventValue(LootGenerateEvent.class, LootContext.class, LootGenerateEvent::getLootContext); | ||
} | ||
|
||
} |
55 changes: 55 additions & 0 deletions
55
src/main/java/org/skriptlang/skript/bukkit/loottables/LootTableUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package org.skriptlang.skript.bukkit.loottables; | ||
|
||
import org.bukkit.block.Block; | ||
import org.bukkit.block.BlockState; | ||
import org.bukkit.loot.LootTable; | ||
import org.bukkit.loot.Lootable; | ||
|
||
/** | ||
* Utility class for loot tables. | ||
*/ | ||
public class LootTableUtils { | ||
|
||
/** | ||
* * Checks whether a block or entity is an instance of {@link Lootable}. This is done because a block is not an instance of Lootable, but a block state is. | ||
* @param object the object to check. | ||
* @return whether the object is lootable. | ||
*/ | ||
public static boolean isLootable(Object object) { | ||
if (object instanceof Block block) | ||
object = block.getState(); | ||
return object instanceof Lootable; | ||
} | ||
|
||
/** | ||
* Gets the Lootable instance of an object. You should call {@link #isLootable(Object)} before calling this method. | ||
* @param object the object to get the Lootable instance of. | ||
* @return the Lootable instance of the object. | ||
*/ | ||
public static Lootable getAsLootable(Object object) { | ||
if (object instanceof Block block) | ||
object = block.getState(); | ||
if (object instanceof Lootable lootable) | ||
return lootable; | ||
return null; | ||
} | ||
|
||
/** | ||
* Gets the loot table of an object. You should call {@link #isLootable(Object)} before calling this method. | ||
* @param object the object to get the loot table of. | ||
* @return returns the LootTable of the object. | ||
*/ | ||
public static LootTable getLootTable(Object object) { | ||
return getAsLootable(object).getLootTable(); | ||
} | ||
|
||
/** | ||
* Updates the state of a Lootable. This is done because setting the LootTable or seed of a BlockState changes the NBT value, but is never updated. | ||
* @param lootable the Lootable to update the state of. | ||
*/ | ||
public static void updateState(Lootable lootable) { | ||
if (lootable instanceof BlockState blockState) | ||
blockState.update(true, false); | ||
} | ||
|
||
} |
Oops, something went wrong.