->Server is now backed up with an Incremental Backup system. This allows

recovery of lost data down to an hour in precision if anything were to
go wrong without using ridiculous amounts of hard drive space.
->Gladomain Lifesaver cooldown increased from 3 minutes -> 5 minutes.
->Critical Chance % on Moonshadow's set base crit increased from
10%->15%, crit increase per tier 5%->7%.
->All damage that is meant to be true damage in Minecraft once again
deals true damage. This includes Poison, Wither, Fall Damage, Fire
Damage, Void Damage, Contact, Suffocation, Falling Blocks.
->Fixed a bug where players leaving and rejoining would cause all glows
to become white due to not properly resetting glow color.
->Fixed a bug where some damage events did not use custom death
messages.
->Added isArrowQuiver() and getArrowQuiverContents() to API.
->'Greed' artifact ability now has a chance to knock off per kill. The
chance a level of Greed gets knocked off has been increased
significantly.
->Wolfsbane and Alustine sets added to the Slayer set arsenal. Both of
these are weaker tiers of Moonshadow and Gladomain, but have their own
unique properties.
->Gladomain and Moonshadow sets drop at Hellfire and Deadly tiers
respectively now.
->Dawntracker main stat changed from Health to "Health taken per hit",
going down with higher tiers.
->Dawntracker 4-piece set bonus changed from Damage bonus to Health
bonus.
->Panros base Damage stat buffed significantly.
->Jamdak 4-Piece set bonus now grants absorption health for each
successful dodge.
->Lorasaadi Damage set bonus values significantly increased.
->Custom arrow damage has been changed from a multiplier to a flat
damage bonus. Diamond-Tipped arrows increase base damage by 15,
Hand-made arrows increase base damage by 5.
->Explosion arrow base damage increased from 40 -> 60 damage.
->Piercing arrows have been added. Piercing arrows provide similar
damage to Handmade arrows, but have infinite speed and hits all targets
aimed in a line. See /craft for the crafting recipe.

->Arrow Quivers have been redone. All old item quivers will
automatically convert to the new type. Arrow Quivers only shoot from
your off-hand now.
--- When Arrow Quivers are equipped in the off-hand, you can press the
'swap items' key to change which arrow is fired from the Arrow Quiver's
inventory. In addition, you can hold shift while pressing the 'swap' key
to toggle the opposite way.
--- Arrow Quiver modes will automatically switch when you run out of
arrows in one mode.
--- Collecting arrows will attempt to place them back in your arrow
quiver's inventory if possible.
--- Right-clicking Arrow Quivers will pull up to 64 arrows at a time
from your Arrow Quiver's current mode.
--- Shift-Clicking a Quiver when not holding anything in your off-hand
will now automatically equip it there.

->Custom Arrows work with the Infinity enchantment! For each level of
Infinity, there's a 10% increased chance of the arrow remaining in your
inventory when fired. This applies to all non-standard arrows.
->Custom Tipped Arrows display their duration properly when linked now.
->The chance of Infinity getting knocked off of a Bow has been increased
significantly.
->Rangers can now hold either a Bow or a Quiver in either hand to be
considered in Ranger mode.
->Rangers now have an active ability for Sniping and Debilitation mode
as well.
--- Sniping Mode Active: Arrow Barrage - 2 Minute Cooldown: The player
becomes still as they fire 26 piercing shots extremely quickly in the
direction they are facing. All arrows from Arrow Barrage ignore no
damage ticks.
--- Debilitation Mode Active: Siphon - 35 Second Cooldown: Can be used
when at least 1 poisoned target is nearby. Deals (Poison Level x 10)
True Damage and Slows all targets the same level as the number of poison
stacks applied to nearby targets for 15 seconds, and grants 4 Absorption
health (2 hearts) to the Ranger per poison stack. Refreshes Poison
duration on all nearby poisoned targets.
->Toggling between Bow modes shows the proper cooldown for that mode.
->Base Dodge Chance increased on all Ranger Set Pieces.
->Important Action Bar messages now have priority over the auto-updating
action bar buff indicator to make action bar sensitive actions more
clear.
->The Absorption Potion Effect now re-applies all base absorption hearts
once every 30 seconds.
->Future Life Vial drops have Absorption effect nerfs applied
appropriately.
->Hellfire Spiders now have a cooldown on their Web Throw. (4 seconds)
->Higher tier Cave Spiders (which do not naturally spawn yet) will apply
Poison 3 (Dangerous), Poison 4 (Deadly), or Poison 5 (Hellfire).
->Higher tier Wither Skeletons will apply Wither 3 (Dangerous), Wither 4
(Deadly), or Wither 5 (Hellfire).
->Hits made with Highwinder now stay on-screen for a moment, allowing
you to see how much the last damage value from Highwinder was.
->Buying back or picking up a shield when not holding anything will
automatically place the shield in your holding hand instead of your
off-hand, putting you in Defender mode.
->Buying back or picking up a quiver will automatically place it in your
off-hand if nothing is already there.
->All buff displays now show up as regular numbers instead of roman
numerals.
->Monster AI has been improved to no longer get stuck while being
directly in front of you.
->Wither Skeletons that spawn in the Nether now have a very high chance
of being Deadly or Hellfire tier.

Barbarian Mode has been released!
==============
->Defined by wielding an axe in both the main hand and the offhand.
->Barbarians swing their off-hand by right-clicking.
->Barbarians gain 2 HP (1 Heart) per 1% of Damage reduction.
->When Barbarians are hit, they take damage as if they had 0% Damage
reduction.
->Barbarians deal 20% more damage for every 20% of an enemy's missing
health.
->Barbarians gain Bonus Lifesteal stacks as they hit enemies. Each stack
increases Lifesteal by 1%, up to a cap of 100% extra Lifesteal. The
stacks refresh every hit, but wear off after 5 seconds.
->Barbarians do not instantly take full damage when hit. Instead, the HP
is stored in a 'Damage Pool' and distributed every second.
->If Barbarians have points in their 'Damage Pool', they will take up to
15 damage every second. The amount taken goes down by wearing Barbarian
gear.
->When a monster is killed by a Barbarian, the amount of remaining
damage in their Damage Pool is divided by 4.
->Barbarians automatically consume Rotten Flesh and Spider Eyes that are
picked up. Each one heals for 1% of their health. Rotten Flesh and
Spider Eyes in a Barbarian's inventory will automatically be consumed as
the Barbarian gets hungry.
->Barbarians build up Weapon Charges in two ways: +1 Charge for
attacking an enemy with the main hand weapon and +2 Charges for taking
damage.
->Barbarians have 70% knockback resistance.
->Barbarians can release their Weapon Charges by using a variety of
commands:
->Right-Click (Costs 10 Charges): Power Swing - Swing your off-hand
weapon to deal an attack with +100% Lifesteal and +100% Crit Chance
bonus. Gives 10 Bonus Lifesteal stacks.
->Shift Left-Click (Costs 30 Charges): Forceful Strike - Hit all enemies
in a line in front of you, dealing double damage and suppressing them
for 3 seconds.
->Shift Right-Click (Costs 30 Charges): Sweep Up - Performs a sweeping
attack which knocks up and damages all enemies within a 4m radius of
you. Doubles your Bonus Lifesteal stacks. Lifesteal effects are doubled
during this attack.
->Swap Item Key (100 Charges Minimum, Costs ALL Charges): Barbarian's
Rage - Converts your missing health into Absorption Hearts and applies
powerful buffs. This ability is stronger the more stacks consumed.
	Barbarian's Rage: 
	-- Strength Level: +1 per 10 charges
	-- LifeSteal: +1% per 2 charges
	-- Speed V
	-- 100% Knockback Resistance
	-- Duration of Rage: +1 second per 10 charges
	-- +2 seconds of invulnerability per 100 charges
	During Rage you gain double the number of Bonus Lifesteal stacks. You
do not gain Weapon Charges during Barbarian's Rage.
->Leaping Strike: Barbarians that take fall damage deal triple the
damage taken from the fall as damage to all enemies nearby. The range of
this attack increases based on how fast the Barbarian falls.
->Mock: Press the drop key to perform a Mock attack to all enemies near
you. Affected enemies become aggro'd to the Barbarian for 15 seconds and
receive 2 stacks of Weakness that lasts 15 seconds. This can stack up to
Weakness VI. 20 second cooldown.


->Fixed a bug where overworld Enderman would deal damage equal to an End
Enderman.
->Fixed a bug where certain monsters that were suppressed still
performed attacks.
->Fixed a bug where Slayers would get the remove stealth effect / sound
for every single hit regardless if they were stealthed or not.
->Fixed a bug allowing Slayers to perform Assassinate on dead targets.
->Fixed a bug where deaths would not keep your inventory, leading to
dropped items on the ground and nothing to buy back.
->Fixed a bug causing the Yellow Glass to not consistently appear when
an Elite Zombie performs the Leap attack.
->Fixed a bug causing regular arrow shots from bows to always hit
targets when looking at them, regardless if you are actually aiming the
arrow properly or not.
->Fixed a bug preventing players from being hit by multiple unique
damage sources at the same time.
->Fixed a bug causing Debilitation mode to not apply the first stack of
poison with a normal hit. (Clarification: Only further stacks of poison
require headshots.)
->Fixed a bug where mobs would ignore aggro rules when hitting each
other.
->Added convertPotionEffectsToLore() to API.
->Added PlayerTumbleEvent() for plugin event listening. - Called each
time a player performs Tumble. Cancellable.
->Added PlayerDodgeEvent() for plugin event listening. - Called each
time a player successfully dodges an attack. Cancellable.
->Added PlayerLineDriveEvent() for plugin event listening. - Called each
time a player performs a Line Drive. Cancellable.
dev
sigonasr2 9 years ago
parent 77efdd3fcc
commit 18aff61a01
  1. BIN
      TwosideKeeper.jar
  2. 2
      src/plugin.yml
  3. 26
      src/sig/plugin/TwosideKeeper/ActionBarBuffUpdater.java
  4. 26
      src/sig/plugin/TwosideKeeper/Boss/EliteZombie.java
  5. 436
      src/sig/plugin/TwosideKeeper/CustomDamage.java
  6. 8
      src/sig/plugin/TwosideKeeper/Drops/SigDrop.java
  7. 60
      src/sig/plugin/TwosideKeeper/Events/PlayerDodgeEvent.java
  8. 40
      src/sig/plugin/TwosideKeeper/Events/PlayerLineDriveEvent.java
  9. 40
      src/sig/plugin/TwosideKeeper/Events/PlayerTumbleEvent.java
  10. 35
      src/sig/plugin/TwosideKeeper/HelperStructures/ArrowBarrage.java
  11. 307
      src/sig/plugin/TwosideKeeper/HelperStructures/Common/ArrowQuiver.java
  12. 472
      src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java
  13. 6
      src/sig/plugin/TwosideKeeper/HelperStructures/Common/RecipeLinker.java
  14. 91
      src/sig/plugin/TwosideKeeper/HelperStructures/CustomItem.java
  15. 23
      src/sig/plugin/TwosideKeeper/HelperStructures/ItemSet.java
  16. 47
      src/sig/plugin/TwosideKeeper/HelperStructures/MonsterDifficulty.java
  17. 58
      src/sig/plugin/TwosideKeeper/HelperStructures/PlayerMode.java
  18. 12
      src/sig/plugin/TwosideKeeper/HelperStructures/Pronouns.java
  19. 84
      src/sig/plugin/TwosideKeeper/HelperStructures/WorldShop.java
  20. 1
      src/sig/plugin/TwosideKeeper/LivingEntityStructure.java
  21. 2
      src/sig/plugin/TwosideKeeper/MonsterController.java
  22. 15
      src/sig/plugin/TwosideKeeper/PlayerStructure.java
  23. 29
      src/sig/plugin/TwosideKeeper/Recipes.java
  24. 1063
      src/sig/plugin/TwosideKeeper/TwosideKeeper.java
  25. 9
      src/sig/plugin/TwosideKeeper/TwosideKeeperAPI.java
  26. 2
      src/sig/plugin/TwosideKeeper/WorldShopManager.java
  27. 64
      src/sig/plugin/TwosideKeeper/runServerHeartbeat.java

Binary file not shown.

@ -1,6 +1,6 @@
name: TwosideKeeper
main: sig.plugin.TwosideKeeper.TwosideKeeper
version: 3.8.6d
version: 3.9.0
commands:
money:
description: Tells the player the amount of money they are holding.

