Implemented all new mechanics for Hellfire monsters. Cleanup and minor

bugs added. Full Notes:

+>Party Matching now does not create a party until at least two players
are within the vicinity of each other. This effectively increases the
cap of players in parties from 16 players to 32 players, if all 16
parties were filled with 2 players each.
+>Added the EntityDamagedEvent which returns the amount of damage an
entity takes and the cause of the damage. This is also cancellable which
will prevent the entity from losing health and prevents on-hit effects
from being applied.
+>Added isWorldShopSign() to the API to detect if a sign is attached to
a world shop.
+>Added getWorldShopItemBasePrice() to the API. Returns the base price
of any item using the new world shop pricing system.
+>Added LivingEntity versions of all Monster commands to the API.
+>The beginning stages of gearing can be a pain as you can get one shot
by most mobs at the Dangerous tier even with some iron pieces. While one
solution may be to lower the damage
output of Dangerous monsters, it seems the drops are good enough to
justify the difficulty of this range. Instead we decided to decrease the
gearing gap between Leather/Iron versus Diamond/Gold.
This provides players with more meaningful upgrade routes and makes
damage reduction feel more impactful early game. After all, the first
30% of defense hardly matters.

The scale went from looking like this:
	L3<I5<LH6<D8<G10<IH10<DH16<GH20 
TO THIS: 
	L6<I7<D8<G10<LH12<IH14<DH16<GH20

Progression-wise, the second scale makes more sense as it keeps the
armor upgrades in the same order while emphasizing that any Hardened
piece is automatically
better than a regular Gold piece.

+>Flat Damage Reduction from Leather armor increased from 3/6% per piece
(Regular/Hardened) to 6/12% per piece.
+>Flat Damage Reduction from Iron armor increased from 5/10% per piece
to 7/14% per piece.
+>Fire eruptions now occur in the Nether to liven up the tame lava seas.
+>Fire Protection now actually reduces damage dealt	by fires. This is
actually very important with the update below!
+>Fire and Lava now increases your fire ticks indefinitely, therefore
the longer you stay in lava, the longer you will burn until it gets
removed!
+>Fire ticks will deal more damage the larger your fire tick count is!
This is mitigated heavily by Fire Protection on armor. Do NOT stand in
fire too long or YOU WILL die!
+>Fire tick stacks now show up in the action bar.
+>World Shops have been revamped. World Shop prices are now controlled
externally and can be rebalanced and modified at any time. Signs will
reflect these changes when viewing the items.
+>Any player can now place and remove world shops, the shop will
automatically be setup. Crafting Recipe for a world shop is
<ITEM>+Chest/Trapped Chest+Sign. <ITEM> can be any item.
+>Prices of World Shops dynamically change based on the location the
shop in relation to the center of Twoside. Every 10000 blocks away
doubles the price of the item. Going underground increases the price by
50% per difficulty level. Placing a world shop in another dimension
multiplies the price by x4.
+>The 'Deal of the Day' has been added as an incentive to purchase items
from world shops on certain days. Keep an eye out for an item you may
want to purchase! The item will be discounted everywhere regardless of
location!
+>Players that can attack on a moment's notice can make the most use of
a weapon's damage. Sprinting and attacking from mid-air deals 20% more
damage.
+>Some sound effects regarding combat has been globalized so all nearby
players can hear the action that is going on.
+>The Tactics job now has bonuses activated on all combat stats.
+>Fixed Localization of the different versions of the Anvil. (Slightly
Damaged and Very Damaged)
+>Added a new version of the 'Earth Wave' artifact ability. Damage
scaling decreased, but has huge AoE potential and deals double damage on
soft ground. Has no cooldown, but difficult to use without a height
advantage.
+>Added in Vacuum Cubes and Filter Cubes. See '/craft' for the crafting
recipes of these two new Cubes.
	Vacuum Cubes only store placeable blocks and suck up all nearby items.
	Filter Cubes have a special inventory accessed by shift-right clicking
which will automatically insert items of the same type into its
inventory automatically!
+>All entity types can now be modified with difficulty tags, this means
Deadly Horses, Dangerous Wolves, and Hellfire Slimes (and many more!)
are now a thing.
+>Nether difficulty spawning rules have been added: As you get further
and further away from the main hub in the Nether, the monsters increase
in difficulty. No longer depth-dependent like in the Overworld.
+>Health of all monsters within the Nether world have been increased
significantly.
+>Hellfire Ghast behavior has been modified. They now shoot faster
fireballs and at a much faster rate. They will also attempt to suicide
when low.
+>Blaze behavior has been modified. Blazes fire more fireballs, and they
explode on contact now. In addition, Hellfire Blazes now set the area on
fire temporarily.
+>Magma Cubes now buff all nearby monsters with higher defenses.
20%/40%/60%/80% damage reduction for Normal/Dangerous/Deadly/Hellfire
tiers respectively.
+>The item drop rate in the Nether has been increased by 30%.
>Diamond armor (8/16% per piece) and Gold armor (10/20% per piece)
defense values remain the same.
>The Hunter's Compass is now more aggressive at looking for Elite spawn
locations.
>Fixed a bug causing the artifact ability leveling menu to never appear
for artifacts T11 or higher.
>Fixed a bug causing shop purchase notifications to crash the server if
certain conditions are met.
>Fixed a bug causing arrow quivers to mysteriously vanish from players'
inventories when running out of arrows.
>Fixed a bug causing Ranger gear to drop with a lower tier rate than
other items.
>Fixed a bug causing Non-Monster creatures to create errors when
attempting to use Eruption on them.
>Fixed a bug causing the party bonus to not increase damage to party
members.
>Fixed a bug preventing Artifact armor from losing durability from all
sources of damage.
>Fixed a bug causing errors when using name tags on non-hostile
creatures.
>Fixed a bug where the cooldown indicator for the Eruption ability was
not properly adjusting with increased cooldown reduction.
>Fixed a bug preventing players from inserting items into Item Cubes
when the ID of the Item Cube window they are viewing is the same as the
ID of the cube they are inserting into.
>Fixed a bug where players were receiving damage reduction by holding
armor in their hand.
>Moved Arrow Quivers from the Misc. Items category to the Containers
category in the /craft menu.
>Modified heart display of mobs to display transparent hearts for
missing health. 
>Fixed bugs relating to players being unable to obtain all achievements
due to plugins manipulating them.
>Fixed a bug preventing Slime and Magma Cube splits from happening
properly when they die.
->Decreased the chance Coal dropped from monsters significantly.
->Decreased the chance Ender Chests dropped from monsters significantly.
->Decreased the drop rate of tier-less/surface monsters.
->Ranger Base Dodge Chance decreased from 50%->40%.
->Proper footing is important to maximizing damage. Attacks from mid-air
now deal 20% less damage when not sprinting.
->Ranger Invincibility Time on Tumble with a full set decreased from 3
seconds -> 1.5 seconds.
->Deprecated all Monster versions of the Monster commands in the API.
The newer system uses Living Entities instead.
testdev
sigonasr2 8 years ago
parent aa25cf1792
commit a15d7dd735
  1. BIN
      TwosideKeeper.jar
  2. 75
      src/sig/plugin/TwosideKeeper/CustomDamage.java
  3. 10
      src/sig/plugin/TwosideKeeper/CustomMonster.java
  4. 8
      src/sig/plugin/TwosideKeeper/HelperStructures/Effects/LavaPlume.java
  5. 10
      src/sig/plugin/TwosideKeeper/HelperStructures/Effects/TemporaryLava.java
  6. 308
      src/sig/plugin/TwosideKeeper/HelperStructures/LivingEntityDifficulty.java
  7. 2
      src/sig/plugin/TwosideKeeper/HelperStructures/Loot.java
  8. 36
      src/sig/plugin/TwosideKeeper/HelperStructures/Utils/EntityUtils.java
  9. 29
      src/sig/plugin/TwosideKeeper/HelperStructures/Utils/MovementUtils.java
  10. 29
      src/sig/plugin/TwosideKeeper/Monster/Blaze.java
  11. 40
      src/sig/plugin/TwosideKeeper/Monster/HellfireGhast.java
  12. 3
      src/sig/plugin/TwosideKeeper/Monster/HellfireSpider.java
  13. 13
      src/sig/plugin/TwosideKeeper/MonsterController.java
  14. 182
      src/sig/plugin/TwosideKeeper/TwosideKeeper.java

