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.
This commit is contained in:
sigonasr2 2016-12-11 14:28:07 -06:00
parent aa25cf1792
commit a15d7dd735
14 changed files with 683 additions and 64 deletions

Binary file not shown.

View File

@ -20,6 +20,7 @@ import org.bukkit.entity.CaveSpider;
import org.bukkit.entity.Creeper; import org.bukkit.entity.Creeper;
import org.bukkit.entity.Enderman; import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock; import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.MagmaCube; 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.ArtifactAbility;
import sig.plugin.TwosideKeeper.HelperStructures.BowMode; import sig.plugin.TwosideKeeper.HelperStructures.BowMode;
import sig.plugin.TwosideKeeper.HelperStructures.ItemSet; import sig.plugin.TwosideKeeper.HelperStructures.ItemSet;
import sig.plugin.TwosideKeeper.HelperStructures.LivingEntityDifficulty;
import sig.plugin.TwosideKeeper.HelperStructures.MonsterDifficulty; import sig.plugin.TwosideKeeper.HelperStructures.MonsterDifficulty;
import sig.plugin.TwosideKeeper.HelperStructures.MonsterType; import sig.plugin.TwosideKeeper.HelperStructures.MonsterType;
import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode; import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode;
import sig.plugin.TwosideKeeper.HelperStructures.WorldShop; import sig.plugin.TwosideKeeper.HelperStructures.WorldShop;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions; 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.HelperStructures.Utils.SoundUtils;
import sig.plugin.TwosideKeeper.Monster.HellfireGhast;
import sig.plugin.TwosideKeeper.Monster.HellfireSpider; import sig.plugin.TwosideKeeper.Monster.HellfireSpider;
public class CustomDamage { public class CustomDamage {
@ -176,7 +180,7 @@ public class CustomDamage {
dmg+=getBaseWeaponDamage(damage, weapon, damager, target, reason); dmg+=getBaseWeaponDamage(damage, weapon, damager, target, reason);
if (weapon.getType()==Material.BOW) { if (weapon.getType()==Material.BOW) {
if ((damager instanceof Projectile)) { 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 += addToPlayerLogger(damager,target,"Custom Arrow",calculateCustomArrowDamageIncrease(weapon,damager,target));
dmg += addMultiplierToPlayerLogger(damager,target,"Ranger Mult",dmg * calculateRangerMultiplier(weapon,damager)); dmg += addMultiplierToPlayerLogger(damager,target,"Ranger Mult",dmg * calculateRangerMultiplier(weapon,damager));
double headshotdmg = addMultiplierToPlayerLogger(damager,target,"Headshot Mult",dmg * calculateHeadshotMultiplier(weapon,damager,target)); 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)); target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,20*20,0));
} }
} }
if (target instanceof Monster) { provokeMonster(target,p,weapon);
provokeMonster((Monster)target,p,weapon);
}
if (GenericFunctions.isArtifactEquip(weapon) && if (GenericFunctions.isArtifactEquip(weapon) &&
GenericFunctions.isArtifactWeapon(weapon)) { GenericFunctions.isArtifactWeapon(weapon)) {
double ratio = 1.0-CalculateDamageReduction(1,target,p); double ratio = 1.0-CalculateDamageReduction(1,target,p);
@ -1060,13 +1062,15 @@ public class CustomDamage {
} }
} }
static void provokeMonster(Monster m, Player p, ItemStack weapon) { static void provokeMonster(LivingEntity m, Player p, ItemStack weapon) {
applyDefenderAggro(m,p);
applyProvokeAggro(m,weapon);
if (!m.hasPotionEffect(PotionEffectType.GLOWING)) { if (!m.hasPotionEffect(PotionEffectType.GLOWING)) {
setMonsterTarget(m,p); 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) { 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); addChargeZombieToList(m);
addHellfireSpiderToList(m); addToCustomStructures(m);
//addHellfireGhastToList(m);
addMonsterToTargetList(m,p); 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()) && if (!TwosideKeeper.chargezombies.containsKey(m.getUniqueId()) &&
MonsterController.isChargeZombie(m)) { MonsterController.isChargeZombie(m)) {
TwosideKeeper.chargezombies.put(m.getUniqueId(),new ChargeZombie((Monster)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()) && if (!TwosideKeeper.custommonsters.containsKey(m.getUniqueId()) &&
MonsterController.isHellfireSpider(m)) { MonsterController.isHellfireSpider(m)) {
TwosideKeeper.custommonsters.put(m.getUniqueId(),new HellfireSpider((Monster)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()) && if (!TwosideKeeper.custommonsters.containsKey(m.getUniqueId()) &&
MonsterController.isHellfireGhast(m)) { MonsterController.isHellfireGhast(m)) {
TwosideKeeper.custommonsters.put(m.getUniqueId(),new HellfireSpider((Monster)m)); TwosideKeeper.custommonsters.put(m.getUniqueId(),new HellfireGhast(m));
TwosideKeeper.log("Added Hellfire Spider.", 2);
} }
} }
public static void addMonsterToTargetList(Monster m,Player p) { public static void addMonsterToTargetList(LivingEntity m,Player p) {
if (!m.hasPotionEffect(PotionEffectType.GLOWING)) {m.setTarget(p);} if (m instanceof Monster && !m.hasPotionEffect(PotionEffectType.GLOWING)) {((Monster)m).setTarget(p);}
if (TwosideKeeper.livingentitydata.containsKey(m.getUniqueId())) { if (TwosideKeeper.livingentitydata.containsKey(m.getUniqueId())) {
LivingEntityStructure ms = (LivingEntityStructure)TwosideKeeper.livingentitydata.get(m.getUniqueId()); LivingEntityStructure ms = (LivingEntityStructure)TwosideKeeper.livingentitydata.get(m.getUniqueId());
ms.SetTarget(p); ms.SetTarget(p);
@ -1448,11 +1463,12 @@ public class CustomDamage {
int resistlevel = 0; int resistlevel = 0;
int partylevel = 0; int partylevel = 0;
int rangeraegislevel = 0; int rangeraegislevel = 0;
double magmacubediv = 0;
double rangerdmgdiv = 0; double rangerdmgdiv = 0;
double tacticspct = 0; double tacticspct = 0;
if (target instanceof LivingEntity) { if (target instanceof LivingEntity) {
ItemStack[] armor = GenericFunctions.getEquipment(target); ItemStack[] armor = GenericFunctions.getArmor(target);
if (target instanceof Player) { 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, 2, 2)/100d;
rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount(GenericFunctions.getEquipment(target), (Player)target, ItemSet.DARNYS, 3, 3)/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.DARNYS, 2, 2)/100d;
rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)target, ItemSet.LORASAADI, 2, 2)/100d;*/ rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)target, ItemSet.LORASAADI, 2, 2)/100d;*/
rangeraegislevel += GenericFunctions.getSwiftAegisAmt((Player)target); 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++) { for (int i=0;i<armor.length;i++) {
@ -1598,6 +1632,7 @@ public class CustomDamage {
*(1d-((projectileprotectionlevel)/100d)) *(1d-((projectileprotectionlevel)/100d))
*(1d-((explosionprotectionlevel)/100d)) *(1d-((explosionprotectionlevel)/100d))
*(1d-rangerdmgdiv) *(1d-rangerdmgdiv)
*(1d-magmacubediv)
*(1d-((partylevel*10d)/100d)) *(1d-((partylevel*10d)/100d))
*(1d-tacticspct) *(1d-tacticspct)
*setbonus *setbonus

View File

@ -14,14 +14,24 @@ public class CustomMonster {
public LivingEntity GetMonster() { public LivingEntity GetMonster() {
return m; return m;
} }
public boolean isAlive() { public boolean isAlive() {
return !m.isDead(); return !m.isDead();
} }
/* /*
public boolean hasTarget() { public boolean hasTarget() {
return (m.getTarget()!=null)?true:false; 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() { public void runTick() {
} }

View File

@ -9,8 +9,10 @@ import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock; import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.SmallFireball;
import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.inventivetalent.glow.GlowAPI; import org.inventivetalent.glow.GlowAPI;
@ -108,6 +110,12 @@ public class LavaPlume {
lavamod.setData((byte)8); lavamod.setData((byte)8);
} }
this.lavablocks.add(new TemporaryLava(lavamod,(int)(3*fb.getVelocity().getY())+6)); 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); SoundUtils.playGlobalSound(fb.getLocation(), Sound.BLOCK_LAVA_POP, 1.0f, 1.0f);
return true; return true;
} else { } else {

View File

@ -15,6 +15,16 @@ public class TemporaryLava {
this.b=b; this.b=b;
this.ttl=timer; 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() { public boolean runTick() {
this.ttl--; this.ttl--;
if (this.ttl<=0) { if (this.ttl<=0) {

View File

@ -1,10 +1,306 @@
package sig.plugin.TwosideKeeper.HelperStructures; 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 { public enum LivingEntityDifficulty {
NORMAL, NORMAL(0),
DANGEROUS, DANGEROUS(500),
DEADLY, DEADLY(1000),
HELLFIRE, HELLFIRE(5000),
ELITE, ELITE(10000),
END; 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;
}
} }

View File

@ -158,7 +158,7 @@ public class Loot {
} }
public static ItemStack GenerateMegaPiece(Material mat_type, boolean hardened, boolean setitem, int settier, Entity damager, Monster m) { 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); ItemStack raresword = new ItemStack(mat_type);
ItemMeta sword_meta = raresword.getItemMeta(); ItemMeta sword_meta = raresword.getItemMeta();
sword_meta.setDisplayName(ChatColor.AQUA+""+ChatColor.BOLD+"Mega "+GenericFunctions.UserFriendlyMaterialName(mat_type)); sword_meta.setDisplayName(ChatColor.AQUA+""+ChatColor.BOLD+"Mega "+GenericFunctions.UserFriendlyMaterialName(mat_type));

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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() {
}
}

View File

@ -4,16 +4,20 @@ import org.bukkit.Sound;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster; import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.entity.Snowball; import org.bukkit.entity.Snowball;
import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.FixedMetadataValue;
import sig.plugin.TwosideKeeper.CustomMonster; import sig.plugin.TwosideKeeper.CustomMonster;
import sig.plugin.TwosideKeeper.TwosideKeeper; 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; import sig.plugin.TwosideKeeper.HelperStructures.Utils.SoundUtils;
public class HellfireGhast extends CustomMonster{ public class HellfireGhast extends CustomMonster{
long lastFireball = 0; long lastFireball = 0;
Player target = null;
public HellfireGhast(LivingEntity m) { public HellfireGhast(LivingEntity m) {
super(m); super(m);
@ -23,7 +27,43 @@ public class HellfireGhast extends CustomMonster{
return lastFireball; 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() { 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();
} }
} }

View File

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

View File

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

View File

@ -41,6 +41,7 @@ import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.AreaEffectCloud; import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.Arrow; import org.bukkit.entity.Arrow;
import org.bukkit.entity.Bat; import org.bukkit.entity.Bat;
import org.bukkit.entity.Blaze;
import org.bukkit.entity.Creeper; import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
@ -51,6 +52,7 @@ import org.bukkit.entity.Ghast;
import org.bukkit.entity.Horse; import org.bukkit.entity.Horse;
import org.bukkit.entity.Horse.Variant; import org.bukkit.entity.Horse.Variant;
import org.bukkit.entity.Skeleton.SkeletonType; import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.entity.SmallFireball;
import org.bukkit.entity.Item; import org.bukkit.entity.Item;
import org.bukkit.entity.LightningStrike; import org.bukkit.entity.LightningStrike;
import org.bukkit.entity.LivingEntity; 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.Common.RecipeLinker;
import sig.plugin.TwosideKeeper.HelperStructures.Effects.EarthWaveTask; import sig.plugin.TwosideKeeper.HelperStructures.Effects.EarthWaveTask;
import sig.plugin.TwosideKeeper.HelperStructures.Effects.LavaPlume; 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.ArrayUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.BlockUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.BlockUtils;
import sig.plugin.TwosideKeeper.HelperStructures.Utils.InventoryUtils; 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.BowModeLogger;
import sig.plugin.TwosideKeeper.Logging.LootLogger; import sig.plugin.TwosideKeeper.Logging.LootLogger;
import sig.plugin.TwosideKeeper.Logging.MysteriousEssenceLogger; import sig.plugin.TwosideKeeper.Logging.MysteriousEssenceLogger;
import sig.plugin.TwosideKeeper.Monster.HellfireGhast;
import sig.plugin.TwosideKeeper.Monster.HellfireSpider; import sig.plugin.TwosideKeeper.Monster.HellfireSpider;
@ -406,6 +410,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
public static AutoUpdatePlugin pluginupdater; public static AutoUpdatePlugin pluginupdater;
public static boolean restarting_server=false; public static boolean restarting_server=false;
public static List<String> log_messages=new ArrayList<String>(); public static List<String> log_messages=new ArrayList<String>();
public static List<TemporaryLava> temporary_lava_list = new ArrayList<TemporaryLava>();
long LastClearStructureTime = 0; long LastClearStructureTime = 0;
@ -580,7 +585,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
public void run(){ public void run(){
//Control charge zombies.. //Control charge zombies..
for (ChargeZombie cz : chargezombies.values()) { 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... //This has to be removed...
ScheduleRemoval(chargezombies,cz.m.getUniqueId()); ScheduleRemoval(chargezombies,cz.m.getUniqueId());
} else { } else {
@ -621,7 +626,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
} }
} }
for (CustomMonster cs : custommonsters.values()) { 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... //This has to be removed...
ScheduleRemoval(custommonsters,cs.m.getUniqueId()); ScheduleRemoval(custommonsters,cs.m.getUniqueId());
} else { } else {
@ -656,6 +661,11 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
runServerHeartbeat.runVacuumCubeSuckup(p); runServerHeartbeat.runVacuumCubeSuckup(p);
runServerHeartbeat.runFilterCubeCollection(p); runServerHeartbeat.runFilterCubeCollection(p);
} }
for (TemporaryLava tl : temporary_lava_list) {
if (!tl.runTick()) {
ScheduleRemoval(temporary_lava_list,tl);
}
}
} }
private void UpdateLavaBlock(Block lavamod) { private void UpdateLavaBlock(Block lavamod) {
@ -854,6 +864,14 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
for (LavaPlume lp : lavaplume_list) { for (LavaPlume lp : lavaplume_list) {
lp.Cleanup(); 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(); long endtime = System.currentTimeMillis();
log("Cleanup Maintenance completed. Total Time: "+(endtime-starttime)+"ms.",CLEANUP_DEBUG); 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) { if (ev.getEntity() instanceof Arrow) {
Arrow a = (Arrow)ev.getEntity(); Arrow a = (Arrow)ev.getEntity();
a.setCustomName("HIT"); 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) { if (ev.getEntity() instanceof Snowball) {
Snowball sb = (Snowball)ev.getEntity(); Snowball sb = (Snowball)ev.getEntity();
if (sb.hasMetadata("SPIDERBALL")) { if (sb.hasMetadata("SPIDERBALL")) {
GenericFunctions.createRandomWeb(sb.getLocation(),2); GenericFunctions.createRandomWeb(sb.getLocation(),2);
} }
return;
} }
} }
@ -4326,14 +4374,14 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
ev.getEntity().remove(); ev.getEntity().remove();
} else } 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())) { if (!habitat_data.addNewStartingLocation(ev.getEntity())) {
ev.getEntity().remove(); ev.getEntity().remove();
ev.setCancelled(true); ev.setCancelled(true);
return; return;
} }
} }
if (!MonsterController.MobHeightControl(ev.getEntity(),false)) { if (!MonsterController.MobHeightControl(ev.getEntity(),false,ev.getSpawnReason())) {
ev.setCancelled(true); ev.setCancelled(true);
return; return;
//This spawn was not allowed by the mob height controller. //This spawn was not allowed by the mob height controller.
@ -4911,6 +4959,15 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
ev.setCancelled(true); 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) @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)); 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(); List<ItemStack> droplist = ev.getDrops();
Monster m = (Monster)ev.getEntity(); LivingEntity m = (LivingEntity)ev.getEntity();
double dropmult = 0.0d; double dropmult = 0.0d;
boolean isBoss=false; boolean isBoss=false;
@ -4999,11 +5056,11 @@ 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); if (killedByPlayer && GenericFunctions.isCoreMonster((Monster)m) && Math.random()<RARE_DROP_RATE*dropmult*ARTIFACT_RARITY) {
isElite=GenericFunctions.isEliteMonster(m);
if (killedByPlayer && GenericFunctions.isCoreMonster(m) && Math.random()<RARE_DROP_RATE*dropmult*ARTIFACT_RARITY) {
switch ((int)(Math.random()*4)) { switch ((int)(Math.random()*4)) {
case 0:{ case 0:{
droplist.add(Artifact.createArtifactItem(ArtifactItem.LOST_CORE)); droplist.add(Artifact.createArtifactItem(ArtifactItem.LOST_CORE));
@ -5019,6 +5076,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
}break; }break;
} }
} }
}
if (killedByPlayer) { if (killedByPlayer) {
//Get the player that killed the monster. //Get the player that killed the monster.
@ -5030,6 +5088,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
boolean isRanger=PlayerMode.isRanger(p); boolean isRanger=PlayerMode.isRanger(p);
boolean isSlayer=PlayerMode.isSlayer(p); boolean isSlayer=PlayerMode.isSlayer(p);
boolean isBarbarian=PlayerMode.isBarbarian(p); boolean isBarbarian=PlayerMode.isBarbarian(p);
boolean isInNether=p.getWorld().getName().equalsIgnoreCase("world_nether");
GenericFunctions.knockOffGreed(p); GenericFunctions.knockOffGreed(p);
@ -5122,7 +5181,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
if (isElite) { if (isElite) {
dropmult+=50; dropmult+=50;
EliteMonster em = GenericFunctions.getEliteMonster(m); EliteMonster em = GenericFunctions.getEliteMonster((Monster)m);
//For each target, drop additional loot and exp. //For each target, drop additional loot and exp.
List<Player> participants = em.getParticipantList(); List<Player> participants = em.getParticipantList();
StringBuilder participants_list = new StringBuilder(); StringBuilder participants_list = new StringBuilder();
@ -5166,6 +5225,10 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
GenericFunctions.generateNewElite(null,""); GenericFunctions.generateNewElite(null,"");
} }
if (isInNether) {
dropmult = dropmult + 0.3;
}
dropmult = dropmult + (luckmult * 0.5) - (unluckmult * 0.5); dropmult = dropmult + (luckmult * 0.5) - (unluckmult * 0.5);
if (luckmult>0 || unluckmult>0) { if (luckmult>0 || unluckmult>0) {
@ -5179,7 +5242,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
i--; 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>(); final List<ItemStack> drop = new ArrayList<ItemStack>();
drop.addAll(droplist); drop.addAll(droplist);
@ -5187,7 +5250,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
int totalexp = 0; int totalexp = 0;
//Determine EXP amount and explosion type. //Determine EXP amount and explosion type.
switch (MonsterController.getMonsterDifficulty(m)) { switch (MonsterController.getLivingEntityDifficulty(m)) {
case NORMAL: case NORMAL:
droplist.addAll(originaldroplist); droplist.addAll(originaldroplist);
break; break;
@ -5199,7 +5262,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f); SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f);
totalexp=ev.getDroppedExp()*8; totalexp=ev.getDroppedExp()*8;
ev.setDroppedExp((int)(totalexp*0.75)); ev.setDroppedExp((int)(totalexp*0.75));
final Monster mer = m; final LivingEntity mer = m;
final int expdrop = totalexp; final int expdrop = totalexp;
droplist.clear(); //Clear the drop list. We are going to delay the drops. droplist.clear(); //Clear the drop list. We are going to delay the drops.
droplist.addAll(originaldroplist); 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); SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f);
totalexp=ev.getDroppedExp()*20; totalexp=ev.getDroppedExp()*20;
ev.setDroppedExp((int)(totalexp*0.75)); ev.setDroppedExp((int)(totalexp*0.75));
final Monster mer1 = m; final LivingEntity mer1 = m;
final int expdrop1 = totalexp; final int expdrop1 = totalexp;
droplist.clear(); //Clear the drop list. We are going to delay the drops. droplist.clear(); //Clear the drop list. We are going to delay the drops.
droplist.addAll(originaldroplist); 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); SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f);
totalexp=ev.getDroppedExp()*40; totalexp=ev.getDroppedExp()*40;
ev.setDroppedExp((int)(totalexp*0.75)); ev.setDroppedExp((int)(totalexp*0.75));
final Monster mer4 = m; final LivingEntity mer4 = m;
final int expdrop4 = totalexp; final int expdrop4 = totalexp;
droplist.clear(); //Clear the drop list. We are going to delay the drops. droplist.clear(); //Clear the drop list. We are going to delay the drops.
droplist.addAll(originaldroplist); droplist.addAll(originaldroplist);
@ -5294,7 +5357,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
break; break;
case ELITE: case ELITE:
totalexp=ev.getDroppedExp()*300; totalexp=ev.getDroppedExp()*300;
final Monster mer2 = m; final LivingEntity mer2 = m;
for (int i=0;i<originaldroplist.size();i++) { for (int i=0;i<originaldroplist.size();i++) {
Item it = deathloc.getWorld().dropItemNaturally(mer2.getLocation(), originaldroplist.get(i)); Item it = deathloc.getWorld().dropItemNaturally(mer2.getLocation(), originaldroplist.get(i));
it.setInvulnerable(true); it.setInvulnerable(true);
@ -6148,11 +6211,50 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
if (arr instanceof Fireball && (arr.getShooter() instanceof Ghast)) { if (arr instanceof Fireball && (arr.getShooter() instanceof Ghast)) {
Ghast g = (Ghast)arr.getShooter(); Ghast g = (Ghast)arr.getShooter();
Fireball fb = (Fireball)arr; 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) { 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)) { if (arr.getCustomName()==null && (arr instanceof Arrow)) {
if (arr.getType()==EntityType.TIPPED_ARROW) { if (arr.getType()==EntityType.TIPPED_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) @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true)
public void onItemCraftEvent(PrepareItemCraftEvent ev) { public void onItemCraftEvent(PrepareItemCraftEvent ev) {
ItemStack result = ev.getInventory().getResult(); ItemStack result = ev.getInventory().getResult();