@ -17,6 +17,7 @@ public class ActionBarBuffUpdater{
actionbardisplay.append(ParseEffect(p,pe));
}
}
actionbardisplay.append(AddAdditionalEffects(p));
if (actionbardisplay.toString().contains(" ")) {
return actionbardisplay.toString().substring(0, actionbardisplay.toString().lastIndexOf(" "));
} else {
@ -24,6 +25,29 @@ public class ActionBarBuffUpdater{
}
}
private static String AddAdditionalEffects(LivingEntity p) {
StringBuilder effectString=new StringBuilder("");
if (p instanceof Player) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure((Player)p);
if (pd.lifestealstacks>4) {
effectString.append(ChatColor.AQUA+"❣");
effectString.append(AppendAmplifier(pd.lifestealstacks-1));
effectString.append(" ");
}
if (pd.weaponcharges>4) {
effectString.append(ChatColor.DARK_AQUA+"☤");
effectString.append(AppendAmplifier(pd.weaponcharges-1));
effectString.append(" ");
}
if (pd.damagepool>4) {
effectString.append(ChatColor.DARK_PURPLE+"♥");
effectString.append(AppendAmplifier((int)(pd.damagepool-1)));
effectString.append(" ");
}
}
return effectString.toString()+ChatColor.RESET;
}
private static String ParseEffect(LivingEntity p, PotionEffect pe) {
StringBuilder effectString=new StringBuilder("");
PotionEffectType pet = pe.getType();
@ -65,7 +89,7 @@ public class ActionBarBuffUpdater{
private static String AppendAmplifier(int amplifier) {
StringBuilder amp = new StringBuilder(" ");
amp.append(ChatColor.GRAY+WorldShop.toRomanNumeral(amplifier+1));
amp.append(ChatColor.GRAY+""+(amplifier+1));
return amp.toString();
}

@ -61,6 +61,7 @@ public class EliteZombie extends EliteMonster{
double storingenergy_hit=0;
Location target_leap_loc = null;
HashMap<Block,Material> storedblocks = new HashMap<Block,Material>();
HashMap<Block,Byte> storedblockdata = new HashMap<Block,Byte>();
public EliteZombie(Monster m) {
super(m);
@ -482,8 +483,24 @@ public class EliteZombie extends EliteMonster{
for (int x=-radius;x<radius+1;x++) {
for (int z=-radius;z<radius+1;z++) {
Block b = target.getLocation().add(x,-0.9,z).getBlock();
if (b.getType()!=Material.AIR && b.getType()!=Material.STAINED_GLASS && aPlugin.API.isExplosionProof(b)) {
storedblocks.put(b, b.getType());
int origy = b.getLocation().getBlockY();
while ((b.getType()==Material.AIR ^ b.isLiquid()) || (b.getRelative(0, 1, 0).getType()!=Material.AIR && !b.getRelative(0,1,0).isLiquid())
&& b.getLocation().getBlockY()>0) {
if (b.getRelative(0, 1, 0).getType()!=Material.AIR && !b.getRelative(0,1,0).isLiquid()) {
b = b.getRelative(0, 1, 0); //Try going up, not down.
} else {
b = b.getRelative(0, -1, 0);
}
if (Math.abs(b.getLocation().getBlockY()-origy)>4) {
break;
}
}
TwosideKeeper.log("Selected block "+b.toString(), 5);
if (!aPlugin.API.isExplosionProof(b) && b.getType()!=Material.STAINED_GLASS) {
Material type = b.getType();
Byte data = b.getData();
storedblocks.put(b, type);
storedblockdata.put(b, data);
b.setType(Material.STAINED_GLASS);
b.setData((byte)4);
}
@ -500,11 +517,10 @@ public class EliteZombie extends EliteMonster{
private void restoreBlocks() {
for (Block b : storedblocks.keySet()) {
if (b.getType()!=Material.AIR && aPlugin.API.isDestroyable(b) && GenericFunctions.isSoftBlock(b)) {
FallingBlock fb = (FallingBlock)b.getLocation().getWorld().spawnFallingBlock(b.getLocation(), storedblocks.get(b), b.getData());
if (GenericFunctions.isSoftBlock(storedblocks.get(b))) {
FallingBlock fb = (FallingBlock)b.getLocation().getWorld().spawnFallingBlock(b.getLocation(), storedblocks.get(b), storedblockdata.get(b));
fb.setMetadata("FAKE", new FixedMetadataValue(TwosideKeeper.plugin,true));
fb.setVelocity(new Vector(0,Math.random()*1.7,0));
//b.setType(storedblocks.get(b));
b.setType(Material.AIR);
} else {
b.setType(storedblocks.get(b));

@ -14,6 +14,8 @@ import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Blaze;
import org.bukkit.entity.CaveSpider;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity;
@ -24,18 +26,23 @@ import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Snowball;
import org.bukkit.entity.SpectralArrow;
import org.bukkit.entity.Spider;
import org.bukkit.entity.TippedArrow;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
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 sig.plugin.TwosideKeeper.Events.PlayerDodgeEvent;
import sig.plugin.TwosideKeeper.HelperStructures.ArtifactAbility;
import sig.plugin.TwosideKeeper.HelperStructures.BowMode;
import sig.plugin.TwosideKeeper.HelperStructures.ItemSet;
@ -104,7 +111,7 @@ public class CustomDamage {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
pd.lasthitproperties=NONE;
}
if (!InvulnerableCheck(damager,target,flags)) {
if (!InvulnerableCheck(damager,target,reason,flags)) {
double dmg = 0.0;
if (isFlagSet(flags,TRUEDMG)) {
if (reason!=null) {
@ -146,12 +153,12 @@ public class CustomDamage {
if (weapon.getType()==Material.BOW) {
if ((damager instanceof Projectile)) {
TwosideKeeper.log("This is a projectile! Reason: "+reason+", Damager: "+damager.toString(), 2);
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;
dmg += addMultiplierToPlayerLogger(damager,target,"Bow Drawback Mult",dmg * calculateBowDrawbackMultiplier(weapon,damager,target));
dmg += addMultiplierToPlayerLogger(damager,target,"Custom Arrow Mult",dmg * calculateCustomArrowMultiplier(weapon,damager,target));
}
}
} else {
@ -186,6 +193,9 @@ public class CustomDamage {
dmg += addToPlayerLogger(damager,target,"Execute",(((GenericFunctions.getAbilityValue(ArtifactAbility.EXECUTION, weapon)*5.0)*(1-(target.getHealth()/target.getMaxHealth())))));
if (shooter instanceof Player) {
dmg += addToPlayerLogger(damager,target,"Execute Set Bonus",(((ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(shooter),(Player)shooter, ItemSet.LORASAADI, 4, 4)*5.0)*(1-(target.getHealth()/target.getMaxHealth())))));
if (PlayerMode.getPlayerMode((Player)shooter)==PlayerMode.BARBARIAN) {
dmg += addMultiplierToPlayerLogger(damager,target,"Barbarian Execute Mult",dmg * (1-(target.getHealth()/target.getMaxHealth())));
}
}
dmg += addMultiplierToPlayerLogger(damager,target,"Striker Mult",dmg * calculateStrikerMultiplier(shooter,target));
double preemptivedmg = addMultiplierToPlayerLogger(damager,target,"Preemptive Strike Mult",dmg * calculatePreemptiveStrikeMultiplier(target,shooter));
@ -198,14 +208,22 @@ public class CustomDamage {
dmg += addMultiplierToPlayerLogger(damager,target,"STRENGTH Mult",dmg * calculateStrengthEffectMultiplier(shooter,target));
dmg += addMultiplierToPlayerLogger(damager,target,"WEAKNESS Mult",dmg * calculateWeaknessEffectMultiplier(shooter,target));
dmg += addMultiplierToPlayerLogger(damager,target,"POISON Mult",dmg * calculatePoisonEffectMultiplier(target));
double critdmg = addMultiplierToPlayerLogger(damager,target,"Critical Strike Mult",dmg * calculateCriticalStrikeMultiplier(weapon,shooter,target,flags));
double critdmg = addMultiplierToPlayerLogger(damager,target,"Critical Strike Mult",dmg * calculateCriticalStrikeMultiplier(weapon,shooter,target,reason,flags));
if (critdmg!=0.0) {crit=true;
aPlugin.API.critEntity(target, 15);}
dmg += critdmg;
double armorpendmg = addToPlayerLogger(damager,target,"Armor Pen",calculateArmorPen(damager,dmg,weapon));
addToLoggerActual(damager,dmg);
addToPlayerRawDamage(dmg,target);
if (!isFlagSet(flags, TRUEDMG)) {dmg = CalculateDamageReduction(dmg-armorpendmg,target,damager);}
if (!isFlagSet(flags, TRUEDMG)) {
if (target instanceof Player) {
if (PlayerMode.getPlayerMode((Player)target)!=PlayerMode.BARBARIAN) {
dmg = CalculateDamageReduction(dmg-armorpendmg,target,damager);
}
} else {
dmg = CalculateDamageReduction(dmg-armorpendmg,target,damager);
}
}
TwosideKeeper.log("Damage: "+dmg+", Armor Pen Damage: "+armorpendmg, 3);
setupDamagePropertiesForPlayer(damager,((crit)?IS_CRIT:0)|((headshot)?IS_HEADSHOT:0)|((preemptive)?IS_PREEMPTIVE:0));
dmg = hardCapDamage(dmg+armorpendmg);
@ -341,6 +359,12 @@ public class CustomDamage {
}
}
}
if (getDamagerEntity(damager) instanceof CaveSpider) {
applyCaveSpiderPoison(damager, p);
}
if (getDamagerEntity(damager) instanceof Skeleton) {
applyWitherSkeletonWither(damager, p);
}
if (getDamagerEntity(damager) instanceof LivingEntity) {
LivingEntity m = getDamagerEntity(damager);
LivingEntityStructure md = LivingEntityStructure.getLivingEntityStructure(m);
@ -348,7 +372,7 @@ public class CustomDamage {
}
increaseStrikerSpeed(p);
healDefenderSaturation(p);
reduceDefenderKnockback(p);
reduceKnockback(p);
reduceSwiftAegisBuff(p);
if (damage<p.getHealth()) {increaseArtifactArmorXP(p,(int)damage);}
aPlugin.API.showDamage(target, GetHeartAmount(damage));
@ -370,12 +394,15 @@ public class CustomDamage {
GenericFunctions.removeStealth(p);
}
}
increaseBarbarianCharges(p);
pd.slayermegahit=false;
pd.lastcombat=TwosideKeeper.getServerTickTime();
pd.lasthitdesc=reason;
damage = calculateDefenderAbsorption(p, damager, damage);
damage = sendDamageToDamagePool(p, damage, reason);
if (GenericFunctions.AttemptRevive(p, damage, reason)) {
damage=0;
}
@ -390,7 +417,7 @@ public class CustomDamage {
//Create an explosion.
TwosideKeeper.log("In here", 5);
Location hitloc = aPlugin.API.getArrowHitLocation(target, a);
GenericFunctions.DealExplosionDamageToEntities(hitloc, getBaseWeaponDamage(weapon,damager,target)+80, 6);
GenericFunctions.DealExplosionDamageToEntities(hitloc, getBaseWeaponDamage(weapon,damager,target)+60, 6);
p.playSound(hitloc, Sound.ENTITY_ENDERDRAGON_FIREBALL_EXPLODE, 0.5f, 1.0f);
aPlugin.API.sendSoundlessExplosion(hitloc, 2);
}
@ -466,13 +493,17 @@ public class CustomDamage {
removePermEnchantments(p,weapon);
//GenericFunctions.knockOffGreed(p);
castEruption(p,target,weapon);
addHealthFromLifesteal(p,damage,weapon);
addHealthFromLifesteal(p,damage,weapon,reason);
triggerEliteHitEvent(p,target,damage);
subtractWeaponDurability(p,weapon);
aPlugin.API.showDamage(target, GetHeartAmount(damage));
suppressTarget(p,weapon,target);
causeSpetralGlowAndAggro(damager,p,target);
removeExperienceFromAlustineSetBonus(p);
pd.slayermegahit=false;
pd.lastcombat=TwosideKeeper.getServerTickTime();
increaseBarbarianStacks(p,weapon);
damage = applyBarbarianBonuses(p,target,weapon,damage,reason);
if (PlayerMode.getPlayerMode(p)==PlayerMode.SLAYER) {
if (isFlagSet(pd.lasthitproperties,IS_CRIT)) {
@ -488,6 +519,9 @@ public class CustomDamage {
p.setHealth(pd.slayermodehp);
}
}
if (ItemSet.HasSetBonusBasedOnSetBonusCount(GenericFunctions.getHotbarItems(p), p, ItemSet.ALUSTINE, 5)) {
GenericFunctions.spawnXP(target.getLocation(), (int)ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getHotbarItems(p), p, ItemSet.ALUSTINE, 5, 4));
}
}
}
if (ItemSet.HasSetBonusBasedOnSetBonusCount(GenericFunctions.getHotbarItems(p), p, ItemSet.MOONSHADOW, 2)) {
@ -513,9 +547,205 @@ public class CustomDamage {
triggerEliteBreakEvent(target);
}
}
if (target!=null && damager instanceof Arrow) {
Arrow proj = (Arrow)damager;
if (proj.hasMetadata("TIPPED_ARROW")) {
String effects = proj.getMetadata("TIPPED_ARROW").get(0).asString();
for (String vals : effects.split(";")) {
String[] pieces = vals.split(",");
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.getByName(pieces[0]),Integer.parseInt(pieces[1]),Integer.parseInt(pieces[2])/8, target);
}
}
if (proj.hasMetadata("BASE_ARROW")) {
String[] pieces = proj.getMetadata("BASE_ARROW").get(0).asString().split(",");
PotionEffectType type = GenericFunctions.convertPotionTypeToPotionEffectType(PotionType.valueOf(pieces[0]));
PotionData pd = new PotionData(PotionType.valueOf(pieces[0]),Boolean.parseBoolean(pieces[1]),Boolean.parseBoolean(pieces[2]));
if (pd.getType()!=PotionType.WATER) {
GenericFunctions.logAndApplyPotionEffectToEntity(type,GenericFunctions.getBasePotionDuration(pd)/8, (pd.isUpgraded())?1:0, target);
}
}
}
return damage;
}
private static void applyWitherSkeletonWither(Entity damager, Player p) {
Skeleton sk = (Skeleton)getDamagerEntity(damager);
if (sk.getSkeletonType()==SkeletonType.WITHER) {
int witherlv=1;
MonsterDifficulty md = MonsterController.getMonsterDifficulty(sk);
if (md.equals(MonsterDifficulty.DANGEROUS)) {
witherlv=2;
} else
if (md.equals(MonsterDifficulty.DEADLY)) {
witherlv=3;
} else
if (md.equals(MonsterDifficulty.HELLFIRE)) {
witherlv=4;
} else
if (md.equals(MonsterDifficulty.END)) {
witherlv=5;
} else
if (md.equals(MonsterDifficulty.ELITE)) {
witherlv=9;
} else
if (p.hasPotionEffect(PotionEffectType.WITHER)) {
int currentWITHERlv = GenericFunctions.getPotionEffectLevel(PotionEffectType.WITHER, p);
if (currentWITHERlv<witherlv) {
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.WITHER, 20*20, witherlv, p, true);
} else { //Refresh it.
if (GenericFunctions.getPotionEffectDuration(PotionEffectType.WITHER, p)<(20*20)) {
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.WITHER, 20*20, currentWITHERlv, p, true);
}
}
} else {
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.WITHER, 20*20, witherlv, p, true);
}
}
}
public static void applyCaveSpiderPoison(Entity damager, Player p) {
int poisonlv=1;
MonsterDifficulty md = MonsterController.getMonsterDifficulty((CaveSpider)getDamagerEntity(damager));
if (md.equals(MonsterDifficulty.DANGEROUS)) {
poisonlv=2;
} else
if (md.equals(MonsterDifficulty.DEADLY)) {
poisonlv=3;
} else
if (md.equals(MonsterDifficulty.HELLFIRE)) {
poisonlv=4;
} else
if (md.equals(MonsterDifficulty.END)) {
poisonlv=5;
} else
if (md.equals(MonsterDifficulty.ELITE)) {
poisonlv=9;
} else
if (p.hasPotionEffect(PotionEffectType.POISON)) {
int currentpoisonlv = GenericFunctions.getPotionEffectLevel(PotionEffectType.POISON, p);
if (currentpoisonlv<poisonlv) {
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.POISON, 20*20, poisonlv, p, true);
} else { //Refresh it.
if (GenericFunctions.getPotionEffectDuration(PotionEffectType.POISON, p)<(20*20)) {
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.POISON, 20*20, currentpoisonlv, p, true);
}
}
} else {
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.POISON, 20*20, poisonlv, p, true);
}
}
private static double applyBarbarianBonuses(Player p, LivingEntity target, ItemStack weapon, double dmg, String reason) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (PlayerMode.getPlayerMode(p)==PlayerMode.BARBARIAN) {
if (reason!=null) {
if (reason.equalsIgnoreCase("power swing")) {
IncreaseLifestealStacks(p,10);
pd.weaponcharges-=10;
GenericFunctions.sendActionBarMessage(p, "");
}
}
if (p.isSneaking() && pd.weaponcharges>=30 && (reason==null || !reason.equalsIgnoreCase("forceful strike")) &&
weapon.equals(p.getEquipment().getItemInMainHand())) {
p.playSound(p.getLocation(), Sound.BLOCK_WOOD_BUTTON_CLICK_ON, 3.0f, 0.6f);
//Apply 10 strikes across the field.
dmg*=2;
GenericFunctions.addSuppressionTime(target, 20*3);
double xspd=p.getLocation().getDirection().getX();
double zspd=p.getLocation().getDirection().getZ();
Location attackloc = p.getLocation().clone();
for (int i=0;i<10;i++) {
attackloc = attackloc.add(xspd,0,zspd);
p.playSound(p.getLocation(), Sound.ENTITY_ENDERDRAGON_FIREBALL_EXPLODE, 0.1f, 1.4f);
aPlugin.API.sendSoundlessExplosion(attackloc, 0.6f);
GenericFunctions.DealDamageToNearbyMobs(attackloc, dmg, 1, true, 0.6, p, weapon, false, "Forceful Strike");
}
pd.weaponcharges-=30;
GenericFunctions.sendActionBarMessage(p, "");
}
}
return dmg;
}
private static void increaseBarbarianCharges(Player p) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (PlayerMode.getPlayerMode(p)==PlayerMode.BARBARIAN) {
IncreaseWeaponCharges(p,2);
}
}
public static void IncreaseWeaponCharges(Player p, int amt) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (pd.rage_time<=TwosideKeeper.getServerTickTime()) {
pd.weaponcharges+=amt;
GenericFunctions.sendActionBarMessage(p, "");
}
}
public static void IncreaseLifestealStacks(Player p, int amt) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
pd.lifestealstacks=Math.min(100,pd.lifestealstacks+amt*((pd.rage_time>TwosideKeeper.getServerTickTime())?2:1));
GenericFunctions.sendActionBarMessage(p, "");
}
private static double sendDamageToDamagePool(Player p, double damage, String reason) {
if (reason==null || !reason.equalsIgnoreCase("damage pool")) {
if (PlayerMode.getPlayerMode(p)==PlayerMode.BARBARIAN) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (pd.damagepool==0) {
pd.damagepooltime=TwosideKeeper.getServerTickTime();
}
if (damage>getTransferDamage(p)) {
pd.damagepool+=damage-getTransferDamage(p);
return getTransferDamage(p);
} else {
pd.damagepool=0;
return damage;
}
} else {
if (damage>GetDamageReductionFromDawntrackerPieces(p)) {
return damage-GetDamageReductionFromDawntrackerPieces(p);
} else {
return 0;
}
}
}
return damage;
}
private static void increaseBarbarianStacks(Player p, ItemStack weapon) {
if (PlayerMode.getPlayerMode(p)==PlayerMode.BARBARIAN) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (pd.rage_time>TwosideKeeper.getServerTickTime()) {
IncreaseLifestealStacks(p,2);
} else {
IncreaseLifestealStacks(p,1);
}
pd.lastattacked=TwosideKeeper.getServerTickTime();
if (p.getEquipment().getItemInMainHand().equals(weapon)) {
IncreaseWeaponCharges(p,1);
}
}
}
private static void removeExperienceFromAlustineSetBonus(Player p) {
if (ItemSet.HasSetBonusBasedOnSetBonusCount(GenericFunctions.getHotbarItems(p), p, ItemSet.ALUSTINE, 7)) {
aPlugin.API.setTotalExperience(p, aPlugin.API.getTotalExperience(p)-p.getLevel());
}
}
private static void causeSpetralGlowAndAggro(Entity damager, Player p, LivingEntity target) {
if (damager instanceof SpectralArrow) {
if (target instanceof Monster) {
provokeMonster((Monster)target,p,p.getEquipment().getItemInMainHand());
setAggroGlowTickTime((Monster)target,100);
} else {
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.GLOWING, 20*5, 0, target);
}
}
}
public static void appendDebuffsToName(LivingEntity target) {
if (target instanceof LivingEntity) {
if (target.getCustomName()==null) {
@ -623,8 +853,8 @@ public class CustomDamage {
}
}
private static void addHealthFromLifesteal(Player p, double damage, ItemStack weapon) {
double lifestealamt = damage*calculateLifeStealAmount(p,weapon);
private static void addHealthFromLifesteal(Player p, double damage, ItemStack weapon, String reason) {
double lifestealamt = damage*calculateLifeStealAmount(p,weapon,reason);
if ((p.getMaxHealth()-p.getHealth())<lifestealamt) {
p.setHealth(p.getMaxHealth());
} else {
@ -690,7 +920,26 @@ public class CustomDamage {
}
}
private static void reduceDefenderKnockback(Player p) {
private static void reduceKnockback(Player p) {
if (PlayerMode.isBarbarian(p)) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (pd.rage_time>TwosideKeeper.getServerTickTime()) {
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
@Override
public void run() {
p.setVelocity(p.getVelocity().multiply(0));
}
},1);
} else {
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
@Override
public void run() {
p.setVelocity(p.getVelocity().multiply(0.3));
}
},1);
}
return;
}
if (PlayerMode.isDefender(p) && p.isBlocking()) {
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
@Override
@ -847,7 +1096,7 @@ public class CustomDamage {
}
static public boolean InvulnerableCheck(Entity damager, LivingEntity target) {
return InvulnerableCheck(damager,target,NONE);
return InvulnerableCheck(damager,target,"",NONE);
}
/**
@ -856,12 +1105,32 @@ public class CustomDamage {
* @param target
* @return Returns true if the target cannot be hit. False otherwise.
*/
static public boolean InvulnerableCheck(Entity damager, LivingEntity target, int flags) {
static public boolean InvulnerableCheck(Entity damager, LivingEntity target, String reason, int flags) {
target.setLastDamage(0);
target.setNoDamageTicks(0);
target.setMaximumNoDamageTicks(0);
if (damager instanceof Player && target instanceof Player && !damager.getWorld().getPVP()) {
return true; //Cancel all PvP related events.
}
if (isFlagSet(flags,IGNORE_DAMAGE_TICK) || (GenericFunctions.enoughTicksHavePassed(target, damager) && canHitMobDueToWeakness(damager) && !GenericFunctions.isSuppressed(getDamagerEntity(damager)))) {
if (isFlagSet(flags,IGNORE_DAMAGE_TICK) || (GenericFunctions.enoughTicksHavePassed(target, damager) && canHitMobDueToWeakness(damager) && !GenericFunctions.isSuppressed(getDamagerEntity(damager)) && !target.isDead())) {
TwosideKeeper.log("Enough ticks have passed.", 5);
if (CanResistExplosionsWithExperienceSet(damager, target, reason)) {
aPlugin.API.setTotalExperience((Player)target, (int)Math.max(aPlugin.API.getTotalExperience((Player)target)-ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getHotbarItems(target), (Player)target, ItemSet.ALUSTINE, 2, 2),0));
((Player)target).playSound(((Player)target).getLocation(), Sound.ENTITY_PLAYER_ATTACK_SWEEP, 3.0f, 1.0f);
((Player)target).playSound(((Player)target).getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1.0f, 0.5f);
GenericFunctions.updateNoDamageTickMap(target, damager);
return true;
}
if (CanResistDotsWithExperienceSet(damager, target, reason)) {
aPlugin.API.setTotalExperience((Player)target, (int)Math.max(aPlugin.API.getTotalExperience((Player)target)-ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getHotbarItems(target), (Player)target, ItemSet.ALUSTINE, 3, 3),0));
((Player)target).playSound(((Player)target).getLocation(), Sound.ENTITY_PLAYER_ATTACK_SWEEP, 3.0f, 1.0f);
((Player)target).playSound(((Player)target).getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1.0f, 0.5f);
GenericFunctions.updateNoDamageTickMap(target, damager);
return true;
}
if (isFlagSet(flags,IGNOREDODGE) || !PassesIframeCheck(target,damager)) {
TwosideKeeper.log("Not in an iframe.", 5);
if (isFlagSet(flags,IGNOREDODGE) || !PassesDodgeCheck(target,damager)) {
@ -871,18 +1140,39 @@ public class CustomDamage {
} else {
if (target instanceof Player) {
Player p = (Player)target;
PlayerDodgeEvent ev = new PlayerDodgeEvent(p,damager,reason,flags);
Bukkit.getPluginManager().callEvent(ev);
if (ev.isCancelled()) {
return false;
}
p.playSound(p.getLocation(), Sound.ENTITY_PLAYER_ATTACK_SWEEP, 3.0f, 1.0f);
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
pd.fulldodge=false;
calculateGracefulDodgeTicks(target);
GenericFunctions.updateNoDamageTickMap(target, damager);
} else {
calculateGracefulDodgeTicks(target);
GenericFunctions.updateNoDamageTickMap(target, damager);
}
calculateGracefulDodgeTicks(target);
GenericFunctions.updateNoDamageTickMap(target, damager);
}
}
}
return true;
}
public static boolean CanResistExplosionsWithExperienceSet(Entity damager, LivingEntity target, String reason) {
return target instanceof Player && ItemSet.HasSetBonusBasedOnSetBonusCount(GenericFunctions.getHotbarItems(target), (Player)target, ItemSet.ALUSTINE, 2) &&
((reason!=null && (reason.equalsIgnoreCase("explosion") || reason.equalsIgnoreCase("entity_explosion")))
|| damager instanceof Creeper) &&
aPlugin.API.getTotalExperience((Player)target)>=ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getHotbarItems(target), (Player)target, ItemSet.ALUSTINE, 2, 2);
}
public static boolean CanResistDotsWithExperienceSet(Entity damager, LivingEntity target, String reason) {
return target instanceof Player && ItemSet.HasSetBonusBasedOnSetBonusCount(GenericFunctions.getHotbarItems(target), (Player)target, ItemSet.ALUSTINE, 3) &&
((reason!=null && (reason.equalsIgnoreCase("poison") || reason.equalsIgnoreCase("wither") || reason.equalsIgnoreCase("fire_tick") || reason.equalsIgnoreCase("lava") || reason.equalsIgnoreCase("fire")))) &&
aPlugin.API.getTotalExperience((Player)target)>=ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getHotbarItems(target), (Player)target, ItemSet.ALUSTINE, 3, 3);
}
private static boolean canHitMobDueToWeakness(Entity damager) {
LivingEntity shooter = getDamagerEntity(damager);
if (shooter!=null &&
@ -1444,9 +1734,11 @@ public class CustomDamage {
if (damager instanceof Player) {
Player p = (Player)damager;
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
dmg += 93.182445*pd.velocity*GenericFunctions.getAbilityValue(ArtifactAbility.HIGHWINDER, weapon);
pd.lasthighwinderhit=TwosideKeeper.getServerTickTime();
GenericFunctions.sendActionBarMessage(p, TwosideKeeper.drawVelocityBar(pd.velocity,pd.highwinderdmg),true);
if (ArtifactAbility.containsEnchantment(ArtifactAbility.HIGHWINDER, weapon)) {
dmg += 93.182445*pd.velocity*GenericFunctions.getAbilityValue(ArtifactAbility.HIGHWINDER, weapon);
pd.lasthighwinderhit=TwosideKeeper.getServerTickTime();
GenericFunctions.sendActionBarMessage(p, TwosideKeeper.drawVelocityBar(pd.velocity,pd.highwinderdmg),true);
}
}
return dmg;
}
@ -1470,10 +1762,11 @@ public class CustomDamage {
if (shooter instanceof Player) {
dmg += ItemSet.GetTotalBaseAmount(GenericFunctions.getEquipment(shooter),shooter,ItemSet.PANROS);
dmg += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(shooter),(Player)shooter, ItemSet.PANROS, 2, 2);
dmg += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(shooter),(Player)shooter, ItemSet.DAWNTRACKER, 4, 4);
//dmg += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(shooter),(Player)shooter, ItemSet.DAWNTRACKER, 4, 4);
dmg += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(shooter),(Player)shooter, ItemSet.LORASAADI, 2, 2);
dmg += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(shooter),(Player)shooter, ItemSet.LORASAADI, 3, 3);
dmg += ItemSet.GetTotalBaseAmount(GenericFunctions.getEquipment(shooter), (Player)shooter, ItemSet.LORASYS);
dmg += ItemSet.HasSetBonusBasedOnSetBonusCount(GenericFunctions.getHotbarItems(shooter), (Player)shooter, ItemSet.ALUSTINE, 7)?((Player)shooter).getLevel():0;
/*dmg += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)shooter, ItemSet.JAMDAK, 3, 3);
dmg += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)shooter, ItemSet.DARNYS, 3, 3);
dmg += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)shooter, ItemSet.ALIKAHN, 3, 3);
@ -1507,7 +1800,7 @@ public class CustomDamage {
}
Location monsterHead = m.getEyeLocation();
TwosideKeeper.log("Distance: "+(arrowLoc.distanceSquared(monsterHead)), 5);
boolean isheadshot=false;
double headshotvaly=0.22/TwosideKeeper.HEADSHOT_ACC;
TwosideKeeper.log("In here.", 2);
if (proj.getShooter() instanceof Player) {
@ -1566,28 +1859,28 @@ public class CustomDamage {
} else {
mult+=2.0;
p.sendMessage(ChatColor.DARK_RED+"Headshot! x2 Damage");
if (PlayerMode.isRanger(p) && GenericFunctions.getBowMode(p.getEquipment().getItemInMainHand())==BowMode.DEBILITATION) {
if (m.hasPotionEffect(PotionEffectType.BLINDNESS)) {
//Add to the current stack of BLINDNESS.
for (PotionEffect pe : m.getActivePotionEffects()) {
if (pe.getType().equals(PotionEffectType.BLINDNESS)) {
int lv = pe.getAmplifier();
TwosideKeeper.log("New BLINDNESS level: "+lv,5);
p.playSound(p.getLocation(), Sound.ENTITY_RABBIT_ATTACK, 0.1f, 0.1f+((lv+1)*0.5f));
m.removePotionEffect(PotionEffectType.BLINDNESS);
m.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,400,lv+1));
break;
}
}
} else {
m.removePotionEffect(PotionEffectType.BLINDNESS);
m.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,400,0));
p.playSound(p.getLocation(), Sound.ENTITY_RABBIT_ATTACK, 0.1f, 0.1f);
}
}
isheadshot=true;
}
}
if (PlayerMode.isRanger(p) && GenericFunctions.getBowMode(p.getEquipment().getItemInMainHand())==BowMode.DEBILITATION) {
if (m.hasPotionEffect(PotionEffectType.BLINDNESS) && isheadshot) {
//Add to the current stack of BLINDNESS.
for (PotionEffect pe : m.getActivePotionEffects()) {
if (pe.getType().equals(PotionEffectType.BLINDNESS)) {
int lv = pe.getAmplifier();
TwosideKeeper.log("New BLINDNESS level: "+lv,5);
p.playSound(p.getLocation(), Sound.ENTITY_RABBIT_ATTACK, 0.1f, 0.1f+((lv+1)*0.5f));
m.removePotionEffect(PotionEffectType.BLINDNESS);
m.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,400,lv+1),true);
break;
}
}
} else {
m.removePotionEffect(PotionEffectType.BLINDNESS);
m.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,400,0));
p.playSound(p.getLocation(), Sound.ENTITY_RABBIT_ATTACK, 0.1f, 0.1f);
}
}
}
}
@ -1626,10 +1919,10 @@ public class CustomDamage {
}
private static double calculateCriticalStrikeMultiplier(ItemStack weapon, LivingEntity shooter,
LivingEntity target, int flags) {
LivingEntity target, String reason, int flags) {
boolean criticalstrike=false;
double critchance = 0.0;
critchance += calculateCriticalStrikeChance(weapon, shooter);
critchance += calculateCriticalStrikeChance(weapon, shooter, reason);
TwosideKeeper.log("Crit Strike chance is "+critchance,4);
criticalstrike = isCriticalStrike(critchance);
if (isFlagSet(flags,CRITICALSTRIKE)) {
@ -1643,6 +1936,10 @@ public class CustomDamage {
}
static double calculateCriticalStrikeChance(ItemStack weapon, Entity damager) {
return calculateCriticalStrikeChance(weapon,damager,null);
}
static double calculateCriticalStrikeChance(ItemStack weapon, Entity damager, String reason) {
double critchance = 0.0;
critchance += 0.01*GenericFunctions.getAbilityValue(ArtifactAbility.CRITICAL,weapon);
LivingEntity shooter = getDamagerEntity(damager);
@ -1653,8 +1950,12 @@ public class CustomDamage {
critchance += (PlayerMode.isStriker(p)?0.2:0.0);
critchance += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(p), p,ItemSet.PANROS,4,4)/100d;
critchance += (PlayerMode.isRanger(p)?(GenericFunctions.getPotionEffectLevel(PotionEffectType.SLOW, p)+1)*0.1:0.0);
critchance += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getHotbarItems(p), p, ItemSet.MOONSHADOW, 5, 4)/100;
critchance += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getHotbarItems(p), p, ItemSet.MOONSHADOW, 5, 4)/100d;
critchance += ItemSet.GetTotalBaseAmount(GenericFunctions.getHotbarItems(p), p, ItemSet.WOLFSBANE)/100d;
critchance += (pd.slayermegahit)?1.0:0.0;
if (reason!=null && reason.equalsIgnoreCase("power swing")) {
critchance += 1.0d;
}
}
}
return critchance;
@ -1744,7 +2045,11 @@ public class CustomDamage {
target.setHealth(0.00001);
target.damage(Integer.MAX_VALUE);
} else {
target.setHealth(target.getHealth()-damage);
if (target.getHealth()-damage>target.getMaxHealth()) {
target.setHealth(target.getMaxHealth());
} else {
target.setHealth(target.getHealth()-damage);
}
}
}
}
@ -1980,10 +2285,25 @@ public class CustomDamage {
}
}
/*0.0-1.0*/
public static double calculateLifeStealAmount(Player p, ItemStack weapon) {
return calculateLifeStealAmount(p,weapon,null);
}
/*0.0-1.0*/
public static double calculateLifeStealAmount(Player p, ItemStack weapon, String reason) {
double lifestealpct = GenericFunctions.getAbilityValue(ArtifactAbility.LIFESTEAL, weapon)/100;
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
lifestealpct += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(p), p, ItemSet.DAWNTRACKER, 3, 3)/100d;
lifestealpct += pd.lifestealstacks/100d;
if (reason!=null && reason.equalsIgnoreCase("power swing")) {
lifestealpct += 1.0d;
}
if (pd.rage_time>TwosideKeeper.getServerTickTime()) {
lifestealpct += (pd.rage_amt/2)*0.01;
}
if (reason!=null && reason.equalsIgnoreCase("sweep up")) {
lifestealpct*=2;
}
return lifestealpct;
}
@ -2164,18 +2484,21 @@ public class CustomDamage {
}
}
private static double calculateCustomArrowMultiplier(ItemStack weapon, Entity damager, LivingEntity target) {
double mult = 0.0;
if (damager instanceof TippedArrow) {
TippedArrow a = (TippedArrow)damager;
private static double calculateCustomArrowDamageIncrease(ItemStack weapon, Entity damager, LivingEntity target) {
double dmg = 0.0;
if (damager instanceof Arrow) {
Arrow a = (Arrow)damager;
if (a.hasMetadata("QUADRUPLE_DAMAGE_ARR")) {
mult += 3.0;
dmg += 15.0;
}
if (a.hasMetadata("DOUBLE_DAMAGE_ARR")) {
mult += 1.0;
dmg += 5.0;
}
if (a.hasMetadata("PIERCING_ARR")) {
dmg += 5.0;
}
}
return mult;
return dmg;
}
private static double calculateIsolationMultiplier(LivingEntity shooter, LivingEntity target) {
@ -2204,4 +2527,13 @@ public class CustomDamage {
GenericFunctions.addSuppressionTime(target, (int)(GenericFunctions.getAbilityValue(ArtifactAbility.SUPPRESS, weapon)*20));
}
}
public static double getTransferDamage(Player p) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
return 15-GetDamageReductionFromDawntrackerPieces(p);
}
public static int GetDamageReductionFromDawntrackerPieces(Player p) {
return ItemSet.GetTotalBaseAmount(GenericFunctions.getEquipment(p), p, ItemSet.DAWNTRACKER)/2;
}
}

