Skip to content

Commit

Permalink
feat(adv): loot_enchantment_applied trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
WakelessSloth56 committed Feb 23, 2024
1 parent 193fae2 commit c7aeb74
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import net.neoforged.neoforge.registries.DeferredRegister;
import org.auioc.mcmod.harmoniclib.HarmonicLib;
import org.auioc.mcmod.harmoniclib.advancement.criterion.EnchantmentPerformedTrigger;
import org.auioc.mcmod.harmoniclib.advancement.criterion.LootEnchantmentAppliedTrigger;

import java.util.function.Supplier;

Expand All @@ -39,5 +40,6 @@ private static <T extends CriterionTrigger<?>> DeferredHolder<CriterionTrigger<?
// ============================================================================================================== //

public static final DeferredHolder<CriterionTrigger<?>, EnchantmentPerformedTrigger> ENCHANTMENT_PERFORMED = register("enchantment_performed", EnchantmentPerformedTrigger::new);
public static final DeferredHolder<CriterionTrigger<?>, LootEnchantmentAppliedTrigger> LOOT_ENCHANTMENT_APPLIED = register("loot_enchantment_applied", LootEnchantmentAppliedTrigger::new);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* Copyright (C) 2024 AUIOC.ORG
*
* This file is part of HarmonicEnchantments, a mod made for Minecraft.
*
* ArnicaLib is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/

package org.auioc.mcmod.harmoniclib.advancement.criterion;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.advancements.Criterion;
import net.minecraft.advancements.critereon.ContextAwarePredicate;
import net.minecraft.advancements.critereon.EntityPredicate;
import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.advancements.critereon.MinMaxBounds;
import net.minecraft.advancements.critereon.SimpleCriterionTrigger;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import org.auioc.mcmod.arnicalib.game.codec.EnumCodec;
import org.auioc.mcmod.arnicalib.game.enchantment.HEnchantmentPredicate;
import org.auioc.mcmod.harmoniclib.advancement.HLCriteriaTriggers;
import org.auioc.mcmod.harmoniclib.enchantment.EnchantmentHelper;

import java.util.Optional;

public class LootEnchantmentAppliedTrigger extends SimpleCriterionTrigger<LootEnchantmentAppliedTrigger.TriggerInstance> {

@Override
public Codec<TriggerInstance> codec() {
return TriggerInstance.CODEC;
}

public void trigger(ServerPlayer player, ItemStack itemStack) {
this.trigger(player, (instance) -> instance.matches(itemStack));
}

public void triggerLootContext(ItemStack itemStack, LootContext lootCtx) {
var entity = lootCtx.getParamOrNull(LootContextParams.KILLER_ENTITY);
if (entity instanceof ServerPlayer player) {
trigger(player, itemStack);
}
}

public static Criterion<LootEnchantmentAppliedTrigger.TriggerInstance> createCriterion(
Optional<ContextAwarePredicate> player, Optional<ItemPredicate> item, MinMaxBounds.Ints count, Optional<HEnchantmentPredicate> enchantment, Optional<Requirement> requirement
) {
return HLCriteriaTriggers.LOOT_ENCHANTMENT_APPLIED.get().createCriterion(
new TriggerInstance(player, item, count, enchantment, requirement)
);
}

// ============================================================================================================== //

public record TriggerInstance(
Optional<ContextAwarePredicate> player,
Optional<ItemPredicate> item,
MinMaxBounds.Ints count,
Optional<HEnchantmentPredicate> enchantment,
Optional<Requirement> requirement

) implements SimpleCriterionTrigger.SimpleInstance {

public boolean matches(ItemStack itemStack) {
if (item.isPresent() && !item.get().matches(itemStack)) {
return false;
}

var enchMap = EnchantmentHelper.getEnchantments(itemStack);

if (count != MinMaxBounds.Ints.ANY && (enchMap.isEmpty() || !count.matches(enchMap.size()))) {
return false;
}

if (enchantment.isPresent()) {
if (enchMap.isEmpty()) {
return false;
}

var enchP = enchantment.get();
int i = (int) enchMap.entrySet().stream().filter(enchP::test).count();

var req = requirement.orElse(Requirement.ANY);
if (!req.matches(enchMap.size(), i)) {
return false;
}
}

return true;
}

// ========================================================================================================== //

public static final Codec<LootEnchantmentAppliedTrigger.TriggerInstance> CODEC = RecordCodecBuilder.create(instance -> instance.group(
ExtraCodecs.strictOptionalField(EntityPredicate.ADVANCEMENT_CODEC, "player").forGetter(TriggerInstance::player),
ExtraCodecs.strictOptionalField(ItemPredicate.CODEC, "item").forGetter(TriggerInstance::item),
ExtraCodecs.strictOptionalField(MinMaxBounds.Ints.CODEC, "count", MinMaxBounds.Ints.ANY).forGetter(TriggerInstance::count),
ExtraCodecs.strictOptionalField(HEnchantmentPredicate.CODEC, "enchantment").forGetter(TriggerInstance::enchantment),
ExtraCodecs.strictOptionalField(EnumCodec.byNameLowerCase(Requirement.class), "enchantment_requirement").forGetter(TriggerInstance::requirement)
).apply(instance, LootEnchantmentAppliedTrigger.TriggerInstance::new));

}

// ============================================================================================================== //

public enum Requirement {
ANY {
@Override
public boolean matches(int size, int i) {
return i > 0;
}
},
ALL {
@Override
public boolean matches(int size, int i) {
return size == i;
}
},
NONE {
@Override
public boolean matches(int size, int i) {
return i == 0;
}
};

public boolean matches(int size, int i) { return false; }
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2024 AUIOC.ORG
*
* This file is part of HarmonicEnchantments, a mod made for Minecraft.
*
* ArnicaLib is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/

package org.auioc.mcmod.harmoniclib.mixin.server;

import net.minecraft.util.RandomSource;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.functions.EnchantWithLevelsFunction;
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
import org.auioc.mcmod.harmoniclib.advancement.HLCriteriaTriggers;
import org.auioc.mcmod.harmoniclib.advancement.criterion.LootEnchantmentAppliedTrigger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;

@Mixin(value = EnchantWithLevelsFunction.class)
public class MixinEnchantWithLevelsFunction {

@Final
@Shadow
private NumberProvider levels;

@Final
@Shadow
private boolean treasure;

/**
* @author WakelessSloth56
* @reason LootEnchantmentAppliedTrigger {@link LootEnchantmentAppliedTrigger#triggerLootContext}
*/
@Overwrite
public ItemStack run(ItemStack pStack, LootContext pContext) {
RandomSource randomsource = pContext.getRandom();
var newItemStack = EnchantmentHelper.enchantItem(randomsource, pStack, this.levels.getInt(pContext), this.treasure);
HLCriteriaTriggers.LOOT_ENCHANTMENT_APPLIED.get().triggerLootContext(newItemStack, pContext);
return newItemStack;
}


}
1 change: 1 addition & 0 deletions src/main/resources/harmoniclib.mixin.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"common.MixinProjectile",
"common.MixinSpectralArrow",
"server.MixinCatRelaxOnOwnerGoal",
"server.MixinEnchantWithLevelsFunction",
"server.MixinPiglinAi"
],
"client": [],
Expand Down

0 comments on commit c7aeb74

Please sign in to comment.