it works on forge. todo mixin until after everything's loaded and shoehorn in the loot func
This commit is contained in:
parent
38a300cb46
commit
ee3f34878e
42 changed files with 722 additions and 489 deletions
|
@ -8,22 +8,14 @@ import at.petrak.hexcasting.api.misc.HexDamageSources
|
|||
import at.petrak.hexcasting.api.mod.HexConfig
|
||||
import at.petrak.hexcasting.api.mod.HexItemTags
|
||||
import at.petrak.hexcasting.api.mod.HexStatistics
|
||||
import at.petrak.hexcasting.api.spell.Operator
|
||||
import at.petrak.hexcasting.api.spell.ParticleSpray
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.Widget
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
import at.petrak.hexcasting.api.spell.mishaps.Mishap
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapDisallowedSpell
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapError
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapTooManyCloseParens
|
||||
import at.petrak.hexcasting.api.spell.*
|
||||
import at.petrak.hexcasting.api.spell.math.HexDir
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
import at.petrak.hexcasting.api.spell.mishaps.*
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
import at.petrak.hexcasting.api.utils.asCompound
|
||||
import at.petrak.hexcasting.api.utils.getList
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.nbt.Tag
|
||||
|
@ -66,7 +58,7 @@ class CastingHarness private constructor(
|
|||
var continuation = SpellContinuation.Done.pushFrame(ContinuationFrame.Evaluate(SpellList.LList(0, iotas)))
|
||||
// Begin aggregating info
|
||||
val info = TempControllerInfo(false, false)
|
||||
var lastResolutionType = ResolvedPatternType.UNKNOWN
|
||||
var lastResolutionType = ResolvedPatternType.UNRESOLVED
|
||||
while (continuation is SpellContinuation.NotDone && !info.earlyExit) {
|
||||
// Take the top of the continuation stack...
|
||||
val next = continuation.frame
|
||||
|
@ -116,7 +108,12 @@ class CastingHarness private constructor(
|
|||
continuation,
|
||||
null,
|
||||
mishap.resolutionType(ctx),
|
||||
listOf(OperatorSideEffect.DoMishap(mishap, Mishap.Context(iota.payload as? HexPattern ?: HexPattern(HexDir.WEST), null))),
|
||||
listOf(
|
||||
OperatorSideEffect.DoMishap(
|
||||
mishap,
|
||||
Mishap.Context(iota.payload as? HexPattern ?: HexPattern(HexDir.WEST), null)
|
||||
)
|
||||
),
|
||||
)
|
||||
} catch (exception: Exception) {
|
||||
exception.printStackTrace()
|
||||
|
@ -124,7 +121,12 @@ class CastingHarness private constructor(
|
|||
continuation,
|
||||
null,
|
||||
ResolvedPatternType.ERRORED,
|
||||
listOf(OperatorSideEffect.DoMishap(MishapError(exception), Mishap.Context(iota.payload as? HexPattern ?: HexPattern(HexDir.WEST), null)))
|
||||
listOf(
|
||||
OperatorSideEffect.DoMishap(
|
||||
MishapError(exception),
|
||||
Mishap.Context(iota.payload as? HexPattern ?: HexPattern(HexDir.WEST), null)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +147,12 @@ class CastingHarness private constructor(
|
|||
if (!HexConfig.server().isActionAllowed(operatorIdPair.second)) {
|
||||
throw MishapDisallowedSpell()
|
||||
}
|
||||
val (cont2, stack2, local2, sideEffectsUnmut) = operatorIdPair.first.operate(continuation, this.stack.toMutableList(), this.localIota, this.ctx)
|
||||
val (cont2, stack2, local2, sideEffectsUnmut) = operatorIdPair.first.operate(
|
||||
continuation,
|
||||
this.stack.toMutableList(),
|
||||
this.localIota,
|
||||
this.ctx
|
||||
)
|
||||
this.localIota = local2
|
||||
// Stick a poofy particle effect at the caster position
|
||||
val sideEffects = sideEffectsUnmut.toMutableList()
|
||||
|
@ -183,7 +190,12 @@ class CastingHarness private constructor(
|
|||
continuation,
|
||||
null,
|
||||
ResolvedPatternType.ERRORED,
|
||||
listOf(OperatorSideEffect.DoMishap(MishapError(exception), Mishap.Context(newPat, operatorIdPair?.second)))
|
||||
listOf(
|
||||
OperatorSideEffect.DoMishap(
|
||||
MishapError(exception),
|
||||
Mishap.Context(newPat, operatorIdPair?.second)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -200,8 +212,9 @@ class CastingHarness private constructor(
|
|||
}
|
||||
|
||||
if (haskellProgrammersShakingandCryingRN is OperatorSideEffect.AttemptSpell &&
|
||||
haskellProgrammersShakingandCryingRN.hasCastingSound) {
|
||||
info.playSound = true
|
||||
haskellProgrammersShakingandCryingRN.hasCastingSound
|
||||
) {
|
||||
info.playSound = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -443,7 +456,10 @@ class CastingHarness private constructor(
|
|||
}
|
||||
|
||||
val localTag = nbt.getCompound(TAG_LOCAL)
|
||||
val localIota = if (localTag.size() == 1) SpellDatum.DeserializeFromNBT(localTag, ctx.world) else SpellDatum.make(Widget.NULL)
|
||||
val localIota =
|
||||
if (localTag.size() == 1) SpellDatum.DeserializeFromNBT(localTag, ctx.world) else SpellDatum.make(
|
||||
Widget.NULL
|
||||
)
|
||||
|
||||
val parenthesized = mutableListOf<SpellDatum<*>>()
|
||||
val parenTag = nbt.getList(TAG_PARENTHESIZED, Tag.TAG_COMPOUND)
|
||||
|
|
|
@ -24,6 +24,7 @@ sealed interface ContinuationFrame {
|
|||
* @return the result of this pattern step
|
||||
*/
|
||||
fun evaluate(continuation: SpellContinuation, level: ServerLevel, harness: CastingHarness): CastResult
|
||||
|
||||
/**
|
||||
* The OpHalt instruction wants us to "jump to" the END of the nearest meta-eval.
|
||||
* In other words, we should consume Evaluate frames until we hit a FinishEval or Thoth frame.
|
||||
|
@ -35,12 +36,16 @@ sealed interface ContinuationFrame {
|
|||
* A list of patterns to be evaluated in sequence.
|
||||
* @property list the *remaining* list of patterns to be evaluated
|
||||
*/
|
||||
data class Evaluate(val list: SpellList): ContinuationFrame {
|
||||
data class Evaluate(val list: SpellList) : ContinuationFrame {
|
||||
// Discard this frame and keep discarding frames.
|
||||
override fun breakDownwards(stack: List<SpellDatum<*>>) = Pair(false, stack)
|
||||
|
||||
// Step the list of patterns, evaluating a single one.
|
||||
override fun evaluate(continuation: SpellContinuation, level: ServerLevel, harness: CastingHarness): CastResult {
|
||||
override fun evaluate(
|
||||
continuation: SpellContinuation,
|
||||
level: ServerLevel,
|
||||
harness: CastingHarness
|
||||
): CastResult {
|
||||
// If there are patterns left...
|
||||
if (list.nonEmpty) {
|
||||
val newCont = if (list.cdr.nonEmpty) { // yay TCO
|
||||
|
@ -51,7 +56,7 @@ sealed interface ContinuationFrame {
|
|||
return harness.getUpdate(list.car, level, newCont)
|
||||
} else {
|
||||
// If there are no patterns (e.g. empty Hermes), just return OK.
|
||||
return CastResult(continuation, null, ResolvedPatternType.OK, listOf())
|
||||
return CastResult(continuation, null, ResolvedPatternType.EVALUATED, listOf())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,13 +66,22 @@ sealed interface ContinuationFrame {
|
|||
* A stack marker representing the end of a Hermes evaluation,
|
||||
* so that we know when to stop removing frames during a Halt.
|
||||
*/
|
||||
class FinishEval(): ContinuationFrame {
|
||||
class FinishEval() : ContinuationFrame {
|
||||
// Don't do anything else to the stack, just finish the halt statement.
|
||||
override fun breakDownwards(stack: List<SpellDatum<*>>) = Pair(true, stack)
|
||||
|
||||
// Evaluating it does nothing; it's only a boundary condition.
|
||||
override fun evaluate(continuation: SpellContinuation, level: ServerLevel, harness: CastingHarness): CastResult {
|
||||
return CastResult(continuation, FunctionalData(harness.stack.toList(), 0, listOf(), false), ResolvedPatternType.OK, listOf())
|
||||
override fun evaluate(
|
||||
continuation: SpellContinuation,
|
||||
level: ServerLevel,
|
||||
harness: CastingHarness
|
||||
): CastResult {
|
||||
return CastResult(
|
||||
continuation,
|
||||
FunctionalData(harness.stack.toList(), 0, listOf(), false),
|
||||
ResolvedPatternType.EVALUATED,
|
||||
listOf()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +94,12 @@ sealed interface ContinuationFrame {
|
|||
* @property baseStack the stack state at Thoth entry
|
||||
* @property acc concatenated list of final stack states after Thoth exit
|
||||
*/
|
||||
data class ForEach(val data: SpellList, val code: SpellList, val baseStack: List<SpellDatum<*>>?, val acc: MutableList<SpellDatum<*>>): ContinuationFrame {
|
||||
data class ForEach(
|
||||
val data: SpellList,
|
||||
val code: SpellList,
|
||||
val baseStack: List<SpellDatum<*>>?,
|
||||
val acc: MutableList<SpellDatum<*>>
|
||||
) : ContinuationFrame {
|
||||
|
||||
/** When halting, we add the stack state at halt to the stack accumulator, then return the original pre-Thoth stack, plus the accumulator. */
|
||||
override fun breakDownwards(stack: List<SpellDatum<*>>): Pair<Boolean, List<SpellDatum<*>>> {
|
||||
|
@ -91,7 +110,11 @@ sealed interface ContinuationFrame {
|
|||
}
|
||||
|
||||
/** Step the Thoth computation, enqueueing one code evaluation. */
|
||||
override fun evaluate(continuation: SpellContinuation, level: ServerLevel, harness: CastingHarness): CastResult {
|
||||
override fun evaluate(
|
||||
continuation: SpellContinuation,
|
||||
level: ServerLevel,
|
||||
harness: CastingHarness
|
||||
): CastResult {
|
||||
// If this isn't the very first Thoth step (i.e. no Thoth computations run yet)...
|
||||
val stack = if (baseStack == null) {
|
||||
// init stack to the harness stack...
|
||||
|
@ -118,7 +141,12 @@ sealed interface ContinuationFrame {
|
|||
}
|
||||
val tStack = stack.toMutableList()
|
||||
tStack.add(stackTop)
|
||||
return CastResult(newCont, FunctionalData(tStack, 0, listOf(), false), ResolvedPatternType.OK, listOf())
|
||||
return CastResult(
|
||||
newCont,
|
||||
FunctionalData(tStack, 0, listOf(), false),
|
||||
ResolvedPatternType.EVALUATED,
|
||||
listOf()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package at.petrak.hexcasting.common.lib;
|
||||
|
||||
import at.petrak.hexcasting.common.loot.AmethystReducerFunc;
|
||||
import at.petrak.hexcasting.common.loot.PatternScrollFunc;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
public class HexLootFunctions {
|
||||
public static void registerSerializers(BiConsumer<LootItemFunctionType, ResourceLocation> r) {
|
||||
for (var e : LOOT_FUNCS.entrySet()) {
|
||||
r.accept(e.getValue(), e.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<ResourceLocation, LootItemFunctionType> LOOT_FUNCS = new LinkedHashMap<>();
|
||||
|
||||
public static final LootItemFunctionType PATTERN_SCROLL = register("pattern_scroll",
|
||||
new LootItemFunctionType(new PatternScrollFunc.Serializer()));
|
||||
public static final LootItemFunctionType AMETHYST_SHARD_REDUCER = register("amethyst_shard_reducer",
|
||||
new LootItemFunctionType(new AmethystReducerFunc.Serializer()));
|
||||
|
||||
private static LootItemFunctionType register(String id, LootItemFunctionType lift) {
|
||||
var old = LOOT_FUNCS.put(modLoc(id), lift);
|
||||
if (old != null) {
|
||||
throw new IllegalArgumentException("Typo? Duplicate id " + id);
|
||||
}
|
||||
return lift;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package at.petrak.hexcasting.common.loot;
|
||||
|
||||
import at.petrak.hexcasting.common.lib.HexLootFunctions;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.functions.LootItemConditionalFunction;
|
||||
import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
|
||||
public class AmethystReducerFunc extends LootItemConditionalFunction {
|
||||
public final double delta;
|
||||
|
||||
public AmethystReducerFunc(LootItemCondition[] lootItemConditions, double delta) {
|
||||
super(lootItemConditions);
|
||||
this.delta = delta;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack run(ItemStack stack, LootContext ctx) {
|
||||
if (stack.getItem() == Items.AMETHYST_SHARD) {
|
||||
if (stack.is(Items.AMETHYST_SHARD)) {
|
||||
stack.setCount((int) (stack.getCount() * (1 + delta)));
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootItemFunctionType getType() {
|
||||
return HexLootFunctions.AMETHYST_SHARD_REDUCER;
|
||||
}
|
||||
|
||||
public static class Serializer extends LootItemConditionalFunction.Serializer<AmethystReducerFunc> {
|
||||
@Override
|
||||
public void serialize(JsonObject json, AmethystReducerFunc value, JsonSerializationContext ctx) {
|
||||
super.serialize(json, value, ctx);
|
||||
json.addProperty("delta", value.delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AmethystReducerFunc deserialize(JsonObject object, JsonDeserializationContext ctx,
|
||||
LootItemCondition[] conditions) {
|
||||
var delta = GsonHelper.getAsDouble(object, "delta");
|
||||
return new AmethystReducerFunc(conditions, delta);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package at.petrak.hexcasting.common.loot;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.storage.loot.LootPool;
|
||||
import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer;
|
||||
import net.minecraft.world.level.storage.loot.entries.LootTableReference;
|
||||
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
// https://github.com/VazkiiMods/Botania/blob/1.18.x/Xplat/src/main/java/vazkii/botania/common/loot/LootHandler.java
|
||||
public class HexLootHandler {
|
||||
public static final ResourceLocation FUNC_AMETHYST_SHARD_REDUCER = modLoc("amethyst_shard_reducer");
|
||||
|
||||
public static final ResourceLocation TABLE_INJECT_AMETHYST_CLUSTER = modLoc("inject/amethyst_cluster");
|
||||
|
||||
public static void lootLoad(ResourceLocation id,
|
||||
Consumer<LootPool> addPool) {
|
||||
if (id.equals(Blocks.AMETHYST_CLUSTER.getLootTable())) {
|
||||
addPool.accept(getInjectPool(TABLE_INJECT_AMETHYST_CLUSTER));
|
||||
} else if (
|
||||
id.equals(new ResourceLocation("minecraft:chests/jungle_temple"))
|
||||
|| id.equals(new ResourceLocation("minecraft:chests/simple_dungeon"))
|
||||
|| id.equals(new ResourceLocation("minecraft:chests/village/village_cartographer"))
|
||||
) {
|
||||
addPool.accept(getInjectPool(modLoc("inject/scroll_loot_few")));
|
||||
} else if (
|
||||
id.equals(new ResourceLocation("minecraft:chests/bastion_treasure"))
|
||||
|| id.equals(new ResourceLocation("minecraft:chests/shipwreck_map"))
|
||||
) {
|
||||
addPool.accept(getInjectPool(modLoc("inject/scroll_loot_some")));
|
||||
} else if (id.equals(new ResourceLocation("minecraft:chests/stronghold_library"))
|
||||
) {
|
||||
addPool.accept(getInjectPool(modLoc("inject/scroll_loot_many")));
|
||||
}
|
||||
}
|
||||
|
||||
public static LootPool getInjectPool(ResourceLocation entry) {
|
||||
return LootPool.lootPool()
|
||||
.add(getInjectEntry(entry, 1))
|
||||
.setBonusRolls(UniformGenerator.between(0, 1))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static LootPoolEntryContainer.Builder<?> getInjectEntry(ResourceLocation table, int weight) {
|
||||
return LootTableReference.lootTableReference(table)
|
||||
.setWeight(weight);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package at.petrak.hexcasting.common.loot;
|
||||
|
||||
import at.petrak.hexcasting.api.PatternRegistry;
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
||||
import at.petrak.hexcasting.common.items.ItemScroll;
|
||||
import at.petrak.hexcasting.common.lib.HexLootFunctions;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.functions.LootItemConditionalFunction;
|
||||
import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
|
||||
public class PatternScrollFunc extends LootItemConditionalFunction {
|
||||
public PatternScrollFunc(LootItemCondition[] lootItemConditions) {
|
||||
super(lootItemConditions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack run(ItemStack stack, LootContext ctx) {
|
||||
var rand = ctx.getRandom();
|
||||
var worldLookup = PatternRegistry.getPerWorldPatterns(ctx.getLevel());
|
||||
|
||||
var keys = worldLookup.keySet().stream().toList();
|
||||
var sig = keys.get(rand.nextInt(keys.size()));
|
||||
|
||||
var entry = worldLookup.get(sig);
|
||||
var opId = entry.component1();
|
||||
var startDir = entry.component2();
|
||||
var tag = new CompoundTag();
|
||||
tag.putString(ItemScroll.TAG_OP_ID, opId.toString());
|
||||
tag.put(ItemScroll.TAG_PATTERN, HexPattern.FromAnglesSig(sig, startDir).serializeToNBT());
|
||||
|
||||
stack.getOrCreateTag().merge(tag);
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootItemFunctionType getType() {
|
||||
return HexLootFunctions.PATTERN_SCROLL;
|
||||
}
|
||||
|
||||
public static class Serializer extends LootItemConditionalFunction.Serializer<PatternScrollFunc> {
|
||||
@Override
|
||||
public void serialize(JsonObject json, PatternScrollFunc value, JsonSerializationContext ctx) {
|
||||
super.serialize(json, value, ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PatternScrollFunc deserialize(JsonObject object, JsonDeserializationContext ctx,
|
||||
LootItemCondition[] conditions) {
|
||||
return new PatternScrollFunc(conditions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.xplat.datagen;
|
||||
package at.petrak.hexcasting.datagen;
|
||||
|
||||
import at.petrak.hexcasting.common.lib.HexBlockTags;
|
||||
import at.petrak.hexcasting.common.lib.HexBlocks;
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.xplat.datagen;
|
||||
package at.petrak.hexcasting.datagen;
|
||||
|
||||
import at.petrak.hexcasting.api.mod.HexItemTags;
|
||||
import at.petrak.hexcasting.common.lib.HexBlockTags;
|
|
@ -1,7 +1,11 @@
|
|||
package at.petrak.hexcasting.xplat.datagen;
|
||||
package at.petrak.hexcasting.datagen;
|
||||
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
import at.petrak.hexcasting.common.blocks.circles.BlockEntitySlate;
|
||||
import at.petrak.hexcasting.common.lib.HexBlocks;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import at.petrak.hexcasting.common.loot.HexLootHandler;
|
||||
import at.petrak.hexcasting.common.loot.PatternScrollFunc;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
@ -25,22 +29,24 @@ import net.minecraft.world.level.storage.loot.LootPool;
|
|||
import net.minecraft.world.level.storage.loot.LootTable;
|
||||
import net.minecraft.world.level.storage.loot.LootTables;
|
||||
import net.minecraft.world.level.storage.loot.entries.LootItem;
|
||||
import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount;
|
||||
import net.minecraft.world.level.storage.loot.functions.ApplyExplosionDecay;
|
||||
import net.minecraft.world.level.storage.loot.functions.CopyNbtFunction;
|
||||
import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||
import net.minecraft.world.level.storage.loot.predicates.AlternativeLootItemCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.MatchTool;
|
||||
import net.minecraft.world.level.storage.loot.predicates.*;
|
||||
import net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider;
|
||||
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
|
||||
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
||||
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
public class HexLootTables extends LootTableProvider {
|
||||
// steal it ALL from paucal
|
||||
protected final DataGenerator generator;
|
||||
|
@ -50,8 +56,9 @@ public class HexLootTables extends LootTableProvider {
|
|||
this.generator = pGenerator;
|
||||
}
|
||||
|
||||
protected void makeLootTables(Map<Block, LootTable.Builder> lootTables) {
|
||||
dropSelf(lootTables, HexBlocks.EMPTY_IMPETUS,
|
||||
protected void makeLootTables(Map<Block, LootTable.Builder> blockTables,
|
||||
Map<ResourceLocation, LootTable.Builder> lootTables) {
|
||||
dropSelf(blockTables, HexBlocks.EMPTY_IMPETUS,
|
||||
HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_STOREDPLAYER,
|
||||
HexBlocks.DIRECTRIX_REDSTONE, HexBlocks.EMPTY_DIRECTRIX,
|
||||
HexBlocks.AKASHIC_RECORD, HexBlocks.AKASHIC_BOOKSHELF, HexBlocks.AKASHIC_CONNECTOR,
|
||||
|
@ -64,24 +71,55 @@ public class HexLootTables extends LootTableProvider {
|
|||
HexBlocks.AKASHIC_TRAPDOOR, HexBlocks.AKASHIC_STAIRS, HexBlocks.AKASHIC_PRESSURE_PLATE,
|
||||
HexBlocks.AKASHIC_BUTTON);
|
||||
|
||||
makeSlabTable(lootTables, HexBlocks.AKASHIC_SLAB);
|
||||
makeSlabTable(blockTables, HexBlocks.AKASHIC_SLAB);
|
||||
|
||||
makeLeafTable(lootTables, HexBlocks.AKASHIC_LEAVES1);
|
||||
makeLeafTable(lootTables, HexBlocks.AKASHIC_LEAVES2);
|
||||
makeLeafTable(lootTables, HexBlocks.AKASHIC_LEAVES3);
|
||||
makeLeafTable(blockTables, HexBlocks.AKASHIC_LEAVES1);
|
||||
makeLeafTable(blockTables, HexBlocks.AKASHIC_LEAVES2);
|
||||
makeLeafTable(blockTables, HexBlocks.AKASHIC_LEAVES3);
|
||||
|
||||
var slatePool = LootPool.lootPool()
|
||||
.setRolls(ConstantValue.exactly(1))
|
||||
.add(LootItem.lootTableItem(HexBlocks.SLATE)
|
||||
.apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY)
|
||||
.copy(BlockEntitySlate.TAG_PATTERN, "BlockEntityTag." + BlockEntitySlate.TAG_PATTERN)));
|
||||
lootTables.put(HexBlocks.SLATE, LootTable.lootTable().withPool(slatePool));
|
||||
blockTables.put(HexBlocks.SLATE, LootTable.lootTable().withPool(slatePool));
|
||||
|
||||
var doorPool = dropThisPool(HexBlocks.AKASHIC_DOOR, 1)
|
||||
.when(new LootItemBlockStatePropertyCondition.Builder(HexBlocks.AKASHIC_DOOR).setProperties(
|
||||
StatePropertiesPredicate.Builder.properties().hasProperty(DoorBlock.HALF, DoubleBlockHalf.LOWER)
|
||||
));
|
||||
lootTables.put(HexBlocks.AKASHIC_DOOR, LootTable.lootTable().withPool(doorPool));
|
||||
blockTables.put(HexBlocks.AKASHIC_DOOR, LootTable.lootTable().withPool(doorPool));
|
||||
|
||||
var dustPool = LootPool.lootPool()
|
||||
.add(LootItem.lootTableItem(HexItems.AMETHYST_DUST))
|
||||
.apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 4)))
|
||||
.apply(ApplyBonusCount.addOreBonusCount(Enchantments.BLOCK_FORTUNE))
|
||||
.when(MatchTool.toolMatches(
|
||||
ItemPredicate.Builder.item().hasEnchantment(
|
||||
new EnchantmentPredicate(Enchantments.SILK_TOUCH, MinMaxBounds.Ints.ANY)))
|
||||
.invert());
|
||||
var isThatAnMFingBrandonSandersonReference = LootPool.lootPool()
|
||||
.add(LootItem.lootTableItem(HexItems.CHARGED_AMETHYST))
|
||||
.apply(SetItemCountFunction.setCount(ConstantValue.exactly(1)))
|
||||
.when(MatchTool.toolMatches(
|
||||
ItemPredicate.Builder.item().hasEnchantment(
|
||||
new EnchantmentPredicate(Enchantments.SILK_TOUCH, MinMaxBounds.Ints.ANY)))
|
||||
.invert())
|
||||
.when(BonusLevelTableCondition.bonusLevelFlatChance(Enchantments.BLOCK_FORTUNE,
|
||||
0.25f, 0.35f, 0.5f, 0.75f, 1.0f));
|
||||
lootTables.put(HexLootHandler.TABLE_INJECT_AMETHYST_CLUSTER, LootTable.lootTable()
|
||||
.withPool(dustPool)
|
||||
.withPool(isThatAnMFingBrandonSandersonReference));
|
||||
|
||||
String[] rarities = new String[]{
|
||||
"few",
|
||||
"some",
|
||||
"many"
|
||||
};
|
||||
for (int i = 0; i < rarities.length; i++) {
|
||||
var scrollPool = makeScrollAdder(i + 1);
|
||||
lootTables.put(modLoc("inject/scroll_loot_" + rarities[i]), scrollPool);
|
||||
}
|
||||
}
|
||||
|
||||
private void makeLeafTable(Map<Block, LootTable.Builder> lootTables, Block block) {
|
||||
|
@ -139,21 +177,34 @@ public class HexLootTables extends LootTableProvider {
|
|||
lootTables.put(block, table);
|
||||
}
|
||||
|
||||
// "stddev"
|
||||
private LootTable.Builder makeScrollAdder(float stddev) {
|
||||
var pool = LootPool.lootPool()
|
||||
.setRolls(UniformGenerator.between(-stddev, stddev))
|
||||
.add(LootItem.lootTableItem(HexItems.SCROLL))
|
||||
.apply(() -> new PatternScrollFunc(new LootItemCondition[0]));
|
||||
return LootTable.lootTable().withPool(pool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(HashCache cache) {
|
||||
var lootTables = new HashMap<Block, LootTable.Builder>();
|
||||
this.makeLootTables(lootTables);
|
||||
var blockTables = new HashMap<Block, LootTable.Builder>();
|
||||
var lootTables = new HashMap<ResourceLocation, LootTable.Builder>();
|
||||
this.makeLootTables(blockTables, lootTables);
|
||||
|
||||
var tables = new HashMap<ResourceLocation, LootTable>();
|
||||
for (var entry : lootTables.entrySet()) {
|
||||
tables.put(entry.getKey().getLootTable(), entry.getValue().setParamSet(LootContextParamSets.BLOCK).build());
|
||||
for (var entry : blockTables.entrySet()) {
|
||||
var old = lootTables.put(entry.getKey().getLootTable(),
|
||||
entry.getValue().setParamSet(LootContextParamSets.BLOCK));
|
||||
if (old != null) {
|
||||
HexAPI.LOGGER.warn("Whoopsy, clobbered a loot table '{}': {}", entry.getKey(), old);
|
||||
}
|
||||
}
|
||||
|
||||
var outputFolder = this.generator.getOutputFolder();
|
||||
tables.forEach((key, lootTable) -> {
|
||||
lootTables.forEach((key, lootTable) -> {
|
||||
Path path = outputFolder.resolve("data/" + key.getNamespace() + "/loot_tables/" + key.getPath() + ".json");
|
||||
try {
|
||||
DataProvider.save(GSON, cache, LootTables.serialize(lootTable), path);
|
||||
DataProvider.save(GSON, cache, LootTables.serialize(lootTable.build()), path);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.xplat.datagen;
|
||||
package at.petrak.hexcasting.datagen;
|
||||
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.xplat.datagen.recipe;
|
||||
package at.petrak.hexcasting.datagen.recipe;
|
||||
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
import at.petrak.hexcasting.api.advancements.OvercastTrigger;
|
||||
|
@ -10,10 +10,10 @@ import at.petrak.hexcasting.common.recipe.SealFocusRecipe;
|
|||
import at.petrak.hexcasting.common.recipe.SealSpellbookRecipe;
|
||||
import at.petrak.hexcasting.common.recipe.ingredient.StateIngredientHelper;
|
||||
import at.petrak.hexcasting.common.recipe.ingredient.VillagerIngredient;
|
||||
import at.petrak.hexcasting.datagen.IXplatIngredients;
|
||||
import at.petrak.hexcasting.datagen.recipe.builders.BrainsweepRecipeBuilder;
|
||||
import at.petrak.hexcasting.mixin.accessor.AccessorRecipeProvider;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import at.petrak.hexcasting.xplat.datagen.IXplatIngredients;
|
||||
import at.petrak.hexcasting.xplat.datagen.recipe.builders.BrainsweepRecipeBuilder;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.advancements.critereon.EntityPredicate;
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.xplat.datagen.recipe.builders;
|
||||
package at.petrak.hexcasting.datagen.recipe.builders;
|
||||
|
||||
import at.petrak.hexcasting.common.recipe.HexRecipeSerializers;
|
||||
import at.petrak.hexcasting.common.recipe.ingredient.StateIngredient;
|
|
@ -0,0 +1,17 @@
|
|||
package at.petrak.hexcasting.mixin.accessor;
|
||||
|
||||
import net.minecraft.world.level.storage.loot.LootTable;
|
||||
import net.minecraft.world.level.storage.loot.functions.LootItemFunction;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(LootTable.class)
|
||||
public interface AccessorLootTable {
|
||||
@Accessor("functions")
|
||||
LootItemFunction[] hex$getFunctions();
|
||||
|
||||
@Accessor("functions")
|
||||
@Mutable
|
||||
void hex$setFunctions(LootItemFunction[] lifs);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"function": "hexcasting:amethyst_shard_reducer",
|
||||
"delta": -2
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
"package": "at.petrak.hexcasting.mixin",
|
||||
"mixins": [
|
||||
"AccessorTagsProvider", "MixinMob", "MixinRaider", "MixinVillager", "MixinWitch", "accessor.AccessorLivingEntity",
|
||||
"accessor.AccessorRecipeProvider", "accessor.AccessorUseOnContext", "accessor.CriteriaTriggersAccessor"
|
||||
"accessor.AccessorLootTable", "accessor.AccessorRecipeProvider", "accessor.AccessorUseOnContext",
|
||||
"accessor.CriteriaTriggersAccessor"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ e125117befadda0785e370969a8e04eff070d057 data\hexcasting\loot_tables\blocks\amet
|
|||
8aa3d09d72255aa4da497ab4225654961063a496 data\hexcasting\recipes\ancient_scroll_paper.json
|
||||
fe5f10e9258f430859f1f1f87320a2b5c7b67654 data\hexcasting\recipes\dye_colorizer_green.json
|
||||
7a535e710c96e39a17606a10bc1f153d7c57b8e7 data\hexcasting\advancements\recipes\hexcasting.creative_tab\akashic_pressure_plate.json
|
||||
c9bf845be14c7fd2a2495265ba2d63d146166bae data\hexcasting\loot_tables\inject\amethyst_cluster.json
|
||||
090b54b026f6fef2502295ddde5a60f5350e2ec6 data\hexcasting\advancements\recipes\hexcasting.creative_tab\artifact.json
|
||||
49b6ea97ddc55ef3d7fa47582f268a07a35cadde data\hexcasting\loot_tables\blocks\slate.json
|
||||
9fcc0862c99c50a1df9d3af95b2b3c2af28afa1b data\hexcasting\advancements\recipes\hexcasting.creative_tab\slate_block_from_slates.json
|
||||
|
@ -20,6 +21,7 @@ add097a7a749bd1ebd5828216f013f6cd5b72b62 data\hexcasting\recipes\akashic_door.js
|
|||
8e73ac3942a94096017e8c775724beafcbade37b data\hexcasting\advancements\recipes\hexcasting.creative_tab\pride_colorizer_12.json
|
||||
5f1e9330dcdf927e128212678c8e262c6daa92f1 data\hexcasting\recipes\pride_colorizer_13.json
|
||||
7351200c8e3eb24772852c578286384c8aab61bd data\hexcasting\advancements\recipes\hexcasting.creative_tab\empty_directrix.json
|
||||
64aef53a076a34dbaaca0d3df8c671476729bec4 data\hexcasting\loot_tables\inject\scroll_loot_some.json
|
||||
eb17a23e7a9543f33922c056cdf0d63def176bf2 data\hexcasting\advancements\recipes\hexcasting.creative_tab\uuid_colorizer.json
|
||||
33fed8fb8e34df026e1eea0df8161c7f842a8648 data\hexcasting\recipes\dye_colorizer_black.json
|
||||
bceac44311dc2771c3744c0cda299f03fb957350 data\hexcasting\loot_tables\blocks\scroll_paper_lantern.json
|
||||
|
@ -30,6 +32,7 @@ b7c248d2627c2a2b398d1c50181c1e0863612424 data\hexcasting\recipes\empty_impetus.j
|
|||
d5122f034678cc53a2921c65f30451caf708046c data\hexcasting\advancements\recipes\hexcasting.creative_tab\akashic_trapdoor.json
|
||||
5d4811f78feefbef0a305555143f488b3dac7ac6 data\hexcasting\advancements\recipes\brainsweep\brainsweep\impetus_storedplayer.json
|
||||
f3c6b6917e504e1c3d5d8875f7cce6f311e791d2 data\hexcasting\tags\items\akashic_logs.json
|
||||
35a9b4beac7c6eddb990464eaeaebec2a9ab9951 data\hexcasting\loot_tables\inject\scroll_loot_many.json
|
||||
6837c1fe0ab23167ca8475086b28115369227e0c data\hexcasting\advancements\recipes\hexcasting.creative_tab\dye_colorizer_light_gray.json
|
||||
556d2e6068965e90c307a435b372ae761cd1c606 data\minecraft\tags\items\doors.json
|
||||
fe8a7288aa27c07932a31c64ff8fadb943b278d5 data\hexcasting\recipes\dye_colorizer_pink.json
|
||||
|
@ -238,6 +241,7 @@ f3c6b6917e504e1c3d5d8875f7cce6f311e791d2 data\minecraft\tags\items\logs_that_bur
|
|||
ddd7bd92b9e1586cebd2cee658315a9336a80a76 data\hexcasting\advancements\recipes\hexcasting.creative_tab\amethyst_dust_packing.json
|
||||
4d4caaea035ae4ee878843dd2455042b299b4e5e data\c\tags\items\amethyst_dusts.json
|
||||
2d52419f3fcdc10643cdb8cef89858efc0ad4d11 data\hexcasting\advancements\recipes\hexcasting.creative_tab\wand_akashic.json
|
||||
3147422bed290cb47ea3763dbdc6f0e96eed5c2a data\hexcasting\loot_tables\inject\scroll_loot_few.json
|
||||
82be04125e60a28701de5bb6bc7855bb46fa9d0f data\hexcasting\advancements\recipes\hexcasting.creative_tab\pride_colorizer_0.json
|
||||
cd3ca380294544b07e91ce85d97808c30ffa5d17 data\hexcasting\advancements\recipes\hexcasting.creative_tab\spellbook.json
|
||||
c36caf44a941a4abc44a15141eba8fe634c76fb8 data\hexcasting\recipes\dye_colorizer_blue.json
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1.0,
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "hexcasting:amethyst_dust"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:inverted",
|
||||
"term": {
|
||||
"condition": "minecraft:match_tool",
|
||||
"predicate": {
|
||||
"enchantments": [
|
||||
{
|
||||
"enchantment": "minecraft:silk_touch"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_count",
|
||||
"count": {
|
||||
"type": "minecraft:uniform",
|
||||
"min": 1.0,
|
||||
"max": 4.0
|
||||
},
|
||||
"add": false
|
||||
},
|
||||
{
|
||||
"function": "minecraft:apply_bonus",
|
||||
"enchantment": "minecraft:fortune",
|
||||
"formula": "minecraft:ore_drops"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"rolls": 1.0,
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "hexcasting:charged_amethyst"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:inverted",
|
||||
"term": {
|
||||
"condition": "minecraft:match_tool",
|
||||
"predicate": {
|
||||
"enchantments": [
|
||||
{
|
||||
"enchantment": "minecraft:silk_touch"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "minecraft:table_bonus",
|
||||
"enchantment": "minecraft:fortune",
|
||||
"chances": [
|
||||
0.25,
|
||||
0.35,
|
||||
0.5,
|
||||
0.75,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_count",
|
||||
"count": 1.0,
|
||||
"add": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": {
|
||||
"type": "minecraft:uniform",
|
||||
"min": -1.0,
|
||||
"max": 1.0
|
||||
},
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "hexcasting:scroll"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "hexcasting:pattern_scroll"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": {
|
||||
"type": "minecraft:uniform",
|
||||
"min": -3.0,
|
||||
"max": 3.0
|
||||
},
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "hexcasting:scroll"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "hexcasting:pattern_scroll"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": {
|
||||
"type": "minecraft:uniform",
|
||||
"min": -2.0,
|
||||
"max": 2.0
|
||||
},
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "hexcasting:scroll"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "hexcasting:pattern_scroll"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -9,6 +9,7 @@ import at.petrak.hexcasting.common.command.PatternResLocArgument
|
|||
import at.petrak.hexcasting.common.entities.HexEntities
|
||||
import at.petrak.hexcasting.common.items.ItemJewelerHammer
|
||||
import at.petrak.hexcasting.common.lib.*
|
||||
import at.petrak.hexcasting.common.loot.HexLootHandler
|
||||
import at.petrak.hexcasting.common.misc.Brainsweeping
|
||||
import at.petrak.hexcasting.common.misc.PlayerPositionRecorder
|
||||
import at.petrak.hexcasting.common.recipe.HexRecipeSerializers
|
||||
|
@ -19,12 +20,14 @@ import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback
|
|||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback
|
||||
import net.fabricmc.fabric.api.event.player.UseEntityCallback
|
||||
import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback
|
||||
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry
|
||||
import net.minecraft.commands.synchronization.ArgumentTypes
|
||||
import net.minecraft.commands.synchronization.EmptyArgumentSerializer
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.InteractionResult
|
||||
import net.minecraft.world.level.storage.loot.LootPool
|
||||
import java.util.function.BiConsumer
|
||||
|
||||
object FabricHexInitializer : ModInitializer {
|
||||
|
@ -64,6 +67,13 @@ object FabricHexInitializer : ModInitializer {
|
|||
ServerTickEvents.END_WORLD_TICK.register(PlayerPositionRecorder::updateAllPlayers)
|
||||
|
||||
CommandRegistrationCallback.EVENT.register { dp, _ -> HexCommands.register(dp) }
|
||||
|
||||
LootTableLoadingCallback.EVENT.register { recman, manager, id, supplier, setter ->
|
||||
HexLootHandler.lootLoad(
|
||||
id,
|
||||
{ b: LootPool -> supplier.withPool(b) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun initRegistries() {
|
||||
|
@ -76,9 +86,10 @@ object FabricHexInitializer : ModInitializer {
|
|||
HexEntities.registerEntities(bind(Registry.ENTITY_TYPE))
|
||||
|
||||
HexRecipeSerializers.registerSerializers(bind(Registry.RECIPE_SERIALIZER))
|
||||
|
||||
HexParticles.registerParticles(bind(Registry.PARTICLE_TYPE))
|
||||
|
||||
HexLootFunctions.registerSerializers(bind(Registry.LOOT_FUNCTION_TYPE))
|
||||
|
||||
// Done with soft implements in forge
|
||||
val flameOn = FlammableBlockRegistry.getDefaultInstance()
|
||||
for (log in listOf(
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package at.petrak.hexcasting.fabric.datagen;
|
||||
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
import at.petrak.hexcasting.datagen.HexBlockTagProvider;
|
||||
import at.petrak.hexcasting.datagen.HexItemTagProvider;
|
||||
import at.petrak.hexcasting.datagen.HexLootTables;
|
||||
import at.petrak.hexcasting.datagen.IXplatIngredients;
|
||||
import at.petrak.hexcasting.datagen.recipe.HexplatRecipes;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import at.petrak.hexcasting.xplat.datagen.HexBlockTagProvider;
|
||||
import at.petrak.hexcasting.xplat.datagen.HexItemTagProvider;
|
||||
import at.petrak.hexcasting.xplat.datagen.HexLootTables;
|
||||
import at.petrak.hexcasting.xplat.datagen.IXplatIngredients;
|
||||
import at.petrak.hexcasting.xplat.datagen.recipe.HexplatRecipes;
|
||||
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
||||
import net.minecraft.core.Registry;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
637e118fc7c371db684d0d831a46833b5851e582 data/forge/loot_modifiers/global_loot_modifiers.json
|
||||
4d4caaea035ae4ee878843dd2455042b299b4e5e data/forge/tags/items/dusts/amethyst.json
|
||||
05e86742a71afd740f47639be62f93bc9898fcde data/forge/tags/items/gems.json
|
||||
cf0ad981bebbb79414d955fb40fbf537fe88b89d data/hexcasting/advancements/recipes/brainsweep/brainsweep/akashic_record.json
|
||||
|
@ -85,15 +84,6 @@ f32ccb2d36d773215d91dee46bec70a20af501c3 data/hexcasting/advancements/recipes/he
|
|||
30950c6dd31102cf145f8f7d2979df0736a7ba1e data/hexcasting/advancements/recipes/hexcasting/wand_oak.json
|
||||
f8d2872c4e692153049b6ae4879755a079954763 data/hexcasting/advancements/recipes/hexcasting/wand_spruce.json
|
||||
3b2bcffe70bb1f732f06c2560cef66de6c273d62 data/hexcasting/advancements/recipes/hexcasting/wand_warped.json
|
||||
70a8f77d38affa642afbfceebe129358737b09ac data/hexcasting/loot_modifiers/amethyst_cluster_charged.json
|
||||
f746acc6b3e798d3b95f4ceb463c648b1f3ae8c3 data/hexcasting/loot_modifiers/amethyst_cluster_dust.json
|
||||
a783e00f46a9ff0206e2495c15cea8ba57bdff31 data/hexcasting/loot_modifiers/amethyst_cluster_shard_reducer.json
|
||||
e04be385fa9daa422e41a38ddd70fdd065107968 data/hexcasting/loot_modifiers/scroll_bastion.json
|
||||
6569766d1579114149eb0a1154d05ec3c964b2a3 data/hexcasting/loot_modifiers/scroll_cartographer.json
|
||||
afecba3144e00505977a4ab4de7940f949ab7818 data/hexcasting/loot_modifiers/scroll_dungeon.json
|
||||
0e8c8a56161586a4021487b27059ca151465af67 data/hexcasting/loot_modifiers/scroll_jungle.json
|
||||
50e7ad657a0ab43f3bd632120e09f109791aaf34 data/hexcasting/loot_modifiers/scroll_shipwreck.json
|
||||
7ffa361bd8a108b504fe450749b42997dc898e5e data/hexcasting/loot_modifiers/scroll_stronghold_library.json
|
||||
5b9b1c15c7a157aa56b3caa7d43a6ad1fa8f4710 data/hexcasting/loot_tables/blocks/akashic_bookshelf.json
|
||||
811177c2ddc341f7a6d8704e1eb273f200aee3a1 data/hexcasting/loot_tables/blocks/akashic_button.json
|
||||
ce79c9e183b57bfbdb75cd074d7ff6e48894d05c data/hexcasting/loot_tables/blocks/akashic_connector.json
|
||||
|
@ -128,6 +118,10 @@ c521621c409275e219f72abf5c6089d60408e646 data/hexcasting/loot_tables/blocks/impe
|
|||
bceac44311dc2771c3744c0cda299f03fb957350 data/hexcasting/loot_tables/blocks/scroll_paper_lantern.json
|
||||
49b6ea97ddc55ef3d7fa47582f268a07a35cadde data/hexcasting/loot_tables/blocks/slate.json
|
||||
584bd8806ef8df5f0e623ed727d6e54a61e60dea data/hexcasting/loot_tables/blocks/slate_block.json
|
||||
c9bf845be14c7fd2a2495265ba2d63d146166bae data/hexcasting/loot_tables/inject/amethyst_cluster.json
|
||||
3147422bed290cb47ea3763dbdc6f0e96eed5c2a data/hexcasting/loot_tables/inject/scroll_loot_few.json
|
||||
35a9b4beac7c6eddb990464eaeaebec2a9ab9951 data/hexcasting/loot_tables/inject/scroll_loot_many.json
|
||||
64aef53a076a34dbaaca0d3df8c671476729bec4 data/hexcasting/loot_tables/inject/scroll_loot_some.json
|
||||
6b4459635b3d53cc2b6836fa97d29244a65b412d data/hexcasting/recipes/abacus.json
|
||||
1f0c9a98d97fb81e1f504cdb6619a3dfab52ba5f data/hexcasting/recipes/ageing_scroll_paper_lantern.json
|
||||
fa04d5bc32f5646cd67bc8e8b572bdb7849b735e data/hexcasting/recipes/akashic_bookshelf.json
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"replace": false,
|
||||
"entries": [
|
||||
"hexcasting:amethyst_cluster_charged",
|
||||
"hexcasting:amethyst_cluster_shard_reducer",
|
||||
"hexcasting:scroll_bastion",
|
||||
"hexcasting:amethyst_cluster_dust",
|
||||
"hexcasting:scroll_dungeon",
|
||||
"hexcasting:scroll_stronghold_library",
|
||||
"hexcasting:scroll_jungle",
|
||||
"hexcasting:scroll_cartographer",
|
||||
"hexcasting:scroll_shipwreck"
|
||||
]
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "forge:loot_table_id",
|
||||
"loot_table_id": "minecraft:blocks/amethyst_cluster"
|
||||
},
|
||||
{
|
||||
"condition": "minecraft:inverted",
|
||||
"term": {
|
||||
"condition": "minecraft:match_tool",
|
||||
"predicate": {
|
||||
"enchantments": [
|
||||
{
|
||||
"enchantment": "minecraft:silk_touch"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "minecraft:table_bonus",
|
||||
"enchantment": "minecraft:fortune",
|
||||
"chances": [
|
||||
0.25,
|
||||
0.35,
|
||||
0.5,
|
||||
0.75,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
],
|
||||
"item": "hexcasting:charged_amethyst",
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_count",
|
||||
"count": 1.0,
|
||||
"add": false
|
||||
}
|
||||
],
|
||||
"type": "paucal:add_item"
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "forge:loot_table_id",
|
||||
"loot_table_id": "minecraft:blocks/amethyst_cluster"
|
||||
},
|
||||
{
|
||||
"condition": "minecraft:inverted",
|
||||
"term": {
|
||||
"condition": "minecraft:match_tool",
|
||||
"predicate": {
|
||||
"enchantments": [
|
||||
{
|
||||
"enchantment": "minecraft:silk_touch"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"item": "hexcasting:amethyst_dust",
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_count",
|
||||
"count": {
|
||||
"type": "minecraft:uniform",
|
||||
"min": 1.0,
|
||||
"max": 4.0
|
||||
},
|
||||
"add": false
|
||||
},
|
||||
{
|
||||
"function": "minecraft:apply_bonus",
|
||||
"enchantment": "minecraft:fortune",
|
||||
"formula": "minecraft:ore_drops"
|
||||
}
|
||||
],
|
||||
"type": "paucal:add_item"
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "forge:loot_table_id",
|
||||
"loot_table_id": "minecraft:blocks/amethyst_cluster"
|
||||
},
|
||||
{
|
||||
"condition": "minecraft:inverted",
|
||||
"term": {
|
||||
"condition": "minecraft:match_tool",
|
||||
"predicate": {
|
||||
"enchantments": [
|
||||
{
|
||||
"enchantment": "minecraft:silk_touch"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"modifier": -2.0,
|
||||
"type": "hexcasting:amethyst_shard_reducer"
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "forge:loot_table_id",
|
||||
"loot_table_id": "minecraft:chests/bastion_treasure"
|
||||
}
|
||||
],
|
||||
"stddev": 2.0,
|
||||
"type": "hexcasting:scrolls"
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "forge:loot_table_id",
|
||||
"loot_table_id": "minecraft:chests/village/village_cartographer"
|
||||
}
|
||||
],
|
||||
"stddev": 1.0,
|
||||
"type": "hexcasting:scrolls"
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "forge:loot_table_id",
|
||||
"loot_table_id": "minecraft:chests/simple_dungeon"
|
||||
}
|
||||
],
|
||||
"stddev": 1.0,
|
||||
"type": "hexcasting:scrolls"
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "forge:loot_table_id",
|
||||
"loot_table_id": "minecraft:chests/jungle_temple"
|
||||
}
|
||||
],
|
||||
"stddev": 1.0,
|
||||
"type": "hexcasting:scrolls"
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "forge:loot_table_id",
|
||||
"loot_table_id": "minecraft:chests/shipwreck_map"
|
||||
}
|
||||
],
|
||||
"stddev": 1.0,
|
||||
"type": "hexcasting:scrolls"
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "forge:loot_table_id",
|
||||
"loot_table_id": "minecraft:chests/stronghold_library"
|
||||
}
|
||||
],
|
||||
"stddev": 3.0,
|
||||
"type": "hexcasting:scrolls"
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1.0,
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "hexcasting:amethyst_dust"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:inverted",
|
||||
"term": {
|
||||
"condition": "minecraft:match_tool",
|
||||
"predicate": {
|
||||
"enchantments": [
|
||||
{
|
||||
"enchantment": "minecraft:silk_touch"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_count",
|
||||
"count": {
|
||||
"type": "minecraft:uniform",
|
||||
"min": 1.0,
|
||||
"max": 4.0
|
||||
},
|
||||
"add": false
|
||||
},
|
||||
{
|
||||
"function": "minecraft:apply_bonus",
|
||||
"enchantment": "minecraft:fortune",
|
||||
"formula": "minecraft:ore_drops"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"rolls": 1.0,
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "hexcasting:charged_amethyst"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:inverted",
|
||||
"term": {
|
||||
"condition": "minecraft:match_tool",
|
||||
"predicate": {
|
||||
"enchantments": [
|
||||
{
|
||||
"enchantment": "minecraft:silk_touch"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "minecraft:table_bonus",
|
||||
"enchantment": "minecraft:fortune",
|
||||
"chances": [
|
||||
0.25,
|
||||
0.35,
|
||||
0.5,
|
||||
0.75,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:set_count",
|
||||
"count": 1.0,
|
||||
"add": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": {
|
||||
"type": "minecraft:uniform",
|
||||
"min": -1.0,
|
||||
"max": 1.0
|
||||
},
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "hexcasting:scroll"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "hexcasting:pattern_scroll"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": {
|
||||
"type": "minecraft:uniform",
|
||||
"min": -3.0,
|
||||
"max": 3.0
|
||||
},
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "hexcasting:scroll"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "hexcasting:pattern_scroll"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": {
|
||||
"type": "minecraft:uniform",
|
||||
"min": -2.0,
|
||||
"max": 2.0
|
||||
},
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "hexcasting:scroll"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"function": "hexcasting:pattern_scroll"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -13,19 +13,20 @@ import at.petrak.hexcasting.common.command.PatternResLocArgument;
|
|||
import at.petrak.hexcasting.common.entities.HexEntities;
|
||||
import at.petrak.hexcasting.common.items.ItemJewelerHammer;
|
||||
import at.petrak.hexcasting.common.lib.*;
|
||||
import at.petrak.hexcasting.common.loot.HexLootHandler;
|
||||
import at.petrak.hexcasting.common.misc.Brainsweeping;
|
||||
import at.petrak.hexcasting.common.misc.PlayerPositionRecorder;
|
||||
import at.petrak.hexcasting.common.recipe.HexRecipeSerializers;
|
||||
import at.petrak.hexcasting.forge.cap.CapSyncers;
|
||||
import at.petrak.hexcasting.forge.cap.ForgeCapabilityHandler;
|
||||
import at.petrak.hexcasting.forge.datagen.HexForgeDataGenerators;
|
||||
import at.petrak.hexcasting.forge.datagen.forge.lootmods.HexLootModifiers;
|
||||
import at.petrak.hexcasting.forge.network.ForgePacketHandler;
|
||||
import at.petrak.hexcasting.forge.network.MsgBrainsweepAck;
|
||||
import at.petrak.hexcasting.forge.recipe.ForgeUnsealedIngredient;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import net.minecraft.commands.synchronization.ArgumentTypes;
|
||||
import net.minecraft.commands.synchronization.EmptyArgumentSerializer;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
@ -38,6 +39,7 @@ import net.minecraftforge.common.ForgeConfigSpec;
|
|||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.ToolActions;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.event.LootTableLoadEvent;
|
||||
import net.minecraftforge.event.RegisterCommandsEvent;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
|
@ -98,8 +100,6 @@ public class ForgeHexInitializer {
|
|||
|
||||
bind(ForgeRegistries.PARTICLE_TYPES, HexParticles::registerParticles);
|
||||
|
||||
HexLootModifiers.LOOT_MODS.register(getModEventBus());
|
||||
|
||||
ArgumentTypes.register(HexAPI.MOD_ID + ":pattern", PatternResLocArgument.class,
|
||||
new EmptyArgumentSerializer<>(PatternResLocArgument::id));
|
||||
HexAdvancementTriggers.registerTriggers();
|
||||
|
@ -137,6 +137,8 @@ public class ForgeHexInitializer {
|
|||
HexRecipeSerializers.registerTypes();
|
||||
CraftingHelper.register(modLoc("unsealed"), ForgeUnsealedIngredient.Serializer.INSTANCE);
|
||||
HexStatistics.register();
|
||||
HexLootFunctions.registerSerializers((lift, id) ->
|
||||
Registry.register(Registry.LOOT_FUNCTION_TYPE, id, lift));
|
||||
});
|
||||
|
||||
modBus.addListener((FMLLoadCompleteEvent evt) ->
|
||||
|
@ -168,6 +170,10 @@ public class ForgeHexInitializer {
|
|||
evBus.addListener((PlayerEvent.BreakSpeed evt) ->
|
||||
evt.setCanceled(ItemJewelerHammer.shouldFailToBreak(evt.getPlayer(), evt.getState(), evt.getPos())));
|
||||
|
||||
evBus.addListener((LootTableLoadEvent evt) -> HexLootHandler.lootLoad(
|
||||
evt.getName(),
|
||||
evt.getTable()::addPool));
|
||||
|
||||
// === Events implemented in other ways on Fabric
|
||||
|
||||
// On Fabric this should be auto-synced
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
package at.petrak.hexcasting.forge.datagen;
|
||||
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
import at.petrak.hexcasting.forge.datagen.forge.lootmods.HexLootModifiers;
|
||||
import at.petrak.hexcasting.datagen.HexBlockTagProvider;
|
||||
import at.petrak.hexcasting.datagen.HexItemTagProvider;
|
||||
import at.petrak.hexcasting.datagen.HexLootTables;
|
||||
import at.petrak.hexcasting.datagen.IXplatIngredients;
|
||||
import at.petrak.hexcasting.datagen.recipe.HexplatRecipes;
|
||||
import at.petrak.hexcasting.forge.datagen.xplat.HexAdvancements;
|
||||
import at.petrak.hexcasting.forge.datagen.xplat.HexBlockStatesAndModels;
|
||||
import at.petrak.hexcasting.forge.datagen.xplat.HexItemModels;
|
||||
import at.petrak.hexcasting.forge.mixin.ForgeAccessorTagsProvider;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import at.petrak.hexcasting.xplat.datagen.HexBlockTagProvider;
|
||||
import at.petrak.hexcasting.xplat.datagen.HexItemTagProvider;
|
||||
import at.petrak.hexcasting.xplat.datagen.HexLootTables;
|
||||
import at.petrak.hexcasting.xplat.datagen.IXplatIngredients;
|
||||
import at.petrak.hexcasting.xplat.datagen.recipe.HexplatRecipes;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
|
@ -67,8 +66,6 @@ public class HexForgeDataGenerators {
|
|||
var itemTagProvider = new HexItemTagProvider(gen, blockTagProvider, IXplatAbstractions.INSTANCE.tags());
|
||||
((ForgeAccessorTagsProvider) itemTagProvider).hex$setExistingFileHelper(efh);
|
||||
gen.addProvider(itemTagProvider);
|
||||
|
||||
gen.addProvider(new HexLootModifiers(gen));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
package at.petrak.hexcasting.forge.datagen.forge.lootmods;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import net.minecraftforge.common.loot.GlobalLootModifierSerializer;
|
||||
import net.minecraftforge.common.loot.LootModifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AmethystShardReducerModifier extends LootModifier {
|
||||
private final double modifier;
|
||||
|
||||
public AmethystShardReducerModifier(double modifier, LootItemCondition[] conditions) {
|
||||
super(conditions);
|
||||
this.modifier = modifier;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<ItemStack> doApply(List<ItemStack> generatedLoot, LootContext context) {
|
||||
for (var stack : generatedLoot) {
|
||||
if (stack.is(Items.AMETHYST_SHARD)) {
|
||||
stack.setCount((int) (stack.getCount() * (1 + modifier)));
|
||||
}
|
||||
}
|
||||
return generatedLoot;
|
||||
}
|
||||
|
||||
public static class Serializer extends GlobalLootModifierSerializer<AmethystShardReducerModifier> {
|
||||
@Override
|
||||
public AmethystShardReducerModifier read(ResourceLocation location, JsonObject json,
|
||||
LootItemCondition[] conditions) {
|
||||
var modifier = GsonHelper.getAsDouble(json, "modifier");
|
||||
return new AmethystShardReducerModifier(modifier, conditions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject write(AmethystShardReducerModifier instance) {
|
||||
var obj = this.makeConditions(instance.conditions);
|
||||
obj.addProperty("modifier", instance.modifier);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package at.petrak.hexcasting.forge.datagen.forge.lootmods;
|
||||
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import at.petrak.paucal.api.forge.datagen.lootmod.PaucalAddItemModifier;
|
||||
import at.petrak.paucal.api.forge.datagen.lootmod.PaucalLootMods;
|
||||
import net.minecraft.advancements.critereon.EnchantmentPredicate;
|
||||
import net.minecraft.advancements.critereon.ItemPredicate;
|
||||
import net.minecraft.advancements.critereon.MinMaxBounds;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount;
|
||||
import net.minecraft.world.level.storage.loot.functions.LootItemFunction;
|
||||
import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction;
|
||||
import net.minecraft.world.level.storage.loot.predicates.BonusLevelTableCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import net.minecraft.world.level.storage.loot.predicates.MatchTool;
|
||||
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
|
||||
import net.minecraftforge.common.data.GlobalLootModifierProvider;
|
||||
import net.minecraftforge.common.loot.GlobalLootModifierSerializer;
|
||||
import net.minecraftforge.common.loot.LootTableIdCondition;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
|
||||
public class HexLootModifiers extends GlobalLootModifierProvider {
|
||||
public static final DeferredRegister<GlobalLootModifierSerializer<?>> LOOT_MODS = DeferredRegister.create(
|
||||
ForgeRegistries.Keys.LOOT_MODIFIER_SERIALIZERS, HexAPI.MOD_ID);
|
||||
private static final RegistryObject<PatternScrollModifier.Serializer> SCROLLS_IN_CHESTS = LOOT_MODS.register(
|
||||
"scrolls", PatternScrollModifier.Serializer::new);
|
||||
private static final RegistryObject<AmethystShardReducerModifier.Serializer> AMETHYST_SHARD_REDUCER = LOOT_MODS.register(
|
||||
"amethyst_shard_reducer", AmethystShardReducerModifier.Serializer::new);
|
||||
|
||||
public HexLootModifiers(DataGenerator gen) {
|
||||
super(gen, HexAPI.MOD_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
ResourceLocation amethystCluster = new ResourceLocation("minecraft:blocks/amethyst_cluster");
|
||||
// 4? that's a lot!
|
||||
add("amethyst_cluster_shard_reducer", AMETHYST_SHARD_REDUCER.get(), new AmethystShardReducerModifier(
|
||||
-2, new LootItemCondition[]{
|
||||
LootTableIdCondition.builder(amethystCluster).build(),
|
||||
MatchTool.toolMatches(
|
||||
ItemPredicate.Builder.item().hasEnchantment(
|
||||
new EnchantmentPredicate(Enchantments.SILK_TOUCH, MinMaxBounds.Ints.ANY)))
|
||||
.invert().build()
|
||||
}));
|
||||
|
||||
add("amethyst_cluster_dust", PaucalLootMods.ADD_ITEM.get(), new PaucalAddItemModifier(
|
||||
HexItems.AMETHYST_DUST, new LootItemFunction[]{
|
||||
SetItemCountFunction.setCount(UniformGenerator.between(1, 4)).build(),
|
||||
ApplyBonusCount.addOreBonusCount(Enchantments.BLOCK_FORTUNE).build()
|
||||
}, new LootItemCondition[]{
|
||||
LootTableIdCondition.builder(amethystCluster).build(),
|
||||
MatchTool.toolMatches(
|
||||
ItemPredicate.Builder.item().hasEnchantment(
|
||||
new EnchantmentPredicate(Enchantments.SILK_TOUCH, MinMaxBounds.Ints.ANY)))
|
||||
.invert().build(),
|
||||
}
|
||||
));
|
||||
add("amethyst_cluster_charged", PaucalLootMods.ADD_ITEM.get(), new PaucalAddItemModifier(
|
||||
HexItems.CHARGED_AMETHYST, 1, new LootItemCondition[]{
|
||||
LootTableIdCondition.builder(amethystCluster).build(),
|
||||
MatchTool.toolMatches(
|
||||
ItemPredicate.Builder.item().hasEnchantment(
|
||||
new EnchantmentPredicate(Enchantments.SILK_TOUCH, MinMaxBounds.Ints.ANY)))
|
||||
.invert().build(),
|
||||
BonusLevelTableCondition.bonusLevelFlatChance(Enchantments.BLOCK_FORTUNE,
|
||||
0.25f, 0.35f, 0.5f, 0.75f, 1.0f).build()
|
||||
}));
|
||||
|
||||
|
||||
add("scroll_jungle", SCROLLS_IN_CHESTS.get(), new PatternScrollModifier(new LootItemCondition[]{
|
||||
LootTableIdCondition.builder(new ResourceLocation("minecraft:chests/jungle_temple")).build()
|
||||
}, 1.0));
|
||||
add("scroll_bastion", SCROLLS_IN_CHESTS.get(), new PatternScrollModifier(new LootItemCondition[]{
|
||||
LootTableIdCondition.builder(new ResourceLocation("minecraft:chests/bastion_treasure")).build()
|
||||
}, 2.0));
|
||||
add("scroll_dungeon", SCROLLS_IN_CHESTS.get(), new PatternScrollModifier(new LootItemCondition[]{
|
||||
LootTableIdCondition.builder(new ResourceLocation("minecraft:chests/simple_dungeon")).build()
|
||||
}, 1.0));
|
||||
add("scroll_stronghold_library", SCROLLS_IN_CHESTS.get(), new PatternScrollModifier(new LootItemCondition[]{
|
||||
LootTableIdCondition.builder(new ResourceLocation("minecraft:chests/stronghold_library")).build()
|
||||
}, 3.0));
|
||||
// Why is there not a village library chest
|
||||
add("scroll_cartographer", SCROLLS_IN_CHESTS.get(), new PatternScrollModifier(new LootItemCondition[]{
|
||||
LootTableIdCondition.builder(
|
||||
new ResourceLocation("minecraft:chests/village/village_cartographer")).build()
|
||||
}, 1.0));
|
||||
add("scroll_shipwreck", SCROLLS_IN_CHESTS.get(), new PatternScrollModifier(new LootItemCondition[]{
|
||||
LootTableIdCondition.builder(new ResourceLocation("minecraft:chests/shipwreck_map")).build()
|
||||
}, 1.0));
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package at.petrak.hexcasting.forge.datagen.forge.lootmods;
|
||||
|
||||
import at.petrak.hexcasting.api.PatternRegistry;
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
||||
import at.petrak.hexcasting.common.items.ItemScroll;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import net.minecraftforge.common.loot.GlobalLootModifierSerializer;
|
||||
import net.minecraftforge.common.loot.LootModifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class PatternScrollModifier extends LootModifier {
|
||||
private final double countStddev;
|
||||
|
||||
public PatternScrollModifier(LootItemCondition[] conditions, double countStddev) {
|
||||
super(conditions);
|
||||
this.countStddev = countStddev;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<ItemStack> doApply(List<ItemStack> generatedLoot, LootContext context) {
|
||||
var rand = context.getRandom();
|
||||
|
||||
var worldLookup = PatternRegistry.getPerWorldPatterns(context.getLevel());
|
||||
var allOpIds = worldLookup.keySet().stream().toList();
|
||||
// Don't generate more than one of the same pattern
|
||||
var seenPats = new HashSet<String>();
|
||||
var scrollAmt = rand.nextGaussian(0.0, this.countStddev);
|
||||
for (int i = 0; i < scrollAmt; i++) {
|
||||
if (seenPats.size() == allOpIds.size()) {
|
||||
break;
|
||||
}
|
||||
String pattern;
|
||||
do {
|
||||
pattern = allOpIds.get(rand.nextInt(allOpIds.size()));
|
||||
} while (seenPats.contains(pattern));
|
||||
|
||||
seenPats.add(pattern);
|
||||
|
||||
var entry = worldLookup.get(pattern);
|
||||
var opId = entry.component1();
|
||||
var startDir = entry.component2();
|
||||
var tag = new CompoundTag();
|
||||
tag.putString(ItemScroll.TAG_OP_ID, opId.toString());
|
||||
tag.put(ItemScroll.TAG_PATTERN,
|
||||
HexPattern.FromAnglesSig(pattern, startDir).serializeToNBT());
|
||||
|
||||
var stack = new ItemStack(HexItems.SCROLL);
|
||||
stack.setTag(tag);
|
||||
generatedLoot.add(stack);
|
||||
|
||||
seenPats.add(pattern);
|
||||
}
|
||||
|
||||
return generatedLoot;
|
||||
}
|
||||
|
||||
public static class Serializer extends GlobalLootModifierSerializer<PatternScrollModifier> {
|
||||
|
||||
@Override
|
||||
public PatternScrollModifier read(ResourceLocation location, JsonObject json,
|
||||
LootItemCondition[] conditions) {
|
||||
var stddev = GsonHelper.getAsFloat(json, "stddev");
|
||||
return new PatternScrollModifier(conditions, stddev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject write(PatternScrollModifier instance) {
|
||||
var obj = this.makeConditions(instance.conditions);
|
||||
obj.addProperty("stddev", instance.countStddev);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue