diff --git a/TwosideKeeper.jar b/TwosideKeeper.jar index 829e1b5..66e95d7 100644 Binary files a/TwosideKeeper.jar and b/TwosideKeeper.jar differ diff --git a/src/sig/plugin/TwosideKeeper/CustomDamage.java b/src/sig/plugin/TwosideKeeper/CustomDamage.java index c955455..1c0f4a5 100644 --- a/src/sig/plugin/TwosideKeeper/CustomDamage.java +++ b/src/sig/plugin/TwosideKeeper/CustomDamage.java @@ -104,7 +104,7 @@ public class CustomDamage { public static final int IS_THORNS = 8; //System Flag. Used for telling a player structure their last hit was with thorns. static public boolean ApplyDamage(double damage, Entity damager, LivingEntity target, ItemStack weapon, String reason) { - TwosideKeeper.log("Weapon: "+weapon, 0); + //TwosideKeeper.log("Weapon: "+weapon, 0); return ApplyDamage(damage,damager,target,weapon,reason,NONE); } @@ -232,17 +232,17 @@ public class CustomDamage { if (shooter!=null && (shooter instanceof Player)) { if (weapon!=null) { dmg+=getBaseWeaponDamage(damage, weapon, damager, target, reason); - TwosideKeeper.log("Weapon: "+weapon, 0); - DebugUtils.showStackTrace(); + //TwosideKeeper.log("Weapon: "+weapon, 0); + //DebugUtils.showStackTrace(); if (weapon.getType()==Material.BOW) { if ((damager instanceof Projectile)) { - TwosideKeeper.log("This is a projectile! Reason: "+reason+", Damager: "+damager.toString(), 0); + //TwosideKeeper.log("This is a projectile! Reason: "+reason+", Damager: "+damager.toString(), 0); dmg += addToPlayerLogger(damager,target,"Custom Arrow",calculateCustomArrowDamageIncrease(weapon,damager,target)); dmg += addMultiplierToPlayerLogger(damager,target,"Ranger Mult",dmg * calculateRangerMultiplier(weapon,damager)); double headshotdmg = addMultiplierToPlayerLogger(damager,target,"Headshot Mult",dmg * calculateHeadshotMultiplier(weapon,damager,target)); if (headshotdmg!=0.0) {headshot=true;} dmg += headshotdmg; - TwosideKeeper.log("Damage currently is: "+dmg, 0); + //TwosideKeeper.log("Damage currently is: "+dmg, 0); dmg += addMultiplierToPlayerLogger(damager,target,"Bow Drawback Mult",dmg * calculateBowDrawbackMultiplier(weapon,damager,target)); } } @@ -304,6 +304,7 @@ public class CustomDamage { dmg += addMultiplierToPlayerLogger(damager,target,"Weapon Charge Bonus Mult",dmg * calculateWeaponChargeBonusMultiplier(shooter)); dmg += addMultiplierToPlayerLogger(damager,target,"Damage Pool Bonus Mult",dmg * calculateDamagePoolBonusMultiplier(shooter)); dmg += addMultiplierToPlayerLogger(damager,target,"Stealth Mult",dmg * calculateStealthMultiplier(shooter)); + dmg += addMultiplierToPlayerLogger(damager,target,"Dark Reverie Mult",dmg * calculateDarkReverieMultiplier(shooter)); if (reason==null || !reason.equalsIgnoreCase("Test Damage")) { double critdmg = addMultiplierToPlayerLogger(damager,target,"Critical Strike Mult",dmg * calculateCriticalStrikeMultiplier(weapon,shooter,target,reason,flags)); if (critdmg!=0.0) {crit=true; @@ -339,6 +340,19 @@ public class CustomDamage { return dmg; } + private static double calculateDarkReverieMultiplier(LivingEntity shooter) { + double mult = 0.0; + if (shooter!=null) { + if (Buff.hasBuff(shooter, "DARKSUBMISSION")) { + Buff b = Buff.getBuff(shooter, "DARKSUBMISSION"); + if (b.getAmplifier()>=10) { + mult -= 0.2; + } + } + } + return mult; + } + private static double calculateStealthMultiplier(LivingEntity shooter) { double mult = 0.0; if (shooter instanceof Player) { @@ -894,13 +908,13 @@ public class CustomDamage { double bonusdmg = 0; if (shooter!=null && TwosideKeeper.custommonsters.containsKey(shooter.getUniqueId())) { CustomMonster cm = TwosideKeeper.custommonsters.get(shooter.getUniqueId()); - TwosideKeeper.log("Custom Monster here. Damage: "+damage, 0); + //TwosideKeeper.log("Custom Monster here. Damage: "+damage, 0); if (cm instanceof Knight) { - TwosideKeeper.log("In here.", 0); + //TwosideKeeper.log("In here.", 0); Knight k = (Knight)cm; if (k.getParticipants().contains(p)) { bonusdmg += damage*k.getDarkSubmissionMultiplier(p); - TwosideKeeper.log(">Bonus True Damage set to "+bonusdmg, 0); + //TwosideKeeper.log(">Bonus True Damage set to "+bonusdmg, 0); } } } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/HighlightCircle.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/HighlightCircle.java new file mode 100644 index 0000000..91b3b79 --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/HighlightCircle.java @@ -0,0 +1,67 @@ +package sig.plugin.TwosideKeeper.HelperStructures.Effects; + +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.util.Vector; + +import sig.plugin.TwosideKeeper.TwosideKeeper; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.ParticleEffect; + +public class HighlightCircle { + final Particle PARTICLE = Particle.BLOCK_DUST; + final int PARTICLE_DENSITY = 16; + final int ANGLE_OFFSET = 10; + Location center = null; + double r = 0; + double h = 0; + long expireTime = 0; + + /** + * Creates a cylinder zone that will be outline by particles. + * @param l The centered location of the zone. + * @param radius The radius of the zone. + * @param height The height of the zone. + * @param duration The amount of time in ticks the zone will exist. + */ + public HighlightCircle(Location l, double radius, double height, int duration) { + this.center=l.clone(); + this.r=radius; + this.h=height; + this.expireTime=TwosideKeeper.getServerTickTime()+duration; + TwosideKeeper.circles.add(this); + } + + public Location getCenter() { + return center; + } + + public double getRadius() { + return r; + } + + public double getHeight() { + return h; + } + + public boolean hasExpired() { + return expireTime beamlocs = new ArrayList(); final static int[] ASSASSINATE_COOLDOWN = new int[]{320,280,240}; long lastusedassassinate = TwosideKeeper.getServerTickTime(); @@ -79,8 +92,18 @@ public class Knight extends CustomMonster{ long lastusedgrandslam = TwosideKeeper.getServerTickTime(); final static int[] GRANDSLAM_COOLDOWN = new int[]{900,700,600}; MixedDamage[] GRANDSLAM_DAMAGE = new MixedDamage[]{MixedDamage.v(450),MixedDamage.v(700),MixedDamage.v(700, 0.55)}; + final Spell DARKREVERIE = new Spell("Dark Reverie",new int[]{60,40,40},new int[]{600,600,600}); + final Spell PHASEII = new Spell("Phase II",new int[]{200,200,200},new int[]{0,0,0}); + final Spell LIGHTNINGBOLT = new Spell("Lightning Bolt",new int[]{80,60,40},new int[]{400,300,200},new MixedDamage[]{MixedDamage.v(100,0.02),MixedDamage.v(250,0.05),MixedDamage.v(400, 0.1)}); + final Spell DARKLIGHT = new Spell("The Dark Light",new int[]{60,60,60},new int[]{500,500,500},new MixedDamage[]{MixedDamage.v(200,0.05),MixedDamage.v(300,0.10),MixedDamage.v(400, 0.15)}); + final Spell MINDFIELD = new Spell("Mind Field",new int[]{120,80,80},new int[]{1200,1000,800},new MixedDamage[]{MixedDamage.v(0,0.04),MixedDamage.v(0,0.07),MixedDamage.v(0, 0.15)}); int randomness = 20; + boolean phaseii = false; + long silverfishtimer = 0; + + List endermites = new ArrayList(); + LivingEntity silverfish = null; public Knight(LivingEntity m) { @@ -121,8 +144,29 @@ public class Knight extends CustomMonster{ preventTargetFromBeingTheSameAsSpider(); increaseBarTextScroll(); performSpells(); + performSilverfishNotification(); } + private void performSilverfishNotification() { + if (silverfish!=null && + silverfishtimer+(MINDFIELD.getCooldowns()[getDifficultySlot()])<=TwosideKeeper.getServerTickTime()) { + SoundUtils.playLocalGlobalSound(Sound.BLOCK_REDSTONE_TORCH_BURNOUT, 1.0f, 1.2f); + for (Player p : participantlist) { + Buff.addBuff(m, "DARKSUBMISSION", new Buff("Dark Submission",20*20,50,org.bukkit.Color.BLACK,ChatColor.BLACK+""+ChatColor.MAGIC+"☁"+ChatColor.RESET,false), true); + TwosideKeeper.ApplyDarkSubmissionEffects(p, Math.min((Buff.getBuff(p, "DARKSUBMISSION").getAmplifier()/10)*10,50)); + } + silverfish.remove(); + for (LivingEntity ent : endermites) { + ent.remove(); + } + endermites.clear(); + silverfish=null; + } else + if (silverfish!=null && silverfishtimer+(MINDFIELD.getCooldowns()[getDifficultySlot()]/2)<=TwosideKeeper.getServerTickTime()) { + silverfish.setGlowing(true); + } + } + public void onPlayerSlayEvent(Player p, String reason) { if (reason.equalsIgnoreCase("Line Drive Knight")) { changeAggroToRandomNewTarget(); @@ -214,24 +258,141 @@ public class Knight extends CustomMonster{ //Failed to clear the shield. removeAllBuffsFromPlayers(); MixedDamage dmgvalues = DARKCLEANSE.getDamageValues()[getDifficultySlot()]; - GenericFunctions.DealDamageToNearbyPlayers(m.getLocation(), dmgvalues.getDmgComponent(), 50, false, false, 0, m, "Dark Cleanse Attack", false, false); + List players = GenericFunctions.DealDamageToNearbyPlayers(m.getLocation(), dmgvalues.getDmgComponent(), 50, false, false, 0, m, "Dark Cleanse Attack", false, false); if (dmgvalues.getTruePctDmgComponent()>0) {GenericFunctions.DealDamageToNearbyPlayers(m.getLocation(), dmgvalues.getTruePctDmgComponent(), 50, false, false, 0, m, "Dark Cleanse Attack", false, true);} if (dmgvalues.getTrueDmgComponent()>0) {GenericFunctions.DealDamageToNearbyPlayers(m.getLocation(), dmgvalues.getTrueDmgComponent(), 50, false, false, 0, m, "Dark Cleanse Attack", true, false);} - Buff.addBuff(m, "DARKSUBMISSION", new Buff("Dark Submission",20*20,10,org.bukkit.Color.BLACK,ChatColor.BLACK+""+ChatColor.MAGIC+"☁"+ChatColor.RESET,false), true); - announceMessageToParticipants(ChatColor.RED+"The "+GenericFunctions.getDisplayName(m)+ChatColor.RESET+""+ChatColor.RED+" screams "+ChatColor.BOLD+"\"SUBMIT TO DARKNESS\"!"); - for (Player p : participantlist) { - GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS, 20*3, 1, p, true); + for (Player p : players) { + Buff.addBuff(p, "DARKSUBMISSION", new Buff("Dark Submission",20*20,10,org.bukkit.Color.BLACK,ChatColor.BLACK+""+ChatColor.MAGIC+"☁"+ChatColor.RESET,false), true); + TwosideKeeper.ApplyDarkSubmissionEffects(p, Math.min((Buff.getBuff(p, "DARKSUBMISSION").getAmplifier()/10)*10,50)); } + announceMessageToParticipants(ChatColor.RED+"The "+GenericFunctions.getDisplayName(m)+ChatColor.RESET+""+ChatColor.RED+" screams "+ChatColor.BOLD+"\"SUBMIT TO DARKNESS\"!"); for (int i=0;i<3;i++) { Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_WITCH_AMBIENT, 1.0f, 0.6f); }, i*3); + for (Player p : participantlist) { + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS, 20*3, 1, p, true); + } } } CustomDamage.setAbsorptionHearts(m, 0); DARKCLEANSE.setLastCastedTime(TwosideKeeper.getServerTickTime()); }break; + case "Dark Reverie":{ + for (Player p : participantlist) { + CreateDarkReveriePool(p.getLocation(),getDifficultySlot()+1); + } + CreateDarkReveriePool(m.getLocation(),getDifficultySlot()+1); + DARKREVERIE.setLastCastedTime(TwosideKeeper.getServerTickTime()); + }break; + case "Lightning Bolt":{ + for (int i=0;i<4;i++) { + m.getWorld().strikeLightningEffect(targetloc); + } + MixedDamage dmg = LIGHTNINGBOLT.getDamageValues()[getDifficultySlot()]; + List players = GenericFunctions.DealDamageToNearbyPlayers(targetloc, dmg.getDmgComponent(), 2, false, true, 0, m, "Lightning Bolt", false, false); + if (dmg.getTruePctDmgComponent()>0) {GenericFunctions.DealDamageToNearbyPlayers(targetloc, dmg.getTruePctDmgComponent(), 2, false, true, 0, m, "Lightning Bolt", false, true);} + if (dmg.getTrueDmgComponent()>0) {GenericFunctions.DealDamageToNearbyPlayers(targetloc, dmg.getTrueDmgComponent(), 2, false, true, 0, m, "Lightning Bolt", true, false);} + for (Player p : players) { + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.SLOW, 20*30, 6, p, true); + } + LIGHTNINGBOLT.setLastCastedTime(TwosideKeeper.getServerTickTime()); + }break; + case "The Dark Light":{ + MixedDamage dmg = DARKLIGHT.getDamageValues()[getDifficultySlot()]; + for (int i=0;i<5;i++) { + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ + SoundUtils.playGlobalSound(m.getLocation(), Sound.BLOCK_REDSTONE_TORCH_BURNOUT, 1.0f, 1.2f); + }, i*3); + } + for (Location l : beamlocs) { + List players = GenericFunctions.DealDamageToNearbyPlayers(l, dmg.getDmgComponent(), 1, true, true, 1.5, m, "Dark Light", false, false); + if (dmg.getTruePctDmgComponent()>0) {GenericFunctions.DealDamageToNearbyPlayers(l, dmg.getTruePctDmgComponent(), 1, true, true, 1.5, m, "Dark Light", false, true);} + if (dmg.getTrueDmgComponent()>0) {GenericFunctions.DealDamageToNearbyPlayers(l, dmg.getTrueDmgComponent(), 1, true, true, 1.5, m, "Dark Light", true, false);} + for (Player p : players) { + Buff.addBuff(p, "CONFUSION", new Buff("Confusion",20*15,1,org.bukkit.Color.PURPLE,ChatColor.DARK_PURPLE+"๑"+ChatColor.RESET,false)); + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.WEAKNESS, 20*15, 2, p); + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS, 20*3, 2, p); + } + double yoffset=0; + for (int i=0;i<50;i++) { + ColoredParticle.RED_DUST.send(l.clone().add(0,yoffset,0), 50, 0, 0, 0); + yoffset+=0.2; + } + } + DARKLIGHT.setLastCastedTime(TwosideKeeper.getServerTickTime()); + }break; + case "Mind Field":{ + spawnEndermiteAndSilverfishNearby(); + }break; + } + } + + public void triggerEndermiteKill(LivingEntity endermite) { + List players = GenericFunctions.DealDamageToNearbyPlayers(m.getLocation(), MINDFIELD.getDamageValues()[getDifficultySlot()].getTruePctDmgComponent(), 50, false, false, 0, m, "Endermite Popped", false, true); + for (Player p : players) { + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS, 20*3, 0, p, true); + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.SLOW, 20*3, 0, p, true); + } + SoundUtils.playLocalGlobalSound(Sound.ENTITY_ZOMBIE_BREAK_DOOR_WOOD, 1.0f, 1.0f); + } + + public void triggerSilverfishKill(LivingEntity silverfish) { + silverfishtimer = 0; + for (LivingEntity ent : endermites) { + ent.remove(); } + endermites.clear(); + this.silverfish=null; + } + + private void spawnEndermiteAndSilverfishNearby() { + silverfish=null; + endermites.clear(); + silverfishtimer = TwosideKeeper.getServerTickTime(); + + final int[] ENDERMITE_COUNT = new int[]{20,40,50}; + for (int i=0;i{ + SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_WITCH_AMBIENT, 1.0f, 0.6f); + }, i*3); + }; + } + + private Location GetFreeRandomLocationAroundPoint(int range) { + int randomx = (int)(Math.random()*(range+1))-range; + int randomz = (int)(Math.random()*(range+1))-range; + Location spawnloc = m.getLocation().clone().add( + randomx, + determineValidYBlock(m.getLocation(),randomx,randomz), + randomz); + return spawnloc; + } + + private double determineValidYBlock(Location loc, int offsetx, int offsetz) { + boolean found=false; + Location currentloc = loc.clone(); + while (currentloc.getBlockY()<255) { + if (currentloc.getBlock().getType()!=Material.AIR && + currentloc.getBlock().getType()!=Material.STATIONARY_WATER && + currentloc.getBlock().getType()!=Material.WATER) { + currentloc.add(0,1,0); + } else { + break; + } + } + return currentloc.getBlockY(); } private void announceMessageToParticipants(String msg) { @@ -279,6 +440,18 @@ public class Knight extends CustomMonster{ m.teleport(loc); } } + private void CreateDarkReveriePool(Location l, int tier) { + AreaEffectCloud aec = (AreaEffectCloud)l.getWorld().spawnEntity(l, EntityType.AREA_EFFECT_CLOUD); + aec.setColor(org.bukkit.Color.BLACK); + aec.setRadius(5f); + aec.setBasePotionData(new PotionData(PotionType.INSTANT_DAMAGE)); + aec.setDuration(1200); + //aec.setReapplicationDelay(1); + aec.setCustomName("DARKSUBMISSION "+tier); + if (tier>=2) { + aec.setRadiusPerTick(0.0042f); + } + } private boolean cooldownIsAvailable(long spell_timer, Spell spell) { return spell_timer+spell.getCooldowns()[getDifficultySlot()]<=TwosideKeeper.getServerTickTime(); @@ -295,74 +468,132 @@ public class Knight extends CustomMonster{ if (attemptSpellCast(DARKCLEANSE)) { CustomDamage.setAbsorptionHearts(m, (float)SHIELD_AMT[getDifficultySlot()]);}}, ()->{ - performGrandSlam();} + performGrandSlam();}, + ()->{ + if (attemptSpellCast(DARKREVERIE)) {SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_CAT_HISS, 0.7f, 1.2f);}} + }; + final Runnable[] actions2 = new Runnable[]{ + ()->{if (attemptSpellCast(LIGHTNINGBOLT)) {Player p = changeAggroToRandomNewTarget(); + createLightningWarning(p);}}, + ()->{if (attemptSpellCast(DARKLIGHT)) { + spawnBeams(); + }}, + ()->{attemptSpellCast(MINDFIELD);}, + ()->{if (attemptSpellCast(DARKREVERIE)) {SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_CAT_HISS, 0.7f, 1.2f);}}, + ()->{performSpellFromFirstPhase(actions);}, }; if (canCastSpells()) { - for (Runnable r : actions) { - if (Math.random()<=1d/actions.length) { - Bukkit.getScheduler().runTask(TwosideKeeper.plugin, r); - break; + if (phaseii) { + for (Runnable r : actions2) { + if (Math.random()<=1d/actions2.length) { + Bukkit.getScheduler().runTask(TwosideKeeper.plugin, r); + break; + } } + } else { + performSpellFromFirstPhase(actions); + } + } + if (!phaseii && m.getHealth()<=m.getMaxHealth()/2 && startedfight) { + if (attemptSpellCast(PHASEII)) { + phaseii=true; } } } - private void performGrandSlam() { - isFlying=true; - lastlandedloc=m.getLocation().clone(); - Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() { - public void run() { - m.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION,Integer.MAX_VALUE,60)); - } - },8); - m.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION,Integer.MAX_VALUE,20)); - for (Player p : participantlist) { - PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); - pd.customtitle.modifyLargeCenterTitle(ChatColor.RED+"WARNING!", 20); + private void spawnBeams() { + final int[] beamcount = new int[]{25,40,50}; + beamlocs.clear(); + for (int i=0;i{ + Location beamloc = new Location(m.getWorld(), + randomx, + 0, + randomz); + Location finalbeamloc = m.getLocation().add(beamloc); + beamlocs.add(finalbeamloc); + new HighlightCircle(finalbeamloc, 1, 15, 60-beamDuration); + TemporaryBlock.createTemporaryBlockCircle(finalbeamloc, 1, Material.STAINED_CLAY, (byte)14, 60-beamDuration, "BEAM"); + }, beamDuration); } - Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin,()->{ - for (int i=0;i<3;i++) { - Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ - SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_WITCH_AMBIENT, 1.0f, 0.6f); - }, i*3); - } - announceMessageToParticipants(ChatColor.YELLOW+""+ChatColor.ITALIC+"\"Hehe, I'm going to "+ChatColor.RESET+""+ChatColor.DARK_RED+""+ChatColor.BOLD+"CRUSH YOU!"+ChatColor.RESET+""+ChatColor.YELLOW+""+ChatColor.ITALIC+"\""); - //SoundUtils.playGlobalSound(loc,Sound.BLOCK_PORTAL_TRIGGER, 0.2f, 2.0f); - SoundUtils.playLocalGlobalSound(Sound.BLOCK_PORTAL_TRIGGER, 0.2f, 2.0f); - },40); - Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin,()->{ - for (Player p : participantlist) { - GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS, 20, 0, p, true); + } + + private void createLightningWarning(Player p) { + TemporaryBlock.createTemporaryBlockCircle(p.getLocation(), 2, Material.STAINED_GLASS, (byte)8, LIGHTNINGBOLT.getCastTimes()[getDifficultySlot()], "LIGHTNINGBOLT"); + targetloc = p.getLocation().clone(); + new HighlightCircle(targetloc,2,30,LIGHTNINGBOLT.getCastTimes()[getDifficultySlot()]); + } + + private void performSpellFromFirstPhase(final Runnable[] actions) { + for (Runnable r : actions) { + if (Math.random()<=1d/actions.length) { + Bukkit.getScheduler().runTask(TwosideKeeper.plugin, r); + break; } - SoundUtils.playLocalGlobalSound(Sound.ENTITY_GENERIC_EXTINGUISH_FIRE, 1.0f, 0.5f); - },80); - Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin,()->{ + } + } + + private void performGrandSlam() { + if (lastusedgrandslam+GRANDSLAM_COOLDOWN[getDifficultySlot()]<=TwosideKeeper.getServerTickTime()) { + isFlying=true; + lastlandedloc=m.getLocation().clone(); + Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() { + public void run() { + m.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION,Integer.MAX_VALUE,60)); + } + },8); + m.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION,Integer.MAX_VALUE,20)); for (Player p : participantlist) { - GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.NIGHT_VISION, 10, 0, p, true); - } - SoundUtils.playLocalGlobalSound(Sound.ENTITY_GENERIC_EXTINGUISH_FIRE, 1.0f, 0.5f); - },90); - Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin,()->{ - isFlying=false; - GenericFunctions.logAndRemovePotionEffectFromEntity(PotionEffectType.LEVITATION, m); - m.teleport(lastlandedloc); - for (int i=0;i<5;i++) { - Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ - //SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_WITCH_AMBIENT, 1.0f, 0.6f); - SoundUtils.playLocalGlobalSound(Sound.ENTITY_GENERIC_EXPLODE, (float)(Math.random()*0.5+0.5), (float)(0.8+Math.random()*0.2)); - }, i*4); + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.customtitle.modifyLargeCenterTitle(ChatColor.RED+"WARNING!", 20); } - for (Player p : participantlist) { - //if (p.isOnGround() || !(p.getLocation().getBlock().isLiquid() || p.getLocation().getBlock().getType()==Material.AIR)) { - if (isOnGround(p)) { - MixedDamage dmg = GRANDSLAM_DAMAGE[getDifficultySlot()]; - CustomDamage.ApplyDamage(dmg.getDmgComponent(), m, p, null, "Grand Slam",CustomDamage.IGNORE_DAMAGE_TICK|CustomDamage.IGNOREDODGE); - if (dmg.getTruePctDmgComponent()>0) {CustomDamage.ApplyDamage(dmg.getTruePctDmgComponent()*p.getMaxHealth(), m, p, null, "Grand Slam",CustomDamage.IGNORE_DAMAGE_TICK|CustomDamage.IGNOREDODGE|CustomDamage.TRUEDMG);} - if (dmg.getTrueDmgComponent()>0) {CustomDamage.ApplyDamage(dmg.getTrueDmgComponent()*p.getMaxHealth(), m, p, null, "Grand Slam",CustomDamage.IGNORE_DAMAGE_TICK|CustomDamage.IGNOREDODGE|CustomDamage.TRUEDMG);} + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin,()->{ + for (int i=0;i<3;i++) { + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ + SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_WITCH_AMBIENT, 1.0f, 0.6f); + }, i*3); } - } - },100); - lastusedgrandslam = TwosideKeeper.getServerTickTime(); + announceMessageToParticipants(ChatColor.YELLOW+""+ChatColor.ITALIC+"\"Hehe, I'm going to "+ChatColor.RESET+""+ChatColor.DARK_RED+""+ChatColor.BOLD+"CRUSH YOU!"+ChatColor.RESET+""+ChatColor.YELLOW+""+ChatColor.ITALIC+"\""); + //SoundUtils.playGlobalSound(loc,Sound.BLOCK_PORTAL_TRIGGER, 0.2f, 2.0f); + SoundUtils.playLocalGlobalSound(Sound.BLOCK_PORTAL_TRIGGER, 0.2f, 2.0f); + },40); + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin,()->{ + for (Player p : participantlist) { + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS, 20, 0, p, true); + } + SoundUtils.playLocalGlobalSound(Sound.ENTITY_GENERIC_EXTINGUISH_FIRE, 1.0f, 0.5f); + },80); + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin,()->{ + for (Player p : participantlist) { + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.NIGHT_VISION, 10, 0, p, true); + } + SoundUtils.playLocalGlobalSound(Sound.ENTITY_GENERIC_EXTINGUISH_FIRE, 1.0f, 0.5f); + },90); + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin,()->{ + isFlying=false; + GenericFunctions.logAndRemovePotionEffectFromEntity(PotionEffectType.LEVITATION, m); + m.teleport(lastlandedloc); + for (int i=0;i<5;i++) { + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ + //SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_WITCH_AMBIENT, 1.0f, 0.6f); + SoundUtils.playLocalGlobalSound(Sound.ENTITY_GENERIC_EXPLODE, (float)(Math.random()*0.5+0.5), (float)(0.8+Math.random()*0.2)); + }, i*4); + } + for (Player p : participantlist) { + //if (p.isOnGround() || !(p.getLocation().getBlock().isLiquid() || p.getLocation().getBlock().getType()==Material.AIR)) { + if (isOnGround(p)) { + MixedDamage dmg = GRANDSLAM_DAMAGE[getDifficultySlot()]; + CustomDamage.ApplyDamage(dmg.getDmgComponent(), m, p, null, "Grand Slam",CustomDamage.IGNORE_DAMAGE_TICK|CustomDamage.IGNOREDODGE); + if (dmg.getTruePctDmgComponent()>0) {CustomDamage.ApplyDamage(dmg.getTruePctDmgComponent()*p.getMaxHealth(), m, p, null, "Grand Slam",CustomDamage.IGNORE_DAMAGE_TICK|CustomDamage.IGNOREDODGE|CustomDamage.TRUEDMG);} + if (dmg.getTrueDmgComponent()>0) {CustomDamage.ApplyDamage(dmg.getTrueDmgComponent()*p.getMaxHealth(), m, p, null, "Grand Slam",CustomDamage.IGNORE_DAMAGE_TICK|CustomDamage.IGNOREDODGE|CustomDamage.TRUEDMG);} + } + } + },100); + lastusedgrandslam = TwosideKeeper.getServerTickTime(); + } } private void performAssassinate() { @@ -408,11 +639,15 @@ public class Knight extends CustomMonster{ } } - private void changeAggroToRandomNewTarget() { + private Player changeAggroToRandomNewTarget() { if (Math.random()<=0.5) { Monster me = (Monster)m; Player newtarget = pickRandomTarget(); setAggro(me, newtarget); + return newtarget; + } else { + Monster me = (Monster)m; + return (Player)me.getTarget(); } } @@ -600,12 +835,28 @@ public class Knight extends CustomMonster{ public void announceFailedTakedown() { if (dpslist.size()>0 && !m.isDead()) { + phaseii=false; Bukkit.getServer().broadcastMessage(GenericFunctions.getDisplayName(m)+" Takedown Failed..."); Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:"); Bukkit.getServer().broadcastMessage(generateDPSReport()); aPlugin.API.discordSendRaw(GenericFunctions.getDisplayName(m)+" Takedown Failed...\n\n"+ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+generateDPSReport()+"\n```"); dpslist.clear(); PerformSpiderCleanup(); + PerformSilverfishAndEndermiteCleanup(); + healthbar.setColor(BarColor.WHITE); + } + } + + public void announceSuccessfulTakedown() { + if (dpslist.size()>0 && !m.isDead()) { + phaseii=false; + Bukkit.getServer().broadcastMessage(GenericFunctions.getDisplayName(m)+" Takedown Failed..."); + Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:"); + Bukkit.getServer().broadcastMessage(generateDPSReport()); + aPlugin.API.discordSendRaw(GenericFunctions.getDisplayName(m)+" Takedown Failed...\n\n"+ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+generateDPSReport()+"\n```"); + dpslist.clear(); + PerformSpiderCleanup(); + PerformSilverfishAndEndermiteCleanup(); healthbar.setColor(BarColor.WHITE); } } @@ -826,6 +1077,22 @@ public class Knight extends CustomMonster{ startedfight=false; } PerformSpiderCleanup(); + PerformSilverfishAndEndermiteCleanup(); + } + + private void PerformSilverfishAndEndermiteCleanup() { + if (silverfish!=null && + silverfish.isValid()) { + silverfish.remove(); + silverfish=null; + } + for (LivingEntity ent : endermites) { + if (ent!=null && + ent.isValid()) { + ent.remove(); + } + } + endermites.clear(); } protected void increaseBarTextScroll() { diff --git a/src/sig/plugin/TwosideKeeper/PlayerStructure.java b/src/sig/plugin/TwosideKeeper/PlayerStructure.java index 4b2406a..b7db051 100644 --- a/src/sig/plugin/TwosideKeeper/PlayerStructure.java +++ b/src/sig/plugin/TwosideKeeper/PlayerStructure.java @@ -232,6 +232,7 @@ public class PlayerStructure { public boolean damagenumbers=true; public OptionsMenu optionsmenu; public ItemStack weaponUsedForShooting; + public boolean hasDarkSubmissionHealthReduction=false; //Needs the instance of the player object to get all other info. Only to be called at the beginning. @SuppressWarnings("deprecation") diff --git a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java index b7720a5..70d692f 100644 --- a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java +++ b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java @@ -48,6 +48,7 @@ import org.bukkit.entity.Bat; import org.bukkit.entity.Blaze; import org.bukkit.entity.Chicken; import org.bukkit.entity.Creeper; +import org.bukkit.entity.Endermite; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.ExperienceOrb; @@ -69,6 +70,7 @@ import org.bukkit.entity.Monster; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.entity.Shulker; +import org.bukkit.entity.Silverfish; import org.bukkit.entity.Skeleton; import org.bukkit.entity.Snowball; import org.bukkit.entity.Snowman; @@ -169,8 +171,10 @@ import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionType; import org.bukkit.util.Vector; import org.inventivetalent.glow.GlowAPI; @@ -238,6 +242,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.Common.RecipeCategory; import sig.plugin.TwosideKeeper.HelperStructures.Common.RecipeLinker; import sig.plugin.TwosideKeeper.HelperStructures.Effects.DarkSlash; import sig.plugin.TwosideKeeper.HelperStructures.Effects.EarthWaveTask; +import sig.plugin.TwosideKeeper.HelperStructures.Effects.HighlightCircle; import sig.plugin.TwosideKeeper.HelperStructures.Effects.LavaPlume; import sig.plugin.TwosideKeeper.HelperStructures.Effects.ReplaceBlockTask; import sig.plugin.TwosideKeeper.HelperStructures.Effects.TemporaryBlock; @@ -501,6 +506,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { public static List blocknodes = new ArrayList(); public static HashMap temporaryblocks = new HashMap(); public static List channels = new ArrayList(); + public static List circles = new ArrayList(); //public static stats StatCommand = new stats(); @@ -885,6 +891,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } TwosideKeeper.HeartbeatLogger.AddEntry("Temporary Block Node Handling", (int)(System.nanoTime()-time));time=System.nanoTime(); + applyConfusionEffectsToPlayers(); + TwosideKeeper.HeartbeatLogger.AddEntry("Potion Effect Handling", (int)(System.nanoTime()-time));time=System.nanoTime(); for (Channel c : channels) { if (!c.runTick()) { @@ -907,6 +915,14 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } + private void applyConfusionEffectsToPlayers() { + for (Player p : Bukkit.getOnlinePlayers()) { + if (Buff.hasBuff(p, "CONFUSION")) { + aPlugin.API.setSlot(p, (int)(Math.random()*9)); + } + } + } + private void UpdateLavaBlock(Block lavamod) { if (lavamod.getType()==Material.AIR) {lavamod.setType(Material.LAVA);lavamod.setData((byte)9);BlockState state = lavamod.getState();state.update(true,true);} } @@ -2006,6 +2022,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener { LivingEntityDifficulty.T1_MINIBOSS); Knight.randomlyConvertAsKnight(m,true); TwosideKeeper.custommonsters.put(m.getUniqueId(),new Knight(m)); + /*Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ + m.setHealth(m.getMaxHealth()*0.3); + }, 100);*/ }break; case "DAMAGETEST":{ LivingEntity m = MonsterController.convertLivingEntity((Skeleton)p.getWorld().spawnEntity(p.getLocation(),EntityType.SKELETON), @@ -2030,16 +2049,34 @@ public class TwosideKeeper extends JavaPlugin implements Listener { ); } }break; - case "DARKSUBMISSION":{ - //TwosideKeeper.log(EntityUtils.getFacingDirection(p).name(),0); - Buff.addBuff(p,"DARKSUBMISSION",new Buff("Dark Submission",20*20,Integer.parseInt(args[1]),Color.BLACK,ChatColor.BLACK+""+ChatColor.MAGIC+"☁"+ChatColor.RESET,false)); - }break; case "ABSORBENEMY":{ Skeleton s = (Skeleton)Bukkit.getWorld("world").spawnEntity(p.getLocation(), EntityType.SKELETON); GlowAPI.setGlowing(s, GlowAPI.Color.AQUA, Bukkit.getOnlinePlayers()); GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.ABSORPTION, 999999, 254, s, true); GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.INVISIBILITY, 999999, 254, s, true); - } + }break; + case "DARKSUBMISSION":{ + CreateDarkReveriePool(p,2); + }break; + case "HIGHLIGHTCIRCLE":{ + new HighlightCircle(p.getLocation(),5,30,200); + }break; + case "BEAM":{ + for (int i=0;i<40;i++) { + int beamDuration = (int)(Math.random()*(50)); + int randomx = (int)(Math.random()*21)-10; + int randomz = (int)(Math.random()*21)-10; + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ + Location beamloc = new Location(p.getWorld(), + randomx, + 0, + randomz); + Location finalbeamloc = p.getLocation().add(beamloc); + new HighlightCircle(finalbeamloc, 1, 15, 60-beamDuration); + TemporaryBlock.createTemporaryBlockCircle(finalbeamloc, 1, Material.STAINED_CLAY, (byte)14, 60-beamDuration, "BEAM"); + }, beamDuration); + } + }break; } } //LivingEntity m = MonsterController.convertMonster((Monster)p.getWorld().spawnEntity(p.getLocation(),EntityType.ZOMBIE), MonsterDifficulty.ELITE); @@ -2507,6 +2544,18 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } return false; } + private void CreateDarkReveriePool(Player p, int tier) { + AreaEffectCloud aec = (AreaEffectCloud)p.getWorld().spawnEntity(p.getLocation(), EntityType.AREA_EFFECT_CLOUD); + aec.setColor(Color.BLACK); + aec.setRadius(5f); + aec.setBasePotionData(new PotionData(PotionType.INSTANT_DAMAGE)); + aec.setDuration(1200); + //aec.setReapplicationDelay(1); + aec.setCustomName("DARKSUBMISSION "+tier); + if (tier>=2) { + aec.setRadiusPerTick(0.0042f); + } + } private void openOptionsMenu(Player p) { new OptionsMenu(p); } @@ -3298,9 +3347,52 @@ public class TwosideKeeper extends JavaPlugin implements Listener { @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) public void onEffectCloud(AreaEffectCloudApplyEvent ev) { - + //TwosideKeeper.log(ev.getEventName()+" is being run with entity "+GenericFunctions.GetEntityDisplayName(ev.getEntity()), 0); + if (ev.getEntity().getCustomName()!=null && + ev.getEntity().getCustomName().contains("DARKSUBMISSION")) { + //TwosideKeeper.log("Dark Reverie Cloud detected.", 0); + for (LivingEntity ent : ev.getAffectedEntities()) { + if (ent instanceof Player) { + Player p = (Player)ent; + int tier = Integer.parseInt(ev.getEntity().getCustomName().split(" ")[1]); + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS, 20*2, 0, p); + Buff.addBuff(p, "DARKSUBMISSION", new Buff(ChatColor.GRAY+"Dark Submission"+ChatColor.RESET,20*20,1,Color.BLACK,ChatColor.BLACK+""+ChatColor.MAGIC+"☁"+ChatColor.RESET,false), true); + ApplyDarkSubmissionEffects(p,tier); + } + } + } } + public static void ApplyDarkSubmissionEffects(Player p,int tier) { + int stackcount = Buff.getBuff(p, "DARKSUBMISSION").getAmplifier(); + if (stackcount==20) { + int buffduration=0; + switch (tier) { + case 1:{ + buffduration=10; + }break; + case 2:{ + buffduration=20; + }break; + case 3:{ + buffduration=30; + }break; + default:{ + TwosideKeeper.log("WARNING! Could not get proper duration for tier "+tier+" of Dark Reverie.", 1); + buffduration=20; + } + } + Buff.addBuff(p, "CONFUSION", new Buff("Confusion",20*buffduration,1,Color.PURPLE,ChatColor.DARK_PURPLE+"๑"+ChatColor.RESET,false)); + } + if (stackcount==50) { + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ + setPlayerMaxHealth(p,p.getHealth()/p.getMaxHealth(),true); + },1); + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.hasDarkSubmissionHealthReduction=true; + } + } + @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) public void onArrowHitBlock(ProjectileHitEvent ev) { Projectile proj = ev.getEntity(); @@ -4749,7 +4841,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { case "FALLING_BLOCK": { return "got "+Pronouns.ChoosePronoun(10)+" by a falling block."; } - case "LIGHTNING": { + case "LIGHTNING": + case "Lightning Bolt":{ return Pronouns.ChoosePronoun(11); } case "FLY_INTO_WALL": { @@ -4806,6 +4899,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener { case "Dark Cleanse Attack":{ return "bursted into the shadow realm."; } + case "Dark Light":{ + return "was evaporated by a brightly dark light."; + } case "Grand Slam":{ return Pronouns.ChoosePronoun(19); } @@ -5515,10 +5611,17 @@ public class TwosideKeeper extends JavaPlugin implements Listener { setPlayerMaxHealth(player,player.getHealth()/player.getMaxHealth()); } },1); + PreventConfusedPlayersFromAdjustingProperly(player); Christmas.RunPlayerItemHeldEvent(ev); } - @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) + private void PreventConfusedPlayersFromAdjustingProperly(Player p) { + if (Buff.hasBuff(p, "CONFUSION")) { + aPlugin.API.setSlot(p, (int)(Math.random()*9)); + } + } + + @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) public void onRegainHealth(EntityRegainHealthEvent ev) { if (ev.getRegainReason()==RegainReason.SATIATED && ev.getEntityType()==EntityType.PLAYER) { ev.setCancelled(true); @@ -7392,6 +7495,21 @@ public class TwosideKeeper extends JavaPlugin implements Listener { if (livingentitydata.containsKey(m.getUniqueId())) { ms = (LivingEntityStructure)livingentitydata.get(m.getUniqueId()); } + + if (m instanceof Silverfish || + m instanceof Endermite) { + for (UUID id : custommonsters.keySet()) { + CustomMonster cm = custommonsters.get(id); + if (cm instanceof Knight) { + Knight k = (Knight)cm; + if (m instanceof Silverfish) { + k.triggerSilverfishKill(m); + } else { + k.triggerEndermiteKill(m); + } + } + } + } if (ms!=null && (ms.GetTarget() instanceof Player)) { if ((m instanceof Slime) || @@ -7686,6 +7804,57 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } + if (custommonsters.containsKey(m.getUniqueId())) { + CustomMonster cm = custommonsters.get(m.getUniqueId()); + if (cm instanceof Knight) { + Knight k = (Knight)cm; + List participants = k.getParticipants(); + StringBuilder participants_list = new StringBuilder(); + for (int i=0;i{ - ItemStack tempitem = p.getEquipment().getItemInMainHand().clone(); + ItemStack tempitem = p.getInventory().getItem(slot); Location loc = p.getLocation().clone(); pd.weaponUsedForShooting = tempitem; - p.getEquipment().setItemInMainHand(new ItemStack(Material.AIR)); + //p.getEquipment().setItemInMainHand(new ItemStack(Material.AIR)); + p.getInventory().setItem(slot, new ItemStack(Material.AIR)); Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, ()->{ if (p!=null && p.isValid()) { - p.getEquipment().setItemInMainHand(tempitem); + p.getInventory().setItem(slot, tempitem); + //p.getEquipment().setItemInMainHand(tempitem); } else { GenericFunctions.dropItem(tempitem, loc); } @@ -10335,6 +10507,13 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } TwosideKeeper.HeartbeatLogger.AddEntry("----====]> Adventurer Mode HP Calculation", (int)(System.nanoTime()-time));time = System.nanoTime(); + if (Buff.hasBuff(p, "DARKSUBMISSION")) { + Buff b = Buff.getBuff(p, "DARKSUBMISSION"); + if (b.getAmplifier()>=50) { + hp*=0.5; + } + } + hp*=maxdeduction; p.resetMaxHealth(); diff --git a/src/sig/plugin/TwosideKeeper/runServerHeartbeat.java b/src/sig/plugin/TwosideKeeper/runServerHeartbeat.java index 2f038c8..246584e 100644 --- a/src/sig/plugin/TwosideKeeper/runServerHeartbeat.java +++ b/src/sig/plugin/TwosideKeeper/runServerHeartbeat.java @@ -51,6 +51,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode; import sig.plugin.TwosideKeeper.HelperStructures.ServerType; import sig.plugin.TwosideKeeper.HelperStructures.WorldShop; import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions; +import sig.plugin.TwosideKeeper.HelperStructures.Effects.HighlightCircle; import sig.plugin.TwosideKeeper.HelperStructures.Effects.LavaPlume; import sig.plugin.TwosideKeeper.HelperStructures.Effects.TemporaryBlock; import sig.plugin.TwosideKeeper.HelperStructures.Utils.EntityUtils; @@ -318,6 +319,9 @@ final class runServerHeartbeat implements Runnable { removeRegenerationStacks(p); TwosideKeeper.HeartbeatLogger.AddEntry("Regeneration Stack Removal", (int)(System.nanoTime()-time));time=System.nanoTime(); + + checkForHealthUpdate(p); + TwosideKeeper.HeartbeatLogger.AddEntry("Check for Health Update.", (int)(System.nanoTime()-time));time=System.nanoTime(); } //TwosideKeeper.outputArmorDurability(p,">"); } @@ -344,6 +348,9 @@ final class runServerHeartbeat implements Runnable { performTimingsReport(); TwosideKeeper.HeartbeatLogger.AddEntry("Server Lag Activation", (int)(System.nanoTime()-time));time=System.nanoTime(); + PerformHighlightCircleEffects(); + TwosideKeeper.HeartbeatLogger.AddEntry("Highlight Server Tick Effects", (int)(System.nanoTime()-time));time=System.nanoTime(); + resetPigmanAggro(); TwosideKeeper.HeartbeatLogger.AddEntry("Reset Pigman Aggro", (int)(System.nanoTime()-time));time=System.nanoTime(); if ((int)(System.nanoTime()-totaltime)/1000000d>50) { @@ -352,6 +359,23 @@ final class runServerHeartbeat implements Runnable { TwosideKeeper.HeartbeatLogger.AddEntry(ChatColor.LIGHT_PURPLE+"Total Server Heartbeat", (int)(System.nanoTime()-totaltime));totaltime=System.nanoTime(); } + private void PerformHighlightCircleEffects() { + for (HighlightCircle hc : TwosideKeeper.circles) { + if (!hc.runTick()) { + TwosideKeeper.ScheduleRemoval(TwosideKeeper.circles, hc); + } + } + } + + private void checkForHealthUpdate(Player p) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + if (pd.hasDarkSubmissionHealthReduction && + !Buff.hasBuff(p, "DARKSUBMISSION")) { + pd.hasDarkSubmissionHealthReduction=false; + TwosideKeeper.setPlayerMaxHealth(p, p.getHealth()/p.getMaxHealth(), true); + } + } + private void PerformStealthSetRegen(Player p, PlayerStructure pd) { if (pd.laststealthheal+100<=TwosideKeeper.getServerTickTime() && GenericFunctions.hasStealth(p) &&