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.sounds.SoundEvents;
|
||||||
import net.minecraft.world.effect.MobEffectCategory;
|
import net.minecraft.world.effect.MobEffectCategory;
|
||||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
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.npc.Villager;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.level.LightLayer;
|
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.LivingEntity;
|
||||||
import net.minecraft.world.entity.animal.IronGolem;
|
import net.minecraft.world.entity.animal.IronGolem;
|
||||||
import net.minecraft.world.entity.animal.SnowGolem;
|
import net.minecraft.world.entity.animal.SnowGolem;
|
||||||
import net.minecraft.world.entity.npc.GossipType;
|
|
||||||
import net.minecraftforge.event.entity.living.LivingEvent;
|
import net.minecraftforge.event.entity.living.LivingEvent;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
|
|
||||||
|
|||||||
@@ -3,16 +3,19 @@ package net.fretux.ascend.event;
|
|||||||
import net.fretux.ascend.AscendMod;
|
import net.fretux.ascend.AscendMod;
|
||||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||||
import net.fretux.ascend.player.StatEffects;
|
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.entity.player.Player;
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
import net.minecraft.world.inventory.MerchantMenu;
|
import net.minecraft.world.inventory.MerchantMenu;
|
||||||
|
import net.minecraft.world.item.trading.Merchant;
|
||||||
import net.minecraft.world.item.trading.MerchantOffer;
|
import net.minecraft.world.item.trading.MerchantOffer;
|
||||||
import net.minecraft.world.entity.npc.Villager;
|
import net.minecraft.world.entity.npc.Villager;
|
||||||
import net.minecraft.world.entity.npc.GossipType;
|
|
||||||
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
|
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
@Mod.EventBusSubscriber(modid = AscendMod.MODID)
|
@Mod.EventBusSubscriber(modid = AscendMod.MODID)
|
||||||
public class CharismaTradeEvents {
|
public class CharismaTradeEvents {
|
||||||
|
|
||||||
@@ -20,45 +23,29 @@ public class CharismaTradeEvents {
|
|||||||
public static void onOpenMerchant(PlayerContainerEvent.Open event) {
|
public static void onOpenMerchant(PlayerContainerEvent.Open event) {
|
||||||
Player player = event.getEntity();
|
Player player = event.getEntity();
|
||||||
if (player.level().isClientSide) return;
|
if (player.level().isClientSide) return;
|
||||||
|
|
||||||
AbstractContainerMenu menu = event.getContainer();
|
AbstractContainerMenu menu = event.getContainer();
|
||||||
if (!(menu instanceof MerchantMenu merchantMenu)) return;
|
if (!(menu instanceof MerchantMenu merchantMenu)) return;
|
||||||
|
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
int cha = stats.getAttributeLevel("charisma");
|
int cha = stats.getAttributeLevel("charisma");
|
||||||
if (cha <= 0) return;
|
if (cha <= 0) return;
|
||||||
|
Merchant merchant = resolveMerchant(merchantMenu);
|
||||||
if (merchantMenu.getTrader() instanceof Villager villager) {
|
if (merchant instanceof Villager villager) {
|
||||||
int reputationBonus = StatEffects.getCharismaVillagerReputationBonus(cha);
|
int reputationBonus = StatEffects.getCharismaVillagerReputationBonus(cha);
|
||||||
if (reputationBonus > 0) {
|
if (reputationBonus > 0) {
|
||||||
villager.getGossips().add(player.getUUID(), GossipType.MINOR_POSITIVE, reputationBonus);
|
villager.getGossips().add(player.getUUID(), GossipType.MINOR_POSITIVE, reputationBonus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double discountFraction = StatEffects.getCharismaTradeDiscount(cha);
|
double discountFraction = StatEffects.getCharismaTradeDiscount(cha);
|
||||||
if (discountFraction <= 0.0d) return;
|
if (discountFraction <= 0.0d) return;
|
||||||
|
|
||||||
var offers = merchantMenu.getOffers();
|
var offers = merchantMenu.getOffers();
|
||||||
if (offers == null) return;
|
if (offers == null) return;
|
||||||
|
|
||||||
for (MerchantOffer offer : offers) {
|
for (MerchantOffer offer : offers) {
|
||||||
if (offer == null) continue;
|
if (offer == null) continue;
|
||||||
|
|
||||||
// Base cost of first input (emeralds, etc.)
|
|
||||||
int base = offer.getBaseCostA().getCount();
|
int base = offer.getBaseCostA().getCount();
|
||||||
if (base <= 0) continue;
|
if (base <= 0) continue;
|
||||||
|
|
||||||
// Desired discounted cost
|
|
||||||
int target = (int) Math.max(1, Math.floor(base * (1.0d - discountFraction)));
|
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();
|
int currentSpecial = offer.getSpecialPriceDiff();
|
||||||
|
|
||||||
// We want: base + newSpecial = target
|
|
||||||
int newSpecial = target - base;
|
int newSpecial = target - base;
|
||||||
|
|
||||||
// Adjust relative to current to avoid stacking each open.
|
|
||||||
int delta = newSpecial - currentSpecial;
|
int delta = newSpecial - currentSpecial;
|
||||||
if (delta != 0) {
|
if (delta != 0) {
|
||||||
offer.addToSpecialPriceDiff(delta);
|
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