Defender rework complete.

+>Defenders have been reworked!
+>Defenders now change their playstyle based on whether they are
blocking/sneaking.
+>See website/wiki (http://45.33.13.215/wiki/index.php/Modes#Defender)
or in-game Defender link (Click Defender in '/stats') for more info.
+>Songsteel set now improves Threat Generation.
+>Songsteel base HP for 2-piece set increased.
+>Songsteel base Defense for 4-piece set increased.
+>Protector set base Defense increased.
+>Sustenance set base Health increased.
+>Added Songsteel set 5-piece stat bonuses: Extra Damage Reduction +
Bonus Health
+>Sustenance set new 5-piece effect:
	Increases the Regeneration Pool for other party members by X whenever
you get hit. When party members are below half health, they will slowly
steal health from you as long as your Health is above 50%.
+>Striker passive damage increased from 10% -> 20%.
+>Striker critical strike chance increased from 20% -> 40%.
+>Line Drive cooldown decreased from 12 -> 6 seconds.
+>World Shop item prices are now consistent regardless of world
location.
+>New players that join are now given a Command guide and a Survival
guide that they can read to learn about the server!
+>When clicking the mode in '/stats' to learn about the perks, you are
given a book to read instead so there is less clutter.
>Protector set now requires you to use Unstoppable Team while
Rejuvenation is on cooldown (Since they use the same key input).
>Protector set 5-piece stat bonuses changed from Armor
Penetration+Damage to Party Damage Reduction+Bonus Party Health.
>Sustenance set 5-piece stat bonuses changed from Armor
Penetration+Damage to Lifesteal+Bonus Health.
>Fixed a bug where setting the damage of EntityDamagedEvent did not
reflect the changes in the damage formula.
>Fixed a bug causing certain damage calculations to not be applied for
basic attacking.
>Fixed a bug causing Ranger mode to not activate without set gear /
artifact gear.
->Absorption Health is now capped to your Maximum Health.
->All old Defender perks no longer apply. See 'Defender Rework' info
above.
->Songsteel set no longer provides Block Chance.
master
sigonasr2 8 years ago
parent b0f634c1d8
commit ffe7d5adb5
  1. 1
      .gitignore
  2. BIN
      TwosideKeeper.jar
  3. 32
      src/sig/plugin/TwosideKeeper/CustomDamage.java
  4. 30
      src/sig/plugin/TwosideKeeper/HelperStructures/Book.java
  5. 13
      src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java
  6. 4
      src/sig/plugin/TwosideKeeper/HelperStructures/ItemSet.java
  7. 114
      src/sig/plugin/TwosideKeeper/HelperStructures/PlayerMode.java
  8. 43
      src/sig/plugin/TwosideKeeper/HelperStructures/Utils/BookUtils.java
  9. 16
      src/sig/plugin/TwosideKeeper/HelperStructures/Utils/SoundUtils.java
  10. 5
      src/sig/plugin/TwosideKeeper/HelperStructures/WorldShop.java
  11. 28
      src/sig/plugin/TwosideKeeper/PlayerStructure.java
  12. 37
      src/sig/plugin/TwosideKeeper/TwosideKeeper.java
  13. 26
      src/sig/plugin/TwosideKeeper/runServerHeartbeat.java

1
.gitignore vendored

@ -1,3 +1,2 @@
.*
/bin
/projectBuilder.xml

Binary file not shown.

@ -826,7 +826,7 @@ public class CustomDamage {
damage = preventPoisonDamageFromKilling(p, damage, reason);
if (PlayerMode.getPlayerMode(p)==PlayerMode.SLAYER) {
TwosideKeeper.log("Is a Slayer.", 2);
//TwosideKeeper.log("Is a Slayer.", 2);
//PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (damage>2) {
damage=2;
@ -2066,6 +2066,15 @@ public class CustomDamage {
}
},1);
}
if (p.getEquipment().getItemInMainHand()!=null && p.getEquipment().getItemInMainHand().getType()==Material.SHIELD &&
p.getEquipment().getItemInOffHand()!=null && p.getEquipment().getItemInOffHand().getType()==Material.SHIELD){
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
@Override
public void run() {
p.setVelocity(p.getVelocity().multiply(0.5));
}
},1);
}
}
/*if (PlayerMode.isDefender(p) && p.isBlocking()) {
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
@ -2850,10 +2859,12 @@ public class CustomDamage {
dmgreductiondiv += ItemSet.GetTotalBaseAmount(p, ItemSet.PROTECTOR)/100d;
for (Player pl : PartyManager.getPartyMembers(p)) {
if (pl!=null && p!=null && !pl.equals(p)) {
if (PlayerMode.getPlayerMode(pl)==PlayerMode.DEFENDER &&
ItemSet.HasSetBonusBasedOnSetBonusCount(pl, ItemSet.PROTECTOR, 2)) {
if (ItemSet.HasSetBonusBasedOnSetBonusCount(pl, ItemSet.PROTECTOR, 2)) {
setbonusdiv += 0.1*ItemSet.GetPlayerModeSpecificMult(p);
}
if (ItemSet.hasFullSet(pl, ItemSet.PROTECTOR)) {
setbonusdiv += (ItemSet.getHighestTierInSet(pl, ItemSet.PROTECTOR)*0.1)*ItemSet.GetPlayerModeSpecificMult(p);
}
}
}
} else {
@ -3403,8 +3414,6 @@ public class CustomDamage {
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.WINDRY, 5) ||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.SHARD, 5) ||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.TOXIN, 5) ||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.PROTECTOR, 5) ||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.SUSTENANCE, 5) ||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.LEGION, 5) ||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.PRIDE, 5) ||
(ItemSet.meetsSlayerSwordConditions(ItemSet.LORASYS, 9, 1, (Player)shooter)) ||
@ -3646,7 +3655,7 @@ public class CustomDamage {
if (shooter instanceof Player) {
Player p = (Player)shooter;
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
critchance = addMultiplicativeValue(critchance,(PlayerMode.isStriker(p)?0.2:0.0));
critchance = addMultiplicativeValue(critchance,(PlayerMode.isStriker(p)?0.4:0.0));
critchance = addMultiplicativeValue(critchance,ItemSet.TotalBaseAmountBasedOnSetBonusCount(p,ItemSet.PANROS,4,4)/100d);
critchance = addMultiplicativeValue(critchance,(PlayerMode.isRanger(p)?(GenericFunctions.getPotionEffectLevel(PotionEffectType.SLOW, p)+1)*0.1:0.0));
critchance = addMultiplicativeValue(critchance,ItemSet.TotalBaseAmountBasedOnSetBonusCount(p, ItemSet.MOONSHADOW, 5, 4)/100d);
@ -3789,7 +3798,7 @@ public class CustomDamage {
if (damager instanceof Player) {
Player p = (Player)damager;
if (PlayerMode.isStriker(p)) {
mult+=0.1;
mult+=0.2;
}
}
return mult;
@ -3917,12 +3926,6 @@ public class CustomDamage {
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.TOXIN, 5)) {
finaldmg += dmg*0.5*armorpenmult;
} else
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.PROTECTOR, 5)) {
finaldmg += dmg*0.5*armorpenmult;
} else
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.SUSTENANCE, 5)) {
finaldmg += dmg*0.5*armorpenmult;
} else
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.LEGION, 5)) {
finaldmg += dmg*0.5*armorpenmult;
} else
@ -4155,6 +4158,9 @@ public class CustomDamage {
ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.PRIDE,6)) {
lifestealpct+=0.1d*ItemSet.GetItemTier(p.getEquipment().getItemInMainHand());
}
if (ItemSet.hasFullSet(p, ItemSet.SUSTENANCE)) {
lifestealpct+=ItemSet.getHighestTierInSet(p, ItemSet.SUSTENANCE)*0.25;
}
lifestealpct+=ItemSet.TotalBaseAmountBasedOnSetBonusCount(p, ItemSet.LEGION, 2, 2)/100d;
if (reason!=null && reason.equalsIgnoreCase("sweep up")) {
lifestealpct*=2;

@ -0,0 +1,30 @@
package sig.plugin.TwosideKeeper.HelperStructures;
import java.io.File;
import sig.plugin.TwosideKeeper.TwosideKeeper;
public enum Book {
BEGINNERSGUIDE("NewPlayerGuide.txt"),
COMMANDGUIDE("CommandGuide.txt"),
STRIKERGUIDE("StrikerGuide.txt"),
DEFENDERGUIDE("DefenderGuide.txt"),
RANGERGUIDE("RangerGuide.txt"),
SLAYERGUIDE("SlayerGuide.txt"),
BARBARIANGUIDE("BarbarianGuide.txt"),
ADVENTURERGUIDE("AdventurerGuide.txt");
String fileLoc;
Book(String loc) {
this.fileLoc=loc;
}
public File getBookFile() {
return new File(TwosideKeeper.plugin.getDataFolder()+"/books/"+this.fileLoc);
}
public String getBookFilepath() {
return TwosideKeeper.plugin.getDataFolder()+"/books/"+this.fileLoc;
}
}

@ -91,6 +91,7 @@ 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.Book;
import sig.plugin.TwosideKeeper.HelperStructures.BowMode;
import sig.plugin.TwosideKeeper.HelperStructures.CubeType;
import sig.plugin.TwosideKeeper.HelperStructures.CustomItem;
@ -2253,11 +2254,11 @@ public class GenericFunctions {
leather=false;
break;
}
ItemSet set = ItemSet.GetItemSet(equip);
/*ItemSet set = ItemSet.GetItemSet(equip);
if (!ItemSet.isRangerSet(set) && !GenericFunctions.isArtifactArmor(equip)) {
leather=false;
break;
}
}*/
}
return leather;
}
@ -2281,9 +2282,10 @@ public class GenericFunctions {
return tc;
}
public static String PlayerModeInformation(String mode) {
public static Book GetPlayerModeBook(String mode) {
PlayerMode pm = PlayerMode.valueOf(mode.toUpperCase());
return pm.getDesription();
//return pm.getDesription();
return pm.getBook();
}
public static boolean holdingNoShield(Player p) {
@ -2292,10 +2294,11 @@ public class GenericFunctions {
public static boolean isRareItem(ItemStack it) {
if (it!=null &&
it.getType()==Material.WRITTEN_BOOK || (
it.getType()!=Material.AIR &&
it.hasItemMeta() &&
it.getItemMeta().hasDisplayName() &&
it.getItemMeta().hasLore()
it.getItemMeta().hasLore())
) {
TwosideKeeper.log("Returning it!", 5);
return true;

@ -972,7 +972,9 @@ public enum ItemSet {
break;
case PROTECTOR:
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+PlayerMode.SLAYER.getColor()+PlayerMode.SLAYER.getName()+"s"+ChatColor.GOLD+" do not benefit from party effects");
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"of this set. "+PlayerMode.RANGER.getColor()+PlayerMode.RANGER.getName()+"s"+ChatColor.GOLD+" receive only half the effects.");
//TODO Enable when Summoner is released.
//lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"of this set. "+PlayerMode.RANGER.getColor()+PlayerMode.RANGER.getName()+"s "+ChatColor.GOLD+" and "+PlayerMode.SUMMONER.getColor()+PlayerMode.SUMMONER.getName()+"s "+ChatColor.GOLD+" receive only half the effects.");
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"of this set. "+PlayerMode.RANGER.getColor()+PlayerMode.RANGER.getName()+"s "+ChatColor.GOLD+" receive only half the effects.");
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:");
lore.add(ChatColor.DARK_AQUA+" 2 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 2, p)+"% Damage Reduction to other party members");
lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 3, p)+" Health to other party members.");

@ -11,108 +11,22 @@ import sig.plugin.TwosideKeeper.HelperStructures.Common.ArrowQuiver;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
public enum PlayerMode {
STRIKER(ChatColor.RED,"S","Striker",
ChatColor.RED+""+ChatColor.BOLD+"Striker mode Perks: "+ChatColor.RESET+"\n"
+ ChatColor.WHITE+"->Players are identified as 'Strikers' when they only carry a sword in their main hand. No off-hand items.\n"
+ ChatColor.GRAY+"->10% passive damage increase.\n"
+ ChatColor.WHITE+"->20% chance to critically strike.\n"
+ ChatColor.WHITE+"->Getting hit increases Speed by 1 Level. Stacks up to Speed V (Lasts five seconds.)\n"
+ ChatColor.GRAY+"->Swinging your weapon stops nearby flying arrows. Each arrow deflected will give you a Strength buff. Stacks up to Strength V (Lasts five seconds.)\n"
+ ChatColor.WHITE+"->Press the drop key to perform a line drive. Enemies you charge through take x1-x5 damage, based on target's missing health. This costs 5% of your durability (Unbreaking decreases this amount.)\n"
+ ChatColor.GRAY+"->Strikers have a 20% chance to dodge incoming attacks from any damage source while moving.\n"
+ 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 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 40% of all incoming attacks from any damage sources.\n"
+ ChatColor.WHITE+"You have immunity to all Thorns damage.\n"
+ ChatColor.GRAY+"Shift-Right Click to change Bow Modes.\n"
+ ChatColor.WHITE+"- "+ChatColor.BOLD+"Close Range Mode (Default):"+ChatColor.RESET+ChatColor.WHITE+" \n"
+ ChatColor.GRAY+" You gain the ability to deal headshots from any distance, even directly onto an enemy's face. Each kill made in this mode gives you 100% dodge chance for the next hit taken. You can tumble and gain invulnerability for 1 second by dropping your bow. Sneak while dropping it to tumble backwards.\n"
+ ChatColor.WHITE+"- "+ChatColor.BOLD+"Sniping Mode:"+ChatColor.RESET+ChatColor.WHITE+" \n"
+ ChatColor.GRAY+" Headshot collision area increases by x3. Headshots will deal an extra x0.125 damage for each headshot landed, up to a cap of 8 stacks. Each stack also increases your Slowness level by 1. You lose 10% dodge chance per Slowness stack, but gain one Resistance level and 10% critical chance per Slowness stack.\n"
+ ChatColor.WHITE+" Arrows are lightning-fast in Sniping Mode.\n"
+ ChatColor.GRAY+" Press the drop key in Sniping Mode to unleash 26 piercing arrows rapidly against your enemies.\n\n"
+ ChatColor.WHITE+"- "+ChatColor.BOLD+"Debilitation Mode:"+ChatColor.RESET+ChatColor.WHITE+" \n"
+ ChatColor.GRAY+" Adds a stack of Poison when hitting non-poisoned targets (15 second duration). Headshots made in this mode will increase the level of Poison on the mob, making the mob more and more vulnerable.\n"
+ ChatColor.WHITE+" Press the drop key in Debilitation Mode 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.\n"),
DEFENDER(ChatColor.GRAY,"D","Defender",
ChatColor.GRAY+""+ChatColor.BOLD+"Defender mode Perks: "+ChatColor.RESET+"\n"
+ ChatColor.WHITE+"->Players are identified as 'Defenders' when they use a shield in their main hand.\n"
+ ChatColor.GRAY+"->Base Damage reduction from shields increases from 5%->10%\n"
+ ChatColor.WHITE+"->Blocking damage reduction increases from 50->70%\n"
+ ChatColor.GRAY+"->When not blocking, you have Regeneration I. Blocking applies Regeneration II.\n"
+ ChatColor.WHITE+"->Blocking gives 8 health (4 hearts) of Absorption damage.\n"
+ ChatColor.GRAY+"->When hit while blocking, you build up Resistance, one level per hit, up to Resistance V (lasts 2 seconds)\n"
+ ChatColor.WHITE+"->While blocking, you absorb 50% of all damage taken by party members.\n"
+ ChatColor.GRAY+"->Blocking will aggro all nearby mobs to the blocking defender. They will glow indicate the aggro shift.\n"
+ ChatColor.WHITE+"->Base Health increased by 10 (5 hearts)\n"
+ ChatColor.GRAY+"->Getting hit as a defender increases saturation.\n"
+ ChatColor.WHITE+"->Hitting mobs as a Defender aggros them to you.\n"
+ ChatColor.GRAY+"->Knockback from attacks reduced by 75% while blocking.\n"
+ ChatColor.WHITE+"- "+ChatColor.BOLD+"Rejuvenation"+ChatColor.RESET+ChatColor.WHITE+"\n"
+ ChatColor.GRAY+"->Dropping your shield will give you 10 seconds of massive health regeneration and 2 seconds of invulnerability. It also costs 400 shield durability!\n"),
BARBARIAN(ChatColor.GOLD,"B","Barbarian",
ChatColor.GOLD+""+ChatColor.BOLD+"Barbarian mode Perks: "+ChatColor.RESET+"\n"
+ ChatColor.WHITE+"->Players are identified as 'Barbarians' by wielding an axe in both the main hand and the offhand.\n"
+ ChatColor.GRAY+"->Barbarians swing their off-hand by right-clicking.\n"
+ ChatColor.WHITE+"->Barbarians gain 2 HP (1 Heart) per 1% of Damage reduction.\n"
+ ChatColor.GRAY+"->When Barbarians are hit, they take damage as if they had 0% Damage reduction.\n"
+ ChatColor.WHITE+"->Barbarians deal 20% more damage for every 20% of an enemy's missing health.\n"
+ ChatColor.GRAY+"->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.\n"
+ ChatColor.WHITE+"->Barbarians do not instantly take full damage when hit. Instead, the HP is stored in a 'Damage Pool' and distributed every second.\n"
+ ChatColor.GRAY+"->If Barbarians have points in their 'Damage Pool', they will take up to 15 damage (+2% of their damage pool) every second. The amount taken goes down by wearing Barbarian gear.\n"
+ ChatColor.WHITE+"->When a monster is killed by a Barbarian, the amount of remaining damage in their Damage Pool is divided by 75%. If an ally kills one, the damage pool is divided by 33%\n"
+ ChatColor.GRAY+"->Extra health from Lifestealing that is not used for healing your health will heal up your Damage Pool instead."
+ ChatColor.WHITE+"->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.\n"
+ ChatColor.GRAY+"->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.\n"
+ ChatColor.WHITE+"->Barbarians have 70% knockback resistance.\n"
+ ChatColor.GRAY+"->Barbarians can release their Weapon Charges by using a variety of commands:\n"
+ ChatColor.WHITE+"->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.\n"
+ ChatColor.GRAY+"->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.\n"
+ ChatColor.WHITE+"->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.\n"
+ ChatColor.GRAY+"->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.\n"
+ ChatColor.WHITE+" Barbarian's Rage: \n"
+ ChatColor.GRAY+" -- Strength Level: +1 per 10 charges\n"
+ ChatColor.WHITE+" -- LifeSteal: +1% per 2 charges\n"
+ ChatColor.GRAY+" -- Speed V\n"
+ ChatColor.WHITE+" -- Duration of Rage: +1 second per 10 charges\n"
+ ChatColor.GRAY+" -- +2 seconds of invulnerability per 100 charges\n"
+ ChatColor.WHITE+"During Rage you gain double the number of Bonus Lifesteal stacks. You do not gain Weapon Charges during Barbarian's Rage.\n"
+ ChatColor.GRAY+"->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.\n"
+ ChatColor.WHITE+"->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.\n"
STRIKER(ChatColor.RED,"S","Striker",Book.STRIKERGUIDE),
RANGER(ChatColor.DARK_GREEN,"R","Ranger",Book.RANGERGUIDE),
DEFENDER(ChatColor.GRAY,"D","Defender",Book.DEFENDERGUIDE),
BARBARIAN(ChatColor.GOLD,"B","Barbarian",Book.BARBARIANGUIDE
),
SLAYER(ChatColor.DARK_BLUE,"SL","Slayer",
ChatColor.DARK_BLUE+""+ChatColor.BOLD+"Slayer mode Perks: "+ChatColor.RESET+"\n"
+ ChatColor.WHITE+"->Players are identified as 'Slayers' by wearing no armor, and wearing a Bauble Pouch in their off hand.\n"
+ ChatColor.GRAY+"->Slayers can make use of up to 9 Baubles by placing them in their Bauble Pouch. Each Bauble adds a certain amount of stats to the Slayer, making them more efficient.\n"
+ ChatColor.WHITE+"->Slayers take a maximum of 1 Heart (2 HP) in damage from all attacks, making this mode essentially 5 lives.\n"
+ ChatColor.GRAY+"->Slayers are not affected by any Health Recovery and Health Regeneration effects. This mode only heals from kills, being out of combat for 1 minute, using the Amulet's set effect, or sleeping. However, Absorption will still work for a Slayer. Absorption hearts just get removed with normal damage calculation rules.\n"
+ ChatColor.WHITE+"->Whenever a Slayer kills a target, they recover 1 Heart (2 HP). This can be modified by a special weapon.\n"
+ ChatColor.GRAY+"->Slayers can enter Stealth mode by pressing Sneak. Once in Stealth mode, Slayers will not leave stealth until they take damage or Sneak again. Stealth mode drains 1 Durability every second from tools on your hotbar.\n"
+ ChatColor.WHITE+"->While in Stealth mode, nothing will be able to detect you. Note this does not get rid of aggression from targets that have already aggro'd you.\n"
+ ChatColor.GRAY+"->Slayers can Backstab targets by getting behind them and hitting them. A backstab does 4x the normal damage of an attack.\n"
+ ChatColor.WHITE+"->Whenever a Slayer critically strikes, it suppresses a target for 0.75 seconds. Suppression prevents movement, attacking, teleporting, and exploding. Suppressed targets glow Black.\n"
+ ChatColor.GRAY+"->Slayers thrive in 1vs1 situations. If a target is completely alone, they will glow white to the Slayer. Isolated targets take 50% more damage from the Slayer. Slayer's Dodge Chance increases by 40% against isolated targets.\n"
+ ChatColor.WHITE+"->Slayers can use the Assassination ability. Press the Drop key while looking at an enemy to perform an assassination: You jump directly behind the enemy, gaining 0.5 seconds of invulnerability. If the next hit after Assassination is performed kills the target, you gain a speed and strength buff. These buffs cap at Speed V and Strength X respectively and last 10 seconds. Assassination cooldown is reset whenever a target is instantly killed in this manner, and you get immediately put back into stealth, preventing further detection from other monsters.\n"),
SLAYER(ChatColor.DARK_BLUE,"SL","Slayer",Book.SLAYERGUIDE),
/*SUMMONER(ChatColor.DARK_PURPLE,"SM","Summoner",
ChatColor.DARK_PURPLE+""+ChatColor.BOLD+"Summoner mode Perks: "+ChatColor.RESET+"\n"),*/
NORMAL(ChatColor.WHITE,"A","Adventurer",
ChatColor.WHITE+""+ChatColor.BOLD+"Adventurer mode Perks: "+ChatColor.RESET+"\n"
+ ChatColor.WHITE+"->Players are identified as 'Adventurers' by default.\n"
+ ChatColor.GRAY+"->Adventurers gain +10 Health.\n"
+ ChatColor.WHITE+"->Adventurers gain +20% Damage Reduction.\n"
+ ChatColor.GRAY+"->Adventurers gain +50% Health Regeneration.\n"
+ ChatColor.WHITE+"->If Adventurers are killed, their Buy-Backs are 50% cheaper.\n"
+ ChatColor.GRAY+"->Adventurers do not get exhausted when performing light activities.\n");
NORMAL(ChatColor.WHITE,"A","Adventurer",Book.ADVENTURERGUIDE);
;
final public static int UPDATE_GRACE_PERIOD=9; //How often to update the mode of the player.
ChatColor col=ChatColor.WHITE;
String symbol="";
Book storedBook;
public ChatColor getColor() {
return col;
@ -339,21 +253,21 @@ public enum PlayerMode {
}
String name="";
String desription="";
Book helperBook;
public String getDesription() {
return desription;
public Book getBook() {
return helperBook;
}
public void setDesription(String desription) {
this.desription = desription;
public void setBook(Book book) {
this.helperBook = book;
}
PlayerMode(ChatColor col, String abbreviation, String fullname, String desc) {
PlayerMode(ChatColor col, String abbreviation, String fullname, Book descBook) {
this.col=col;
this.symbol=abbreviation;
this.name=fullname;
this.desription=desc;
this.helperBook=descBook;
}

@ -0,0 +1,43 @@
package sig.plugin.TwosideKeeper.HelperStructures.Utils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import sig.plugin.TwosideKeeper.TwosideKeeper;
import sig.plugin.TwosideKeeper.HelperStructures.Book;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
public class BookUtils {
public static void GiveBookToPlayer(Player p,Book book) {
File file = book.getBookFile();
if (file.exists()) {
ItemStack bookItem = new ItemStack(Material.WRITTEN_BOOK);
BookMeta meta = (BookMeta)bookItem.getItemMeta();
String[] contents = FileUtils.readFromFile(book.getBookFilepath());
List<String> bookContents = new ArrayList<String>();
for (int i=0;i<contents.length;i++) {
bookContents.add(ChatColor.translateAlternateColorCodes('&', contents[i]).replace("\\n", "\n"));
}
//meta.setTitle(bookContents.remove(0));
meta.setDisplayName(bookContents.remove(0));
meta.setAuthor(bookContents.remove(0));
meta.setPages(bookContents);
bookItem.setItemMeta(meta);
GenericFunctions.giveItem(p, bookItem);
} else {
try {
TwosideKeeper.log("WARNING! Book "+book.name()+" does not exist! Create a file in "+file.getCanonicalPath(), 1);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

@ -25,27 +25,35 @@ public class SoundUtils {
*/
public static void playIndividualGlobalSound(Location loc, Sound sound, float vol, float pitch) {
for (Player p : Bukkit.getOnlinePlayers()) {
p.playSound(loc, sound, vol, pitch);
if (!p.isDead()) {
p.playSound(loc, sound, vol, pitch);
}
}
}
/**
* Plays a sound at the player's location, as if they were hearing a regular sound in the client.
*/
public static void playLocalSound(Player p, Sound sound, float vol, float pitch) {
SoundUtils.playLocalSound(p,p.getLocation(), sound, vol, pitch);
if (!p.isDead()) {
SoundUtils.playLocalSound(p,p.getLocation(), sound, vol, pitch);
}
}
/**
* Plays a sound at the specified location for a single player, as if they were hearing a regular sound in the client.
*/
public static void playLocalSound(Player p, Location loc, Sound sound, float vol, float pitch) {
p.playSound(loc, sound, vol, pitch);
if (!p.isDead()) {
p.playSound(loc, sound, vol, pitch);
}
}
/**
* Plays a sound at the player's location for every player, as if they were hearing a regular sound in the client. Useful for notifications/pings.
*/
public static void playLocalGlobalSound(Sound sound, float vol, float pitch) {
for (Player p : Bukkit.getOnlinePlayers()) {
SoundUtils.playLocalSound(p, sound, vol, pitch);
if (!p.isDead()) {
SoundUtils.playLocalSound(p, sound, vol, pitch);
}
}
}

@ -181,7 +181,8 @@ public class WorldShop {
}
private double ModifyPriceBasedOnLocation(double price) {
if (!loc.getWorld().equals(TwosideKeeper.TWOSIDE_LOCATION.getWorld())) {
////NO LONGER INCREASES BASED ON DISTANCE OR WORLD!!
/*if (!loc.getWorld().equals(TwosideKeeper.TWOSIDE_LOCATION.getWorld())) {
//This is in another world. Automatically increase price by x4.
price *= 4;
} else {
@ -202,7 +203,7 @@ public class WorldShop {
if (loc.getBlockY()<=16) {
price *= 1.5;
}
}
}*/
return Math.round(price*100)/100d;
}

@ -17,14 +17,21 @@ import org.bukkit.boss.BossBar;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.scoreboard.Team;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import sig.plugin.TwosideKeeper.HelperStructures.AdvancedTitle;
import sig.plugin.TwosideKeeper.HelperStructures.Book;
import sig.plugin.TwosideKeeper.HelperStructures.BowMode;
import sig.plugin.TwosideKeeper.HelperStructures.Channel;
import sig.plugin.TwosideKeeper.HelperStructures.DeathStructure;
@ -33,6 +40,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.OptionsMenu;
import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode;
import sig.plugin.TwosideKeeper.HelperStructures.ServerType;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.BookUtils;
import sig.plugin.TwosideKeeper.Logging.DamageLogger;
//import com.google.common.graph.*;
@ -385,13 +393,16 @@ public class PlayerStructure {
p.getInventory().addItem(new ItemStack(Material.LEATHER_LEGGINGS,1));
p.getInventory().addItem(new ItemStack(Material.TORCH,8));
p.getInventory().addItem(new ItemStack(Material.BREAD,16));*/
ItemStack manual = new ItemStack(Material.WRITTEN_BOOK);
/*ItemStack manual = new ItemStack(Material.WRITTEN_BOOK);
BookMeta bm = (BookMeta)manual.getItemMeta();
bm.setAuthor("Sig's Minecraft");
//bm.setPage(arg0, arg1);
CreateBeginnersManual(bm);
manual.setItemMeta(bm);
p.getInventory().addItem(manual);
*/
BookUtils.GiveBookToPlayer(p, Book.COMMANDGUIDE);
BookUtils.GiveBookToPlayer(p, Book.BEGINNERSGUIDE);
//Make sure it's not already there...?
if (Bukkit.getServer().getScoreboardManager().getMainScoreboard().getTeam(this.name.toLowerCase())==null) {
Bukkit.getServer().getScoreboardManager().getMainScoreboard().registerNewTeam(this.name.toLowerCase()).addPlayer(p);
@ -419,6 +430,17 @@ public class PlayerStructure {
}
}
private void CreateBeginnersManual(BookMeta bm) {
TextComponent com = new TextComponent("This is a test component");
com.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,"/stats"));
com.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,new ComponentBuilder("Hello").create()));
List<String> bookContents = new ArrayList<String>();
bm.setPages();
}
public static void setDefaultCooldowns(Player p) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
aPluginAPIWrapper.sendCooldownPacket(p, Material.BOW, GenericFunctions.GetRemainingCooldownTime(p, pd.last_dodge, TwosideKeeper.DODGE_COOLDOWN));

@ -271,6 +271,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.Effects.WindSlash;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.ArrayUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.ArtifactUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.BlockUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.BookUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.DebugUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.EntityUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.InventoryUtils;
@ -486,7 +487,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
public static final int DEATHMARK_COOLDOWN=240;
public static final int EARTHWAVE_COOLDOWN=100;
public static final int ERUPTION_COOLDOWN=100;
public static final int LINEDRIVE_COOLDOWN=240;
public static final int LINEDRIVE_COOLDOWN=120;
public static final int MOBCONTROL_COOLDOWN=200;
public static final int ASSASSINATE_COOLDOWN=200;
public static final int LIFESAVER_COOLDOWN=6000;
@ -1411,6 +1412,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
selectednumb = (int)(Math.random()*101);
attempts--;
}
aPlugin.API.discordSendRaw("Rolled **"+selectednumb+"**");
recentnumbers.add(selectednumb);
},"roll");
}, 90);
@ -1945,6 +1947,20 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
}
}
}break;
case "IDENTIFYBLOCKS":{
StringBuilder blocklist = new StringBuilder();
for (int y=-1;y<2;y++) {
for (int z=-1;z<2;z++) {
for (int x=-1;x<2;x++) {
blocklist.append(p.getLocation().getBlock().getRelative(x, y, z).getType()+",");
}
blocklist.append("\n");
}
blocklist.append("==========\n");
}
p.sendMessage(blocklist.toString());
TwosideKeeper.log(blocklist.toString(),0);
}break;
case "GLOWNEARBY":{
List<Entity> nearby = p.getNearbyEntities(10, 10, 10);
for (Entity e : nearby) {
@ -2078,7 +2094,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
}
}break;
case "PARTICLE":{
aPluginAPIWrapper.sendParticle(p.getLocation(), EnumParticle.valueOf(args[1]), 0, 1, 0, 1, 50);
//aPluginAPIWrapper.sendParticle(p.getLocation(), EnumParticle.valueOf(args[1]), 0, 1, 0, 1, 50);
ColoredParticle.RED_DUST.send(p.getLocation().add(p.getLocation().getDirection()), 500, Integer.parseInt(args[1]), Integer.parseInt(args[2]), Integer.parseInt(args[3]));
}break;
case "SPECIALHORSE":{
Horse h = (Horse)p.getWorld().spawnEntity(p.getLocation(), EntityType.HORSE);
@ -2700,6 +2717,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
case "MINIBOSSES":{
p.sendMessage("There are "+(GenericBoss.nearbyBosses(p.getLocation(),50))+" Minibosses nearby.");
}break;
case "SETHEALTH":{
p.setHealth(Integer.parseInt(args[1]));
}break;
}
}
//LivingEntity m = MonsterController.convertMonster((Monster)p.getWorld().spawnEntity(p.getLocation(),EntityType.ZOMBIE), MonsterDifficulty.ELITE);
@ -3013,7 +3033,11 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
} else
if (cmd.getName().equalsIgnoreCase("mode")) {
if (args.length==1) {
sender.sendMessage(GenericFunctions.PlayerModeInformation(args[0]));
Player p = (Player)sender;
//sender.sendMessage(GenericFunctions.PlayerModeInformation(args[0]));
PlayerMode mode = PlayerMode.valueOf(args[0].toUpperCase());
sender.sendMessage("You have obtained a book describing "+mode.getColor()+mode.getName()+"s");
BookUtils.GiveBookToPlayer(p, GenericFunctions.GetPlayerModeBook(args[0]));
return true;
} else {
sender.sendMessage("Wrong arguments!");
@ -6381,7 +6405,6 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
@SuppressWarnings("deprecation")
@EventHandler(priority=EventPriority.LOW,ignoreCancelled = true)
public void onPlayerDropItem(PlayerDropItemEvent ev) {
InventoryUpdateEvent.TriggerUpdateInventoryEvent(ev.getPlayer(),ev.getItemDrop().getItemStack(),UpdateReason.DROPPEDITEM);
if (GenericFunctions.isArtifactEquip(ev.getItemDrop().getItemStack())) {
@ -11824,6 +11847,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
if (ItemSet.hasFullSet(p, ItemSet.SONGSTEEL)) {
bonushp+=(ItemSet.getHighestTierInSet(p, ItemSet.SONGSTEEL)*20)+30;
} else
if (ItemSet.hasFullSet(p, ItemSet.SUSTENANCE)) {
bonushp+=ItemSet.getHighestTierInSet(p, ItemSet.SUSTENANCE)*25;
}
bonushp+=ItemSet.TotalBaseAmountBasedOnSetBonusCount(p, ItemSet.ALIKAHN, 2, 2)+ItemSet.TotalBaseAmountBasedOnSetBonusCount(p, ItemSet.ALIKAHN, 3, 3);
@ -11886,6 +11912,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
if (pl!=null && p!=null && !pl.equals(p)) {
//TwosideKeeper.log("Found a Defender: "+pl.getName(), 0);
bonushp+=ItemSet.TotalBaseAmountBasedOnSetBonusCount(pl, ItemSet.PROTECTOR, 3, 3)*ItemSet.GetPlayerModeSpecificMult(p);
if (ItemSet.hasFullSet(pl, ItemSet.PROTECTOR)) {
bonushp+=(ItemSet.getHighestTierInSet(pl, ItemSet.PROTECTOR)*5)*ItemSet.GetPlayerModeSpecificMult(p);
}
//TwosideKeeper.log("Increased health by: "+(ItemSet.TotalBaseAmountBasedOnSetBonusCount(pl, ItemSet.PROTECTOR, 3, 3)*ItemSet.GetPlayerModeSpecificMult(p))+" HP.", 0);
}
}

@ -1118,6 +1118,32 @@ final public class runServerHeartbeat implements Runnable {
}
}
}
if (p.getHealth()>p.getMaxHealth()/2 && ItemSet.hasFullSet(p, ItemSet.SUSTENANCE)) {
double healAmt = p.getHealth()*0.05;
Player lowestHPPlayer = null;
List<Player> partymembers = PartyManager.getPartyMembers(p);
for (Player pl : partymembers) {
if (!pl.equals(p)) {
if (pl.getHealth()<pl.getMaxHealth()/2) {
if (lowestHPPlayer==null || (lowestHPPlayer.getHealth()/lowestHPPlayer.getMaxHealth())>(pl.getHealth()/pl.getMaxHealth())) {
lowestHPPlayer = pl;
}
}
}
}
if (lowestHPPlayer!=null) {
SoundUtils.playGlobalSound(p.getLocation(), Sound.BLOCK_NOTE_HAT, 1.0f, 0.8f);
p.setHealth(Math.max(0, p.getHealth()-healAmt));
lowestHPPlayer.setHealth(Math.min(lowestHPPlayer.getMaxHealth(), lowestHPPlayer.getHealth()+healAmt));
Vector dir = MovementUtils.pointTowardsLocation(lowestHPPlayer.getLocation(), p.getLocation());
for (int i=0;i<p.getLocation().distance(lowestHPPlayer.getLocation())*4;i++) {
Vector newdir = dir.clone();
newdir.multiply(i*0.25);
newdir.setY(newdir.getY()+1);
ColoredParticle.RED_DUST.send(lowestHPPlayer.getLocation().add(newdir), 50, 0, 255, 0);
}
}
}
}
private void ApplyCometRegenBonus(Player p) {

Loading…
Cancel
Save