Binary file not shown.

@ -20,6 +20,7 @@ import org.bukkit.entity.CaveSpider;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.MagmaCube;
@ -49,12 +50,15 @@ import sig.plugin.TwosideKeeper.Events.PlayerDodgeEvent;
import sig.plugin.TwosideKeeper.HelperStructures.ArtifactAbility;
import sig.plugin.TwosideKeeper.HelperStructures.BowMode;
import sig.plugin.TwosideKeeper.HelperStructures.ItemSet;
import sig.plugin.TwosideKeeper.HelperStructures.LivingEntityDifficulty;
import sig.plugin.TwosideKeeper.HelperStructures.MonsterDifficulty;
import sig.plugin.TwosideKeeper.HelperStructures.MonsterType;
import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode;
import sig.plugin.TwosideKeeper.HelperStructures.WorldShop;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.EntityUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.SoundUtils;
import sig.plugin.TwosideKeeper.Monster.HellfireGhast;
import sig.plugin.TwosideKeeper.Monster.HellfireSpider;
public class CustomDamage {
@ -176,7 +180,7 @@ public class CustomDamage {
dmg+=getBaseWeaponDamage(damage, weapon, damager, target, reason);
if (weapon.getType()==Material.BOW) {
if ((damager instanceof Projectile)) {
TwosideKeeper.log("This is a projectile! Reason: "+reason+", Damager: "+damager.toString(), 2);
TwosideKeeper.log("This is a projectile! Reason: "+reason+", Damager: "+damager.toString(), 5);
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));
@ -514,9 +518,7 @@ public class CustomDamage {
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,20*20,0));
}
}
if (target instanceof Monster) {
provokeMonster((Monster)target,p,weapon);
}
provokeMonster(target,p,weapon);
if (GenericFunctions.isArtifactEquip(weapon) &&
GenericFunctions.isArtifactWeapon(weapon)) {
double ratio = 1.0-CalculateDamageReduction(1,target,p);
@ -1060,13 +1062,15 @@ public class CustomDamage {
}
}
static void provokeMonster(Monster m, Player p, ItemStack weapon) {
applyDefenderAggro(m,p);
applyProvokeAggro(m,weapon);
static void provokeMonster(LivingEntity m, Player p, ItemStack weapon) {
if (!m.hasPotionEffect(PotionEffectType.GLOWING)) {
setMonsterTarget(m,p);
}
leaderRallyNearbyMonsters(m,p);
if (m instanceof Monster) {
applyDefenderAggro((Monster)m,p);
applyProvokeAggro((Monster)m,weapon);
leaderRallyNearbyMonsters((Monster)m,p);
}
}
static void leaderRallyNearbyMonsters(Monster m, Player p) {
@ -1097,38 +1101,49 @@ public class CustomDamage {
}
}
static void setMonsterTarget(Monster m, Player p) {
static void setMonsterTarget(LivingEntity m, Player p) {
addChargeZombieToList(m);
addHellfireSpiderToList(m);
//addHellfireGhastToList(m);
addToCustomStructures(m);
addMonsterToTargetList(m,p);
}
static void addChargeZombieToList(Monster m) {
public static void addToCustomStructures(LivingEntity m) {
addHellfireSpiderToList(m);
addHellfireGhastToList(m);
addBlazeToList(m);
}
static void addChargeZombieToList(LivingEntity m) {
if (!TwosideKeeper.chargezombies.containsKey(m.getUniqueId()) &&
MonsterController.isChargeZombie(m)) {
TwosideKeeper.chargezombies.put(m.getUniqueId(),new ChargeZombie((Monster)m));
}
}
static void addHellfireSpiderToList(Monster m) {
static void addHellfireSpiderToList(LivingEntity m) {
if (!TwosideKeeper.custommonsters.containsKey(m.getUniqueId()) &&
MonsterController.isHellfireSpider(m)) {
TwosideKeeper.custommonsters.put(m.getUniqueId(),new HellfireSpider((Monster)m));
TwosideKeeper.log("Added Hellfire Spider.", 2);
TwosideKeeper.log("Added Hellfire Spider.", 5);
}
}
static void addHellfireGhastToList(Monster m) {
static void addBlazeToList(LivingEntity m) {
if (!TwosideKeeper.custommonsters.containsKey(m.getUniqueId()) &&
m instanceof Blaze) {
TwosideKeeper.custommonsters.put(m.getUniqueId(),new sig.plugin.TwosideKeeper.Monster.Blaze((Monster)m));
}
}
static void addHellfireGhastToList(LivingEntity m) {
if (!TwosideKeeper.custommonsters.containsKey(m.getUniqueId()) &&
MonsterController.isHellfireGhast(m)) {
TwosideKeeper.custommonsters.put(m.getUniqueId(),new HellfireSpider((Monster)m));
TwosideKeeper.log("Added Hellfire Spider.", 2);
TwosideKeeper.custommonsters.put(m.getUniqueId(),new HellfireGhast(m));
}
}
public static void addMonsterToTargetList(Monster m,Player p) {
if (!m.hasPotionEffect(PotionEffectType.GLOWING)) {m.setTarget(p);}
public static void addMonsterToTargetList(LivingEntity m,Player p) {
if (m instanceof Monster && !m.hasPotionEffect(PotionEffectType.GLOWING)) {((Monster)m).setTarget(p);}
if (TwosideKeeper.livingentitydata.containsKey(m.getUniqueId())) {
LivingEntityStructure ms = (LivingEntityStructure)TwosideKeeper.livingentitydata.get(m.getUniqueId());
ms.SetTarget(p);
@ -1448,11 +1463,12 @@ public class CustomDamage {
int resistlevel = 0;
int partylevel = 0;
int rangeraegislevel = 0;
double magmacubediv = 0;
double rangerdmgdiv = 0;
double tacticspct = 0;
if (target instanceof LivingEntity) {
ItemStack[] armor = GenericFunctions.getEquipment(target);
ItemStack[] armor = GenericFunctions.getArmor(target);
if (target instanceof Player) {
rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(target), (Player)target, ItemSet.DARNYS, 2, 2)/100d;
rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(target), (Player)target, ItemSet.DARNYS, 3, 3)/100d;
@ -1461,6 +1477,24 @@ public class CustomDamage {
rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)target, ItemSet.DARNYS, 2, 2)/100d;
rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)target, ItemSet.LORASAADI, 2, 2)/100d;*/
rangeraegislevel += GenericFunctions.getSwiftAegisAmt((Player)target);
} else {
LivingEntityDifficulty diff = EntityUtils.GetStrongestNearbyEntityDifficulty(EntityType.MAGMA_CUBE, target, 4);
double reduction = 0.0d;
switch (diff) {
case DANGEROUS:{
reduction=0.4d;
}break;
case DEADLY:{
reduction=0.6d;
}break;
case HELLFIRE:{
reduction=0.8d;
}break;
default:{
reduction=0.2d;
}
}
magmacubediv+=Math.min(reduction,1);
}
for (int i=0;i<armor.length;i++) {
@ -1598,6 +1632,7 @@ public class CustomDamage {
*(1d-((projectileprotectionlevel)/100d))
*(1d-((explosionprotectionlevel)/100d))
*(1d-rangerdmgdiv)
*(1d-magmacubediv)
*(1d-((partylevel*10d)/100d))
*(1d-tacticspct)
*setbonus

@ -14,14 +14,24 @@ public class CustomMonster {
public LivingEntity GetMonster() {
return m;
}
public boolean isAlive() {
return !m.isDead();
}
/*
public boolean hasTarget() {
return (m.getTarget()!=null)?true:false;
}*/
public static CustomMonster getCustomMonster(LivingEntity m) {
if (TwosideKeeper.custommonsters.containsKey(m.getUniqueId())) {
return TwosideKeeper.custommonsters.get(m.getUniqueId());
} else {
return null;
}
}
public void runTick() {
}

@ -9,8 +9,10 @@ import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
import org.bukkit.entity.SmallFireball;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import org.inventivetalent.glow.GlowAPI;
@ -108,6 +110,12 @@ public class LavaPlume {
lavamod.setData((byte)8);
}
this.lavablocks.add(new TemporaryLava(lavamod,(int)(3*fb.getVelocity().getY())+6));
if (Math.random()<=0.1) {
SoundUtils.playGlobalSound(lavamod.getLocation(), Sound.ENTITY_BLAZE_SHOOT, 0.6f, 0.6f);
SmallFireball sf = (SmallFireball)fb.getWorld().spawnEntity(lavamod.getLocation(), EntityType.SMALL_FIREBALL);
sf.setDirection(new Vector(Math.random()-0.5,-Math.random()*0.5,Math.random()-0.5));
sf.setVelocity(new Vector(Math.random()-0.5,-Math.random()*0.5,Math.random()-0.5));
}
SoundUtils.playGlobalSound(fb.getLocation(), Sound.BLOCK_LAVA_POP, 1.0f, 1.0f);
return true;
} else {

@ -15,6 +15,16 @@ public class TemporaryLava {
this.b=b;
this.ttl=timer;
}
public TemporaryLava(Block b, int timer, boolean convert) {
if (convert) {
if (b.getType()==Material.AIR) {
b.setType(Material.LAVA);
//b.setData((byte)8);
}
}
this.b=b;
this.ttl=timer;
}
public boolean runTick() {
this.ttl--;
if (this.ttl<=0) {

@ -1,10 +1,306 @@
package sig.plugin.TwosideKeeper.HelperStructures;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import aPlugin.API.Chests;
import net.md_5.bungee.api.ChatColor;
import sig.plugin.TwosideKeeper.CustomDamage;
import sig.plugin.TwosideKeeper.MonsterController;
import sig.plugin.TwosideKeeper.TwosideKeeper;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
public enum LivingEntityDifficulty {
NORMAL,
DANGEROUS,
DEADLY,
HELLFIRE,
ELITE,
END;
NORMAL(0),
DANGEROUS(500),
DEADLY(1000),
HELLFIRE(5000),
ELITE(10000),
END(6000);
int rating;
LivingEntityDifficulty(int rating) {
this.rating=rating;
}
/*private ItemStack Artifact() {
sig.plugin.TwosideKeeper.Artifact.createArtifactItem(ArtifactItem.ARTIFACT_ESSENCE,3);
return null;
}*/
public int getRating() {
return rating;
}
/**
* Returns whether diff is stronger than the current difficulty. This is a numerical comparison,
* and so will always be accurate.
*/
public boolean isStronger(LivingEntityDifficulty diff) {
return (this.getRating()>diff.getRating());
}
public List<ItemStack> RandomizeDrops(double dropmult, boolean isBoss, boolean isRanger, Entity damager, LivingEntity m) {
return RandomizeDrops(dropmult,isBoss,false,isRanger,damager,m);
}
public List<ItemStack> RandomizeDrops(double dropmult, boolean isBoss, boolean isElite, boolean isRanger, Entity damager, LivingEntity m) {
LivingEntityDifficulty diff = MonsterController.getLivingEntityDifficulty(m);
TwosideKeeper.log(ChatColor.AQUA+"->Entering RandomizeDrops()", 5);
List<ItemStack> droplist = new ArrayList<ItemStack>();
dropmult += 1; //Base dropmult is 1.0.
if (Math.random() < dropmult % 1)
{
dropmult++;
}
//Basically for each additional dropmult integer value, the
//amount of rolls increases. (A dropmult of 1.0 is required for
//an additional roll.)
Player p = (Player)CustomDamage.getDamagerEntity(damager);
for (int i=0;i<dropmult;i++) {
TwosideKeeper.Loot_Logger.AddLootRoll();
TwosideKeeper.log("Attempting a roll...", TwosideKeeper.LOOT_DEBUG);
ItemStack goodie = null;
if (Math.random()<=0.1 || isBoss) {
TwosideKeeper.log("Inside!", 5);
switch (diff) {
case DANGEROUS:{
goodie=aPlugin.API.Chests.LOOT_DANGEROUS.getSingleDrop(p);
KeepRollingForBosses(isBoss, droplist, goodie, aPlugin.API.Chests.LOOT_DANGEROUS, p);
}break;
case DEADLY:{
goodie=aPlugin.API.Chests.LOOT_DEADLY.getSingleDrop(p);
KeepRollingForBosses(isBoss, droplist, goodie, aPlugin.API.Chests.LOOT_DEADLY, p);
}break;
case HELLFIRE:{
goodie=aPlugin.API.Chests.LOOT_HELLFIRE.getSingleDrop(p);
KeepRollingForBosses(isBoss, droplist, goodie, aPlugin.API.Chests.LOOT_HELLFIRE, p);
}break;
case END:{
goodie=aPlugin.API.Chests.LOOT_CUSTOM.getSingleDrop(p);
KeepRollingForBosses(isBoss, droplist, goodie, aPlugin.API.Chests.LOOT_CUSTOM, p);
}break;
case ELITE:{
}break;
default:{
if (Math.random()<=0.4) {
goodie=aPlugin.API.Chests.LOOT_NORMAL.getSingleDrop(p);
}
KeepRollingForBosses(isBoss, droplist, goodie, aPlugin.API.Chests.LOOT_NORMAL, p);
}
}
TwosideKeeper.Loot_Logger.AddCommonLoot();
ModifyAndAddDropToList(droplist,goodie,damager);
}
}
TwosideKeeper.log("New Droplist: "+droplist.toString(), 5);
return droplist;
}
public void KeepRollingForBosses(boolean isBoss, List<ItemStack> droplist, ItemStack goodie, Chests chest, Player damager) {
int roll=0;
while (isBoss && !isValidSetItem(goodie) && roll<50) {
goodie=chest.getSingleDrop(damager);
ModifyAndAddDropToList(droplist,goodie,damager);
roll++;
TwosideKeeper.Loot_Logger.AddCommonLoot();
}
}
private void ModifyAndAddDropToList(List<ItemStack> droplist, ItemStack goodie, Entity damager) {
/*LivingEntity shooter = CustomDamage.getDamagerEntity(damager);
if (shooter instanceof Player) {
Player p = (Player)shooter;
if (isValidSetItem(goodie)) {
if (Math.random()<0.8) {
//Convert it to a set piece.
PlayerMode pm = PlayerMode.getPlayerMode(p);
if (AllowedToConvert(pm,goodie)) {
ItemSet set = PickAnItemSet(pm,goodie);
goodie = ConvertSetPieceIfNecessary(goodie, set);
goodie = Loot.GenerateSetPiece(goodie.getType(), set, (Math.random()<0.1)?true:false, 0, false);
}
} else {
//Convert it to a mega piece.
PlayerMode pm = PlayerMode.getPlayerMode(p);
if (AllowedToConvert(pm,goodie)) {
goodie = Loot.GenerateMegaPiece(goodie.getType(), (Math.random()<0.1)?true:false);
}
}
}
}
TwosideKeeper.log("Adding item "+goodie, 2);*/ //LEGACY CODE.
droplist.add(goodie);
}
@SuppressWarnings("unused")
private boolean AllowedToConvert(PlayerMode pm, ItemStack goodie) {
if (goodie.getType()==Material.SKULL_ITEM && pm!=PlayerMode.NORMAL && pm!=PlayerMode.SLAYER) {
goodie.setDurability((short)3);
SkullMeta sm = (SkullMeta)goodie.getItemMeta();
sm.setOwner(Bukkit.getOfflinePlayers()[(int)(Math.random()*Bukkit.getOfflinePlayers().length)].getName());
goodie.setItemMeta(sm);
return false;
}
return true;
}
public static ItemStack ConvertSetPieceIfNecessary(ItemStack goodie, ItemSet set) {
if ((set==ItemSet.JAMDAK ||
set==ItemSet.ALIKAHN ||
set==ItemSet.DARNYS ||
set==ItemSet.LORASAADI) &&
!goodie.getType().name().contains("LEATHER") &&
GenericFunctions.isArmor(goodie)) {
goodie.setType(Material.valueOf("LEATHER_"+goodie.getType().name().split("_")[1]));
} else
if (goodie.getType().name().contains("LEATHER") &&
!(set==ItemSet.JAMDAK ||
set==ItemSet.ALIKAHN ||
set==ItemSet.DARNYS ||
set==ItemSet.LORASAADI) &&
GenericFunctions.isArmor(goodie)) {
goodie.setType(Material.valueOf("IRON_"+goodie.getType().name().split("_")[1]));
} else
if (goodie.getType()!=Material.SKULL_ITEM &&
(set==ItemSet.MOONSHADOW ||
set==ItemSet.GLADOMAIN ||
set==ItemSet.WOLFSBANE ||
set==ItemSet.ALUSTINE)) {
goodie.setType(Material.SKULL_ITEM);
}
return goodie;
}
private boolean isValidSetItem(ItemStack goodie) {
if (goodie!=null) {
return TwosideKeeper.validsetitems.contains(goodie.getType());
} else {
return false;
}
}
public static ItemSet PickAnItemSet(PlayerMode pm, LivingEntityDifficulty md) {
ItemSet set;
switch (pm) {
case STRIKER:{
set = ItemSet.PANROS;
}break;
case DEFENDER:{
set = ItemSet.SONGSTEEL;
}break;
case BARBARIAN:{
set = ItemSet.DAWNTRACKER;
}break;
case RANGER:{
final int NUMBER_OF_MODES=4;
int totalweight=50*NUMBER_OF_MODES; //50 for each mode.
int selectweight=(int)(Math.random()*totalweight);
if (selectweight<50) {
set = ItemSet.JAMDAK;
} else
if (selectweight<100) {
set = ItemSet.ALIKAHN;
} else
if (selectweight<150) {
set = ItemSet.DARNYS;
} else
{
set = ItemSet.LORASAADI;
}
}break;
case SLAYER:{
final int NUMBER_OF_MODES=3;
int totalweight=50*NUMBER_OF_MODES; //50 for each mode.
int selectweight=(int)(Math.random()*totalweight);
if (selectweight<10) {
set = ItemSet.LORASYS;
} else
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(md);
}
}
return set;
}
public static ItemSet PickRandomSet(LivingEntityDifficulty md) {
final int NUMBER_OF_MODES=5;
int totalweight=50*NUMBER_OF_MODES; //50 for each mode.
int selectweight=(int)(Math.random()*totalweight);
if (selectweight<50) {
return ItemSet.PANROS;
} else
if (selectweight<100) {
return ItemSet.SONGSTEEL;
} else
if (selectweight<150) {
return ItemSet.DAWNTRACKER;
} else
if (selectweight<200) {
//12.5 per set type.
if (selectweight<162.5) {
return ItemSet.JAMDAK;
} else
if (selectweight<175) {
return ItemSet.ALIKAHN;
} else
if (selectweight<187.5) {
return ItemSet.DARNYS;
} else
if (selectweight<200) {
return ItemSet.LORASAADI;
}
} else
if (selectweight<250) {
if (selectweight<205) {
return ItemSet.LORASYS;
} else
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;
}
}

@ -158,7 +158,7 @@ public class Loot {
}
public static ItemStack GenerateMegaPiece(Material mat_type, boolean hardened, boolean setitem, int settier, Entity damager, Monster m) {
TwosideKeeper.log("Calling this with "+mat_type.name()+","+hardened+","+setitem+".", 2);
TwosideKeeper.log("Calling this with "+mat_type.name()+","+hardened+","+setitem+".", 5);
ItemStack raresword = new ItemStack(mat_type);
ItemMeta sword_meta = raresword.getItemMeta();
sword_meta.setDisplayName(ChatColor.AQUA+""+ChatColor.BOLD+"Mega "+GenericFunctions.UserFriendlyMaterialName(mat_type));

@ -0,0 +1,36 @@
package sig.plugin.TwosideKeeper.HelperStructures.Utils;
import java.util.List;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import sig.plugin.TwosideKeeper.MonsterController;
import sig.plugin.TwosideKeeper.HelperStructures.LivingEntityDifficulty;
public class EntityUtils {
public static int CountNearbyEntityType(EntityType type, Entity ent, double range) {
List<Entity> ents = ent.getNearbyEntities(range, range, range);
int count=0;
for (Entity e : ents) {
if (e.getType()==type) {
count++;
}
}
return count;
}
public static LivingEntityDifficulty GetStrongestNearbyEntityDifficulty(EntityType type, Entity ent, double range) {
List<Entity> ents = ent.getNearbyEntities(range, range, range);
LivingEntityDifficulty strongest = LivingEntityDifficulty.NORMAL;
for (Entity e : ents) {
if (e instanceof LivingEntity) {
LivingEntityDifficulty diff = MonsterController.getLivingEntityDifficulty((LivingEntity)e);
if (e.getType()==type && !strongest.isStronger(diff)) {
strongest = diff;
}
}
}
return strongest;
}
}

@ -0,0 +1,29 @@
package sig.plugin.TwosideKeeper.HelperStructures.Utils;
import org.bukkit.Location;
import org.bukkit.util.Vector;
import sig.plugin.TwosideKeeper.TwosideKeeper;
public class MovementUtils {
public static Vector moveTowardsLocation(Location currloc, Location targetloc, double spd) {
/*double deltax = currloc.getX()-targetloc.getX();
double deltay = currloc.getY()-targetloc.getY();
double deltaz = currloc.getZ()-targetloc.getZ();
//Move at max speed in each direction until it matches the delta.
double velx = Math.min(Math.abs(deltax), spd)*Math.signum(deltax);
double vely = Math.min(Math.abs(deltax), spd)*Math.signum(deltay);
double velz = Math.min(Math.abs(deltax), spd)*Math.signum(deltaz);
return new Vector(-velx,-vely,-velz); //Flip the sign so we're moving towards the point instead of away from it.*/
double a = currloc.getX()-targetloc.getX();
double c = currloc.getY()-targetloc.getY();
double b = currloc.getZ()-targetloc.getZ();
double angle = Math.atan2(b, a);
double angle2 = Math.atan2(c, a);
double velz = spd * Math.sin(angle);
double velx = spd * Math.cos(angle);
double vely = spd * Math.sin(angle2);
//TwosideKeeper.log("New angle is "+angle, 0);
return new Vector(-velx,-vely,-velz);
}
}

@ -0,0 +1,29 @@
package sig.plugin.TwosideKeeper.Monster;
import org.bukkit.entity.LivingEntity;
import sig.plugin.TwosideKeeper.CustomMonster;
import sig.plugin.TwosideKeeper.TwosideKeeper;
public class Blaze extends CustomMonster{
private long lastFireball = 0;
public Blaze(LivingEntity m) {
super(m);
this.lastFireball=TwosideKeeper.getServerTickTime();
}
public long getLastFireball() {
return lastFireball;
}
public void resetLastFireball() {
this.lastFireball = TwosideKeeper.getServerTickTime();
}
public void runTick() {
}
}

@ -4,16 +4,20 @@ import org.bukkit.Sound;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.entity.Snowball;
import org.bukkit.metadata.FixedMetadataValue;
import sig.plugin.TwosideKeeper.CustomMonster;
import sig.plugin.TwosideKeeper.TwosideKeeper;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.MovementUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.SoundUtils;
public class HellfireGhast extends CustomMonster{
long lastFireball = 0;
Player target = null;
public HellfireGhast(LivingEntity m) {
super(m);
@ -23,7 +27,43 @@ public class HellfireGhast extends CustomMonster{
return lastFireball;
}
public Player getTarget() {
if (target!=null && !target.isDead() &&
target.isValid()) {
return target;
} else {
return null;
}
}
public void setTarget(Player p) {
this.target=p;
}
public void recordLastFireball() {
lastFireball = TwosideKeeper.getServerTickTime();
}
public void runTick() {
double pcthealth = m.getHealth()/m.getMaxHealth();
if (pcthealth<=0.2 && target!=null) {
//Begin charging towards player.
m.setAI(false);
m.setVelocity(MovementUtils.moveTowardsLocation(m.getLocation(), target.getLocation(), 2));
if (m.getLocation().distanceSquared(target.getLocation())<49) {
explode();
}
} else {
m.setAI(true);
}
}
private void explode() {
aPlugin.API.sendSoundlessExplosion(m.getLocation(), 4);
m.getWorld().createExplosion(m.getLocation().getBlockX(), m.getLocation().getBlockY(), m.getLocation().getBlockZ(), 6.0f, false, false);
GenericFunctions.DealExplosionDamageToEntities(m.getLocation(), 1600, 5, m);
GenericFunctions.RandomlyCreateFire(m.getLocation(), 5);
m.remove();
}
}

@ -2,6 +2,7 @@ package sig.plugin.TwosideKeeper.Monster;
import org.bukkit.Sound;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Snowball;
import org.bukkit.metadata.FixedMetadataValue;
@ -14,7 +15,7 @@ public class HellfireSpider extends CustomMonster{
long lastSpiderBallThrow = 0;
public HellfireSpider(Monster m) {
public HellfireSpider(LivingEntity m) {
super(m);
}

@ -23,7 +23,9 @@ import org.bukkit.entity.PigZombie;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Zombie;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.entity.Slime;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@ -40,6 +42,9 @@ public class MonsterController {
* @return Returns false if this spawn is not allowed.
*/
public static boolean MobHeightControl(LivingEntity ent, boolean minion) {
return MobHeightControl(ent,minion,SpawnReason.DEFAULT);
}
public static boolean MobHeightControl(LivingEntity ent, boolean minion, SpawnReason reason) {
if (ent instanceof Monster) {
Monster m = (Monster)ent;
@ -59,7 +64,11 @@ public class MonsterController {
return false;
}
} else
if (!meetsConditionsToSpawn(ent)) {
if (!meetsConditionsToSpawn(ent) &&
reason!=SpawnReason.SPAWNER_EGG &&
reason!=SpawnReason.SPAWNER &&
reason!=SpawnReason.SLIME_SPLIT &&
reason!=SpawnReason.SILVERFISH_BLOCK) {
return false;
}
if (isZombieLeader(ent)) {
@ -206,7 +215,7 @@ public class MonsterController {
}
}
}
return (dist<4096 && GenericFunctions.getNearbyMobs(ent.getLocation(), 16).size()<(nearbyplayers*3)+1);
return (dist<4096 && (GenericFunctions.getNearbyMobs(ent.getLocation(), 16).size()<(nearbyplayers*3)+1));
}
private static boolean meetsConditionsToBeElite(LivingEntity ent) {

@ -41,6 +41,7 @@ import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Bat;
import org.bukkit.entity.Blaze;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@ -51,6 +52,7 @@ import org.bukkit.entity.Ghast;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Horse.Variant;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.entity.SmallFireball;
import org.bukkit.entity.Item;
import org.bukkit.entity.LightningStrike;
import org.bukkit.entity.LivingEntity;
@ -195,6 +197,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.Common.RecipeCategory;
import sig.plugin.TwosideKeeper.HelperStructures.Common.RecipeLinker;
import sig.plugin.TwosideKeeper.HelperStructures.Effects.EarthWaveTask;
import sig.plugin.TwosideKeeper.HelperStructures.Effects.LavaPlume;
import sig.plugin.TwosideKeeper.HelperStructures.Effects.TemporaryLava;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.ArrayUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.BlockUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.InventoryUtils;
@ -205,6 +208,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.Utils.TimeUtils;
import sig.plugin.TwosideKeeper.Logging.BowModeLogger;
import sig.plugin.TwosideKeeper.Logging.LootLogger;
import sig.plugin.TwosideKeeper.Logging.MysteriousEssenceLogger;
import sig.plugin.TwosideKeeper.Monster.HellfireGhast;
import sig.plugin.TwosideKeeper.Monster.HellfireSpider;
@ -406,6 +410,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
public static AutoUpdatePlugin pluginupdater;
public static boolean restarting_server=false;
public static List<String> log_messages=new ArrayList<String>();
public static List<TemporaryLava> temporary_lava_list = new ArrayList<TemporaryLava>();
long LastClearStructureTime = 0;
@ -580,7 +585,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
public void run(){
//Control charge zombies..
for (ChargeZombie cz : chargezombies.values()) {
if (cz.m==null || !cz.m.isValid() || !cz.isAlive() || !cz.hasTarget() || cz.GetZombie().getLocation().getY()>32) {
if (cz.m==null || !cz.m.isValid() || !cz.isAlive() || !cz.hasTarget() || (cz.GetZombie().getWorld().getName().equalsIgnoreCase("world") && cz.GetZombie().getLocation().getY()>32)) {
//This has to be removed...
ScheduleRemoval(chargezombies,cz.m.getUniqueId());
} else {
@ -621,7 +626,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
}
}
for (CustomMonster cs : custommonsters.values()) {
if (cs.m==null || !cs.m.isValid() || !cs.isAlive() || cs.m.getLocation().getY()>32) {
if (cs.m==null || !cs.m.isValid() || !cs.isAlive()) {
//This has to be removed...
ScheduleRemoval(custommonsters,cs.m.getUniqueId());
} else {
@ -656,6 +661,11 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
runServerHeartbeat.runVacuumCubeSuckup(p);
runServerHeartbeat.runFilterCubeCollection(p);
}
for (TemporaryLava tl : temporary_lava_list) {
if (!tl.runTick()) {
ScheduleRemoval(temporary_lava_list,tl);
}
}
}
private void UpdateLavaBlock(Block lavamod) {
@ -854,6 +864,14 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
for (LavaPlume lp : lavaplume_list) {
lp.Cleanup();
}
log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-starttime)+"ms",CLEANUP_DEBUG);
long betweentime = System.currentTimeMillis();
log("Cleaning up Temporary Lava ["+temporary_lava_list.size()+"]",CLEANUP_DEBUG);
for (TemporaryLava tl : temporary_lava_list) {
tl.Cleanup();
}
log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-betweentime)+"ms",CLEANUP_DEBUG);
betweentime = System.currentTimeMillis();
long endtime = System.currentTimeMillis();
log("Cleanup Maintenance completed. Total Time: "+(endtime-starttime)+"ms.",CLEANUP_DEBUG);
}
@ -1970,12 +1988,42 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
if (ev.getEntity() instanceof Arrow) {
Arrow a = (Arrow)ev.getEntity();
a.setCustomName("HIT");
return;
}
if (ev.getEntity() instanceof SmallFireball) {
SmallFireball sf = (SmallFireball)ev.getEntity();
if (sf.getShooter() instanceof Blaze) {
Blaze b = (Blaze)sf.getShooter();
LivingEntityDifficulty led = MonsterController.getLivingEntityDifficulty(b);
switch (led) {
case DANGEROUS:{
GenericFunctions.DealExplosionDamageToEntities(ev.getEntity().getLocation(), 100f, 2, b);
aPlugin.API.sendSoundlessExplosion(ev.getEntity().getLocation(), 2);
SoundUtils.playGlobalSound(ev.getEntity().getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 0.6f, 0.5f);
}break;
case DEADLY:{
GenericFunctions.DealExplosionDamageToEntities(ev.getEntity().getLocation(), 250f, 3, b);
aPlugin.API.sendSoundlessExplosion(ev.getEntity().getLocation(), 3);
SoundUtils.playGlobalSound(ev.getEntity().getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 0.6f, 0.5f);
}break;
case HELLFIRE:{
GenericFunctions.DealExplosionDamageToEntities(ev.getEntity().getLocation(), 500f, 4, b);
aPlugin.API.sendSoundlessExplosion(ev.getEntity().getLocation(), 4);
SoundUtils.playGlobalSound(ev.getEntity().getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 0.6f, 0.5f);
temporary_lava_list.add(new TemporaryLava(ev.getEntity().getLocation().getBlock().getRelative(0, 1, 0),4,true));
}break;
default:{
}
}
}
}
if (ev.getEntity() instanceof Snowball) {
Snowball sb = (Snowball)ev.getEntity();
if (sb.hasMetadata("SPIDERBALL")) {
GenericFunctions.createRandomWeb(sb.getLocation(),2);
}
return;
}
}
@ -4326,14 +4374,14 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
ev.getEntity().remove();
} else
{
if (!ev.getSpawnReason().equals(SpawnReason.SPAWNER_EGG)) {
if (!ev.getSpawnReason().equals(SpawnReason.SPAWNER_EGG) && !ev.getSpawnReason().equals(SpawnReason.SLIME_SPLIT)) {
if (!habitat_data.addNewStartingLocation(ev.getEntity())) {
ev.getEntity().remove();
ev.setCancelled(true);
return;
}
}
if (!MonsterController.MobHeightControl(ev.getEntity(),false)) {
if (!MonsterController.MobHeightControl(ev.getEntity(),false,ev.getSpawnReason())) {
ev.setCancelled(true);
return;
//This spawn was not allowed by the mob height controller.
@ -4911,6 +4959,15 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
ev.setCancelled(true);
}
}
if (ev.getTarget() instanceof Player &&
ev.getEntity() instanceof LivingEntity) {
CustomDamage.addToCustomStructures((LivingEntity)ev.getEntity());
CustomMonster cm = CustomMonster.getCustomMonster((LivingEntity)ev.getEntity());
if (cm!=null && cm instanceof HellfireGhast) {
HellfireGhast hg = (HellfireGhast)cm;
hg.setTarget((Player)ev.getTarget());
}
}
}
@EventHandler(priority=EventPriority.LOW,ignoreCancelled = true)
@ -4935,9 +4992,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
}
ev.getEntity().getLocation().getWorld().dropItemNaturally(ev.getEntity().getLocation(), Artifact.createArtifactItem(ArtifactItem.MYSTERIOUS_ESSENCE));
}
if (ev.getEntity() instanceof Monster) {
if (ev.getEntity() instanceof LivingEntity) {
List<ItemStack> droplist = ev.getDrops();
Monster m = (Monster)ev.getEntity();
LivingEntity m = (LivingEntity)ev.getEntity();
double dropmult = 0.0d;
boolean isBoss=false;
@ -4999,26 +5056,27 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
}
}
if (m instanceof Monster) {
isBoss=GenericFunctions.isBossMonster((Monster)m);
isElite=GenericFunctions.isEliteMonster((Monster)m);
isBoss=GenericFunctions.isBossMonster(m);
isElite=GenericFunctions.isEliteMonster(m);
if (killedByPlayer && GenericFunctions.isCoreMonster(m) && Math.random()<RARE_DROP_RATE*dropmult*ARTIFACT_RARITY) {
switch ((int)(Math.random()*4)) {
case 0:{
droplist.add(Artifact.createArtifactItem(ArtifactItem.LOST_CORE));
}break;
case 1:{
droplist.add(Artifact.createArtifactItem(ArtifactItem.ANCIENT_CORE));
}break;
case 2:{
droplist.add(Artifact.createArtifactItem(ArtifactItem.ARTIFACT_CORE));
}break;
case 3:{
droplist.add(Artifact.createArtifactItem(ArtifactItem.DIVINE_CORE));
}break;
if (killedByPlayer && GenericFunctions.isCoreMonster((Monster)m) && Math.random()<RARE_DROP_RATE*dropmult*ARTIFACT_RARITY) {
switch ((int)(Math.random()*4)) {
case 0:{
droplist.add(Artifact.createArtifactItem(ArtifactItem.LOST_CORE));
}break;
case 1:{
droplist.add(Artifact.createArtifactItem(ArtifactItem.ANCIENT_CORE));
}break;
case 2:{
droplist.add(Artifact.createArtifactItem(ArtifactItem.ARTIFACT_CORE));
}break;
case 3:{
droplist.add(Artifact.createArtifactItem(ArtifactItem.DIVINE_CORE));
}break;
}
}
}
}
if (killedByPlayer) {
//Get the player that killed the monster.
@ -5030,6 +5088,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
boolean isRanger=PlayerMode.isRanger(p);
boolean isSlayer=PlayerMode.isSlayer(p);
boolean isBarbarian=PlayerMode.isBarbarian(p);
boolean isInNether=p.getWorld().getName().equalsIgnoreCase("world_nether");
GenericFunctions.knockOffGreed(p);
@ -5122,7 +5181,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
if (isElite) {
dropmult+=50;
EliteMonster em = GenericFunctions.getEliteMonster(m);
EliteMonster em = GenericFunctions.getEliteMonster((Monster)m);
//For each target, drop additional loot and exp.
List<Player> participants = em.getParticipantList();
StringBuilder participants_list = new StringBuilder();
@ -5166,6 +5225,10 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
GenericFunctions.generateNewElite(null,"");
}
if (isInNether) {
dropmult = dropmult + 0.3;
}
dropmult = dropmult + (luckmult * 0.5) - (unluckmult * 0.5);
if (luckmult>0 || unluckmult>0) {
@ -5179,7 +5242,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
i--;
}
droplist.addAll(MonsterController.getMonsterDifficulty((Monster)ev.getEntity()).RandomizeDrops(dropmult, isBoss, isRanger, p, m));
droplist.addAll(MonsterController.getLivingEntityDifficulty(ev.getEntity()).RandomizeDrops(dropmult, isBoss, isRanger, p, m));
final List<ItemStack> drop = new ArrayList<ItemStack>();
drop.addAll(droplist);
@ -5187,7 +5250,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
int totalexp = 0;
//Determine EXP amount and explosion type.
switch (MonsterController.getMonsterDifficulty(m)) {
switch (MonsterController.getLivingEntityDifficulty(m)) {
case NORMAL:
droplist.addAll(originaldroplist);
break;
@ -5199,7 +5262,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f);
totalexp=ev.getDroppedExp()*8;
ev.setDroppedExp((int)(totalexp*0.75));
final Monster mer = m;
final LivingEntity mer = m;
final int expdrop = totalexp;
droplist.clear(); //Clear the drop list. We are going to delay the drops.
droplist.addAll(originaldroplist);
@ -5230,7 +5293,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f);
totalexp=ev.getDroppedExp()*20;
ev.setDroppedExp((int)(totalexp*0.75));
final Monster mer1 = m;
final LivingEntity mer1 = m;
final int expdrop1 = totalexp;
droplist.clear(); //Clear the drop list. We are going to delay the drops.
droplist.addAll(originaldroplist);
@ -5263,7 +5326,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f);
totalexp=ev.getDroppedExp()*40;
ev.setDroppedExp((int)(totalexp*0.75));
final Monster mer4 = m;
final LivingEntity mer4 = m;
final int expdrop4 = totalexp;
droplist.clear(); //Clear the drop list. We are going to delay the drops.
droplist.addAll(originaldroplist);
@ -5294,7 +5357,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
break;
case ELITE:
totalexp=ev.getDroppedExp()*300;
final Monster mer2 = m;
final LivingEntity mer2 = m;
for (int i=0;i<originaldroplist.size();i++) {
Item it = deathloc.getWorld().dropItemNaturally(mer2.getLocation(), originaldroplist.get(i));
it.setInvulnerable(true);
@ -6148,10 +6211,49 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
if (arr instanceof Fireball && (arr.getShooter() instanceof Ghast)) {
Ghast g = (Ghast)arr.getShooter();
Fireball fb = (Fireball)arr;
if (MonsterController.getLivingEntityDifficulty(g)==LivingEntityDifficulty.DANGEROUS) {
fb.setVelocity(fb.getDirection().multiply(5f));
} else
if (MonsterController.getLivingEntityDifficulty(g)==LivingEntityDifficulty.DEADLY) {
fb.setVelocity(fb.getDirection().multiply(10f));
} else
if (MonsterController.getLivingEntityDifficulty(g)==LivingEntityDifficulty.HELLFIRE) {
//We will fire additional fireballs, directly after it.
CustomMonster mon = CustomMonster.getCustomMonster(g);
if (mon!=null && ((HellfireGhast)mon).getLastFireball()+45<TwosideKeeper.getServerTickTime()) {
Bukkit.getScheduler().scheduleSyncDelayedTask(this, ()->{FireSpecialFireball(g,fb);},15);
Bukkit.getScheduler().scheduleSyncDelayedTask(this, ()->{FireSpecialFireball(g,fb);},30);
Bukkit.getScheduler().scheduleSyncDelayedTask(this, ()->{FireSpecialFireball(g,fb);},45);
((HellfireGhast)mon).recordLastFireball();
fb.setVelocity(fb.getDirection().multiply(20f));
}
}
fb.setVelocity(fb.getDirection().multiply(20f));
return;
}
if (arr instanceof SmallFireball && (arr.getShooter() instanceof Blaze)) {
Blaze b = (Blaze)arr.getShooter();
SmallFireball sf = (SmallFireball)arr;
LivingEntity le = b.getTarget();
if (le!=null) {
CustomMonster mon = CustomMonster.getCustomMonster(b);
if (mon!=null && ((sig.plugin.TwosideKeeper.Monster.Blaze)mon).getLastFireball()+60<TwosideKeeper.getServerTickTime()) {
if (MonsterController.getLivingEntityDifficulty(b)==LivingEntityDifficulty.DANGEROUS) {
Bukkit.getScheduler().scheduleSyncDelayedTask(this, ()->{FireExtraBlazeFireball(b,le,sf);},45);
} else
if (MonsterController.getLivingEntityDifficulty(b)==LivingEntityDifficulty.DEADLY) {
Bukkit.getScheduler().scheduleSyncDelayedTask(this, ()->{FireExtraBlazeFireball(b,le,sf);},30);
Bukkit.getScheduler().scheduleSyncDelayedTask(this, ()->{FireExtraBlazeFireball(b,le,sf);},45);
} else
if (MonsterController.getLivingEntityDifficulty(b)==LivingEntityDifficulty.HELLFIRE) {
Bukkit.getScheduler().scheduleSyncDelayedTask(this, ()->{FireExtraBlazeFireball(b,le,sf);},15);
Bukkit.getScheduler().scheduleSyncDelayedTask(this, ()->{FireExtraBlazeFireball(b,le,sf);},30);
Bukkit.getScheduler().scheduleSyncDelayedTask(this, ()->{FireExtraBlazeFireball(b,le,sf);},45);
}
((sig.plugin.TwosideKeeper.Monster.Blaze)mon).resetLastFireball();
}
sf.setVelocity(sf.getDirection().multiply(5f));
}
return;
}
if (arr.getCustomName()==null && (arr instanceof Arrow)) {
@ -6253,6 +6355,20 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
}
}
private void FireExtraBlazeFireball(Blaze b, LivingEntity le, SmallFireball ref) {
SmallFireball sf = b.launchProjectile(SmallFireball.class);
sf.setShooter(b);
sf.setDirection(ref.getDirection());
SoundUtils.playGlobalSound(sf.getLocation(), Sound.ENTITY_BLAZE_SHOOT, 1.0f, 1.0f);
}
public void FireSpecialFireball(Ghast g, Fireball fireref) {
Fireball fireball = g.launchProjectile(Fireball.class);
fireball.setShooter(g);
fireball.setVelocity(fireref.getDirection().multiply(20f));
SoundUtils.playGlobalSound(fireball.getLocation(), Sound.ENTITY_GHAST_SHOOT, 1.0f, 1.0f);
}
@EventHandler(priority=EventPriority.LOW,ignoreCancelled = true)
public void onItemCraftEvent(PrepareItemCraftEvent ev) {
ItemStack result = ev.getInventory().getResult();

Loading…
Cancel
Save