@ -122,11 +122,11 @@ public class SigDrop extends Drop{
switch (isWeapon) {
case ARMOR: {
item = new ItemStack(Material.valueOf(armorprefix+"_"+armorsuffix));
item = CreateModifiedLootPiece(p, item);
item = CreateModifiedLootPiece(p, item, diff);
}break;
case WEAPON: {
item = new ItemStack(Material.valueOf(toolprefix+"_SWORD"));
item = CreateModifiedLootPiece(p, item);
item = CreateModifiedLootPiece(p, item, diff);
}break;
case TOOL: {
item = new ItemStack(Material.valueOf(toolprefix+"_"+toolsuffix));
@ -140,9 +140,9 @@ public class SigDrop extends Drop{
return item;
}
public ItemStack CreateModifiedLootPiece(Player p, ItemStack item) {
public ItemStack CreateModifiedLootPiece(Player p, ItemStack item, MonsterDifficulty md) {
if (isSet) {
ItemSet set = MonsterDifficulty.PickAnItemSet(PlayerMode.getPlayerMode(p)); //This is the set we have to generate.
ItemSet set = MonsterDifficulty.PickAnItemSet(PlayerMode.getPlayerMode(p),md); //This is the set we have to generate.
//Turn it into the appropriate piece if necessary.
item = MonsterDifficulty.ConvertSetPieceIfNecessary(item, set);

@ -0,0 +1,60 @@
package sig.plugin.TwosideKeeper.Events;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.inventory.ItemStack;
public class PlayerDodgeEvent extends Event implements Cancellable{
private Player p;
private Entity damager;
private String reason;
private int flags;
private boolean cancelled;
private static final HandlerList handlers = new HandlerList();
public PlayerDodgeEvent(Player p, Entity damager, String reason, int flags) {
this.p=p;
this.damager=damager;
this.reason=reason;
this.flags=flags;
}
public Player getPlayer() {
return p;
}
public Entity getDamager() {
return damager;
}
public String getReason() {
return reason;
}
public int getFlags() {
return flags;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled=cancelled;
}
}

@ -0,0 +1,40 @@
package sig.plugin.TwosideKeeper.Events;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public final class PlayerLineDriveEvent extends Event implements Cancellable{
private Player p;
private boolean cancelled;
private static final HandlerList handlers = new HandlerList();
public PlayerLineDriveEvent(Player p) {
this.p=p;
}
public Player getPlayer() {
return p;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled=cancelled;
}
}

@ -0,0 +1,40 @@
package sig.plugin.TwosideKeeper.Events;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class PlayerTumbleEvent extends Event implements Cancellable{
private Player p;
private boolean cancelled;
private static final HandlerList handlers = new HandlerList();
public PlayerTumbleEvent(Player p) {
this.p=p;
}
public Player getPlayer() {
return p;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled=cancelled;
}
}

@ -0,0 +1,35 @@
package sig.plugin.TwosideKeeper.HelperStructures;
import org.bukkit.Bukkit;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffectType;
import sig.plugin.TwosideKeeper.TwosideKeeper;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
public class ArrowBarrage implements Runnable{
int shots_left=20;
Player p;
int tick_spd = 3;
public ArrowBarrage(int shots, Player p, int spd) {
this.shots_left=shots;
this.p = p;
this.tick_spd=spd;
}
@Override
public void run() {
shots_left--;
Arrow arr = p.launchProjectile(Arrow.class);
arr.setVelocity(p.getLocation().getDirection().multiply(2));
TwosideKeeper.ShootPiercingArrow(arr, p);
arr.remove();
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.SLOW, 4, 9, p, true);
if (shots_left>0) {
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, this, 3);
}
}
}

@ -0,0 +1,307 @@
package sig.plugin.TwosideKeeper.HelperStructures.Common;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.metadata.MetadataValue;
import sig.plugin.TwosideKeeper.TwosideKeeper;
public class ArrowQuiver {
public final static String ARROW_QUIVER_IDENTIFIER = ChatColor.AQUA+"Arrow Quiver";
public final static String ID_PREFIX = ChatColor.DARK_AQUA+""+ChatColor.BOLD+"ID ";
public final static String FIRINGMODE_IDENTIFIER = ChatColor.BLACK+""+ChatColor.MAGIC+"MODE ";
public static boolean isValidQuiver(ItemStack item) {
return (item!=null && item.getType()==Material.TIPPED_ARROW &&
item.hasItemMeta() && item.getItemMeta().hasLore() &&
item.getItemMeta().getLore().contains(ARROW_QUIVER_IDENTIFIER));
}
public static int getID(ItemStack quiver) {
//Try to find the ID line.
List<String> lore = quiver.getItemMeta().getLore();
for (int i=0;i<lore.size();i++) {
if (lore.get(i).contains(ID_PREFIX)) {
return Integer.parseInt(lore.get(i).replace(ID_PREFIX, ""));
}
}
TwosideKeeper.log("Could not find ID for "+quiver.toString()+". Something went horribly wrong here!!!", 0);
return -1;
}
public static void setID(ItemStack quiver) {
List<String> lore = quiver.getItemMeta().getLore();
for (int i=0;i<lore.size();i++) {
if (lore.get(i).contains(ID_PREFIX)) {
//This line needs to be replaced.
lore.set(i, ID_PREFIX+TwosideKeeper.ARROWQUIVERID);
TwosideKeeper.ARROWQUIVERID++;
ItemMeta meta = quiver.getItemMeta();
meta.setLore(lore);
quiver.setItemMeta(meta);
return;
}
}
TwosideKeeper.log("Could not find ID for "+quiver.toString()+". Something went horribly wrong here!!!", 0);
return;
}
public static List<ItemStack> getContents(int id) {
File arrowquiver_dir = new File(TwosideKeeper.filesave+"/arrowquivers/");
if (!arrowquiver_dir.exists()) {
arrowquiver_dir.mkdir();
}
File config;
config = new File(TwosideKeeper.filesave,"/arrowquivers/"+id+".data");
if (!config.exists()) {
try {
config.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
List<ItemStack> inv = new ArrayList<ItemStack>();
FileConfiguration workable = YamlConfiguration.loadConfiguration(config);
for (String key : workable.getKeys(false)) {
inv.add(workable.getItemStack(key));
}
return inv;
}
public static void addContents(ItemStack quiver, ItemStack...item) {
addContents(getID(quiver),item);
}
public static void addContents(int id, ItemStack...item) {
List<ItemStack> currentinv = getContents(id);
for (ItemStack it : item) {
if (it!=null) {
addItemToQuiver(currentinv, it);
}
}
saveInventory(id, currentinv);
}
public static void removeContents(ItemStack quiver, ItemStack...item) {
removeContents(getID(quiver),item);
}
public static void removeContents(int id, ItemStack...item) {
List<ItemStack> currentinv = getContents(id);
for (ItemStack it : item) {
if (it!=null) {
removeItemFromQuiver(currentinv, it);
}
}
saveInventory(id, currentinv);
}
private static void saveInventory(int id, List<ItemStack> currentinv) {
File arrowquiver_dir = new File(TwosideKeeper.filesave+"/arrowquivers/");
if (!arrowquiver_dir.exists()) {
arrowquiver_dir.mkdir();
}
File config;
config = new File(TwosideKeeper.filesave,"/arrowquivers/"+id+".data");
if (config.exists()) {
config.delete();
try {
config.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileConfiguration workable = YamlConfiguration.loadConfiguration(config);
for (ItemStack item : currentinv) {
workable.set(item.getType().name()+"_"+item.hashCode(), item);
}
try {
workable.save(config);
} catch (IOException e) {
e.printStackTrace();
}
//updateQuiverLore(id, currentinv);
}
private static List<String> getBaseQuiverLore(int id, int mode) {
List<String> baselore = new ArrayList<String>();
baselore.add(ARROW_QUIVER_IDENTIFIER);
baselore.add(FIRINGMODE_IDENTIFIER+mode);
baselore.add(ID_PREFIX+id);
return baselore;
}
public static void updateQuiverLore(ItemStack quiver) {
ItemMeta m = quiver.getItemMeta();
List<ItemStack> contents = getContents(getID(quiver));
List<String> lore = getBaseQuiverLore(getID(quiver), getArrowQuiverMode(quiver));
if (contents.size()>0) {
lore.add("");
lore.add(ChatColor.WHITE+"Contains:");
for (ItemStack item : contents) {
lore.add(ChatColor.GRAY+""+ChatColor.ITALIC+" - "+GenericFunctions.UserFriendlyMaterialName(item)+" x"+item.getAmount());
}
} else {
lore.add(ChatColor.WHITE+"This quiver is empty!");
lore.add(ChatColor.AQUA+"Click arrows into the quiver or");
lore.add(ChatColor.AQUA+"pick up arrows off the ground");
lore.add(ChatColor.AQUA+"to load them up!");
}
m.setLore(lore);
m.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
m.addItemFlags(ItemFlag.HIDE_ENCHANTS);
quiver.setItemMeta(m);
quiver.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 5);
}
private static void removeItemFromQuiver(List<ItemStack> currentitems, ItemStack it) {
//First compare all items that exist.
int slot = getItemSlot(currentitems, it);
if (slot!=-1) { //Remove from the previous amount in the list.
if (currentitems.get(slot).getAmount()-it.getAmount()<1) { //Delete it if we run out of these arrows.
currentitems.remove(slot);
} else {
currentitems.get(slot).setAmount(currentitems.get(slot).getAmount()-it.getAmount());
}
}
}
private static void addItemToQuiver(List<ItemStack> currentitems, ItemStack it) {
//First compare all items that exist.
int slot = getItemSlot(currentitems, it);
if (slot==-1) { //No similar item found, add a new entry.
TwosideKeeper.log("No slot found. Adding this way.", 5);
currentitems.add(it);
} else { //Add to the previous amount in the list.
currentitems.get(slot).setAmount(currentitems.get(slot).getAmount()+it.getAmount());
}
}
private static int getItemSlot(List<ItemStack> currentitems, ItemStack it) {
for (int i=0;i<currentitems.size();i++) {
if (currentitems.get(i).isSimilar(it)) {
return i;
}
}
return -1;
}
public static List<ItemStack> getContentsAPI(ItemStack i) {
return getContents(getID(i));
}
public static int getArrowQuiverMode(ItemStack item) {
//Arrow quiver mode will be determined by an integer dictating which item slot we are on.
//If the slot is non-existent or out-of-bounds, we set it to 0 to indicate the first slot.
List<String> lore = item.getItemMeta().getLore();
List<ItemStack> contents = getContents(getID(item));
for (String text : lore) {
if (text.contains(FIRINGMODE_IDENTIFIER)) {
int mode = Integer.parseInt(text.replace(FIRINGMODE_IDENTIFIER, ""));
if (mode>=0 && contents.size()-1>=mode) {
return setArrowQuiverMode(item,mode);
} else {
return setArrowQuiverMode(item,0);
}
}
}
return setArrowQuiverMode(item,0);
}
public static int setArrowQuiverMode(ItemStack item, int mode) {
ItemMeta m = item.getItemMeta();
List<String> lore = m.getLore();
List<ItemStack> contents = getContents(getID(item));
int arrow_quiver_identifier_line = 0;
for (int i=0;i<lore.size();i++) {
if (lore.get(i).contains(FIRINGMODE_IDENTIFIER)) {
if (contents.size()-1>=mode) {
lore.set(i,FIRINGMODE_IDENTIFIER+mode);
} else {
lore.set(i,FIRINGMODE_IDENTIFIER+0);
}
m.setLore(lore);
item.setItemMeta(m);
return mode;
}
if (lore.get(i).contains(ARROW_QUIVER_IDENTIFIER)) {
arrow_quiver_identifier_line = i;
}
}
//Firing mode does not exist in the lore yet. Add it under the arrow quiver line.
TwosideKeeper.log("Adding a line @ "+arrow_quiver_identifier_line, 5);
lore.add(arrow_quiver_identifier_line+1,FIRINGMODE_IDENTIFIER+mode);
m.setLore(lore);
item.setItemMeta(m);
return mode;
}
public static boolean isQuiverEmpty(ItemStack quiver) {
return getContents(getID(quiver)).size()==0;
}
public static ItemStack ReturnAndRemoveShotArrow(ItemStack quiver) {
return ReturnAndRemoveShotArrow(quiver,null);
}
/**
* Returns the first arrow quiver in the player's inventory following the same
* arrow check rules as Minecraft does. Off-hand slot, then hotbar, then inventory.
*
* Returns null if it cannot find an arrow quiver at all.
*/
public static ItemStack getArrowQuiverInPlayerInventory(Player p) {
ItemStack offhandslot = p.getInventory().getExtraContents()[0];
ItemStack[] storagecontents = p.getInventory().getStorageContents();
if (offhandslot!=null && ArrowQuiver.isValidQuiver(offhandslot)) {
return offhandslot;
} else {
for (int i=0;i<storagecontents.length;i++) {
if (storagecontents[i]!=null && ArrowQuiver.isValidQuiver(storagecontents[i])) {
return storagecontents[i];
}
}
}
return null;
}
/**
* Same as normal version of this method, but checks a bow item to determine if we really are supposed to remove
* an arrow by using Infinity as a formula.
*/
public static ItemStack ReturnAndRemoveShotArrow(ItemStack quiver, ItemStack bow) {
List<ItemStack> contents = getContents(getID(quiver));
if (contents.size()>0) {
ItemStack arrow = contents.get(getArrowQuiverMode(quiver)).clone();
arrow.setAmount(1);
if (bow==null) {
ArrowQuiver.removeContents(getID(quiver), arrow);
}
return arrow;
} else {
return null;
}
}
}

@ -45,8 +45,10 @@ import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
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;
import org.inventivetalent.glow.GlowAPI.Color;
@ -63,12 +65,17 @@ import sig.plugin.TwosideKeeper.EliteMonster;
import sig.plugin.TwosideKeeper.MonsterController;
import sig.plugin.TwosideKeeper.LivingEntityStructure;
import sig.plugin.TwosideKeeper.PlayerStructure;
import sig.plugin.TwosideKeeper.Recipes;
import sig.plugin.TwosideKeeper.TwosideKeeper;
import sig.plugin.TwosideKeeper.TwosideKeeperAPI;
import sig.plugin.TwosideKeeper.Boss.EliteZombie;
import sig.plugin.TwosideKeeper.Boss.MegaWither;
import sig.plugin.TwosideKeeper.Events.PlayerLineDriveEvent;
import sig.plugin.TwosideKeeper.Events.PlayerTumbleEvent;
import sig.plugin.TwosideKeeper.HelperStructures.ArrowBarrage;
import sig.plugin.TwosideKeeper.HelperStructures.ArtifactAbility;
import sig.plugin.TwosideKeeper.HelperStructures.BowMode;
import sig.plugin.TwosideKeeper.HelperStructures.CustomItem;
import sig.plugin.TwosideKeeper.HelperStructures.EliteMonsterLocationFinder;
import sig.plugin.TwosideKeeper.HelperStructures.ItemSet;
import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode;
@ -577,7 +584,7 @@ public class GenericFunctions {
return "Iron Shovel";
}
case GOLD_SPADE:{
return "Gold Shovel";
return "Golden Shovel";
}
case DIAMOND_SPADE:{
return "Diamond Shovel";
@ -1801,6 +1808,27 @@ public class GenericFunctions {
}
}
}
case GOLD_HELMET:{
return "Golden Helmet";
}
case GOLD_LEGGINGS:{
return "Golden Leggings";
}
case GOLD_CHESTPLATE:{
return "Golden Chestplate";
}
case GOLD_BOOTS:{
return "Golden Boots";
}
case GOLD_AXE:{
return "Golden Axe";
}
case GOLD_PICKAXE:{
return "Golden Pickaxe";
}
case GOLD_HOE:{
return "Golden Hoe";
}
default:{
return GenericFunctions.CapitalizeFirstLetters(type.getType().toString().replace("_", " "));
}
@ -2454,7 +2482,7 @@ public class GenericFunctions {
}
p.sendMessage(ChatColor.DARK_AQUA+"A level of "+ChatColor.YELLOW+"Mending"+ChatColor.DARK_AQUA+" has been knocked off of your "+((item.hasItemMeta() && item.getItemMeta().hasDisplayName())?item.getItemMeta().getDisplayName():UserFriendlyMaterialName(item)));
}
if (infinitylv>0 && Math.random()<=0.00048828125*(isHarvestingTool(item)?0.75:1d)) {
if (infinitylv>0 && Math.random()<=0.005*(isHarvestingTool(item)?0.75:1d)) {
infinitylv--;
if (infinitylv>0) {
item.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, infinitylv);
@ -2724,26 +2752,29 @@ public class GenericFunctions {
(GenericFunctions.getBowMode(p.getEquipment().getItemInMainHand())==BowMode.CLOSE)) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (pd.last_dodge+GetModifiedCooldown(TwosideKeeper.DODGE_COOLDOWN,p)<=TwosideKeeper.getServerTickTime()) {
pd.last_dodge=TwosideKeeper.getServerTickTime();
aPlugin.API.sendCooldownPacket(p, p.getEquipment().getItemInMainHand(), 100);
p.playSound(p.getLocation(), Sound.ENTITY_DONKEY_CHEST, 1.0f, 1.0f);
int dodgeduration = 20;
PlayerTumbleEvent ev = new PlayerTumbleEvent(p);
Bukkit.getPluginManager().callEvent(ev);
if (!ev.isCancelled()) {
pd.last_dodge=TwosideKeeper.getServerTickTime();
aPlugin.API.sendCooldownPacket(p, p.getEquipment().getItemInMainHand(), 100);
p.playSound(p.getLocation(), Sound.ENTITY_DONKEY_CHEST, 1.0f, 1.0f);
if (GenericFunctions.HasFullRangerSet(p)) {
dodgeduration=60;
}
int dodgeduration = 20;
if (p.isSneaking()) { //Do a backwards dodge + jump.
p.setVelocity(p.getLocation().getDirection().multiply(-0.7f));
} else {
p.setVelocity(p.getLocation().getDirection().multiply(1.4f));
}
ApplySwiftAegis(p);
CustomDamage.addIframe(dodgeduration, p);
if (GenericFunctions.HasFullRangerSet(p)) {
dodgeduration=60;
}
if (p.isSneaking()) { //Do a backwards dodge + jump.
p.setVelocity(p.getLocation().getDirection().multiply(-0.7f));
} else {
p.setVelocity(p.getLocation().getDirection().multiply(1.4f));
}
ApplySwiftAegis(p);
CustomDamage.addIframe(dodgeduration, p);
logAndApplyPotionEffectToEntity(PotionEffectType.SPEED,dodgeduration,2,p);
logAndApplyPotionEffectToEntity(PotionEffectType.SPEED,dodgeduration,2,p);
}
}
}
}
@ -2758,7 +2789,7 @@ public class GenericFunctions {
}
public static void logAndApplyPotionEffectToEntity(PotionEffectType type, int ticks, int amplifier, LivingEntity p, boolean force) {
TwosideKeeper.log(ChatColor.WHITE+"Adding Potion Effect "+type.getName()+" "+WorldShop.toRomanNumeral((amplifier+1))+"("+amplifier+") to "+p.getName()+" with "+ticks+" tick duration. "+((force)?ChatColor.RED+"FORCED":""), TwosideKeeper.POTION_DEBUG_LEVEL);
TwosideKeeper.log(ChatColor.WHITE+"Adding Potion Effect "+type.getName()+" "+WorldShop.toRomanNumeral((amplifier+1))+"("+amplifier+") to "+p.getName()+" with "+ticks+" tick duration. "+((force)?ChatColor.RED+"FORCED":""), 5);
if (p.hasPotionEffect(type)) {
TwosideKeeper.log(ChatColor.YELLOW+" Already had effect on Player "+p.getName()+". "+type.getName()+" "+WorldShop.toRomanNumeral((getPotionEffectLevel(type,p)+1))+"("+getPotionEffectLevel(type,p)+"), Duration: "+getPotionEffectDuration(type,p)+" ticks", TwosideKeeper.POTION_DEBUG_LEVEL);
if (!force) {
@ -3112,9 +3143,36 @@ public class GenericFunctions {
UpdateVials(item);
UpdateHuntersCompass(item);
UpdateUpgradeShard(item);
UpdateOldQuivers(item);
return item;
}
private static void UpdateOldQuivers(ItemStack item) {
if (item!=null &&
item.getType()==Material.TIPPED_ARROW &&
item.getEnchantmentLevel(Enchantment.ARROW_INFINITE)==5) {
//This might be an old arrow quiver.
if (!ArrowQuiver.isValidQuiver(item)) {
//Okay, we convert this with a brand new ID.
int amt = playerGetOldArrowQuiverAmt(item);
ItemMeta m = CustomItem.ArrowQuiver().getItemMeta();
item.setItemMeta(m);
ArrowQuiver.setID(item);
item.addUnsafeEnchantments(CustomItem.ArrowQuiver().getEnchantments());
ArrowQuiver.addContents(ArrowQuiver.getID(item), new ItemStack(Material.ARROW,amt));
ArrowQuiver.updateQuiverLore(item);
}
}
}
/**
* Legacy code to help turn an old arrow quiver into a new one. Gets the amount of arrows in an old quiver.
*/
private static int playerGetOldArrowQuiverAmt(ItemStack ArrowQuiver) {
int ArrowQuiver_amt = Integer.parseInt(ArrowQuiver.getItemMeta().getLore().get(1).split(": "+ChatColor.YELLOW)[1]);
return ArrowQuiver_amt;
}
public static void UpdateArtifactItemType(ItemStack item) {
if (isArtifactArmor(item) &&
item.getType()!=Material.SULPHUR) {
@ -3526,24 +3584,44 @@ public class GenericFunctions {
}
}
}
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);
}
public static void DealDamageToNearbyMobs(Location l, double basedmg, double range, boolean knockup, double knockupamt, Entity damager, ItemStack weapon, boolean isLineDrive, String reason) {
Collection<Entity> ents = l.getWorld().getNearbyEntities(l, range, range, range);
//We cleared the non-living entities, deal damage to the rest.
double origdmg = basedmg;
for (Entity e : ents) {
if (e instanceof LivingEntity && !e.equals(damager)) {
if (e instanceof LivingEntity && !(e instanceof Player) && !e.equals(damager)) {
LivingEntity m = (LivingEntity)e;
if (enoughTicksHavePassed(m,(Player)damager)) {
basedmg=origdmg;
boolean isForcefulStrike = (reason!=null && reason.equalsIgnoreCase("forceful strike"));
boolean isSweepUp = (reason!=null && reason.equalsIgnoreCase("sweep up"));
if (isSweepUp) {
aPlugin.API.sendSoundlessExplosion(m.getLocation(), 1.5f);
if (damager instanceof Player) {
Player p = (Player)damager;
p.playEffect(m.getLocation(), Effect.LAVA_POP, null);
}
}
if (isForcefulStrike) {
GenericFunctions.addSuppressionTime(m, 20*2);
}
if (isLineDrive) {
basedmg*=1.0d+(4*((CustomDamage.getPercentHealthMissing(m))/100d));
CustomDamage.ApplyDamage(basedmg, damager, m, weapon, "Line Drive");
if (CustomDamage.ApplyDamage(basedmg, damager, m, weapon, "Line Drive")) {
if (knockup) {
m.setVelocity(new Vector(0,knockupamt,0));
}
}
} else {
CustomDamage.ApplyDamage(basedmg, damager, m, weapon, null);
}
if (knockup) {
m.setVelocity(new Vector(0,knockupamt,0));
if (CustomDamage.ApplyDamage(basedmg, damager, m, weapon, reason)) {
if (knockup) {
m.setVelocity(new Vector(0,knockupamt,0));
}
}
}
//TwosideKeeperAPI.DealDamageToEntity(basedmg, m, damager,"Line Drive");
if (m.isDead() && isLineDrive) {
@ -3856,11 +3934,11 @@ public class GenericFunctions {
* @param type
* @param maxlv The maximum level (Represented as a POTION level, not in-game displayed level.
*/
public static void addStackingPotionEffect(Player p, PotionEffectType type, int tick_duration, int maxlv) {
public static void addStackingPotionEffect(LivingEntity p, PotionEffectType type, int tick_duration, int maxlv) {
addStackingPotionEffect(p,type,tick_duration,maxlv,1);
}
public static void addStackingPotionEffect(Player p, PotionEffectType type, int tick_duration, int maxlv, int incr_amt) {
public static void addStackingPotionEffect(LivingEntity p, PotionEffectType type, int tick_duration, int maxlv, int incr_amt) {
final int BUFFER = 20*20; //20 extra seconds difference required to prevent buffs from being overwritten by this method.
if (p.hasPotionEffect(type)) {
int duration = getPotionEffectDuration(type,p);
@ -3870,7 +3948,7 @@ public class GenericFunctions {
logAndApplyPotionEffectToEntity(neweffect.getType(), neweffect.getDuration(),neweffect.getAmplifier(), p, true);
}
} else {
PotionEffect neweffect = new PotionEffect(type,tick_duration,0);
PotionEffect neweffect = new PotionEffect(type,tick_duration,incr_amt-1);
logAndApplyPotionEffectToEntity(neweffect.getType(), neweffect.getDuration(),neweffect.getAmplifier(), p, true);
}
}
@ -3972,7 +4050,6 @@ public class GenericFunctions {
pw.println(message);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
@ -4011,82 +4088,86 @@ public class GenericFunctions {
}
public static void PerformLineDrive(Player p, ItemStack weaponused, boolean second_charge) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
boolean ex_version = ItemSet.hasFullSet(GenericFunctions.getEquipment(p), p, ItemSet.PANROS);
Vector facing = p.getLocation().getDirection();
if (!second_charge) {
facing = p.getLocation().getDirection().setY(0);
logAndApplyPotionEffectToEntity(PotionEffectType.SLOW,(ex_version)?7:15,20,p);
}
if (!ex_version || second_charge) {
aPlugin.API.sendCooldownPacket(p, weaponused, GetModifiedCooldown(TwosideKeeper.LINEDRIVE_COOLDOWN,p));
pd.last_strikerspell=TwosideKeeper.getServerTickTime();
}
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1.0f, 1.0f);
aPlugin.API.damageItem(p, weaponused, (weaponused.getType().getMaxDurability()/10)+7);
final Player p1 = p;
int mult=2;
final double xspd=p.getLocation().getDirection().getX()*mult;
double tempyspd=0;
final double yspd=tempyspd;
final double zspd=p.getLocation().getDirection().getZ()*mult;
final double xpos=p.getLocation().getX();
final double ypos=p.getLocation().getY();
final double zpos=p.getLocation().getZ();
final Vector facing1 = facing;
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
public void run() {
p.setVelocity(facing1.multiply(8));
addIFrame(p, 10);
p.playSound(p.getLocation(), Sound.ITEM_CHORUS_FRUIT_TELEPORT, 1.0f, 1.0f);
final Location newpos=new Location(p.getWorld(),xpos,ypos,zpos);
double dmgdealt=CustomDamage.getBaseWeaponDamage(weaponused, p, null);
//List<Monster> monsters = getNearbyMobs(newpos, 2);
List<Entity> ents = new ArrayList<Entity>(newpos.getWorld().getNearbyEntities(newpos, 2, 2, 2));
List<Monster> monsters = CustomDamage.trimNonMonsterEntities(ents);
for (int i=0;i<monsters.size();i++) {
removeNoDamageTick(monsters.get(i), p);
}
for (int i=0;i<50;i++) {
newpos.getWorld().playEffect(newpos, Effect.FLAME, 60);
}
DealDamageToNearbyMobs(newpos, dmgdealt, 2, true, 0.8d, p, weaponused, true);
//DecimalFormat df = new DecimalFormat("0.00");
p.playSound(p.getLocation(), Sound.ENTITY_ARMORSTAND_HIT, 1.0f, 0.5f);
int range=8;
for (int i=0;i<range;i++) {
final double xpos2=p.getLocation().getX();
final double ypos2=p.getLocation().getY();
final double zpos2=p.getLocation().getZ();
final Location newpos2=new Location(p.getWorld(),xpos2,ypos2,zpos2).add(i*xspd,i*yspd,i*zspd);
for (int j=0;j<50;j++) {
PlayerLineDriveEvent ev = new PlayerLineDriveEvent(p);
Bukkit.getPluginManager().callEvent(ev);
if (!ev.isCancelled()) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
boolean ex_version = ItemSet.hasFullSet(GenericFunctions.getEquipment(p), p, ItemSet.PANROS);
Vector facing = p.getLocation().getDirection();
if (!second_charge) {
facing = p.getLocation().getDirection().setY(0);
logAndApplyPotionEffectToEntity(PotionEffectType.SLOW,(ex_version)?7:15,20,p);
}
if (!ex_version || second_charge) {
aPlugin.API.sendCooldownPacket(p, weaponused, GetModifiedCooldown(TwosideKeeper.LINEDRIVE_COOLDOWN,p));
pd.last_strikerspell=TwosideKeeper.getServerTickTime();
}
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1.0f, 1.0f);
aPlugin.API.damageItem(p, weaponused, (weaponused.getType().getMaxDurability()/10)+7);
final Player p1 = p;
int mult=2;
final double xspd=p.getLocation().getDirection().getX()*mult;
double tempyspd=0;
final double yspd=tempyspd;
final double zspd=p.getLocation().getDirection().getZ()*mult;
final double xpos=p.getLocation().getX();
final double ypos=p.getLocation().getY();
final double zpos=p.getLocation().getZ();
final Vector facing1 = facing;
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
public void run() {
p.setVelocity(facing1.multiply(8));
addIFrame(p, 10);
p.playSound(p.getLocation(), Sound.ITEM_CHORUS_FRUIT_TELEPORT, 1.0f, 1.0f);
final Location newpos=new Location(p.getWorld(),xpos,ypos,zpos);
double dmgdealt=CustomDamage.getBaseWeaponDamage(weaponused, p, null);
//List<Monster> monsters = getNearbyMobs(newpos, 2);
List<Entity> ents = new ArrayList<Entity>(newpos.getWorld().getNearbyEntities(newpos, 2, 2, 2));
List<Monster> monsters = CustomDamage.trimNonMonsterEntities(ents);
for (int i=0;i<monsters.size();i++) {
removeNoDamageTick(monsters.get(i), p);
}
for (int i=0;i<50;i++) {
newpos.getWorld().playEffect(newpos, Effect.FLAME, 60);
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Bukkit.getPluginManager().getPlugin("TwosideKeeper"), new Runnable() {
public void run() {
DealDamageToNearbyMobs(newpos2, dmgdealt, 2, true, 0.4d, p, weaponused, true);
p1.playSound(newpos2, Sound.ENTITY_ARMORSTAND_HIT, 1.0f, 0.3f);
}
},1);
DealDamageToNearbyMobs(newpos, dmgdealt, 2, true, 0.8d, p, weaponused, true);
//DecimalFormat df = new DecimalFormat("0.00");
p.playSound(p.getLocation(), Sound.ENTITY_ARMORSTAND_HIT, 1.0f, 0.5f);
int range=8;
for (int i=0;i<range;i++) {
final double xpos2=p.getLocation().getX();
final double ypos2=p.getLocation().getY();
final double zpos2=p.getLocation().getZ();
final Location newpos2=new Location(p.getWorld(),xpos2,ypos2,zpos2).add(i*xspd,i*yspd,i*zspd);
for (int j=0;j<50;j++) {
newpos.getWorld().playEffect(newpos, Effect.FLAME, 60);
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Bukkit.getPluginManager().getPlugin("TwosideKeeper"), new Runnable() {
public void run() {
DealDamageToNearbyMobs(newpos2, dmgdealt, 2, true, 0.4d, p, weaponused, true);
p1.playSound(newpos2, Sound.ENTITY_ARMORSTAND_HIT, 1.0f, 0.3f);
}
},1);
}
}
},(ex_version)?7:15);
if (ex_version) {
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
public void run() {
aPlugin.API.sendCooldownPacket(p, weaponused, GetModifiedCooldown(TwosideKeeper.LINEDRIVE_COOLDOWN,p));;
pd.last_strikerspell=TwosideKeeper.getServerTickTime();
}
},17);
}
},(ex_version)?7:15);
if (ex_version) {
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
public void run() {
aPlugin.API.sendCooldownPacket(p, weaponused, GetModifiedCooldown(TwosideKeeper.LINEDRIVE_COOLDOWN,p));;
pd.last_strikerspell=TwosideKeeper.getServerTickTime();
}
},17);
}
}
public static void PerformAssassinate(Player player, Material name) {
//Try to find a target to look at.
LivingEntity target = aPlugin.API.getTargetEntity(player, 100);
if (target!=null) {
if (target!=null && !target.isDead()) {
//We found a target, try to jump behind them now.
double mult = 0.0;
double pitch = 0.0;
@ -4259,6 +4340,10 @@ public class GenericFunctions {
//Automatically appends status effect buffs to the beginning of it.
public static void sendActionBarMessage(Player p, String message, boolean important) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (pd.rage_time>TwosideKeeper.getServerTickTime()) {
message = ChatColor.RED+" !! RAGE ACTIVE !! "+message;
}
if (important || (pd.lastimportantactionbarmsg+20<TwosideKeeper.getServerTickTime())) {
String prefix=ActionBarBuffUpdater.getActionBarPrefix(p);
if (prefix.length()>0) {
@ -4312,4 +4397,199 @@ public class GenericFunctions {
TwosideKeeper.log("Elite Monster for monster "+target.getName()+" UNDEFINED. Defaulting to EliteZombie type.", 0);
return new EliteZombie(target);
}
public static boolean AllowedToBeEquippedToOffHand(Player p, ItemStack item, int clickedslot) {
//TwosideKeeper.log("Slot:"+clickedslot, 0); 36-44 is hotbar.
return (ArrowQuiver.isValidQuiver(item)); /*||
(item.getType()==Material.SHIELD && (clickedslot<36 || !p.getEquipment().getItemInMainHand().equals(p.getInventory().getContents()[clickedslot-36])) && (PlayerMode.isDefender(p) || PlayerMode.isNormal(p))));*/
}
public static boolean isValidArrow(ItemStack item) {
return isValidArrow(item,false);
}
public static boolean isValidArrow(ItemStack item, boolean includeQuivers) {
if (item!=null && item.getType().name().contains("ARROW")) {
if (ArrowQuiver.isValidQuiver(item) && includeQuivers) {
return true;
} else
if (!ArrowQuiver.isValidQuiver(item)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
public static double calculateInfinityChance(Player p) {
return calculateInfinityChance(p.getEquipment().getItemInMainHand());
}
public static double calculateInfinityChance(ItemStack bow) {
if (bow.getType()==Material.BOW &&
bow.containsEnchantment(Enchantment.ARROW_INFINITE)) {
return bow.getEnchantmentLevel(Enchantment.ARROW_INFINITE)*0.1d;
} else {
return 0.0;
}
}
public static int getBasePotionDuration(PotionData bpd) {
boolean extended = bpd.isExtended();
boolean upgraded = bpd.isUpgraded();
if (bpd.getType()==PotionType.FIRE_RESISTANCE ||
bpd.getType()==PotionType.INVISIBILITY ||
bpd.getType()==PotionType.JUMP ||
bpd.getType()==PotionType.NIGHT_VISION ||
bpd.getType()==PotionType.POISON ||
bpd.getType()==PotionType.REGEN ||
bpd.getType()==PotionType.SPEED ||
bpd.getType()==PotionType.STRENGTH ||
bpd.getType()==PotionType.WATER_BREATHING) {
return (extended?20*0+(1200*8):upgraded?20*30+(1200*1):20*0+(1200*3));
}
if (bpd.getType()==PotionType.LUCK) {
return (20*0+(1200*5));
}
if (bpd.getType()==PotionType.POISON ||
bpd.getType()==PotionType.SLOWNESS ||
bpd.getType()==PotionType.WEAKNESS) {
return (extended?20*0+(1200*4):20*30+(1200*1));
}
return 0;
}
public static PotionEffectType convertPotionTypeToPotionEffectType(PotionType pt) {
switch (pt) {
case FIRE_RESISTANCE:
return PotionEffectType.FIRE_RESISTANCE;
case INSTANT_DAMAGE:
return PotionEffectType.HARM;
case INSTANT_HEAL:
return PotionEffectType.HEAL;
case INVISIBILITY:
return PotionEffectType.INVISIBILITY;
case JUMP:
return PotionEffectType.JUMP;
case LUCK:
return PotionEffectType.LUCK;
case NIGHT_VISION:
return PotionEffectType.NIGHT_VISION;
case POISON:
return PotionEffectType.POISON;
case REGEN:
return PotionEffectType.REGENERATION;
case SLOWNESS:
return PotionEffectType.SLOW;
case SPEED:
return PotionEffectType.SPEED;
case STRENGTH:
return PotionEffectType.INCREASE_DAMAGE;
case WATER_BREATHING:
return PotionEffectType.WATER_BREATHING;
case WEAKNESS:
return PotionEffectType.WEAKNESS;
default:
return PotionEffectType.HARM;
}
}
/**
* Attempts to heal the entity provided. This verifies that we do not
* surpass the maximum health of the entity.
*/
public static void HealEntity(LivingEntity p, double healamt) {
if (p.getHealth()+healamt<p.getMaxHealth()) {
p.setHealth(p.getHealth()+healamt);
} else {
p.setHealth(p.getMaxHealth());
}
}
public static boolean isAutoConsumeFood(ItemStack item) {
if (item!=null &&
(item.getType()==Material.ROTTEN_FLESH ||
item.getType()==Material.SPIDER_EYE)) {
return true;
} else {
return false;
}
}
@SuppressWarnings("deprecation")
public static void PerformArrowBarrage(Player p) {
if (p.isOnGround() && PlayerMode.isRanger(p) &&
(GenericFunctions.getBowMode(p.getEquipment().getItemInMainHand())==BowMode.SNIPE)) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (pd.last_arrowbarrage+GetModifiedCooldown(TwosideKeeper.ARROWBARRAGE_COOLDOWN,p)<=TwosideKeeper.getServerTickTime()) {
pd.last_arrowbarrage=TwosideKeeper.getServerTickTime();
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new ArrowBarrage(26,p,3), 3);
aPlugin.API.sendCooldownPacket(p, p.getEquipment().getItemInMainHand(), GetModifiedCooldown(TwosideKeeper.ARROWBARRAGE_COOLDOWN,p));
}
}
}
@SuppressWarnings("deprecation")
public static void PerformSiphon(Player p) {
if (p.isOnGround() && PlayerMode.isRanger(p) &&
(GenericFunctions.getBowMode(p.getEquipment().getItemInMainHand())==BowMode.DEBILITATION)) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (pd.last_siphon+GetModifiedCooldown(TwosideKeeper.SIPHON_COOLDOWN,p)<=TwosideKeeper.getServerTickTime()) {
List<LivingEntity> list = GenericFunctions.getNearbyMobs(p.getLocation(), 8);
List<LivingEntity> poisonlist = new ArrayList<LivingEntity>();
int totalpoisonstacks = 0;
for (LivingEntity ent : list) {
if (!(ent instanceof Player)) {
boolean haspoison=false;
if (ent.hasPotionEffect(PotionEffectType.POISON)) {
int poisonlv = GenericFunctions.getPotionEffectLevel(PotionEffectType.POISON, ent);
totalpoisonstacks+=poisonlv+1;
haspoison=true;
}
if (ent.hasPotionEffect(PotionEffectType.BLINDNESS)) {
int blindnesslv = GenericFunctions.getPotionEffectLevel(PotionEffectType.BLINDNESS, ent);
totalpoisonstacks+=blindnesslv+1;
haspoison=true;
}
if (haspoison) {
poisonlist.add(ent);
}
}
}
if (totalpoisonstacks>0) {
pd.last_siphon=TwosideKeeper.getServerTickTime();
p.playSound(p.getLocation(), Sound.BLOCK_FENCE_GATE_OPEN, 1.0f, 0.4f);
aPlugin.API.sendCooldownPacket(p, p.getEquipment().getItemInMainHand(), GetModifiedCooldown(TwosideKeeper.SIPHON_COOLDOWN,p));
for (LivingEntity ent : poisonlist) {
//Refresh poison stacks if necessary.
int totalpoisonlv = 0;
if (ent.hasPotionEffect(PotionEffectType.POISON)) {
int poisonlv = GenericFunctions.getPotionEffectLevel(PotionEffectType.POISON, ent);
int poisondur = GenericFunctions.getPotionEffectDuration(PotionEffectType.POISON, ent);
totalpoisonlv+=poisonlv+1;
if (poisondur<20*15) {
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.POISON, 20*15, poisonlv, ent, true);
}
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.SLOW, 20*15, poisonlv, ent);
}
if (ent.hasPotionEffect(PotionEffectType.BLINDNESS)) {
int poisonlv = GenericFunctions.getPotionEffectLevel(PotionEffectType.BLINDNESS, ent);
int poisondur = GenericFunctions.getPotionEffectDuration(PotionEffectType.BLINDNESS, ent);
totalpoisonlv+=poisonlv+1;
if (poisondur<20*15) {
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS, 20*15, poisonlv, ent, true);
}
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.SLOW, 20*15, poisonlv, ent);
}
CustomDamage.ApplyDamage(totalpoisonlv*10, p, ent, null, "Siphon", CustomDamage.TRUEDMG|CustomDamage.IGNOREDODGE|CustomDamage.IGNORE_DAMAGE_TICK);
}
CustomDamage.setAbsorptionHearts(p, CustomDamage.getAbsorptionHearts(p)+totalpoisonstacks*4);
}
}
}
}
}

@ -350,6 +350,12 @@ public enum RecipeLinker {
Recipes.getArrowFromMeta("POISON_ARR"),
new ItemStack(Material.RAW_FISH,1,(short)3),new ItemStack(Material.STICK),null,
new ItemStack(Material.FEATHER),
}),
piercingarrow("Custom Arrows",ChatColor.GREEN,"Piercing Arrow",new ItemStack[]{
Recipes.getArrowFromMeta("PIERCING_ARR"),
new ItemStack(Material.REDSTONE,1),new ItemStack(Material.REDSTONE,1),new ItemStack(Material.REDSTONE,1),
new ItemStack(Material.REDSTONE,1),new ItemStack(Material.FEATHER),new ItemStack(Material.FLINT),
new ItemStack(Material.STICK),
});
String name = "";

@ -6,14 +6,24 @@ import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Item;
import org.bukkit.entity.TippedArrow;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
import sig.plugin.TwosideKeeper.Artifact;
import sig.plugin.TwosideKeeper.Recipes;
import sig.plugin.TwosideKeeper.TwosideKeeper;
import sig.plugin.TwosideKeeper.HelperStructures.Common.ArrowQuiver;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
public class CustomItem {
@ -100,6 +110,17 @@ public class CustomItem {
TwosideKeeper.TRAPPING_ARROW_RECIPE = TrappingArrowRecipe();
TwosideKeeper.EXPLODING_ARROW_RECIPE = ExplodingArrowRecipe();
TwosideKeeper.POISON_ARROW_RECIPE = PoisonArrowRecipe();
TwosideKeeper.PIERCING_ARROW_RECIPE = PiercingArrowRecipe();
}
private static ShapelessRecipe PiercingArrowRecipe() {
ItemStack piercingarrow = Recipes.getArrowFromMeta("PIERCING_ARR");
ShapelessRecipe piercingarrow_recipe = new ShapelessRecipe(piercingarrow);
piercingarrow_recipe.addIngredient(Material.FLINT);
piercingarrow_recipe.addIngredient(4,Material.REDSTONE);
piercingarrow_recipe.addIngredient(Material.STICK);
piercingarrow_recipe.addIngredient(Material.FEATHER);
return piercingarrow_recipe;
}
@SuppressWarnings("deprecation")
@ -147,6 +168,67 @@ public class CustomItem {
return handmadearrow_recipe;
}
//Returns null if none found. This means you should probably just leave the arrow as it is.
public static ItemStack convertArrowEntityFromMeta(Arrow arrow) {
if (arrow.hasMetadata("DOUBLE_DAMAGE_ARR")) {
return Recipes.getArrowFromMeta("DOUBLE_DAMAGE_ARR");
}
if (arrow.hasMetadata("QUADRUPLE_DAMAGE_ARR")) {
return Recipes.getArrowFromMeta("QUADRUPLE_DAMAGE_ARR");
}
if (arrow.hasMetadata("TRAP_ARR")) {
return Recipes.getArrowFromMeta("TRAP_ARR");
}
if (arrow.hasMetadata("EXPLODE_ARR")) {
return Recipes.getArrowFromMeta("EXPLODE_ARR");
}
if (arrow.hasMetadata("POISON_ARR")) {
return Recipes.getArrowFromMeta("POISON_ARR");
}
if (arrow.hasMetadata("PIERCING_ARR")) {
return Recipes.getArrowFromMeta("PIERCING_ARR");
}
if (arrow.hasMetadata("SPECTRAL_ARROW")) {
return new ItemStack(Material.SPECTRAL_ARROW);
}
if (arrow.hasMetadata("TIPPED_ARROW") || arrow.hasMetadata("BASE_ARROW") || arrow instanceof TippedArrow) {
if (arrow instanceof TippedArrow) {
ItemStack item = new ItemStack(Material.TIPPED_ARROW);
PotionMeta pm = (PotionMeta)item.getItemMeta();
for (PotionEffect eff : ((TippedArrow)arrow).getCustomEffects()) {
pm.addCustomEffect(eff, true);
}
pm.setBasePotionData(((TippedArrow)arrow).getBasePotionData());
item.setItemMeta(pm);
TwosideKeeper.log("This item is "+item.toString(), 5);
return item;
} else {
ItemStack item = new ItemStack(Material.TIPPED_ARROW);
PotionMeta pm = (PotionMeta)item.getItemMeta();
if (arrow.hasMetadata("TIPPED_ARROW")) {
String effects = arrow.getMetadata("TIPPED_ARROW").get(0).asString();
for (String vals : effects.split(";")) {
String[] pieces = vals.split(",");
pm.addCustomEffect(new PotionEffect(PotionEffectType.getByName(pieces[0]),Integer.parseInt(pieces[1]),Integer.parseInt(pieces[2])),true);
}
}
if (arrow.hasMetadata("BASE_ARROW")) {
String[] pieces = arrow.getMetadata("BASE_ARROW").get(0).asString().split(",");
TwosideKeeper.log("Found Base Arrow. Pieces: "+pieces.toString(), 5);
if (PotionType.valueOf(pieces[0])!=PotionType.WATER) {
PotionData pd = new PotionData(PotionType.valueOf(pieces[0]),Boolean.parseBoolean(pieces[1]),Boolean.parseBoolean(pieces[2]));
TwosideKeeper.log("Applying"+pd.toString(), 5);
pm.setBasePotionData(pd);
}
}
item.setItemMeta(pm);
TwosideKeeper.log("This item is "+item.toString(), 5);
return item;
}
}
return null;
}
private static ShapelessRecipe CheckRecipe() {
ItemStack check = MoneyCheck();
ShapelessRecipe checkrecipe = new ShapelessRecipe(check);
@ -286,16 +368,17 @@ public class CustomItem {
ItemStack arrow_quiver = new ItemStack(Material.TIPPED_ARROW);
List<String> arrow_quiver_lore = new ArrayList<String>();
arrow_quiver_lore.add("A quiver that holds many arrows.");
arrow_quiver_lore.add(ChatColor.GRAY+"Arrows Remaining: "+ChatColor.YELLOW+"5");
arrow_quiver_lore.add(ArrowQuiver.ARROW_QUIVER_IDENTIFIER);
arrow_quiver_lore.add(ArrowQuiver.ID_PREFIX+"1");
ItemMeta arrow_quiver_meta=arrow_quiver.getItemMeta();
arrow_quiver_meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
arrow_quiver_meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
arrow_quiver_meta.setLore(arrow_quiver_lore);
arrow_quiver_meta.setDisplayName(ChatColor.BLUE+"Arrow Quiver");
arrow_quiver.setItemMeta(arrow_quiver_meta);
arrow_quiver.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 5);
arrow_quiver.setAmount(1);
arrow_quiver.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 5);
return arrow_quiver;
}

@ -14,9 +14,9 @@ import sig.plugin.TwosideKeeper.TwosideKeeper;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
public enum ItemSet {
PANROS(1,1, 3,2, 10,10, 20,10),
PANROS(1,1, 6,4, 10,10, 20,10),
SONGSTEEL(4,2, 6,2, 8,8, 20,10),
DAWNTRACKER(4,4, 20,10, 20,10, 6,4),
DAWNTRACKER(2,1, 20,10, 20,10, 10,5),
LORASYS(2,2, 0,0, 0,0, 0,0),
JAMDAK(3,3, 5,1, 10,1, 10,2), //Graceful Dodge is in ticks.
DARNYS(2,1, 10,5, 20,5, 1,1),
@ -25,7 +25,7 @@ public enum ItemSet {
MOONSHADOW(4,2, 1,1, 8,8, 15,7),
GLADOMAIN(1,1, 12,10, 8,8, 1,1),
WOLFSBANE(2,1, 15,10, 10,5, 15,10),
ALUSTINE(10,10, 10,-1, 5,-1, 6,4);
ALUSTINE(3,2, 300,-30, 50,-5, 6,2);
int baseval;
int increase_val;
@ -238,7 +238,7 @@ public enum ItemSet {
case DAWNTRACKER:{
lore.add(ChatColor.LIGHT_PURPLE+"Barbarian Gear");
lore.add(ChatColor.GOLD+""+ChatColor.BOLD+"T"+tier+" Dawntracker Set");
lore.add(ChatColor.YELLOW+"+"+ItemSet.GetBaseAmount(set, tier, 1)+" Health");
lore.add(ChatColor.YELLOW+"-"+(ItemSet.GetBaseAmount(set, tier, 1)/2)+" Health taken per hit");
}break;
case LORASYS:{
lore.add(ChatColor.LIGHT_PURPLE+"Slayer Gear");
@ -315,10 +315,12 @@ public enum ItemSet {
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:");
lore.add(ChatColor.DARK_AQUA+" 2 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 2)+"% Debuff Resistance");
lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 3)+"% Lifesteal");
lore.add(ChatColor.DARK_AQUA+" 4 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 4)+" Damage");
lore.add(ChatColor.DARK_AQUA+" 4 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 4)+" Max Health");
lore.add(ChatColor.DARK_AQUA+" 5 - "+ChatColor.WHITE+" Powered Mock");
lore.add(ChatColor.GRAY+" Mock debuff duration increases from");
lore.add(ChatColor.GRAY+" 10 -> 20 seconds, making it stackable.");
lore.add(ChatColor.GRAY+" All Lifesteal Stacks and Weapon Charges");
lore.add(ChatColor.GRAY+" gained are doubled.");
}break;
case LORASYS:{
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Bonus Effects");
@ -434,11 +436,14 @@ public enum ItemSet {
case ALUSTINE:{
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:");
lore.add(ChatColor.DARK_AQUA+" 2 - "+ChatColor.WHITE+" Gain immunity to Explosions.");
lore.add(ChatColor.DARK_AQUA+" "+ChatColor.WHITE+" Consumes "+ItemSet.GetBaseAmount(set, tier, 2)+" XP per absorbed hit.");
lore.add(ChatColor.DARK_AQUA+" "+ChatColor.WHITE+" Consumes "+ChatColor.YELLOW+ItemSet.GetBaseAmount(set, tier, 2)+" XP"+ChatColor.WHITE+" per absorbed hit.");
lore.add(ChatColor.DARK_AQUA+" "+ChatColor.GRAY+ChatColor.ITALIC+"Must have at least "+ChatColor.YELLOW+ChatColor.ITALIC+ItemSet.GetBaseAmount(set, tier, 2)+" XP"+ChatColor.GRAY+ChatColor.ITALIC+" to trigger.");
lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" Resists all fire, poison, and wither damage.");
lore.add(ChatColor.DARK_AQUA+" "+ChatColor.WHITE+" Consumes "+ItemSet.GetBaseAmount(set, tier, 3)+" XP per absorbed hit.");
lore.add(ChatColor.DARK_AQUA+" 5 - "+ChatColor.WHITE+" Backstabs spill "+ItemSet.GetBaseAmount(set, tier, 4)+" XP out from the target hit.");
lore.add(ChatColor.DARK_AQUA+" "+ChatColor.WHITE+" Has a "+Math.min((ItemSet.GetBaseAmount(set, tier, 4)/20d)*100d,100)+"% chance to restore 2 HP (1 Heart) on XP gain.");
lore.add(ChatColor.DARK_AQUA+" "+ChatColor.WHITE+" Consumes "+ChatColor.YELLOW+ItemSet.GetBaseAmount(set, tier, 3)+" XP"+ChatColor.WHITE+" per absorbed hit.");
lore.add(ChatColor.DARK_AQUA+" "+ChatColor.GRAY+ChatColor.ITALIC+"Must have at least "+ChatColor.YELLOW+ChatColor.ITALIC+ItemSet.GetBaseAmount(set, tier, 3)+" XP"+ChatColor.GRAY+ChatColor.ITALIC+" to trigger.");
lore.add(ChatColor.DARK_AQUA+" 5 - "+ChatColor.WHITE+" Backstabs spill "+ChatColor.YELLOW+ItemSet.GetBaseAmount(set, tier, 4)+" XP"+ChatColor.WHITE+" out from the target hit.");
lore.add(ChatColor.DARK_AQUA+" "+ChatColor.WHITE+" Collecting experience has a "+Math.min((ItemSet.GetBaseAmount(set, tier, 4)/20d)*100d,100)+"% chance");
lore.add(ChatColor.DARK_AQUA+" "+ChatColor.WHITE+" to restore 2 HP (1 Heart).");
lore.add(ChatColor.DARK_AQUA+" 7 - "+ChatColor.WHITE+" Provides the Following Bonuses:");
lore.add(ChatColor.GRAY+" "+ChatColor.WHITE+"Deal additional base damage equal to the");
lore.add(ChatColor.GRAY+" "+ChatColor.WHITE+"number of levels you have. Drains XP equal");

@ -158,7 +158,9 @@ public enum MonsterDifficulty {
} else
if (goodie.getType()!=Material.SKULL_ITEM &&
(set==ItemSet.MOONSHADOW ||
set==ItemSet.GLADOMAIN)) {
set==ItemSet.GLADOMAIN ||
set==ItemSet.WOLFSBANE ||
set==ItemSet.ALUSTINE)) {
goodie.setType(Material.SKULL_ITEM);
}
return goodie;
@ -172,7 +174,7 @@ public enum MonsterDifficulty {
}
}
public static ItemSet PickAnItemSet(PlayerMode pm) {
public static ItemSet PickAnItemSet(PlayerMode pm, MonsterDifficulty md) {
ItemSet set;
switch (pm) {
case STRIKER:{
@ -208,21 +210,30 @@ public enum MonsterDifficulty {
if (selectweight<10) {
set = ItemSet.LORASYS;
} else
if (selectweight<80) {
set = ItemSet.MOONSHADOW;
} else
{
set = ItemSet.GLADOMAIN;
switch (md) {
case DANGEROUS:{
set = ItemSet.ALUSTINE;
}
case DEADLY:{
set = ItemSet.MOONSHADOW;
}
case HELLFIRE:
case END:{
set = ItemSet.GLADOMAIN;
}
default:{
set = ItemSet.WOLFSBANE;
}
}
}break;
default:{
set = PickRandomSet();
set = PickRandomSet(md);
}
}
return set;
}
public static ItemSet PickRandomSet() {
public static ItemSet PickRandomSet(MonsterDifficulty md) {
final int NUMBER_OF_MODES=5;
int totalweight=50*NUMBER_OF_MODES; //50 for each mode.
int selectweight=(int)(Math.random()*totalweight);
@ -254,10 +265,20 @@ public enum MonsterDifficulty {
if (selectweight<205) {
return ItemSet.LORASYS;
} else
if (selectweight<223) {
return ItemSet.GLADOMAIN;
} else {
return ItemSet.MOONSHADOW;
switch (md) {
case DANGEROUS:{
return ItemSet.ALUSTINE;
}
case DEADLY:{
return ItemSet.MOONSHADOW;
}
case HELLFIRE:
case END:{
return ItemSet.GLADOMAIN;
}
default:{
return ItemSet.WOLFSBANE;
}
}
}
return ItemSet.PANROS;

@ -6,6 +6,7 @@ import org.bukkit.entity.Player;
import sig.plugin.TwosideKeeper.PlayerStructure;
import sig.plugin.TwosideKeeper.TwosideKeeper;
import sig.plugin.TwosideKeeper.HelperStructures.Common.ArrowQuiver;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
public enum PlayerMode {
@ -21,7 +22,7 @@ public enum PlayerMode {
+ ChatColor.WHITE+"->Hitting a target when they have not noticed you yet does x3 normal damage.\n"),
RANGER(ChatColor.DARK_GREEN,"R","Ranger",
ChatColor.DARK_GREEN+""+ChatColor.BOLD+"Ranger mode Perks: "+ChatColor.RESET+"\n"
+ ChatColor.WHITE+"->Players are identified as 'Rangers' when they carry a bow in their main hand. Off-hand items are permitted, except for a shield. Can only be wearing leather armor, or no armor.\n"
+ ChatColor.WHITE+"->Players are identified as 'Rangers' when they carry a bow or a quiver in one of their hands. Off-hand items are permitted, except for a shield. Can only be wearing leather armor, or no armor.\n"
+ ChatColor.GRAY+"->Left-clicking mobs will cause them to be knocked back extremely far, basically in headshot range, when walls permit.\n"
+ ChatColor.WHITE+"->Base Arrow Damage increases from x2->x4.\n"
+ ChatColor.GRAY+"->You can dodge 50% of all incoming attacks from any damage sources.\n"
@ -102,6 +103,9 @@ public enum PlayerMode {
if (Check_isStriker(p)) {
pd.lastmode=PlayerMode.STRIKER;
} else
if (Check_isBarbarian(p)) {
pd.lastmode=PlayerMode.BARBARIAN;
} else
if (Check_isDefender(p)) {
pd.lastmode=PlayerMode.DEFENDER;
} else
@ -175,15 +179,41 @@ public enum PlayerMode {
}
}
public static boolean isBarbarian(Player p) {
if (p!=null && !p.isDead()) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (needsUpdating(pd)) {
return getPlayerMode(p)==PlayerMode.BARBARIAN;
} else {
return pd.lastmode==PlayerMode.BARBARIAN;
}
} else {
return false;
}
}
public static boolean isNormal(Player p) {
if (p!=null && !p.isDead()) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (needsUpdating(pd)) {
return getPlayerMode(p)==PlayerMode.NORMAL;
} else {
return pd.lastmode==PlayerMode.NORMAL;
}
} else {
return false;
}
}
public static boolean Check_isRanger(Player p) {
if (p!=null && !p.isDead()) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (needsUpdating(pd)) {
if ((((p.getEquipment().getItemInMainHand()!=null && p.getEquipment().getItemInMainHand().getType()==Material.BOW && (p.getInventory().getExtraContents()[0]==null || p.getInventory().getExtraContents()[0].getType()==Material.AIR)) || //Satisfy just a bow in main hand.
(p.getEquipment().getItemInMainHand()!=null && p.getEquipment().getItemInMainHand().getType()==Material.BOW && p.getInventory().getExtraContents()[0]!=null && !GenericFunctions.isEquip(p.getInventory().getExtraContents()[0])) || /*Satisfy a bow in main hand and no shield in off-hand.*/
(p.getEquipment().getItemInMainHand()!=null && !GenericFunctions.isEquip(p.getEquipment().getItemInMainHand()) && p.getInventory().getExtraContents()[0]!=null && p.getInventory().getExtraContents()[0].getType()==Material.BOW) || /*Satisfy a bow in off-hand and no shield in main hand.*/
((p.getEquipment().getItemInMainHand()==null || p.getEquipment().getItemInMainHand().getType()==Material.AIR) && p.getInventory().getExtraContents()[0]!=null && p.getInventory().getExtraContents()[0].getType()==Material.BOW)) /*Satisfy just a bow in off-hand.*/ &&
if ((((p.getEquipment().getItemInMainHand()!=null && (p.getEquipment().getItemInMainHand().getType()==Material.BOW || ArrowQuiver.isValidQuiver(p.getEquipment().getItemInMainHand())) && (p.getInventory().getExtraContents()[0]==null || p.getInventory().getExtraContents()[0].getType()==Material.AIR)) || //Satisfy just a bow/quiver in main hand.
(p.getEquipment().getItemInMainHand()!=null && (p.getEquipment().getItemInMainHand().getType()==Material.BOW || ArrowQuiver.isValidQuiver(p.getEquipment().getItemInMainHand())) && p.getInventory().getExtraContents()[0]!=null && !GenericFunctions.isEquip(p.getInventory().getExtraContents()[0])) || /*Satisfy a bow/quiver in main hand and no shield in off-hand.*/
(p.getEquipment().getItemInMainHand()!=null && !GenericFunctions.isEquip(p.getEquipment().getItemInMainHand()) && p.getInventory().getExtraContents()[0]!=null && (p.getInventory().getExtraContents()[0].getType()==Material.BOW || ArrowQuiver.isValidQuiver(p.getInventory().getExtraContents()[0]))) || /*Satisfy a bow/quiver in off-hand and no shield in main hand.*/
((p.getEquipment().getItemInMainHand()==null || p.getEquipment().getItemInMainHand().getType()==Material.AIR) && p.getInventory().getExtraContents()[0]!=null && (p.getInventory().getExtraContents()[0].getType()==Material.BOW || ArrowQuiver.isValidQuiver(p.getInventory().getExtraContents()[0])))) /*Satisfy just a bow/quiver in off-hand.*/ &&
GenericFunctions.AllLeatherArmor(p))) {
return true;
} else {
@ -250,6 +280,24 @@ public enum PlayerMode {
}
}
public static boolean Check_isBarbarian(Player p) {
if (p!=null && !p.isDead()) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (needsUpdating(pd)) {
if (p.getEquipment().getItemInMainHand()!=null && p.getEquipment().getItemInMainHand().getType().toString().contains("_AXE") &&
p.getInventory().getExtraContents()[0]!=null && p.getInventory().getExtraContents()[0].getType().toString().contains("_AXE")) {
return true;
} else {
return false;
}
} else {
return pd.lastmode==PlayerMode.BARBARIAN;
}
} else {
return false;
}
}
String name="";
String desription="";

@ -228,6 +228,18 @@ public class Pronouns {
"got tangled by webs.",
};
}
case 18:{
pronouns = new String[]{
"took too much damage, and wilted away...",
"was a brave fighter. We will never forget.",
"could not handle the pressure, finally getting killed.",
"was not aware of how much damage they soaked up.",
"could not handle all the damage.",
"did not lifesteal fast enough.",
"braved the terrors of the world, but could not live to see another day.",
"fought until the very end of their life. But it was not enough.",
};
}
}
return pronouns[(int)(Math.random()*pronouns.length)];
}

@ -32,7 +32,9 @@ import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.Repairable;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import sig.plugin.TwosideKeeper.Artifact;
@ -150,26 +152,17 @@ public class WorldShop {
PotionMeta pot = (PotionMeta)item.getItemMeta();
if (!pot.getItemFlags().contains(ItemFlag.HIDE_POTION_EFFECTS)) {
List<PotionEffect> effects = pot.getCustomEffects();
PotionData baseeffects = pot.getBasePotionData();
for (int i=0;i<effects.size();i++) {
message+="\n"+ChatColor.GRAY+GenericFunctions.UserFriendlyPotionEffectTypeName(effects.get(i).getType())+" "+toRomanNumeral(effects.get(i).getAmplifier()+1)+ ((effects.get(i).getAmplifier()+1>0)?" ":"")+"("+toReadableDuration(effects.get(i).getDuration())+")";
}
if (effects.size()==0) { //Try this instead. It might be a legacy potion.
String duration = " "+(pot.getBasePotionData().isExtended()?"(8:00)":(pot.getBasePotionData().isUpgraded())?"(1:30)":"(3:00)");
String badduration = " "+(pot.getBasePotionData().isExtended()?"(4:00)":"(1:30)");
String luckduration = " (5:00)";
if (baseeffects!=null) { //Try this instead. It might be a legacy potion.
int duration = GenericFunctions.getBasePotionDuration(pot.getBasePotionData());
String power = (pot.getBasePotionData().isUpgraded()?"II":"");
if (item.getType() == Material.LINGERING_POTION) {
duration = " "+(pot.getBasePotionData().isExtended()?"(2:00)":(pot.getBasePotionData().isUpgraded())?"(0:22)":"(0:45)");
badduration = " "+(pot.getBasePotionData().isExtended()?"(1:00)":"(0:22)");
luckduration = " (1:15)";
if (item.getType()==Material.TIPPED_ARROW) {
duration/=8;
}
switch (pot.getBasePotionData().getType()) {
case FIRE_RESISTANCE:
message+="\n"+ChatColor.BLUE+"Fire Resistance"+duration;
message+="\n"+ChatColor.BLUE+"Fire Resistance ("+toReadableDuration(duration)+")";
break;
case INSTANT_DAMAGE:
message+="\n"+ChatColor.RED+"Instant Damage "+power;
@ -178,43 +171,49 @@ public class WorldShop {
message+="\n"+ChatColor.BLUE+"Instant Health "+power;
break;
case INVISIBILITY:
message+="\n"+ChatColor.BLUE+"Invisibility"+duration;
message+="\n"+ChatColor.BLUE+"Invisibility ("+toReadableDuration(duration)+")";
break;
case JUMP:
message+="\n"+ChatColor.BLUE+"Jump Boost "+power+duration;
message+="\n"+ChatColor.BLUE+"Leaping "+power+" ("+toReadableDuration(duration)+")";
break;
case LUCK:
message+="\n"+ChatColor.BLUE+"Luck"+luckduration;
message+="\n"+ChatColor.BLUE+"Luck ("+toReadableDuration(duration)+")";
break;
case NIGHT_VISION:
message+="\n"+ChatColor.BLUE+"Night Vision"+duration;
message+="\n"+ChatColor.BLUE+"Night Vision ("+toReadableDuration(duration)+")";
break;
case POISON:
message+="\n"+ChatColor.RED+"Poison "+power+badduration;
message+="\n"+ChatColor.RED+"Poison "+power +" ("+toReadableDuration(duration)+")";
break;
case REGEN:
message+="\n"+ChatColor.BLUE+"Regeneration "+power+duration;
message+="\n"+ChatColor.BLUE+"Regeneration "+power+" ("+toReadableDuration(duration)+")";
break;
case SLOWNESS:
message+="\n"+ChatColor.RED+"Slowness"+badduration;
message+="\n"+ChatColor.RED+"Slowness ("+toReadableDuration(duration)+")";
break;
case SPEED:
message+="\n"+ChatColor.BLUE+"Speed "+power+duration;
message+="\n"+ChatColor.BLUE+"Speed "+power +" ("+toReadableDuration(duration)+")";
break;
case STRENGTH:
message+="\n"+ChatColor.BLUE+"Strength "+power+duration;
message+="\n"+ChatColor.BLUE+"Strength "+power +" ("+toReadableDuration(duration)+")";
break;
case WATER_BREATHING:
message+="\n"+ChatColor.BLUE+"Water Breathing"+duration;
message+="\n"+ChatColor.BLUE+"Water Breathing ("+toReadableDuration(duration)+")";
break;
case WEAKNESS:
message+="\n"+ChatColor.RED+"Weakness"+badduration;
break;
default:
message+="\n"+ChatColor.GRAY+"No Effects";
message+="\n"+ChatColor.RED+"Weakness ("+toReadableDuration(duration)+")";
break;
default:
break;
}
}
for (int i=0;i<effects.size();i++) {
int duration = effects.get(i).getDuration();
if (item.getType()==Material.TIPPED_ARROW) {
duration/=8;
}
message+="\n"+(isBadPotionEffect(effects.get(i).getType())?ChatColor.RED:ChatColor.BLUE)+GenericFunctions.UserFriendlyPotionEffectTypeName(effects.get(i).getType())+" "+toRomanNumeral(effects.get(i).getAmplifier()+1)+ ((effects.get(i).getAmplifier()+1>0)?" ":"")+"("+toReadableDuration(duration)+")";
}
}
}
@ -469,6 +468,33 @@ public class WorldShop {
return message;
}
private static String divideDurationByEight(String dur) {
return dur.replace("0:22", "0:02").replace("0:45", "0:05").replace("1:00", "0:07").replace("1:15", "0:09").replace("1:30", "0:11").replace("2:00", "0:15").replace("3:00", "0:22").replace("4:00", "0:30").replace("5:00", "0:37").replace("8:00", "1:00");
}
private static boolean isBadPotionEffect(PotionEffectType type) {
if (type.equals(PotionEffectType.ABSORPTION) ||
type.equals(PotionEffectType.DAMAGE_RESISTANCE) ||
type.equals(PotionEffectType.FAST_DIGGING) ||
type.equals(PotionEffectType.FIRE_RESISTANCE) ||
type.equals(PotionEffectType.GLOWING) ||
type.equals(PotionEffectType.HEAL) ||
type.equals(PotionEffectType.HEALTH_BOOST) ||
type.equals(PotionEffectType.INCREASE_DAMAGE) ||
type.equals(PotionEffectType.INVISIBILITY) ||
type.equals(PotionEffectType.JUMP) ||
type.equals(PotionEffectType.LUCK) ||
type.equals(PotionEffectType.NIGHT_VISION) ||
type.equals(PotionEffectType.REGENERATION) ||
type.equals(PotionEffectType.SATURATION) ||
type.equals(PotionEffectType.SPEED) ||
type.equals(PotionEffectType.WATER_BREATHING)) {
return false;
} else {
return true;
}
}
public static String toReadableDuration(int duration) {
DecimalFormat df = new DecimalFormat("00");
return duration/1200+":"+df.format((duration/20)%60);

@ -21,6 +21,7 @@ public class LivingEntityStructure {
public double original_movespd = 0.0d;
public HashMap<UUID,Long> hitlist = new HashMap<UUID,Long>();
public HashMap<Player,GlowAPI.Color> glowcolorlist = new HashMap<Player,GlowAPI.Color>();
public long lastSpiderBallThrow = 0;
public LivingEntityStructure(LivingEntity m) {
target=null;

@ -700,7 +700,7 @@ public class MonsterController {
if (m.getCustomName().contains("Elite")) {
return MonsterDifficulty.ELITE;
} else
if (m.getCustomName().contains("End")) {
if (m.getCustomName().contains("End ")) {
return MonsterDifficulty.END;
} else
{

@ -75,7 +75,7 @@ public class PlayerStructure {
public List<ItemCubeWindow> openeditemcube;
public boolean openinginventory=false;
public boolean fulldodge=false;
public long last_dodge=TwosideKeeper.getServerTickTime();
public long last_arrowbarrage=TwosideKeeper.getServerTickTime();
public long last_laugh_time=TwosideKeeper.getServerTickTime();
public long last_rejuvenate=TwosideKeeper.getServerTickTime();
public DamageLogger damagedata;
@ -112,6 +112,11 @@ public class PlayerStructure {
public double thorns_amt = 0.0;
public long lastimportantactionbarmsg=0;
public long lasthighwinderhit=0;
public int lifestealstacks=0;
public int weaponcharges=0;
public double damagepool=0;
public long lastattacked=0;
public int lasthitfromdamagepool=0;
public long iframetime = 0;
@ -136,6 +141,12 @@ public class PlayerStructure {
public long lastrightclick = 0;
public boolean opened_another_cube=false;
public long damagepooltime=0;
public long last_siphon=0;
public long last_dodge=0;
public long last_mock=0;
public long rage_time=0; //Set this to the last tick that rage is supposed to last. It'll wear off after this.
public int rage_amt=0;
//Needs the instance of the player object to get all other info. Only to be called at the beginning.
@SuppressWarnings("deprecation")
@ -177,7 +188,7 @@ public class PlayerStructure {
this.openeditemcube = new ArrayList<ItemCubeWindow>();
this.openinginventory = false;
this.fulldodge=false;
this.last_dodge=(TwosideKeeper.getServerType()==ServerType.MAIN)?TwosideKeeper.getServerTickTime():0;
this.last_arrowbarrage=(TwosideKeeper.getServerType()==ServerType.MAIN)?TwosideKeeper.getServerTickTime():0;
this.lastarrowwasinrangermode=false;
this.isViewingInventory=false;
this.destroyedminecart=false;

@ -247,6 +247,15 @@ public class Recipes {
explosionarrow_recipe.addIngredient(Material.STICK);
explosionarrow_recipe.addIngredient(Material.FEATHER);
Bukkit.addRecipe(explosionarrow_recipe);
ItemStack piercingarrow = getArrowFromMeta("PIERCING_ARR");
ShapelessRecipe piercingarrow_recipe = new ShapelessRecipe(piercingarrow);
piercingarrow_recipe.addIngredient(Material.FLINT);
piercingarrow_recipe.addIngredient(4,Material.REDSTONE);
piercingarrow_recipe.addIngredient(Material.STICK);
piercingarrow_recipe.addIngredient(Material.FEATHER);
Bukkit.addRecipe(piercingarrow_recipe);
}
public static void Initialize_NotchApple_Recipe() {
@ -265,7 +274,7 @@ public class Recipes {
//pm.setBasePotionData(data);
pm.addCustomEffect(new PotionEffect(PotionEffectType.INVISIBILITY,0,0),true);
List<String> lore = new ArrayList<String>();
lore.add(ChatColor.GRAY+"Explodes on Contact (+80 dmg)");
lore.add(ChatColor.GRAY+"Explodes on Contact (+60 dmg)");
pm.setLore(lore);
pm.setDisplayName(ChatColor.GRAY+"Exploding Arrow");
explosionarrow.setItemMeta(pm);
@ -304,7 +313,7 @@ public class Recipes {
//pm.setBasePotionData(data);
pm.addCustomEffect(new PotionEffect(PotionEffectType.SPEED,0,0),true);
List<String> lore = new ArrayList<String>();
lore.add(ChatColor.GRAY+"x4 Damage");
lore.add(ChatColor.GRAY+"+15 Damage");
pm.setLore(lore);
pm.setDisplayName(ChatColor.AQUA+"Diamond-Tipped Arrow");
diamondtippedarrow.setItemMeta(pm);
@ -317,12 +326,26 @@ public class Recipes {
//pm.setBasePotionData(data);
pm.addCustomEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE,0,0),true);
List<String> lore = new ArrayList<String>();
lore.add(ChatColor.GRAY+"x2 Damage");
lore.add(ChatColor.GRAY+"+5 Damage");
pm.setLore(lore);
pm.setDisplayName(ChatColor.YELLOW+"Handmade Arrow");
handmadearrow.setItemMeta(pm);
return handmadearrow;
}
case "PIERCING_ARR": {
ItemStack piercingarrow = new ItemStack(Material.TIPPED_ARROW);
PotionMeta pm = (PotionMeta)piercingarrow.getItemMeta();
pm.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
//pm.setBasePotionData(data);
pm.addCustomEffect(new PotionEffect(PotionEffectType.HEAL,0,0),true);
List<String> lore = new ArrayList<String>();
lore.add(ChatColor.GRAY+"+5 Damage");
lore.add(ChatColor.RED+"Goes through all targets.");
pm.setLore(lore);
pm.setDisplayName(ChatColor.RED+"Piercing Arrow");
piercingarrow.setItemMeta(pm);
return piercingarrow;
}
}
return new ItemStack(Material.TIPPED_ARROW);
}

File diff suppressed because it is too large Load Diff

@ -21,6 +21,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.MonsterType;
import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode;
import sig.plugin.TwosideKeeper.HelperStructures.ServerType;
import sig.plugin.TwosideKeeper.HelperStructures.WorldShop;
import sig.plugin.TwosideKeeper.HelperStructures.Common.ArrowQuiver;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
public final class TwosideKeeperAPI {
@ -383,6 +384,14 @@ public final class TwosideKeeperAPI {
GenericFunctions.setUpgradeShardTier(item, tier);
}
//Arrow Quiver COMMANDS.
public static boolean isArrowQuiver(ItemStack i) {
return ArrowQuiver.isValidQuiver(i);
}
public static List<ItemStack> getArrowQuiverContents(ItemStack i) {
return ArrowQuiver.getContentsAPI(i);
}
//Localization COMMANDS.
public static String getLocalizedItemName(ItemStack i) {
return GenericFunctions.UserFriendlyMaterialName(i);

@ -268,8 +268,8 @@ public class WorldShopManager {
public void SaveShopPurchases() {
File config;
new File(TwosideKeeper.filesave,"shoppurchases.data").delete();
config = new File(TwosideKeeper.filesave,"shoppurchases.data");
config.delete();
FileConfiguration workable = YamlConfiguration.loadConfiguration(config);
//workable.set("recycling_center.count", nodes.size());

@ -14,6 +14,7 @@ import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import aPlugin.DiscordMessageSender;
import sig.plugin.TwosideKeeper.HelperStructures.ArtifactAbility;
@ -190,6 +191,22 @@ final class runServerHeartbeat implements Runnable {
if (pd.lastcombat+(20*60)<serverTickTime) {
pd.vendetta_amt=0;
pd.thorns_amt=0;
pd.weaponcharges=0;
}
if (pd.lastattacked+(20*5)<serverTickTime) {
pd.lastattacked=0;
pd.lifestealstacks=0;
}
if (pd.damagepool>0 && pd.damagepooltime+20<=serverTickTime) {
double transferdmg = CustomDamage.getTransferDamage(p);
TwosideKeeper.log("Transfer Dmg is "+transferdmg+". Damage Pool: "+pd.damagepool, 5);
CustomDamage.ApplyDamage(transferdmg, null, p, null, "Damage Pool", CustomDamage.IGNORE_DAMAGE_TICK|CustomDamage.TRUEDMG|CustomDamage.IGNOREDODGE);
if (pd.damagepool-transferdmg<=0) {
pd.damagepool=0;
} else {
pd.damagepool-=transferdmg;
}
}
if (pd.last_regen_time+TwosideKeeper.HEALTH_REGENERATION_RATE<=serverTickTime) {
@ -270,23 +287,10 @@ final class runServerHeartbeat implements Runnable {
GenericFunctions.deAggroNearbyTargets(p);
GenericFunctions.applyStealth(p, true);
}
/*List<Monster> mobs = GenericFunctions.getNearbyMobs(p.getLocation(), 16);
for (Monster m : mobs) {
if (!GenericFunctions.isIsolatedTarget(m,p) &&
!GenericFunctions.isSpecialGlowMonster(m) &&
m.getLocation().distanceSquared(p.getLocation())<196) {GlowAPI.setGlowing(m, GlowAPI.Color.WHITE, p);}
if (GenericFunctions.isIsolatedTarget(m,p) &&
!GenericFunctions.isSpecialGlowMonster(m) &&
GenericFunctions.GetNearbyMonsterCount(m, 8)>0) {
GlowAPI.setGlowing(m, false, p);
}
}*/
} else {
/*List<Monster> mobs = GenericFunctions.getNearbyMobs(p.getLocation(), 16);
for (Monster m : mobs) {
if (GenericFunctions.isIsolatedTarget(m,p) &&
!GenericFunctions.isSpecialGlowMonster(m)) {GlowAPI.setGlowing(m, false, p);}
}*/
}
if (PlayerMode.isBarbarian(p)) {
AutoConsumeFoods(p);
}
GenericFunctions.sendActionBarMessage(p, "");
@ -301,6 +305,24 @@ final class runServerHeartbeat implements Runnable {
TwosideKeeper.TwosideSpleefGames.TickEvent();
}
private void AutoConsumeFoods(Player p) {
if (p.getFoodLevel()<20 && PlayerMode.getPlayerMode(p)==PlayerMode.BARBARIAN) {
ItemStack[] contents = p.getInventory().getStorageContents();
for (int i=0;i<contents.length;i++) {
if (contents[i]!=null &&
GenericFunctions.isAutoConsumeFood(contents[i])) {
p.playSound(p.getLocation(), Sound.ENTITY_GENERIC_EAT, 1.0f, 1.0f);
p.setFoodLevel(Math.min(20, p.getFoodLevel()+1));
double basepercent = p.getMaxHealth()*0.01;
GenericFunctions.HealEntity(p,basepercent);
ItemStack singlecopy = contents[i].clone();
singlecopy.setAmount(1);
p.getInventory().removeItem(singlecopy);
}
}
}
}
private void MaintainMonsterData() {
Set<UUID> data= TwosideKeeper.livingentitydata.keySet();
TwosideKeeper.log("Size: "+TwosideKeeper.livingentitydata.size(), 2);
@ -310,9 +332,15 @@ final class runServerHeartbeat implements Runnable {
//TwosideKeeper.monsterdata.remove(data);
TwosideKeeper.ScheduleRemoval(TwosideKeeper.livingentitydata, ms);
TwosideKeeper.ScheduleRemoval(data, id);
TwosideKeeper.log("Removed Monster Structure for "+id+".", 2);
TwosideKeeper.log("Removed Monster Structure for "+id+".", 5);
} else {
AddEliteStructureIfOneDoesNotExist(ms);
if (ms.GetTarget()!=null && ms.GetTarget().isValid() && !ms.GetTarget().isDead()) {
//Randomly move this monster a tiny bit in case they are stuck.
double xdir=((ms.m.getLocation().getX()>ms.GetTarget().getLocation().getX())?-0.25:0.25)+(Math.random()/8)-(Math.random()/8);
double zdir=((ms.m.getLocation().getZ()>ms.GetTarget().getLocation().getZ())?-0.25:0.25)+(Math.random()/8)-(Math.random()/8);
ms.m.setVelocity(ms.m.getVelocity().add(new Vector(xdir,0,zdir)));
}
ms.UpdateGlow();
}
}

Loading…
Cancel
Save