package me.km.events; import java.util.HashMap; import java.util.LinkedList; import me.hammerle.snuviscript.code.Script; import me.km.DamageUtils; import me.km.playerbank.PlayerManager; import me.km.scheduler.SnuviScheduler; import me.km.utils.ReflectionUtils; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.server.MinecraftServer; import net.minecraft.util.CombatRules; import net.minecraft.util.DamageSource; import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; public class CustomEventCaller { private final HashMap moveData = new HashMap<>(); private final LinkedList removeQueue = new LinkedList<>(); private final LinkedList addQueue = new LinkedList<>(); private final PlayerManager pManager; private final MinecraftServer server; private final SnuviScheduler scheduler; public CustomEventCaller(PlayerManager pManager, MinecraftServer server, SnuviScheduler scheduler) { this.pManager = pManager; this.server = server; this.scheduler = scheduler; } public int registerMoveData(PlayerMoveData data) { addQueue.add(data); return data.getId(); } public void removeScriptData(Script sc) { moveData.entrySet().forEach(e -> { if(e.getValue().isSameScript(sc)) { removeQueue.add(e.getValue().getId()); } }); } public void removeMoveData(int id) { removeQueue.add(id); } @SubscribeEvent public void onServerTick(TickEvent.ServerTickEvent e) { if(e.phase == TickEvent.Phase.END) { scheduler.tick(); if(!addQueue.isEmpty()) { addQueue.forEach(data -> moveData.put(data.getId(), data)); addQueue.clear(); } moveData.values().removeIf(data -> { if(data.tickLiving()) { return true; } if(data.tick()) { return false; } return server.getPlayerList().getPlayers().stream().anyMatch(p -> data.check(p)); }); if(!removeQueue.isEmpty()) { removeQueue.forEach(i -> moveData.remove(i)); removeQueue.clear(); } } } private float getRealDamage(float damageAmount, DamageSource ds, LivingEntity liv) { if(ds != DamageSource.LAVA && ds != DamageSource.IN_WALL && ds != DamageSource.CRAMMING && ds != DamageSource.DROWN) { if(ds.isMagicDamage() && !ds.isDamageAbsolute()) // Magic Damage { ReflectionUtils.damageArmor(liv, damageAmount); int armor = DamageUtils.getMagicDefense(liv); damageAmount = CombatRules.getDamageAfterAbsorb(damageAmount, armor, 0); } else if(!ds.isUnblockable()) { ReflectionUtils.damageArmor(liv, damageAmount); int armor = liv.getTotalArmorValue(); damageAmount = CombatRules.getDamageAfterAbsorb(damageAmount, armor, (float) liv.getAttribute(SharedMonsterAttributes.ARMOR_TOUGHNESS).getValue()); } damageAmount = ReflectionUtils.applyPotionDamageCalculations(liv, ds, damageAmount); } else { damageAmount = liv.getMaxHealth() / 10; } return damageAmount; } @SubscribeEvent(priority = EventPriority.LOWEST) public void newDamageSystem(LivingHurtEvent e) { // --------------------------------------------------------------------- // injection of new damage system // --------------------------------------------------------------------- if(!e.isCanceled()) { e.setCanceled(true); DamageSource ds = e.getSource(); LivingEntity liv = e.getEntityLiving(); float damageAmount = getRealDamage(e.getAmount(), ds, liv); float f = damageAmount; damageAmount = Math.max(damageAmount - liv.getAbsorptionAmount(), 0.0f); liv.setAbsorptionAmount(liv.getAbsorptionAmount() - (f - damageAmount)); if(damageAmount != 0.0f) { float f1 = liv.getHealth(); liv.setHealth(f1 - damageAmount); liv.getCombatTracker().trackDamage(ds, f1, damageAmount); liv.setAbsorptionAmount(liv.getAbsorptionAmount() - damageAmount); } } } }