diff --git a/TwosideKeeper.jar b/TwosideKeeper.jar index 6966683..134c084 100644 Binary files a/TwosideKeeper.jar and b/TwosideKeeper.jar differ diff --git a/src/sig/plugin/TwosideKeeper/Boss/EliteZombie.java b/src/sig/plugin/TwosideKeeper/Boss/EliteZombie.java index 89f945c..1dbdceb 100644 --- a/src/sig/plugin/TwosideKeeper/Boss/EliteZombie.java +++ b/src/sig/plugin/TwosideKeeper/Boss/EliteZombie.java @@ -36,6 +36,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.Loot; import sig.plugin.TwosideKeeper.HelperStructures.MonsterDifficulty; import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode; import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.APIUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.SoundUtils; public class EliteZombie extends EliteMonster{ @@ -524,7 +525,7 @@ public class EliteZombie extends EliteMonster{ } } TwosideKeeper.log("Selected block "+b.toString(), 5); - if (!aPlugin.API.isExplosionProof(b) && b.getType()!=Material.STAINED_GLASS) { + if (!APIUtils.isExplosionProof(b) && b.getType()!=Material.STAINED_GLASS) { Material type = b.getType(); Byte data = b.getData(); storedblocks.put(b, type); diff --git a/src/sig/plugin/TwosideKeeper/CustomDamage.java b/src/sig/plugin/TwosideKeeper/CustomDamage.java index 30116b2..5fe16e6 100644 --- a/src/sig/plugin/TwosideKeeper/CustomDamage.java +++ b/src/sig/plugin/TwosideKeeper/CustomDamage.java @@ -128,6 +128,7 @@ public class CustomDamage { * @return Whether or not this attack actually was applied. Returns false if it was dodged, nodamageticks, cancelled, etc. */ static public boolean ApplyDamage(double damage, Entity damager, LivingEntity target, ItemStack weapon, String reason, int flags) { + long time = System.nanoTime(); if (!isFlagSet(flags,CONTROLLED)) { TwosideKeeper.damagequeue++; if (TwosideKeeper.damagequeue>8) { @@ -171,6 +172,7 @@ public class CustomDamage { //TwosideKeeper.log("Inside of here.", 0); DealDamageToEntity(dmg, damager, target, weapon, reason, flags); addToLoggerTotal(damager,dmg); + TwosideKeeper.HeartbeatLogger.AddEntry("Damage Calculations", (int)(System.nanoTime()-time));time=System.nanoTime(); } else { return false; } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java index 5f92426..9bdd7be 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java @@ -92,6 +92,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode; import sig.plugin.TwosideKeeper.HelperStructures.WorldShop; import sig.plugin.TwosideKeeper.HelperStructures.Utils.ArrayUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.ArtifactUtils; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.BlockUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.DebugUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.ItemCubeUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.ItemUtils; @@ -3937,6 +3938,9 @@ public class GenericFunctions { } } + /** + * ONLY FOR BLITZEN LIGHTNING STRIKE + */ public static void DealDamageToNearbyMobs(Location l, double basedmg, int range, Entity damager, int flags) { List nearbyentities = getNearbyMobs(l,range); for (LivingEntity ent : nearbyentities) { @@ -3945,11 +3949,17 @@ public class GenericFunctions { } } } - + + /** + * Line Drive variant. + */ public static void DealDamageToNearbyMobs(Location l, double basedmg, int range, boolean knockup, double knockupamt, Entity damager, ItemStack weapon, boolean isLineDrive) { DealDamageToNearbyMobs(l,basedmg,range,knockup,knockupamt,damager,weapon,isLineDrive,(isLineDrive)?"Line Drive":null); } + /** + * Use this to customize dealing damage to nearby mobs. + */ public static void DealDamageToNearbyMobs(Location l, double basedmg, double range, boolean knockup, double knockupamt, Entity damager, ItemStack weapon, boolean isLineDrive, String reason) { Collection ents = l.getWorld().getNearbyEntities(l, range, range, range); //We cleared the non-living entities, deal damage to the rest. @@ -4544,12 +4554,7 @@ public class GenericFunctions { for (int j=0;j<50;j++) { newpos.getWorld().playEffect(newpos, Effect.FLAME, 60); } - if (newpos2.getBlock().getType()!=Material.AIR && - !newpos2.getBlock().isLiquid() && - !(newpos2.getBlock().getType()==Material.STEP) && - !(newpos2.getBlock().getType()==Material.WOOD_STEP) && - !(newpos2.getBlock().getType()==Material.PURPUR_SLAB) && - !(newpos2.getBlock().getType()==Material.STONE_SLAB2)) { + if (!BlockUtils.isPassThrough(newpos2)) { break; } Bukkit.getScheduler().scheduleSyncDelayedTask(Bukkit.getPluginManager().getPlugin("TwosideKeeper"), new Runnable() { diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/ReplaceBlockTask.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/ReplaceBlockTask.java new file mode 100644 index 0000000..074ae86 --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/ReplaceBlockTask.java @@ -0,0 +1,33 @@ +package sig.plugin.TwosideKeeper.HelperStructures.Effects; + +import org.bukkit.Material; +import org.bukkit.block.Block; + +import sig.plugin.TwosideKeeper.TwosideKeeper; + +public class ReplaceBlockTask implements Runnable{ + String str; + + public ReplaceBlockTask(String str) { + this.str=str; + } + + @Override + public void run() { + if (TwosideKeeper.temporaryblocks.containsKey(str)) { + TemporaryBlock tb = TwosideKeeper.temporaryblocks.get(str); + CleanupTemporaryBlock(tb); + TwosideKeeper.temporaryblocks.remove(TemporaryBlock.getLocationKey(tb)); + TwosideKeeper.temporaryblocks.remove(TemporaryBlock.getLocationKey(tb, false)); + } + } + + public static void CleanupTemporaryBlock(TemporaryBlock tb) { + if (tb.getBlock()!=null && + tb.getBlock().getType()==tb.getConvertedMaterial() && + tb.getBlock().getData()==tb.getConvertedData()) { + tb.getBlock().setType(tb.getOriginalMaterial()); + tb.getBlock().setData(tb.getOriginalData()); + } + } +} diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/TemporaryBlock.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/TemporaryBlock.java new file mode 100644 index 0000000..7fb729a --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/TemporaryBlock.java @@ -0,0 +1,223 @@ +package sig.plugin.TwosideKeeper.HelperStructures.Effects; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import sig.plugin.TwosideKeeper.TwosideKeeper; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.APIUtils; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.TextUtils; + +public class TemporaryBlock { + Material origmat; + Material convertedmat; + byte origdata; + byte converteddata; + int duration; + String specialKey; + Block bl; + + public Material getOriginalMaterial() { + return origmat; + } + + public Material getConvertedMaterial() { + return convertedmat; + } + + public byte getOriginalData() { + return origdata; + } + + public byte getConvertedData() { + return converteddata; + } + + public String getSpecialKey() { + return specialKey; + } + + public Block getBlock() { + return bl; + } + + public TemporaryBlock(Block b, Material convertedmat, int duration) { + this.origmat = b.getType(); + this.convertedmat = convertedmat; + this.origdata = b.getData(); + this.converteddata = b.getData(); + this.duration = duration; + this.specialKey = ""; + this.bl=b; + Block tempblock = getBlockToModify(b); + if (tempblock!=null) { + modifyBlock(this.bl); + } + setupStructureAndScheduler(); + } + + public TemporaryBlock(Block b, Material convertedmat, byte converteddata, int duration) { + this.origmat = b.getType(); + this.convertedmat = convertedmat; + this.origdata = b.getData(); + this.converteddata = converteddata; + this.duration = duration; + this.specialKey = ""; + this.bl=b; + Block tempblock = getBlockToModify(b); + if (tempblock!=null) { + this.bl = tempblock; + modifyBlock(this.bl); + } + setupStructureAndScheduler(); + } + + public TemporaryBlock(Block b, Material convertedmat, byte converteddata, int duration, String specialKey) { + this.origmat = b.getType(); + this.convertedmat = convertedmat; + this.origdata = b.getData(); + this.converteddata = converteddata; + this.duration = duration; + this.specialKey = specialKey; + this.bl=b; + Block tempblock = getBlockToModify(b); + if (tempblock!=null) { + this.bl = tempblock; + modifyBlock(this.bl); + } + setupStructureAndScheduler(); + } + + private void modifyBlock(Block b) { + if (b!=null && !APIUtils.isExplosionProof(b)) { + b.setType(convertedmat); + b.setData(converteddata); + } + } + + private void setupStructureAndScheduler() { + if (bl!=null) { + if (!TwosideKeeper.temporaryblocks.containsKey(getLocationKey(bl))) { + AddToTemporaryBlockStructure(this); + } + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, + new ReplaceBlockTask(getLocationKey(this)), + duration); + //TwosideKeeper.log(TextUtils.outputHashmap(TwosideKeeper.temporaryblocks),0); + } + } + + private static void AddToTemporaryBlockStructure(TemporaryBlock tb) { + if (tb.getSpecialKey().length()>0) { + TwosideKeeper.temporaryblocks.put(getLocationKey(tb), tb); + } + TwosideKeeper.temporaryblocks.put(getLocationKey(tb,false), tb); + } + + private static String getLocationKey(Block bl) { + return getLocationKey(bl, ""); + } + + public static String getLocationKey(TemporaryBlock tb) { + return tb.getLocationKey(tb.getBlock(), tb.getSpecialKey()); + } + + public static String getLocationKey(TemporaryBlock tb, boolean includeSpecialKey) { + return tb.getLocationKey(tb.getBlock(), (includeSpecialKey)?tb.getSpecialKey():""); + } + + private static String getLocationKey(Block bl, String specialKey) { + if (bl!=null) { + StringBuilder sb = new StringBuilder(Integer.toString(bl.getLocation().getBlockX())); + sb.append("_"); + sb.append(Integer.toString(bl.getLocation().getBlockY())); + sb.append("_"); + sb.append(Integer.toString(bl.getLocation().getBlockZ())); + sb.append("_"); + sb.append(bl.getLocation().getWorld().getName()); + sb.append("_"); + sb.append(specialKey); + return sb.toString(); + } else { + return ""; + } + } + + private Block getBlockToModify(Block b) { + //Attempt to detect areas above and below ground to place this modified block. + int yoffset = 0; + while (yoffset<=5) { + Block checkblock = b.getRelative(0, yoffset, 0); + Block checkblock2 = b.getRelative(0, yoffset+1, 0); + if (checkblock!=null && checkblock2!=null) { + if ((checkblock.getType()==Material.AIR || checkblock.isLiquid() || checkblock.getType().isTransparent())) { + yoffset = adjustYOffset(yoffset); + //TwosideKeeper.log(Integer.toString(yoffset), 0); + } else { + if ((checkblock2.getType()==Material.AIR || checkblock2.isLiquid())) { + this.origmat = checkblock.getType(); + this.origdata = checkblock.getData(); + return b.getRelative(0, yoffset, 0); + } else { + yoffset = adjustYOffset(yoffset); + } + } + } else { + yoffset = adjustYOffset(yoffset); + } + } + return null; + } + + private int adjustYOffset(int yoffset) { + yoffset=(yoffset>-5 && yoffset<=0)?(yoffset-1):(yoffset<0)?1:(yoffset+1); + return yoffset; + } + + public String toString() { + StringBuilder sb = new StringBuilder("TemporaryBlock{"); + sb.append("orig:(");sb.append(origmat);sb.append(",");sb.append(origdata);sb.append(")"); + sb.append(","); + sb.append("converted:(");sb.append(convertedmat);sb.append(",");sb.append(converteddata);sb.append(")"); + sb.append(","); + sb.append("duration:");sb.append(duration); + sb.append(","); + sb.append("key:");sb.append(specialKey); + sb.append(","); + sb.append("block:");sb.append(bl); + sb.append("}"); + return sb.toString(); + } + + public static boolean isTemporaryBlock(Block b) { + return TwosideKeeper.temporaryblocks.containsKey(TemporaryBlock.getLocationKey(b)); + } + public static boolean isStandingOnSpecialBlock(Player p, String specialKey) { + //return TwosideKeeper.temporaryblocks.containsKey(TemporaryBlock.getLocationKey(b)); + Block b = p.getLocation().getBlock(); + if (b!=null) { + return TwosideKeeper.temporaryblocks.containsKey(TemporaryBlock.getLocationKey(b,specialKey)); + } else { + return false; + } + } + public static boolean isInRangeOfSpecialBlock(Player p, double range, String specialKey) { + Block b = p.getLocation().getBlock(); + while (range-->0 && b.getLocation().getBlockY()>0) { + if (TwosideKeeper.temporaryblocks.containsKey(TemporaryBlock.getLocationKey(b,specialKey))) { + return true; + } else { + b = b.getRelative(0, -1, 0); + } + } + return false; + } + public static TemporaryBlock getTemporaryBlock(Block b) { + if (TwosideKeeper.temporaryblocks.containsKey(TemporaryBlock.getLocationKey(b))) { + return TwosideKeeper.temporaryblocks.get(TemporaryBlock.getLocationKey(b)); + } else { + return null; + } + } +} diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/WindSlash.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/WindSlash.java new file mode 100644 index 0000000..be31445 --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Effects/WindSlash.java @@ -0,0 +1,70 @@ +package sig.plugin.TwosideKeeper.HelperStructures.Effects; + +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import sig.plugin.TwosideKeeper.CustomDamage; +import sig.plugin.TwosideKeeper.TwosideKeeper; +import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.BlockUtils; + +public class WindSlash { + Location loc; + Player sourcep; + double dmg; + long lasteffect; + long death_time; + final static int EFFECT_DENSITY = 20; + final static int EFFECT_FREQUENCY = 4; + final static int SLASH_SIZE = 3; //Radius. + final static Particle EFFECT_PARTICLE = Particle.FIREWORKS_SPARK; + final static float SPEED_MULT = 3.5f; + + public WindSlash(Location loc, Player p, double dmg, int tick_duration) { + this.loc=loc.clone(); + this.sourcep=p; + this.dmg=dmg; + this.death_time = TwosideKeeper.getServerTickTime()+tick_duration; + this.lasteffect=TwosideKeeper.getServerTickTime(); + } + + public boolean runTick() { + if (!moveWindSlash()) { + return false; + } + createParticles(); + damageNearbyTargets(); + if (TwosideKeeper.getServerTickTime()>death_time) { + return false; + } + return true; + } + + private void damageNearbyTargets() { + GenericFunctions.DealDamageToNearbyMobs(loc, dmg, SLASH_SIZE, false, 0, sourcep, sourcep.getEquipment().getItemInMainHand(), false, "Wind Slash"); + } + + private boolean moveWindSlash() { + Location origloc = loc.clone(); + Vector move = origloc.getDirection().setY(origloc.getDirection().getY()/1.4).multiply(SPEED_MULT); + float dist = SPEED_MULT; + loc.add(move); + while (dist-->0) { + if (!BlockUtils.isPassThrough(origloc.add(origloc.getDirection()))) { + return false; + } + } + return true; + //TwosideKeeper.log("New Location: "+loc, 0); + } + + private void createParticles() { + loc.getWorld().spawnParticle(Particle.SWEEP_ATTACK, loc.clone().add(0,-SLASH_SIZE/2,0), 2); + for (int i=0;i=2) { + lore.add(ChatColor.DARK_AQUA+" T18 - "); + lore.add(ChatColor.WHITE+" Decreases cooldown of Assassinate by 50% when"); + lore.add(ChatColor.WHITE+" a backstab occurs."); + if (tier>=3) { + lore.add(ChatColor.DARK_AQUA+" T27 - "); + lore.add(ChatColor.WHITE+" Backstabs deal 6x normal damage."); + if (tier>=4) { + lore.add(ChatColor.DARK_AQUA+" T40 - "); + lore.add(ChatColor.WHITE+" +30% Cooldown Reduction"); + lore.add(ChatColor.WHITE+" +100% Critical Strike Chance"); + } + } + } + break; + case LEGION: + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:"); + lore.add(ChatColor.DARK_AQUA+" 2 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 2)+"% Lifesteal"); + lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 3)+"% Damage per Weapon Charge"); + lore.add(ChatColor.DARK_AQUA+" 4 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 4)+"% Damage per 100 Damage Pool"); + lore.add(ChatColor.DARK_AQUA+" 5 - "+ABILITY_LABEL+" Undying Rage"+ABILITY_LABEL_END); + lore.add(ChatColor.GRAY+" When taking fatal damage, removes all Damage"); + lore.add(ChatColor.GRAY+" Pool stacks and prevents your health from"); + lore.add(ChatColor.GRAY+" going below 1 for "+(tier+6)+" seconds."); + lore.add(ChatColor.GRAY+" "); + lore.add(ChatColor.GRAY+" (120s Cooldown)"); + lore.add(ChatColor.DARK_AQUA+" 6 - "+ChatColor.WHITE+""); + lore.add(ChatColor.WHITE+" +"+(tier*25)+"% Lifesteal"); + lore.add(ChatColor.WHITE+" +"+(tier*25)+"% Health Regeneration"); + lore.add(ChatColor.WHITE+" +"+(tier*25)+"% Maximum Health"); + break; + case LUCI: + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:"); + lore.add(ChatColor.DARK_AQUA+" 2 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 2)+"% Dodge Chance"); + lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" Adds "+ItemSet.GetBaseAmount(set, tier, 3)+"% Damage"); + lore.add(ChatColor.DARK_AQUA+" "+ChatColor.GRAY+" for every 1% Dodge Chance"); + lore.add(ChatColor.DARK_AQUA+" 4 - "+ChatColor.WHITE+" Adds "+ItemSet.GetBaseAmount(set, tier, 4)+"% Damage"); + lore.add(ChatColor.DARK_AQUA+" "+ChatColor.GRAY+" for every 1% Damage Reduction"); + lore.add(ChatColor.DARK_AQUA+" 5 - "+ABILITY_LABEL+" Beast Within"+ABILITY_LABEL_END); + lore.add(ChatColor.GRAY+" Press the drop key to obtain a buff lasting "+(tier+6)); + lore.add(ChatColor.GRAY+" seconds, giving you 100% Dodge Chance and"); + lore.add(ChatColor.GRAY+" Damage Reduction. Beast Within's Cooldown"); + lore.add(ChatColor.GRAY+" decreases by 1 second for each successful"); + lore.add(ChatColor.GRAY+" Dodge performed."); + lore.add(ChatColor.GRAY+" "); + lore.add(ChatColor.GRAY+" (120s Cooldown)"); + break; + case PRIDE: + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:"); + lore.add(ChatColor.DARK_AQUA+" 2 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 2)+" Weapon Charges per hit"); + lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" "+ABILITY_LABEL+"Power Swing"+ABILITY_LABEL_END+" (Right-Click) provides double"); + lore.add(" "+ChatColor.WHITE+" the lifesteal stacks and increases Regeneration"); + lore.add(" "+ChatColor.WHITE+" level by "+ItemSet.GetBaseAmount(set, tier, 3)+" for 15 seconds. (Max. 10 Levels)"); + lore.add(ChatColor.DARK_AQUA+" 4 - "+ChatColor.WHITE+" "+ABILITY_LABEL+"Forceful Strike"+ABILITY_LABEL_END+" (Shift+Left-Click) applies"); + lore.add(" "+ChatColor.WHITE+" Poison "+ItemSet.GetBaseAmount(set, tier, 4)+" to everything it hits for 15 seconds."); + lore.add(ChatColor.DARK_AQUA+" 5 - "+ChatColor.WHITE+" "+ABILITY_LABEL+"Sweep Up"+ABILITY_LABEL_END+" (Shift+Right-Click) heals"); + lore.add(" "+ChatColor.WHITE+" half the health it deals as HP directly."); + lore.add(ChatColor.DARK_AQUA+" 6 - "+ChatColor.WHITE+""); + lore.add(ChatColor.WHITE+" +"+(tier*25)+"% Lifesteal"); + lore.add(ChatColor.WHITE+" +"+(tier*25)+"% Health Regeneration"); + lore.add(ChatColor.WHITE+" +"+(tier*25)+"% Maximum Health"); + break; + case PROTECTOR: + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+PlayerMode.SLAYER.getColor()+PlayerMode.SLAYER.getName()+"s"+ChatColor.GOLD+" do not benefit from party effects"); + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"of this set. "+PlayerMode.RANGER.getColor()+PlayerMode.RANGER.getName()+"s"+ChatColor.GOLD+" receive only half the effects."); + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:"); + lore.add(ChatColor.DARK_AQUA+" 2 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 2)+"% Damage Reduction to other party members"); + lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 3)+"% Health to other party members."); + lore.add(ChatColor.DARK_AQUA+" 4 - "+ABILITY_LABEL+" Reinforce"+ABILITY_LABEL_END+" - Each hit taken restores"); + lore.add(" "+ChatColor.WHITE+" "+ItemSet.GetBaseAmount(set, tier, 4)+"Health to your party members."); + lore.add(ChatColor.DARK_AQUA+" 5 - "+ABILITY_LABEL+" Unstoppable Team"+ABILITY_LABEL_END); + lore.add(ChatColor.GRAY+" Press the swap item key to channel for 1 second,"); + lore.add(ChatColor.GRAY+" creating a "+(tier*20)+" Health shield for 30"); + lore.add(ChatColor.GRAY+" seconds on all party members."); + lore.add(ChatColor.GRAY+" "); + lore.add(ChatColor.GRAY+" (150 second cooldown)"); + break; + case SHARD: + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:"); + lore.add(ChatColor.DARK_AQUA+" 2 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 2)+"% Headshot Damage"); + lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 3)+"% Critical Damage"); + lore.add(ChatColor.DARK_AQUA+" 4 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 4)+" Health"); + lore.add(ChatColor.DARK_AQUA+" 5 - "+ABILITY_LABEL+" Shrapnel Bombs"+ABILITY_LABEL_END); + lore.add(ChatColor.GRAY+" When arrows land or hit a target, they explode"); + lore.add(ChatColor.GRAY+" into shrapnel, dealing damage to all nearby targets"); + lore.add(ChatColor.GRAY+" and dealing ticks of additional fire damage for 10"); + lore.add(ChatColor.GRAY+" seconds. Shrapnel stacks infinitely on a target."); + break; + case STEALTH: + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Increases in power based on "+ChatColor.BOLD+"Total Tier Amount"); + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"of all baubles in your bauble pouch."); + lore.add(ChatColor.DARK_AQUA+" T9 - "); + lore.add(ChatColor.WHITE+" Stealth does not cause durability to decrease."); + lore.add(ChatColor.WHITE+" Stealth does not get removed when getting hit."); + if (tier>=2) { + lore.add(ChatColor.DARK_AQUA+" T18 - "); + lore.add(ChatColor.WHITE+" Going from Visible to Stealth will remove"); + lore.add(ChatColor.WHITE+" all aggro from nearby targets. While in"); + lore.add(ChatColor.WHITE+" Stealth mode, you deal 50% more damage."); + if (tier>=3) { + lore.add(ChatColor.DARK_AQUA+" T27 - "); + lore.add(ChatColor.WHITE+" Each kill gives a stack of Strength"); + lore.add(ChatColor.WHITE+" (Max. 20 stacks). Getting hit removes"); + lore.add(ChatColor.WHITE+" a level of Strength."); + if (tier>=4) { + lore.add(ChatColor.DARK_AQUA+" T40 - "); + lore.add(ChatColor.WHITE+" Recovers 1 Heart (2 HP) every 5 seconds"); + lore.add(ChatColor.WHITE+" while in Stealth mode."); + } + } + } + break; + case SUSTENANCE: + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:"); + lore.add(ChatColor.DARK_AQUA+" 2 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 2)+" Lifesteal Stacks every hit taken"); + lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 3)+" Regeneration Level per hit"); + lore.add(ChatColor.GRAY+" (Max. Regeneration "+WorldShop.toRomanNumeral(Math.min(2*tier,10))+")"); + lore.add(ChatColor.GRAY+" Decays at 1 Regeneration Level per second."); + lore.add(ChatColor.DARK_AQUA+" 4 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 4)+"% Healing per Regeneration tick"); + lore.add(ChatColor.DARK_AQUA+" 5 - "+ABILITY_LABEL+" Share the Life"+ABILITY_LABEL_END); + lore.add(ChatColor.GRAY+" Increases lifesteal stacks for other party members"); + lore.add(ChatColor.GRAY+" by "+(tier)+" whenever you get hit."); + break; + case TOXIN: + lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:"); + lore.add(ChatColor.DARK_AQUA+" 2 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 2)+"% Chance of applying Bleeding "+WorldShop.toRomanNumeral(tier)+" to target."); + lore.add(ChatColor.GRAY+" (Bleed deals faster damage over time compared to Poison."); + lore.add(ChatColor.GRAY+" it is not affected by Poison Resistance.)"); + lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 3)+"% Chance of applying Infection "+WorldShop.toRomanNumeral(tier)+" to target."); + lore.add(ChatColor.GRAY+" (Infection deals damage over time and applies all debuffs"); + lore.add(ChatColor.GRAY+" this target has to nearby targets.)"); + lore.add(ChatColor.DARK_AQUA+" 4 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 4)+"% Chance of applying Cripple "+WorldShop.toRomanNumeral(tier)+" to target."); + lore.add(ChatColor.GRAY+" (Cripple slows the target and decreases target's damage"); + lore.add(ChatColor.GRAY+" by 10% per level.)"); + lore.add(ChatColor.DARK_AQUA+" 5 - "+ABILITY_LABEL+" Fire Cesspool"+ABILITY_LABEL_END); + lore.add(ChatColor.GRAY+" Shooting arrows at the ground converts the land into"); + lore.add(ChatColor.GRAY+" a temporary fire pool, applying stacking Burn to all"); + lore.add(ChatColor.GRAY+" enemy targets in the fire pool. (Burn deals more damage"); + lore.add(ChatColor.GRAY+" as the number of stacks increase.)"); + break; } return lore; } @@ -808,7 +1047,7 @@ public enum ItemSet { } } } - TwosideKeeper.log("Offhand: "+p.getInventory().getExtraContents()[0]+";;"+item+ChatColor.RESET+"Is equal? "+p.getInventory().getExtraContents()[0].equals(item)+";; Is Bauble Pouch? "+BaublePouch.isBaublePouch(item), 5); + //TwosideKeeper.log("Offhand: "+p.getInventory().getExtraContents()[0]+";;"+item+ChatColor.RESET+"Is equal? "+p.getInventory().getExtraContents()[0].equals(item)+";; Is Bauble Pouch? "+BaublePouch.isBaublePouch(item), 5); } TwosideKeeper.log("Updated HashMap for player "+p.getName()+". New Map: \n"+TextUtils.outputHashmap(map), 5); } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/APIUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/APIUtils.java new file mode 100644 index 0000000..6b6488d --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/APIUtils.java @@ -0,0 +1,15 @@ +package sig.plugin.TwosideKeeper.HelperStructures.Utils; + +import org.bukkit.Material; + +import org.bukkit.block.Block; + +public class APIUtils { + public static boolean isExplosionProof(Block b) { + if (b!=null) { + return (aPlugin.API.isExplosionProof(b) || BlockUtils.isSign(b)); + } else { + return false; + } + } +} diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/BlockUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/BlockUtils.java index 3e43896..b97a859 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/BlockUtils.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/BlockUtils.java @@ -64,4 +64,23 @@ public class BlockUtils { } } } + + /** + * Returns if a block can be passed through by regular means (A player can get past it). + * Usually used for detecting when abilities stop. + */ + public static boolean isPassThrough(Location l) { + return l.getBlock().getType()==Material.AIR || + l.getBlock().isLiquid() || + l.getBlock().getType()==Material.STEP || + l.getBlock().getType()==Material.WOOD_STEP || + l.getBlock().getType()==Material.PURPUR_SLAB || + l.getBlock().getType()==Material.STONE_SLAB2; + } + + public static boolean isSign(Block b) { + return b.getType()==Material.SIGN || + b.getType()==Material.WALL_SIGN || + b.getType()==Material.SIGN_POST; + } } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/WorldShop.java b/src/sig/plugin/TwosideKeeper/HelperStructures/WorldShop.java index b5c3f25..a1550f2 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/WorldShop.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/WorldShop.java @@ -838,7 +838,7 @@ public class WorldShop { } public static boolean isWorldShopSign(Block b) { - if (b!=null && (b.getType()==Material.SIGN || b.getType()==Material.WALL_SIGN || b.getType()==Material.SIGN_POST) && b.getState() instanceof Sign) { + if (b!=null && BlockUtils.isSign(b) && b.getState() instanceof Sign) { Sign s = (Sign)b.getState(); return isWorldShopSign(s); } else { diff --git a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java index 3dcfc15..4fdfbf1 100644 --- a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java +++ b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java @@ -244,8 +244,11 @@ import sig.plugin.TwosideKeeper.HelperStructures.Common.RecipeCategory; import sig.plugin.TwosideKeeper.HelperStructures.Common.RecipeLinker; import sig.plugin.TwosideKeeper.HelperStructures.Effects.EarthWaveTask; import sig.plugin.TwosideKeeper.HelperStructures.Effects.LavaPlume; +import sig.plugin.TwosideKeeper.HelperStructures.Effects.ReplaceBlockTask; +import sig.plugin.TwosideKeeper.HelperStructures.Effects.TemporaryBlock; import sig.plugin.TwosideKeeper.HelperStructures.Effects.TemporaryIce; import sig.plugin.TwosideKeeper.HelperStructures.Effects.TemporaryLava; +import sig.plugin.TwosideKeeper.HelperStructures.Effects.WindSlash; import sig.plugin.TwosideKeeper.HelperStructures.Utils.ArrayUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.ArtifactUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.BlockUtils; @@ -255,6 +258,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.Utils.ItemCubeUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.ItemUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.MessageUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.SoundUtils; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.TextUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.TimeUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.SoundData; import sig.plugin.TwosideKeeper.HolidayEvents.Christmas; @@ -488,6 +492,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { public static List jobrecipes = new ArrayList(); public static List cameras = new ArrayList(); public static List arenas = new ArrayList(); + public static List windslashes = new ArrayList(); + public static HashMap temporaryblocks = new HashMap(); //public static stats StatCommand = new stats(); @@ -851,6 +857,12 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } TwosideKeeper.HeartbeatLogger.AddEntry("Temporary Camera Handling", (int)(System.nanoTime()-time));time=System.nanoTime(); + for (WindSlash slash : windslashes) { + if (!slash.runTick()) { + ScheduleRemoval(windslashes,slash); + } + } + TwosideKeeper.HeartbeatLogger.AddEntry("Temporary Wind Slash Handling", (int)(System.nanoTime()-time));time=System.nanoTime(); if ((int)(System.nanoTime()-totaltime)/1000000d>50) { TwosideKeeper.log("WARNING! Structure Handling took longer than 1 tick! "+((int)(System.nanoTime()-totaltime)/1000000d)+"ms", 0); } @@ -1180,6 +1192,13 @@ public class TwosideKeeper extends JavaPlugin implements Listener { arena.Cleanup(); } log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-betweentime)+"ms",CLEANUP_DEBUG); + betweentime = System.currentTimeMillis(); + log("Cleaning up TemporaryBlocks ["+temporaryblocks.size()+"]",CLEANUP_DEBUG); + for (String ss : temporaryblocks.keySet()) { + TemporaryBlock tb = temporaryblocks.get(ss); + ReplaceBlockTask.CleanupTemporaryBlock(tb); + } + log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-betweentime)+"ms",CLEANUP_DEBUG); long endtime = System.currentTimeMillis(); log("Cleanup Maintenance completed. Total Time: "+(endtime-starttime)+"ms.",CLEANUP_DEBUG); } @@ -1848,6 +1867,25 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } }break; + case "TESTSLASH":{ + windslashes.add(new WindSlash(p.getLocation().add(0,p.getEyeHeight(),0),p,10,200)); + }break; + case "TEMPBLOCK":{ + for (int i=-5;i<=5;i++) { + for (int j=-5;j<=5;j++) { + new TemporaryBlock(p.getLocation().getBlock().getRelative(i, 0, j),Material.STAINED_GLASS,(byte)6,200,"TEST"); + } + } + //new TemporaryBlock(p.getLocation().getBlock(),Material.STAINED_GLASS,(byte)6,200,"TEST"); + }break; + case "TEMPBLOCK_TEST":{ + TwosideKeeper.log("Is temporary block? "+TemporaryBlock.isTemporaryBlock(p.getLocation().getBlock()), 0); + TwosideKeeper.log("Is on special block? "+TemporaryBlock.isStandingOnSpecialBlock(p, "TEST"),0); + TwosideKeeper.log("Range of special block? "+TemporaryBlock.isInRangeOfSpecialBlock(p,5,"TEST"), 0); + TwosideKeeper.log("Range of fake special block? "+TemporaryBlock.isInRangeOfSpecialBlock(p,5,"TEST2"), 0); + //new TemporaryBlock(p.getLocation().getBlock(),Material.STAINED_GLASS,(byte)6,200,"TEST"); + //TwosideKeeper.log(TextUtils.outputHashmap(TwosideKeeper.temporaryblocks), 0); + }break; } } @@ -4978,7 +5016,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } }*/ - + ItemSet.updateItemSets(ev.getPlayer()); return; } @@ -6828,6 +6866,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener { @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) public void monsterDeathEvent(final EntityDeathEvent ev) { log("Has died.",5); + if (ev.getEntity() instanceof Player) { + return; //We do not handle players in here!! + } if (livingentitydata.containsKey(ev.getEntity().getUniqueId())){ev.setDroppedExp(ev.getDroppedExp()+5);} if (ev.getEntity() instanceof Snowman) { Snowman snowy = (Snowman)ev.getEntity(); @@ -7732,6 +7773,11 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } } + + if (TemporaryBlock.isTemporaryBlock(ev.getBlock())) { + ev.setCancelled(true); + return; + } } @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true)