Refactor CharismaTradeEvents: Add GossipType import and resolve merchant using reflection
This commit is contained in:
@@ -10,6 +10,7 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.effect.MobEffectCategory;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.entity.ai.gossip.GossipType;
|
||||
import net.minecraft.world.entity.npc.Villager;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
@@ -28,7 +29,6 @@ import net.minecraftforge.event.entity.living.LivingDamageEvent;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.animal.IronGolem;
|
||||
import net.minecraft.world.entity.animal.SnowGolem;
|
||||
import net.minecraft.world.entity.npc.GossipType;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
|
||||
@@ -3,16 +3,19 @@ package net.fretux.ascend.event;
|
||||
import net.fretux.ascend.AscendMod;
|
||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||
import net.fretux.ascend.player.StatEffects;
|
||||
import net.minecraft.world.entity.ai.gossip.GossipType;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.MerchantMenu;
|
||||
import net.minecraft.world.item.trading.Merchant;
|
||||
import net.minecraft.world.item.trading.MerchantOffer;
|
||||
import net.minecraft.world.entity.npc.Villager;
|
||||
import net.minecraft.world.entity.npc.GossipType;
|
||||
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = AscendMod.MODID)
|
||||
public class CharismaTradeEvents {
|
||||
|
||||
@@ -20,45 +23,29 @@ public class CharismaTradeEvents {
|
||||
public static void onOpenMerchant(PlayerContainerEvent.Open event) {
|
||||
Player player = event.getEntity();
|
||||
if (player.level().isClientSide) return;
|
||||
|
||||
AbstractContainerMenu menu = event.getContainer();
|
||||
if (!(menu instanceof MerchantMenu merchantMenu)) return;
|
||||
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
int cha = stats.getAttributeLevel("charisma");
|
||||
if (cha <= 0) return;
|
||||
|
||||
if (merchantMenu.getTrader() instanceof Villager villager) {
|
||||
Merchant merchant = resolveMerchant(merchantMenu);
|
||||
if (merchant instanceof Villager villager) {
|
||||
int reputationBonus = StatEffects.getCharismaVillagerReputationBonus(cha);
|
||||
if (reputationBonus > 0) {
|
||||
villager.getGossips().add(player.getUUID(), GossipType.MINOR_POSITIVE, reputationBonus);
|
||||
}
|
||||
}
|
||||
|
||||
double discountFraction = StatEffects.getCharismaTradeDiscount(cha);
|
||||
if (discountFraction <= 0.0d) return;
|
||||
|
||||
var offers = merchantMenu.getOffers();
|
||||
if (offers == null) return;
|
||||
|
||||
for (MerchantOffer offer : offers) {
|
||||
if (offer == null) continue;
|
||||
|
||||
// Base cost of first input (emeralds, etc.)
|
||||
int base = offer.getBaseCostA().getCount();
|
||||
if (base <= 0) continue;
|
||||
|
||||
// Desired discounted cost
|
||||
int target = (int) Math.max(1, Math.floor(base * (1.0d - discountFraction)));
|
||||
|
||||
// Current special price diff already includes:
|
||||
// popularity, hero-of-village, etc.
|
||||
int currentSpecial = offer.getSpecialPriceDiff();
|
||||
|
||||
// We want: base + newSpecial = target
|
||||
int newSpecial = target - base;
|
||||
|
||||
// Adjust relative to current to avoid stacking each open.
|
||||
int delta = newSpecial - currentSpecial;
|
||||
if (delta != 0) {
|
||||
offer.addToSpecialPriceDiff(delta);
|
||||
@@ -66,4 +53,19 @@ public class CharismaTradeEvents {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Merchant resolveMerchant(MerchantMenu merchantMenu) {
|
||||
for (Field field : MerchantMenu.class.getDeclaredFields()) {
|
||||
if (!Merchant.class.isAssignableFrom(field.getType())) {
|
||||
continue;
|
||||
}
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
return (Merchant) field.get(merchantMenu);
|
||||
} catch (IllegalAccessException ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user