package net.fretux.ascend.event; import net.fretux.ascend.AscendMod; import net.fretux.ascend.config.AscendConfig; import net.fretux.ascend.player.PlayerStatsProvider; import net.fretux.ascend.player.StatEffects; import net.minecraft.core.BlockPos; import net.minecraft.world.effect.MobEffectCategory; 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; import net.minecraft.world.level.block.Block; import net.minecraft.world.entity.TamableAnimal; import net.minecraft.world.entity.animal.horse.AbstractHorse; import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.entity.living.LivingDeathEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.event.level.BlockEvent; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.animal.IronGolem; import net.minecraft.world.entity.animal.SnowGolem; import net.minecraftforge.event.entity.living.LivingEvent; import net.minecraft.world.phys.AABB; import java.util.UUID; @Mod.EventBusSubscriber(modid = AscendMod.MODID) public class ActivityEvents { @SubscribeEvent public static void onMobKilled(LivingDeathEvent event) { if (event.getSource().getEntity() instanceof Player player && !player.level().isClientSide) { player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { stats.addAscendXP((int) (AscendConfig.COMMON.xpPerMobKill.get() * AscendConfig.COMMON.xpMultiplier.get())); LivingEntity mob = event.getEntity(); if (mob.getMaxHealth() > 100f || mob.getType().toString().toLowerCase().contains("boss")) { stats.addKnowledgeScaled(2); } PlayerStatsProvider.sync(player); }); } } @SubscribeEvent public static void onBlockBreak(BlockEvent.BreakEvent event) { Player player = event.getPlayer(); if (player == null || player.level().isClientSide) return; Block block = event.getState().getBlock(); String name = block.getName().getString().toLowerCase(); player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { if (name.contains("log") || name.contains("ore") || name.contains("stone")) { stats.addAscendXP((int) (AscendConfig.COMMON.xpPerBlockBreak.get() * AscendConfig.COMMON.xpMultiplier.get())); PlayerStatsProvider.sync(player); } }); } @SubscribeEvent public static void onPlayerDamaged(LivingHurtEvent event) { if (event.getEntity() instanceof Player player && !player.level().isClientSide) { player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { int gain = Math.min((int) event.getAmount() / 2, 10); stats.addAscendXP(gain); PlayerStatsProvider.sync(player); }); } } @SubscribeEvent public static void onPlayerTickSurvivalXP(TickEvent.PlayerTickEvent event) { Player player = event.player; if (player.level().isClientSide || event.phase != TickEvent.Phase.END) return; if (player.tickCount % 100 != 0) return; player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { boolean hasNegativeEffect = player.getActiveEffects().stream() .anyMatch(e -> e.getEffect().getCategory() == MobEffectCategory.HARMFUL); if (player.getFoodData().getFoodLevel() <= 6 || hasNegativeEffect) { stats.addAscendXP((int) (AscendConfig.COMMON.xpPerDamageTaken.get() * AscendConfig.COMMON.xpMultiplier.get())); PlayerStatsProvider.sync(player); } }); } @SubscribeEvent public static void onPlayerTickAgility(TickEvent.PlayerTickEvent event) { Player player = event.player; if (player.level().isClientSide || event.phase != TickEvent.Phase.END) return; if (player.tickCount % 40 != 0) return; player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { boolean didAgileThing = player.isSprinting() || player.isCrouching() || Math.abs(player.getDeltaMovement().y) > 0.25 || player.onClimbable(); if (didAgileThing) { stats.addAscendXP((int) (AscendConfig.COMMON.xpPerMovement.get() * AscendConfig.COMMON.xpMultiplier.get())); PlayerStatsProvider.sync(player); } }); } @SubscribeEvent public static void onItemCrafted(PlayerEvent.ItemCraftedEvent event) { Player player = event.getEntity(); if (player.level().isClientSide) return; player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { stats.addAscendXP((int) (AscendConfig.COMMON.xpPerCraft.get() * AscendConfig.COMMON.xpMultiplier.get())); PlayerStatsProvider.sync(player); }); } @SubscribeEvent public static void onItemSmelted(PlayerEvent.ItemSmeltedEvent event) { Player player = event.getEntity(); if (player.level().isClientSide) return; player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { stats.addAscendXP((int) (AscendConfig.COMMON.xpPerSmelt.get() * AscendConfig.COMMON.xpMultiplier.get())); PlayerStatsProvider.sync(player); }); } @SubscribeEvent public static void onPlayerTickWillpower(TickEvent.PlayerTickEvent event) { Player player = event.player; if (player.level().isClientSide || event.phase != TickEvent.Phase.END) return; player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { if (player.tickCount % 200 != 0) return; boolean hasNegativeEffect = player.getActiveEffects().stream() .anyMatch(e -> e.getEffect().getCategory() == MobEffectCategory.HARMFUL); boolean lowHealth = player.getHealth() <= player.getMaxHealth() * 0.25f; BlockPos pos = player.blockPosition(); int blockLight = player.level().getBrightness(LightLayer.BLOCK, pos); int skyLight = player.level().getBrightness(LightLayer.SKY, pos); int light = Math.max(blockLight, skyLight); boolean inDarkness = light <= 3; if (lowHealth || (hasNegativeEffect && inDarkness)) { stats.addAscendXP(1); PlayerStatsProvider.sync(player); } }); } @SubscribeEvent public static void onPlayerTickCharisma(TickEvent.PlayerTickEvent event) { Player player = event.player; if (player.level().isClientSide || event.phase != TickEvent.Phase.END) return; if (player.tickCount % 40 != 0) return; player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { int charisma = stats.getAttributeLevel("charisma"); if (charisma <= 0) return; double radius = 16.0d; AABB range = player.getBoundingBox().inflate(radius); for (LivingEntity entity : player.level().getEntitiesOfClass(LivingEntity.class, range, candidate -> isCharismaAlly(player, candidate))) { StatEffects.applyCharismaAllyBuff(entity, charisma); } }); } @SubscribeEvent public static void onCharismaAllyTick(LivingEvent.LivingTickEvent event) { LivingEntity entity = event.getEntity(); if (entity.level().isClientSide) return; if (!isCharismaAllyCandidate(entity)) return; if (entity.tickCount % 40 != 0) return; double radius = 16.0d; if (hasNearbyCharismaSource(entity, radius)) return; StatEffects.clearCharismaAllyBuff(entity); } @SubscribeEvent public static void onVillagerTrade(PlayerInteractEvent.EntityInteract event) { if (!(event.getTarget() instanceof Villager)) return; Player player = event.getEntity(); if (player.level().isClientSide) return; player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { int charisma = stats.getAttributeLevel("charisma"); if (charisma > 0) { int reputationBonus = StatEffects.getCharismaVillagerReputationBonus(charisma); if (reputationBonus > 0 && event.getTarget() instanceof Villager villager) { villager.getGossips().add(player.getUUID(), GossipType.MINOR_POSITIVE, reputationBonus); } } stats.addAscendXP((int) (AscendConfig.COMMON.xpPerTrade.get() * AscendConfig.COMMON.xpMultiplier.get())); PlayerStatsProvider.sync(player); }); } @SubscribeEvent public static void onWeaponUsed(LivingHurtEvent event) { if (!(event.getSource().getEntity() instanceof Player player)) return; if (player.level().isClientSide) return; if (event.getEntity() == player) return; player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { var heldItem = player.getMainHandItem(); if (heldItem.isEmpty()) return; stats.addAscendXP(3); PlayerStatsProvider.sync(player); }); } @SubscribeEvent public static void onPotionUse(PlayerInteractEvent.RightClickItem event) { Player player = event.getEntity(); if (player.level().isClientSide) return; if (event.getItemStack().getItem().getDescriptionId().contains("potion")) { player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { stats.addAscendXP((int) (AscendConfig.COMMON.xpPerPotion.get() * AscendConfig.COMMON.xpMultiplier.get())); PlayerStatsProvider.sync(player); }); } } @SubscribeEvent public static void onGainPotionEffect(net.minecraftforge.event.entity.living.MobEffectEvent.Added event) { if (!(event.getEntity() instanceof Player player)) return; if (player.level().isClientSide) return; if (event.getEffectInstance().getEffect().getCategory() == net.minecraft.world.effect.MobEffectCategory.BENEFICIAL) { player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { stats.addAscendXP(2); PlayerStatsProvider.sync(player); }); } } @SubscribeEvent public static void onItemSmeltedForMagic(PlayerEvent.ItemSmeltedEvent event) { Player player = event.getEntity(); if (player.level().isClientSide) return; String itemName = event.getSmelting().getDisplayName().getString().toLowerCase(); if (itemName.contains("potion") || itemName.contains("elixir")) { player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { stats.addAscendXP(3); PlayerStatsProvider.sync(player); }); } } private static boolean isCharismaAlly(Player player, LivingEntity entity) { if (entity instanceof TamableAnimal tame) { return tame.isTame() && tame.isOwnedBy(player); } if (entity instanceof AbstractHorse horse) { return horse.isTamed() && player.getUUID().equals(horse.getOwnerUUID()); } if (entity instanceof IronGolem) { return true; } if (entity instanceof SnowGolem) { return true; } return false; } private static boolean isCharismaAllyCandidate(LivingEntity entity) { if (entity instanceof TamableAnimal tame) { return tame.isTame(); } if (entity instanceof AbstractHorse horse) { return horse.isTamed(); } if (entity instanceof IronGolem) { return true; } if (entity instanceof SnowGolem) { return true; } return false; } private static boolean hasNearbyCharismaSource(LivingEntity entity, double radius) { if (entity instanceof TamableAnimal tame) { Player owner = tame.getOwner() instanceof Player player ? player : null; return owner != null && owner.distanceToSqr(entity) <= radius * radius && hasCharisma(owner); } if (entity instanceof AbstractHorse horse) { UUID ownerId = horse.getOwnerUUID(); if (ownerId == null) return false; Player owner = entity.level().getPlayerByUUID(ownerId); return owner != null && owner.distanceToSqr(entity) <= radius * radius && hasCharisma(owner); } if (entity instanceof IronGolem || entity instanceof SnowGolem) { AABB range = entity.getBoundingBox().inflate(radius); for (Player player : entity.level().getEntitiesOfClass(Player.class, range)) { if (hasCharisma(player)) { return true; } } } return false; } private static boolean hasCharisma(Player player) { return player.getCapability(PlayerStatsProvider.PLAYER_STATS) .map(stats -> stats.getAttributeLevel("charisma") > 0) .orElse(false); } }