1
0

refactor: clean source code

This commit is contained in:
labalityowo
2022-07-07 10:09:42 +07:00
parent 49950087f5
commit de68079e8a
16487 changed files with 721393 additions and 227033 deletions

View File

@ -0,0 +1,21 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-parent</artifactId>
<version>dev-SNAPSHOT</version>
</parent>
<artifactId>mineplex-minecraft-game-core</artifactId>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mineplex-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,10 @@
package mineplex.minecraft.game.core;
import org.bukkit.entity.Player;
public interface IRelation
{
public boolean canHurt(Player a, Player b);
public boolean canHurt(String a, String b);
public boolean isSafe(Player a);
}

View File

@ -0,0 +1,113 @@
package mineplex.minecraft.game.core.boss;
import java.util.HashMap;
import java.util.UUID;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public abstract class BossAbility<T extends EventCreature, Y extends Entity> implements Listener
{
private T _creature;
private HashMap<UUID, Long> _damaged = new HashMap<UUID, Long>();
public boolean canDamage(Entity player)
{
if (_damaged.containsKey(player.getUniqueId()))
{
if (!UtilTime.elapsed(_damaged.get(player.getUniqueId()), 400))
{
return false;
}
}
_damaged.put(player.getUniqueId(), System.currentTimeMillis());
return true;
}
public BossAbility(T creature)
{
_creature = creature;
}
public abstract boolean canMove();
public abstract boolean inProgress();
public int getCooldown()
{
return 3;
}
public Y getEntity()
{
return (Y) getBoss().getEntity();
}
public T getBoss()
{
return _creature;
}
public Location getLocation()
{
return getEntity().getLocation();
}
public Player getTarget()
{
return getTarget(30);
}
public Player getTarget(double minDistance, double maxDistance)
{
Player target = null;
double dist = 0;
for (Player player : UtilPlayer.getNearby(getLocation(), maxDistance, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
double d = player.getLocation().distance(getLocation());
if (d < minDistance)
{
continue;
}
if (target == null || dist > d)
{
target = player;
dist = d;
}
}
return target;
}
public Player getTarget(double maxDistance)
{
return getTarget(0, maxDistance);
}
public abstract boolean hasFinished();
public abstract void setFinished();
public abstract void tick();
}

View File

@ -0,0 +1,41 @@
package mineplex.minecraft.game.core.boss;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.event.Listener;
public abstract class BossPassive<T extends EventCreature, Y extends Entity> implements Listener
{
private T _creature;
public BossPassive(T creature)
{
_creature = creature;
Bukkit.getPluginManager().registerEvents(this, creature.getEvent().getPlugin());
}
public int getCooldown()
{
return 3;
}
public Y getEntity()
{
return (Y) getBoss().getEntity();
}
public T getBoss()
{
return _creature;
}
public Location getLocation()
{
return getEntity().getLocation();
}
public abstract boolean isProgressing();
public abstract void tick();
}

View File

@ -0,0 +1,358 @@
package mineplex.minecraft.game.core.boss;
import java.util.UUID;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.core.disguise.disguises.DisguiseBase;
import mineplex.core.disguise.disguises.DisguiseInsentient;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.world.ChunkUnloadEvent;
public abstract class EventCreature<T extends LivingEntity> implements Listener
{
private WorldEvent _event;
// Spawn Data
private T _entity;
private Class<? extends T> _entityClass;
private Location _spawnLocation, _lastLocation;
// Creature Data
private String _name;
private String _displayName;
private boolean _useName;
private double _health;
private double _maxHealth;
private boolean _showHealthName;
private long _teleportHome;
// Fight Data
private long _lastDamaged;
private UUID _lastDamager;
public EventCreature(WorldEvent event, Location spawnLocation, String name, boolean useName, double health, Class<T> entityClass)
{
_event = event;
_entityClass = entityClass;
_spawnLocation = spawnLocation;
_name = name;
_displayName = name;
_useName = useName;
_health = health;
_maxHealth = health;
_showHealthName = true;
_teleportHome = -1L;
}
public double getDifficulty()
{
return getEvent().getDifficulty();
}
protected void spawnEntity()
{
Location spawnLocation = _entity == null ? _spawnLocation : _entity.getLocation();
T entity = _spawnLocation.getWorld().spawn(spawnLocation, getEntityClass());
setEntity(entity);
updateEntityHealth();
entity.setRemoveWhenFarAway(false);
spawnCustom();
updateName();
}
protected abstract void spawnCustom();
protected void updateEntityHealth()
{
_entity.setMaxHealth(500d);
_entity.setHealth(500d);
}
protected void updateName()
{
String name = _displayName;
if (_showHealthName)
{
String healthString = (int) _health + "/" + (int) _maxHealth;
double per =_health / _maxHealth;
if (per > 0.5) healthString = C.cGreen + healthString;
if (per > 0.2) healthString = C.cYellow + healthString;
else healthString = C.cRed + healthString;
name += " " + C.cWhite + "(" + healthString + C.cWhite + ")";
}
DisguiseBase disguise = getEvent().getDisguiseManager().getDisguise(getEntity());
if (disguise != null && disguise instanceof DisguiseInsentient)
{
((DisguiseInsentient) disguise).setName(name);
((DisguiseInsentient) disguise).setCustomNameVisible(_useName);
}
_entity.setCustomName(name);
_entity.setCustomNameVisible(_useName);
}
public void remove()
{
remove(true);
}
public void remove(boolean removeFromEvent)
{
if (_entity != null)
{
if (getHealth() > 0)
{
_entity.remove();
}
else
{
_entity.setHealth(0);
_entity.setCustomName("");
_entity.setCustomNameVisible(false);
}
}
if (removeFromEvent)
_event.removeCreature(this);
}
protected final void die()
{
dieCustom();
remove();
}
public abstract void dieCustom();
public WorldEvent getEvent()
{
return _event;
}
public void setEvent(WorldEvent event)
{
_event = event;
}
public T getEntity()
{
return _entity;
}
public void setEntity(T entity)
{
if (_entity != null) _entity.remove();
_entity = entity;
}
public Class<? extends T> getEntityClass()
{
return _entityClass;
}
public void setEntityClass(Class<? extends T> clazz)
{
_entityClass = clazz;
}
public double getHealthPercent()
{
return getHealth() / getMaxHealth();
}
public Location getSpawnLocation()
{
return _spawnLocation;
}
public Location getLastKnownLocation()
{
return _lastLocation;
}
public void setSpawnLocation(Location spawnLocation)
{
_spawnLocation = spawnLocation;
}
public String getDisplayName()
{
return _displayName;
}
public String getName()
{
return _name;
}
public void setName(String name)
{
_displayName = name == null ? _name : name;
updateName();
}
public boolean isUseName()
{
return _useName;
}
public void setUseName(boolean useName)
{
_useName = useName;
updateName();
}
public void applyDamage(double damage)
{
setHealth(getHealth() - damage);
}
public double getHealth()
{
return _health;
}
public void setHealth(double health)
{
_health = health;
if (_health <= 0)
die();
else
updateName();
}
public double getMaxHealth()
{
return _maxHealth;
}
public void setMaxHealth(double maxHealth)
{
_maxHealth = maxHealth;
}
public void setShowHealthName(boolean showHealthName)
{
_showHealthName = showHealthName;
updateName();
}
/**
* Events
*/
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event)
{
if (_entity != null && _entity.getLocation().getChunk().equals(event.getChunk()))
event.setCancelled(true);
}
@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
return;
if (_entity == null || _entity.isDead() || !_entity.isValid())
{
System.out.println("Respawning " + getName() + " because it is null or dead");
spawnEntity();
}
if (UtilMath.offset2d(_entity.getLocation(), _spawnLocation) > 30)
{
if (_teleportHome != -1 && System.currentTimeMillis() >= _teleportHome)
{
_entity.teleport(_spawnLocation);
_teleportHome = -1;
}
else
{
_entity.setVelocity(UtilAlg.getTrajectory(_entity.getLocation(), _spawnLocation).normalize().multiply(2));
if (_teleportHome == -1)
{
_teleportHome = System.currentTimeMillis() + 5000;
}
}
}
else
{
if (_teleportHome != -1)
{
_teleportHome = -1;
}
}
_lastLocation = _entity.getLocation();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onDamage(CustomDamageEvent event)
{
if (_entity == null)
return;
if (!event.GetDamageeEntity().equals(_entity))
return;
updateEntityHealth();
applyDamage(event.GetDamage());
updateName();
_event.updateLastActive();
}
@EventHandler
public void damageType(CustomDamageEvent event)
{
if (_entity == null)
return;
if (!event.GetDamageeEntity().equals(_entity))
return;
DamageCause cause = event.GetCause();
if (cause == DamageCause.FALL && !getEvent().getCondition().HasCondition(_entity, ConditionType.FALLING, null))
event.SetCancelled("Cancel");
if (cause == DamageCause.DROWNING || cause == DamageCause.SUFFOCATION)
event.SetCancelled("Cancel");
}
@EventHandler
public void cancelCombust(EntityCombustEvent event)
{
if (_entity == null)
return;
if (!event.getEntity().equals(_entity))
return;
event.setCancelled(true);
}
}

View File

@ -0,0 +1,31 @@
package mineplex.minecraft.game.core.boss;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class EventCreatureDeathEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private EventCreature _creature;
public EventCreatureDeathEvent(EventCreature creature)
{
_creature = creature;
}
public EventCreature getCreature()
{
return _creature;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@ -0,0 +1,53 @@
package mineplex.minecraft.game.core.boss;
import org.bukkit.Location;
import org.bukkit.Material;
import mineplex.core.common.block.schematic.Schematic;
public class EventMap
{
private Schematic _schematic;
private Location _centerLocation;
private double _xDiff;
private double _yDiff;
private double _zDiff;
private double _xLength;
private double _yLength;
private double _zLength;
public EventMap(Schematic schematic, Location cornerLocation)
{
_schematic = schematic;
_xLength = schematic.getWidth();
_yLength = schematic.getHeight();
_zLength = schematic.getLength();
_xDiff = _xLength / 2D;
_yDiff = _yLength / 2D;
_zDiff = _zLength / 2D;
_centerLocation = cornerLocation.clone().add(_xDiff, _yDiff, _zDiff);
}
public Location getCenterLocation()
{
return _centerLocation;
}
public boolean isInMap(Location checkLocation)
{
Location center = getCenterLocation();
double x = Math.abs(center.getX() - checkLocation.getX());
double y = Math.abs(center.getY() - checkLocation.getY());
double z = Math.abs(center.getZ() - checkLocation.getZ());
return x <= _xDiff && y <= _yDiff && z <= _zDiff;
}
public Schematic getSchematic()
{
return _schematic;
}
}

View File

@ -0,0 +1,10 @@
package mineplex.minecraft.game.core.boss;
public enum EventState
{
PREPARE,
LIVE,
UNLOADING,
COMPLETE,
CANCELLED
}

View File

@ -0,0 +1,466 @@
package mineplex.minecraft.game.core.boss;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.blockrestore.BlockRestoreMap;
import mineplex.core.common.block.BlockData;
import mineplex.core.common.block.schematic.Schematic;
import mineplex.core.common.block.schematic.SchematicRunnable;
import mineplex.core.common.block.schematic.UtilSchematic;
import mineplex.core.common.util.C;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilWorld;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager;
import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
public abstract class WorldEvent implements Listener, ScoreboardElement
{
// 20 Minutes
private static final int ACTIVE_TIMEOUT = 1200000;
private DamageManager _damageManager;
private ConditionManager _conditionManager;
private DisguiseManager _disguiseManager;
private ProjectileManager _projectileManager;
private String _name;
private EventState _state;
private Location _cornerLocation;
private EventMap _map;
private Random _random;
private long _timeStarted = System.currentTimeMillis();
private long _lastActive;
private Schematic _schematic;
// Creatures
private List<EventCreature<?>> _creatures;
// Block Restore
private BlockRestoreMap _blocks;
private boolean _isArcade;
private double _difficulty = 1;
private double _minX;
private double _minY;
private double _minZ;
private double _maxX;
private double _maxY;
private double _maxZ;
public WorldEvent(DisguiseManager disguiseManager, ProjectileManager projectileManager, DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, String name, Location cornerLocation)
{
this(disguiseManager, projectileManager, damageManager, blockRestore, conditionManager, name, cornerLocation, null);
}
public WorldEvent(DisguiseManager disguiseManager, ProjectileManager projectileManager, DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, String name, Location cornerLocation, String schematicName)
{
_disguiseManager = disguiseManager;
_projectileManager = projectileManager;
_damageManager = damageManager;
_conditionManager = conditionManager;
_name = name;
_state = EventState.PREPARE;
_cornerLocation = cornerLocation;
_random = new Random();
_creatures = new ArrayList<>();
_blocks = blockRestore.createMap();
_lastActive = System.currentTimeMillis();
if (schematicName != null)
{
try
{
_schematic = UtilSchematic.loadSchematic(new File(schematicName));
_cornerLocation.subtract(_schematic.getWidth() / 2, 0, _schematic.getLength() / 2);
}
catch (IOException e)
{
e.printStackTrace();
setState(EventState.COMPLETE);
}
}
}
public DisguiseManager getDisguiseManager()
{
return _disguiseManager;
}
public ProjectileManager getProjectileManager()
{
return _projectileManager;
}
public void setDifficulty(double difficulty)
{
_difficulty = difficulty;
}
public void setArcadeGame(boolean isArcade)
{
_isArcade = isArcade;
}
public void loadMap()
{
loadMap(new Runnable()
{
@Override
public void run()
{
System.out.println("Runnable on complete");
}
});
}
public double getDifficulty()
{
return _difficulty;
}
public void loadMap(Runnable runnable)
{
if (_schematic == null)
{
return;
}
EventMap map = new EventMap(_schematic, _cornerLocation);
setMap(map, runnable);
}
public Schematic getSchematic()
{
return _schematic;
}
public ConditionManager getCondition()
{
return _conditionManager;
}
public final void start()
{
customStart();
}
@Override
public List<String> getLines(ScoreboardManager manager, Player player, List<String> out)
{
return null;
}
protected abstract void customStart();
public final void cleanup()
{
clearCreatures();
restoreBlocks();
customCleanup();
}
public void customCleanup()
{
}
public final void cancel()
{
cleanup();
setState(EventState.CANCELLED);
customCancel();
}
protected final void triggerEnd()
{
setState(EventState.COMPLETE);
}
protected void customCancel()
{
}
protected void customTick()
{
}
protected void setState(EventState state)
{
_state = state;
}
public EventState getState()
{
return _state;
}
public long getTimeRunning()
{
return System.currentTimeMillis() - _timeStarted;
}
public DamageManager getDamageManager()
{
return _damageManager;
}
public String getName()
{
return _name;
}
public void setName(String name)
{
_name = name;
}
protected Random getRandom()
{
return _random;
}
public Location getCenterLocation()
{
return _map == null ? _cornerLocation : _map.getCenterLocation();
}
public List<EventCreature<?>> getCreatures()
{
return _creatures;
}
public void registerCreature(EventCreature<?> creature)
{
UtilServer.getServer().getPluginManager().registerEvents(creature, _damageManager.getPlugin());
_creatures.add(creature);
}
public void removeCreature(EventCreature<?> creature)
{
Bukkit.getPluginManager().callEvent(new EventCreatureDeathEvent(creature));
HandlerList.unregisterAll(creature);
_creatures.remove(creature);
}
public void announceStart()
{
UtilTextMiddle.display(C.cGreen + getName(), UtilWorld.locToStrClean(getCenterLocation()), 10, 100, 40);
UtilServer.broadcast(F.main("Event", F.elem(getName()) + " has started at coordinates " + F.elem(UtilWorld.locToStrClean(getCenterLocation()))));
}
public void clearCreatures()
{
for (EventCreature<?> creature : _creatures)
{
creature.remove(false);
HandlerList.unregisterAll(creature);
}
_creatures.clear();
}
public JavaPlugin getPlugin()
{
return _damageManager.getPlugin();
}
public void restoreBlocks()
{
_blocks.restore();
}
public long getLastActive()
{
return _lastActive;
}
public void updateLastActive()
{
_lastActive = System.currentTimeMillis();
}
public EventMap getEventMap()
{
return _map;
}
public void setMap(EventMap map, final Runnable onComplete)
{
_map = map;
SchematicRunnable task = new SchematicRunnable(_damageManager.getPlugin(), map.getSchematic(), _cornerLocation.getBlock(), new Callback<List<BlockData>>()
{
@Override
public void run(List<BlockData> data)
{
if (!_isArcade)
{
for (BlockData blockData : data)
{
_blocks.addBlockData(blockData);
}
}
if (onComplete != null)
{
onComplete.run();
}
}
});
task.setBlocksPerTick(_isArcade ? 2000000 : 1000);
task.start();
}
protected BlockRestoreMap getBlocks()
{
return _blocks;
}
public void setBlock(Block block, Material material)
{
setBlock(block, material, (byte) 0);
}
public void setBlock(Block block, Material material, byte data)
{
setBlock(block, material.getId(), data);
}
public void setBlock(Block block, int id, byte data)
{
_blocks.set(block, id, data);
}
public int getRandomRange(int min, int max)
{
return min + _random.nextInt(UtilMath.clamp(max - min, min, max));
}
@EventHandler
public void tick(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
customTick();
}
@EventHandler
public void endInactive(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
long diff = System.currentTimeMillis() - getLastActive();
if (diff > ACTIVE_TIMEOUT)
{
setState(EventState.COMPLETE);
}
}
@EventHandler
public void prepareTimeout(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
if (getState() != EventState.PREPARE)
{
return;
}
// Event was preparing for more than 5 minutes
if (getTimeRunning() > 1000 * 60 * 5)
{
cancel();
}
}
public boolean isInBounds(Location location)
{
if (_minX == 0)
{
// Calculate bounds
Set<Block> blocks = _blocks.getChangedBlocks();
for (Block block : blocks)
{
if (_minX > block.getX())
{
_minX = block.getX();
}
if (_minY > block.getY())
{
_minY = block.getY();
}
if (_minZ > block.getZ())
{
_minZ = block.getZ();
}
if (_maxX < block.getX())
{
_maxX = block.getX();
}
if (_maxY < block.getY())
{
_maxY = block.getY();
}
if (_maxZ < block.getZ())
{
_maxZ = block.getZ();
}
}
_maxY++;
}
return UtilAlg.inBoundingBox(location, new Vector(_minX, _minY, _minZ), new Vector(_maxX, _maxY, _maxZ));
}
}

View File

@ -0,0 +1,96 @@
package mineplex.minecraft.game.core.boss.broodmother;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.common.util.UtilMath;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.EventState;
import mineplex.minecraft.game.core.boss.WorldEvent;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
public class SpiderBoss extends WorldEvent
{
public SpiderBoss(DisguiseManager disguiseManager, DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, ProjectileManager projectileManager, Location cornerLocation)
{
super(disguiseManager, projectileManager, damageManager, blockRestore, conditionManager, "Brood Mother", cornerLocation);
}
@EventHandler
public void onBreak(BlockBreakEvent event)
{
Block block = event.getBlock();
if (UtilMath.offset2d(event.getBlock().getLocation(), getCenterLocation()) > 40)
{
return;
}
if (block.getType() != Material.WEB)
{
return;
}
event.setCancelled(true);
event.getBlock().setType(Material.AIR);
}
@Override
protected void customStart()
{
Bukkit.broadcastMessage("Custom Start");
spawnSpider(getCenterLocation());
setState(EventState.LIVE);
announceStart();
}
/**
* Check if this spider boss has been defeated
*/
private void checkDeath()
{
if (getCreatures().size() == 0)
{
setState(EventState.COMPLETE);
Bukkit.broadcastMessage("FINISHED!");
}
}
@Override
public void removeCreature(EventCreature creature)
{
super.removeCreature(creature);
if (creature instanceof SpiderCreature)
{
checkDeath();
}
}
public SpiderMinionCreature spawnMinion(Location location)
{
if (getState() != EventState.LIVE)
{
return null;
}
SpiderMinionCreature minionCreature = new SpiderMinionCreature(this, location, 15);
registerCreature(minionCreature);
return minionCreature;
}
private SpiderCreature spawnSpider(Location location)
{
SpiderCreature spiderCreature = new SpiderCreature(this, location, 2500);
registerCreature(spiderCreature);
return spiderCreature;
}
}

View File

@ -0,0 +1,445 @@
package mineplex.minecraft.game.core.boss.broodmother;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.entity.Spider;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.broodmother.attacks.SpiderCeilingCling;
import mineplex.minecraft.game.core.boss.broodmother.attacks.SpiderEggScatter;
import mineplex.minecraft.game.core.boss.broodmother.attacks.SpiderEggplosm;
import mineplex.minecraft.game.core.boss.broodmother.attacks.SpiderPoisonBarrage;
import mineplex.minecraft.game.core.boss.broodmother.attacks.SpiderWebBarrage;
import mineplex.minecraft.game.core.boss.broodmother.attacks.SpiderWebStomp;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class SpiderCreature extends EventCreature<Spider>
{
private ArrayList<BossAbility> _currentAbilities = new ArrayList<BossAbility>();
private int _lastAbility;
private long _lastWalked;
private long _reverseWalk;
private Location _standing;
private Vector _afkWalk = new Vector();
private HashMap<Class, Long> _cooldowns = new HashMap<Class, Long>();
private long _lastAttack;
public SpiderCreature(SpiderBoss boss, Location location, double maxHealth)
{
super(boss, location, "Brood Mother", true, maxHealth, Spider.class);
spawnEntity();
}
@Override
protected void spawnCustom()
{
UtilEnt.vegetate(getEntity());
}
@Override
public void dieCustom()
{
/*for (Block block : Webs)
{
block.setType(Material.AIR);
}*/
}
@EventHandler
public void onTick(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<BossAbility> itel = _currentAbilities.iterator();
boolean canDoNew = _currentAbilities.size() < 3;
while (itel.hasNext())
{
BossAbility ability = itel.next();
if (ability.hasFinished())
{
itel.remove();
ability.setFinished();
_lastAbility = 20;// _currentAbility.getCooldown();
HandlerList.unregisterAll(ability);
System.out.print("Unregistered spider ability " + ability.getClass().getSimpleName());
_cooldowns.put(ability.getClass(), System.currentTimeMillis() + (ability.getCooldown() * 1000));
}
else if (ability.inProgress())
{
canDoNew = false;
_lastAbility = 20;// _currentAbility.getCooldown();
}
}
if (_lastAbility-- <= 0 && canDoNew && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN)))
{
HashMap<Class, Integer> weight = new HashMap<Class, Integer>();
HashMap<Player, Double> dist = new HashMap<Player, Double>();
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
{
if (player.hasLineOfSight(getEntity()))
{
dist.put(player, player.getLocation().distance(getEntity().getLocation()));
}
}
if (!dist.isEmpty())
{
{// Eggsplosm
ArrayList<Player> players = getPlayers(dist, 30);
if (getEvent().getCreatures().size() < 5 && !players.isEmpty())
{
weight.put(SpiderEggplosm.class, 4);
}
}
{ // Ceiling Cling
if (getEvent().getCreatures().size() < 5)
{
weight.put(SpiderCeilingCling.class, 2);
}
}
{ // Poison barrage
if (!getPlayers(dist, 10, 30).isEmpty())
{
weight.put(SpiderPoisonBarrage.class, 4);
}
}
{// Spider egg scatter
if (getEvent().getCreatures().size() < 5 && !getPlayers(dist, 20, 40).isEmpty())
{
weight.put(SpiderEggScatter.class, 4);
}
}
{ // Spider web barrage
if (!getPlayers(dist, 30).isEmpty())
{
weight.put(SpiderWebBarrage.class, 4);
}
}
{ // Spider web stomp
if (!getPlayers(dist, 20).isEmpty())
{
weight.put(SpiderWebStomp.class, 4);
}
}
}
for (BossAbility ability : _currentAbilities)
{
weight.remove(ability.getClass());
}
for (Class c : _cooldowns.keySet())
{
if (_cooldowns.get(c) > System.currentTimeMillis())
{
weight.remove(c);
}
}
BossAbility ability = null;
if (!weight.isEmpty())
{
int i = 0;
for (Integer entry : weight.values())
{
i += entry;
}
loop: for (int a = 0; a < 10; a++)
{
int luckyNumber = UtilMath.r(i);
for (Entry<Class, Integer> entry : weight.entrySet())
{
luckyNumber -= entry.getValue();
if (luckyNumber <= 0)
{
try
{
ability = (BossAbility) entry.getKey().getConstructor(SpiderCreature.class).newInstance(this);
if (ability.getTarget() == null || ability.hasFinished())
{
ability = null;
}
else
{
break loop;
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
break;
}
}
}
}
if (ability != null && ability.getTarget() != null)
{
Bukkit.getPluginManager().registerEvents(ability, getEvent().getPlugin());
System.out.print("Spider boss is using " + ability.getClass().getSimpleName());
_currentAbilities.add(ability);
}
_lastAbility = 10;
}
boolean canMove = true;
for (BossAbility ability : _currentAbilities)
{
try
{
ability.tick();
}
catch (Exception e)
{
e.printStackTrace();
}
if (!ability.canMove())
{
canMove = false;
}
}
if (canMove && System.currentTimeMillis() % 20000 > 2000)
{
for (double x = -.5; x <= .5; x += 1)
{
for (double y = 0; y <= 1; y += 1)
{
for (double z = -.5; z <= .5; z += 1)
{
Block block = getEntity().getLocation().add(x, y, z).getBlock();
if (block.getType() == Material.WEB)
{
block.setType(Material.AIR);
}
}
}
}
if (UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN))
|| getEntity().getVelocity().length() > 0.1)
{
Player target = null;
double dist = 0;
boolean canAttack = UtilTime.elapsed(_lastAttack, 1300);
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
double d = player.getLocation().distance(getEntity().getLocation());
if ((canAttack || d > 1.5) && (d < 7 || d > 15) && (target == null || (d < 50 && dist > d)))
{
target = player;
dist = d;
}
}
if (target != null && dist < 1.5 && canAttack)
{
// UtilEnt.CreatureMoveFast(getEntity(), target.getLocation(), 1F);
_lastAttack = System.currentTimeMillis();
Vector vec = UtilAlg.getTrajectory2d(getEntity(), target);
vec.multiply(0.5).setY(0.4);
getEntity().setVelocity(vec);
getEvent().getCondition().Factory()
.Confuse("Brood Mother Bite", target, getEntity(), 4, 0, false, true, true);
getEvent().getCondition().Factory()
.Blind("Brood Mother Bite", target, getEntity(), 1.5, 0, false, true, true);
getEvent().getCondition().Factory()
.Slow("Brood Mother Bite", target, getEntity(), 4, 1, false, true, true, true);
getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.ENTITY_ATTACK,
2 * getDifficulty(), true, false, false, "Brood Mother Attack", "Brood Mother Attack");
return;
}
Vector vec = null;
boolean superWalk = false;
if (target != null)
{
vec = target.getLocation().subtract(getEntity().getLocation()).toVector();
vec.setY(getEntity().getLocation().getY());
double len = vec.length();
vec.setX(vec.getX() * (UtilMath.random.nextDouble() / 3D));
vec.setZ(vec.getZ() * (UtilMath.random.nextDouble() / 3D));
vec.multiply(len);
if (target != null && dist < 8)
{
vec.multiply(-1);
superWalk = true;
}
if (!UtilAlg.HasSight(getEntity().getLocation(),
getEntity().getLocation().add(vec.clone().normalize().multiply(2))))
{
_reverseWalk = System.currentTimeMillis();
}
if (!UtilTime.elapsed(_reverseWalk, 4000))
{
vec.multiply(-1);
}
}
else if (!UtilTime.elapsed(_lastWalked, 7000))
{
vec = _afkWalk;
}
else if (UtilTime.elapsed(_lastWalked, 12000))
{
_afkWalk = new Vector();
for (int i = 0; i < 10; i++)
{
Vector vector = new Vector(UtilMath.r(20) - 10, 0, UtilMath.r(20) - 10);
if (UtilAlg.HasSight(getEntity().getLocation(),
getEntity().getLocation().add(vector.clone().normalize().multiply(2))))
{
vec = _afkWalk = vector;
break;
}
}
_lastWalked = System.currentTimeMillis();
}
if (vec != null)
{
// if (vec.length() > 1)
{
UtilEnt.CreatureMoveFast(getEntity(), getEntity().getLocation().add(vec), (target != null ? 1.8F : 1.1F)
+ (superWalk ? 0.4F : 0));
}
}
}
_standing = getEntity().getLocation();
}
else if (_standing != null)
{
Location l = getEntity().getLocation();
_standing.setYaw(l.getYaw());
_standing.setPitch(l.getPitch());
_standing.setY(l.getY());
getEntity().teleport(_standing);
}
}
private ArrayList<Player> getPlayers(HashMap<Player, Double> map, double maxDist)
{
return getPlayers(map, 0, maxDist);
}
private ArrayList<Player> getPlayers(final HashMap<Player, Double> map, double minDist, double maxDist)
{
ArrayList<Player> list = new ArrayList<Player>();
for (Player p : map.keySet())
{
if (map.get(p) >= minDist && map.get(p) <= maxDist)
{
list.add(p);
}
}
Collections.sort(list, new Comparator<Player>()
{
@Override
public int compare(Player o1, Player o2)
{
return Double.compare(map.get(o2), map.get(o1));
}
});
return list;
}
@EventHandler
public void noFallDamage(CustomDamageEvent event)
{
if (getEntity() == null)
return;
if (!event.GetDamageeEntity().equals(getEntity()))
return;
DamageCause cause = event.GetCause();
if (cause == DamageCause.FALL)
event.SetCancelled("Cancel");
}
}

View File

@ -0,0 +1,137 @@
package mineplex.minecraft.game.core.boss.broodmother;
import java.util.HashMap;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.CaveSpider;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
public class SpiderMinionCreature extends EventCreature<CaveSpider>
{
private long _lastAttack;
private Location _moveTo;
public SpiderMinionCreature(SpiderBoss boss, Location location, double maxHealth)
{
super(boss, location, "Spider Minion", true, maxHealth, CaveSpider.class);
spawnEntity();
}
@EventHandler
@Override
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
return;
if (getEntity() == null || getEntity().isDead() || !getEntity().isValid())
{
remove();
}
}
@Override
protected void spawnCustom()
{
UtilEnt.vegetate(getEntity(), true);
getEntity().setVelocity(new Vector(UtilMath.rr(0.5, true), 0.4, UtilMath.rr(0.4, true)));
}
@Override
public void dieCustom()
{
}
@EventHandler
public void onTick(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
if (UtilMath.r(150) == 0)
{
getEntity().getWorld().playSound(getEntity().getLocation(), Sound.SPIDER_IDLE, 2.5F, 1);
}
Location loc = getEntity().getLocation();
Player target = null;
HashMap<Player, Double> players = UtilPlayer.getInRadius(loc, 30);
for (Player player : players.keySet())
{
if (player.hasLineOfSight(getEntity()) && !UtilPlayer.isSpectator(player)
&& player.getGameMode() != GameMode.CREATIVE && (target == null || players.get(player) < players.get(target)))
{
target = player;
}
}
if (target == null)
{
if (UtilTime.elapsed(_lastAttack, 6000))
{
_lastAttack = System.currentTimeMillis();
_moveTo = loc.clone().add(UtilMath.rr(3, true), 0, UtilMath.rr(3, true));
}
if (_moveTo != null && _moveTo.distance(loc) > 0.2)
{
_moveTo.setY(loc.getY());
UtilEnt.CreatureMoveFast(getEntity(), _moveTo, 1.2F);
}
return;
}
UtilEnt.CreatureMoveFast(getEntity(), target.getLocation(), 1.6F);
if (UtilTime.elapsed(_lastAttack, 3000) && target.getLocation().distance(loc) < 2)
{
_lastAttack = System.currentTimeMillis();
Vector vec = UtilAlg.getTrajectory2d(getEntity(), target);
vec.multiply(0.4).setY(0.3);
getEntity().setVelocity(vec);
getEvent().getCondition().Factory().Blind("Spider Minion Bite", target, getEntity(), 1.5, 0, false, true, true);
getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.ENTITY_ATTACK,
2 * getDifficulty(), true, false, false, "Spider Minion Attack", "Spider Minion Attack");
}
}
@EventHandler
public void noFallDamage(CustomDamageEvent event)
{
if (getEntity() == null)
return;
if (!event.GetDamageeEntity().equals(getEntity()))
return;
DamageCause cause = event.GetCause();
if (cause == DamageCause.FALL)
event.SetCancelled("Cancel");
}
}

View File

@ -0,0 +1,218 @@
package mineplex.minecraft.game.core.boss.broodmother.attacks;
import java.util.Collections;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilShapes;
import mineplex.minecraft.game.core.boss.broodmother.SpiderCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class SpiderCeilingCling extends SpiderEggAbility
{
private double _startedHealth;
private boolean _isClinging;
private int _tick;
private Location _clingTo;
private double _lastY;
private int _eggsToLay = UtilMath.r(10) + 10;
private boolean _upsideDown;
public SpiderCeilingCling(SpiderCreature creature)
{
super(creature);
_startedHealth = creature.getHealth();
for (int i = 0; i < 10; i++)
{
Location loc = getLocation().add(UtilMath.rr(10, true), 12, UtilMath.rr(10, true));
if (UtilAlg.HasSight(getLocation(), loc))
{
while (loc.getBlock().getRelative(BlockFace.UP).getType() == Material.AIR)
{
loc.add(0, 1, 0);
}
if (UtilAlg.HasSight(getLocation(), loc))
{
_clingTo = loc;
break;
}
}
}
}
@Override
public boolean canMove()
{
return !_isClinging;
}
@Override
public int getCooldown()
{
return 90;
}
public Player getTarget()
{
List<Player> targets = UtilPlayer.getNearby(getLocation(), 35, true);
Collections.shuffle(targets);
for (Player player : targets)
{
if (UtilAlg.HasSight(getLocation(), player))
{
return player;
}
}
return null;
}
@Override
public boolean hasFinished()
{
return _clingTo == null;
}
@Override
public boolean inProgress()
{
return true;
}
@EventHandler
public void onKnockback(CustomDamageEvent event)
{
if (!event.GetDamageeEntity().equals(getEntity()))
{
return;
}
if (!_isClinging)
{
return;
}
event.SetKnockback(false);
}
@Override
public void setFinished()
{
if (_upsideDown)
{
getBoss().setUseName(true);
getBoss().setShowHealthName(true);
getBoss().setName(null);
}
setEggsFinished();
}
@Override
public void tick()
{
if (!_isClinging && _upsideDown)
{
if (Math.abs(getLocation().getY() - _lastY) < 0.05)
{
_isClinging = true;
}
_lastY = getLocation().getY();
}
if (_isClinging && _upsideDown)
{
getEntity().setVelocity(new Vector(0, 1, 0));
if (getBoss().getEvent().getCreatures().size() <= 3
&& (_tick > 30 * 20 || _startedHealth - getBoss().getHealth() > 150 || getEggs() == 0))
{
_isClinging = false;
_clingTo = null;
}
}
if (!_isClinging && _clingTo != null)
{
int i = 0;
for (Location loc : UtilShapes.getLinesDistancedPoints(getLocation(), _clingTo, 0.3))
{
if (i++ % 3 == _tick % 3)
{
UtilParticle.PlayParticle(ParticleType.FIREWORKS_SPARK, loc, 0F, 0F, 0F, 0, 1, ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
if (_eggsToLay > 0)
{
if (_tick % 3 == 0)
{
Vector vec = new Vector(UtilMath.rr(1, true), UtilMath.rr(0.5, false), UtilMath.rr(1, true)).normalize()
.multiply(0.7).setY(0.4 + (UtilMath.rr(0.4, false)));
UtilEnt.CreatureLook(getEntity(), getLocation().add(vec));
shootEgg(vec);
_eggsToLay--;
}
}
if (_eggsToLay < 3)
{
if (!_upsideDown)
{
_upsideDown = true;
getBoss().setUseName(false);
getBoss().setShowHealthName(false);
getBoss().setName("Dinnerbone");
}
getEntity().setVelocity(UtilAlg.getTrajectory(getLocation(), _clingTo).multiply(0.4));
}
}
_tick++;
}
@EventHandler
public void onDamage(CustomDamageEvent event)
{
if (!event.GetDamageeEntity().equals(getEntity()))
{
return;
}
if (event.GetCause() != DamageCause.FALL)
{
return;
}
event.SetCancelled("Cancelled");
}
}

View File

@ -0,0 +1,71 @@
package mineplex.minecraft.game.core.boss.broodmother.attacks;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilShapes;
import mineplex.core.common.util.UtilTime;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.broodmother.SpiderCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Location;
import org.bukkit.entity.Spider;
import org.bukkit.event.EventHandler;
public class SpiderCocoon extends BossAbility<SpiderCreature, Spider>
{
private static final long ABILITY_DURATION = 7000;
private long _start;
public SpiderCocoon(SpiderCreature creature)
{
super(creature);
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, ABILITY_DURATION);
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - ABILITY_DURATION;
}
@Override
public void tick()
{
for (Location loc : UtilShapes.getSphereBlocks(getEntity().getLocation(), 3, 3, false))
{
UtilParticle.PlayParticleToAll(ParticleType.FIREWORKS_SPARK, loc, null, 0, 1, ViewDist.NORMAL);
}
}
@EventHandler
public void onDamage(CustomDamageEvent event)
{
if (hasFinished())
{
return;
}
if (event.GetDamageeEntity() != null && event.GetDamageeEntity().equals(getEntity()))
{
event.SetCancelled("Cocoon Defense");
}
}
}

View File

@ -0,0 +1,228 @@
package mineplex.minecraft.game.core.boss.broodmother.attacks;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.broodmother.SpiderBoss;
import mineplex.minecraft.game.core.boss.broodmother.SpiderCreature;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Vec3D;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Spider;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.util.Vector;
public abstract class SpiderEggAbility extends BossAbility<SpiderCreature, Spider>
{
private HashMap<Block, Long> _eggs = new HashMap<Block, Long>();
private ArrayList<FallingBlock> _fallingBlocks = new ArrayList<FallingBlock>();
public SpiderEggAbility(SpiderCreature creature)
{
super(creature);
}
@EventHandler
public void onMove(PlayerMoveEvent event)
{
if (UtilPlayer.isSpectator(event.getPlayer()))
return;
if (event.getPlayer().getGameMode() == GameMode.CREATIVE)
return;
Block block = event.getTo().getBlock().getRelative(BlockFace.DOWN);
if (!_eggs.containsKey(block))
{
return;
}
_eggs.remove(block);
block.setType(Material.AIR);
block.getWorld().playSound(block.getLocation(), Sound.DIG_SNOW, 2.5F, 0F);
block.getWorld().playSound(block.getLocation(), Sound.BURP, 2.5F, 1.5F);
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.SNOW_BLOCK, 0),
block.getLocation().add(0.5, 0.4, 0.5), 0.4F, 0.4F, 0.4F, 0, 40, ViewDist.NORMAL, UtilServer.getPlayers());
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.DRAGON_EGG, 0),
block.getLocation().add(0.5, 0.6, 0.5), 0.6F, 0.5F, 0.6F, 0, 80, ViewDist.NORMAL, UtilServer.getPlayers());
}
public boolean hasEggsFinished()
{
return getEggs() == 0;
}
public void setEggsFinished()
{
for (FallingBlock block : _fallingBlocks)
{
block.remove();
}
for (Block b : _eggs.keySet())
{
b.setType(Material.AIR);
}
}
protected void shootEgg(Vector vector)
{
FallingBlock block = getLocation().getWorld().spawnFallingBlock(getLocation(), Material.DRAGON_EGG, (byte) 0);
block.setDropItem(false);
block.setVelocity(vector);
_fallingBlocks.add(block);
getLocation().getWorld().playSound(getLocation(), Sound.SHEEP_SHEAR, 2.5F, 0F);
}
@EventHandler
public void onEggTeleport(BlockFromToEvent event)
{
if (!_eggs.containsKey(event.getBlock()))
{
return;
}
event.setCancelled(true);
}
@EventHandler
public void onEggyUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<Entry<Block, Long>> itel = _eggs.entrySet().iterator();
while (itel.hasNext())
{
Entry<Block, Long> entry = itel.next();
if (entry.getValue() < System.currentTimeMillis())
{
itel.remove();
entry.getKey().setType(Material.AIR);
entry.getKey().getWorld()
.playEffect(entry.getKey().getLocation(), Effect.STEP_SOUND, Material.DRAGON_EGG.getId());
((SpiderBoss) getBoss().getEvent()).spawnMinion(entry.getKey().getLocation().add(0.5, 0.5, 0.5));
}
}
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getVelocity().length() < 0.05 || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
if ((UtilBlock.airFoliage(block) || block.getType() == Material.DRAGON_EGG)
&& block.getRelative(BlockFace.DOWN).getType() != Material.DRAGON_EGG)
{
block.setType(Material.DRAGON_EGG);
_eggs.put(block, System.currentTimeMillis() + 10000 + UtilMath.r(10000));
}
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ
+ nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ
* nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
if ((UtilBlock.airFoliage(block) || block.getType() == Material.DRAGON_EGG)
&& block.getRelative(BlockFace.DOWN).getType() != Material.DRAGON_EGG)
{
block.setType(Material.DRAGON_EGG);
_eggs.put(block, System.currentTimeMillis() + 5000 + UtilMath.r(5000));
}
fallingIterator.remove();
cur.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), cur.getLocation()
.add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, UtilServer.getPlayers());
}
}
}
public int getEggs()
{
return _fallingBlocks.size() + _eggs.size();
}
}

View File

@ -0,0 +1,80 @@
package mineplex.minecraft.game.core.boss.broodmother.attacks;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.minecraft.game.core.boss.broodmother.SpiderCreature;
public class SpiderEggScatter extends SpiderEggAbility
{
private int _eggsToSpray = 25;
private float _yaw;
private float _addYaw;
private int _tick;
public SpiderEggScatter(SpiderCreature creature)
{
super(creature);
_eggsToSpray = 6 + UtilMath.r(5);
_addYaw = (360F / _eggsToSpray) / 4;
}
public int getCooldown()
{
return 120;
}
@Override
public boolean canMove()
{
return _eggsToSpray <= 0;
}
@Override
public boolean inProgress()
{
return _eggsToSpray > 0 || !hasEggsFinished();
}
@Override
public boolean hasFinished()
{
return _eggsToSpray <= 0 && hasEggsFinished();
}
@Override
public void setFinished()
{
setEggsFinished();
}
@Override
public void tick()
{
if (_eggsToSpray <= 0)
{
return;
}
UtilEnt.CreatureLook(getEntity(), 0, _yaw);
_yaw += _addYaw;
if (_tick % 4 == 0 && _eggsToSpray > 0)
{
_eggsToSpray--;
Vector vec = getEntity().getLocation().getDirection();
vec.setY(0).normalize().multiply(0.7 + UtilMath.rr(0.16, false)).setY(0.4 + (UtilMath.rr(0.4, false)));
shootEgg(vec);
}
_tick++;
}
}

View File

@ -0,0 +1,72 @@
package mineplex.minecraft.game.core.boss.broodmother.attacks;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.minecraft.game.core.boss.broodmother.SpiderCreature;
public class SpiderEggplosm extends SpiderEggAbility
{
private int _eggsToSpray = 25;
private float _yaw;
private float _addYaw;
public SpiderEggplosm(SpiderCreature creature)
{
super(creature);
_eggsToSpray = 20 + (int) Math.ceil(15 * (1 - creature.getHealthPercent()));
_addYaw = 360F / _eggsToSpray;
}
public int getCooldown()
{
return 120;
}
@Override
public boolean canMove()
{
return _eggsToSpray <= 0;
}
@Override
public boolean inProgress()
{
return _eggsToSpray > 0 || !hasEggsFinished();
}
@Override
public boolean hasFinished()
{
return _eggsToSpray <= 0 && hasEggsFinished();
}
@Override
public void setFinished()
{
setEggsFinished();
}
@Override
public void tick()
{
if (_eggsToSpray > 0)
{
_eggsToSpray--;
UtilEnt.CreatureLook(getEntity(), 0, _yaw);
_yaw += _addYaw;
Vector vec = getEntity().getLocation().getDirection();
vec.setY(0).normalize().multiply(0.7).setY(0.4 + (UtilMath.rr(0.4, false)));
shootEgg(vec);
}
}
}

View File

@ -0,0 +1,71 @@
package mineplex.minecraft.game.core.boss.broodmother.attacks;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.projectile.IThrown;
import mineplex.core.projectile.ProjectileUser;
import mineplex.minecraft.game.core.boss.EventCreature;
public class SpiderPoison implements IThrown
{
private EventCreature _boss;
public SpiderPoison(EventCreature boss, Entity item)
{
_boss = boss;
boss.getEvent().getProjectileManager().AddThrow(item, boss.getEntity(), this, -1, true, true, true, false, 2f);
}
@Override
public void Collide(LivingEntity target, Block block, ProjectileUser data)
{
if (target instanceof Player)
{
_boss.getEvent().getCondition().Factory()
.Poison("Brood Mother Poison", target, _boss.getEntity(), 2, 1, false, true, false);
_boss.getEvent()
.getDamageManager()
.NewDamageEvent(target, _boss.getEntity(), null, DamageCause.PROJECTILE, 2, true, false, false,
"Brood Mother Poison", "Brood Mother Poison");
}
burst(data);
}
@Override
public void Idle(ProjectileUser data)
{
burst(data);
}
private void burst(ProjectileUser data)
{
data.getThrown().remove();
UtilParticle.PlayParticle(ParticleType.ICON_CRACK.getParticle(Material.SLIME_BALL, 0), data.getThrown().getLocation(),
0.3F, 0.3F, 0.3F, 0, 30, ViewDist.NORMAL, UtilServer.getPlayers());
}
@Override
public void Expire(ProjectileUser data)
{
burst(data);
}
@Override
public void ChunkUnload(ProjectileUser data)
{
data.getThrown().remove();
}
}

View File

@ -0,0 +1,146 @@
package mineplex.minecraft.game.core.boss.broodmother.attacks;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilServer;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.broodmother.SpiderCreature;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.entity.Spider;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
public class SpiderPoisonBarrage extends BossAbility<SpiderCreature, Spider>
{
private int _poisonAmount = UtilMath.r(20) + 30;
private int _tick;
private float _yawToFace;
public SpiderPoisonBarrage(SpiderCreature creature)
{
super(creature);
}
@Override
public boolean canMove()
{
return _poisonAmount <= 0;
}
@Override
public boolean inProgress()
{
return _poisonAmount > 0;
}
@Override
public boolean hasFinished()
{
return _poisonAmount <= 0;
}
@Override
public void setFinished()
{
}
@Override
public int getCooldown()
{
return 10;
}
/*@Override
public Player getTarget()
{
return getTarget(1, 30);
}*/
@Override
public void tick()
{
if (_tick == 0)
{
Player target = getTarget();
if (target != null)
{
UtilEnt.CreatureLook(getEntity(), target);
Vector vec = UtilAlg.getTrajectory(getEntity(), target);
_yawToFace = UtilAlg.GetYaw(vec);
}
}
{
Location loc = getEntity().getEyeLocation().add(getLocation().getDirection().setY(0).normalize().multiply(0.4));
UtilParticle.PlayParticle(ParticleType.ICON_CRACK.getParticle(Material.SLIME_BALL, 0), loc, 0.3F, 0.3F, 0.3F, 0, 30,
ViewDist.NORMAL, UtilServer.getPlayers());
}
if (_tick > 30)
{
Player target = getTarget();
if (target != null)
{
Vector vec = UtilAlg.getTrajectory(getEntity(), target);
_yawToFace = UtilAlg.GetYaw(vec);
}
float currentYaw = getLocation().getYaw();
if ((int) currentYaw != (int) _yawToFace)
{
// How much should the yaw change if we go either direction, would it be faster if we subtracted or added?
float added = ((_yawToFace + 720) - currentYaw) % 360;
float subtracted = /*-*/((currentYaw + 720) - _yawToFace) % 360;
float diff = Math.max(-10, Math.min(10, added > subtracted ? -subtracted : added));
float newYaw = (currentYaw + diff + 720) % 360;
UtilEnt.CreatureLook(getEntity(), 0, newYaw);
System.out.print("Current yaw: " + currentYaw + ", Yaw to face: " + _yawToFace + ", New Yaw: " + newYaw
+ ", Add: " + added + ", Subtracted: " + subtracted);
}
if (_tick % 2 == 0)
{
Vector vec = getLocation().getDirection();
vec.setX(vec.getX() + UtilMath.rr(0.09, true));
vec.setZ(vec.getZ() + UtilMath.rr(0.09, true));
vec.setY(0).normalize().multiply(1 + UtilMath.rr(0.2, true));
vec.setY(0.35 + UtilMath.rr(0.3, false));
Item item = getLocation().getWorld()
.dropItem(getLocation().add(0, 0.5, 0), new ItemStack(Material.SLIME_BALL));
item.setVelocity(vec);
new SpiderPoison(getBoss(), item);
getLocation().getWorld().playSound(getLocation(), Sound.CREEPER_HISS, 2, 0F);
_poisonAmount--;
}
}
_tick++;
}
}

View File

@ -0,0 +1,149 @@
package mineplex.minecraft.game.core.boss.broodmother.attacks;
import java.util.ArrayList;
import java.util.Iterator;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.broodmother.SpiderCreature;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
import org.bukkit.entity.Spider;
import org.bukkit.event.EventHandler;
import org.bukkit.util.Vector;
public class SpiderWebBarrage extends BossAbility<SpiderCreature, Spider>
{
private int _canShoot;
private ArrayList<FallingBlock> _fallingBlocks = new ArrayList<FallingBlock>();
private int _tick;
public SpiderWebBarrage(SpiderCreature creature)
{
super(creature);
_canShoot = (int) (40 + ((1 - creature.getHealthPercent()) * 50));
Player target = getTarget();
if (target != null)
{
UtilEnt.CreatureLook(getEntity(), target);
}
}
@Override
public boolean canMove()
{
return _canShoot <= 0;
}
@Override
public int getCooldown()
{
return 120;
}
@Override
public boolean inProgress()
{
return _canShoot > 0 || !_fallingBlocks.isEmpty();
}
@Override
public boolean hasFinished()
{
return _canShoot <= 0 && _fallingBlocks.isEmpty();
}
@Override
public void setFinished()
{
for (FallingBlock block : _fallingBlocks)
{
block.remove();
}
}
public Player getTarget()
{
return getTarget(10, 30);
}
@Override
public void tick()
{
if (_canShoot > 0 && _tick % 2 == 0)
{
_canShoot--;
Vector vec = getLocation().getDirection().setY(0).normalize();
vec.add(new Vector(UtilMath.rr(0.45, true), 0, UtilMath.rr(0.45, true))).normalize();
vec.setY(0.8).multiply(0.75 + UtilMath.rr(0.3, true));
FallingBlock block = getLocation().getWorld().spawnFallingBlock(getLocation(), Material.WEB, (byte) 0);
block.setDropItem(false);
_fallingBlocks.add(block);
block.setVelocity(vec);
getLocation().getWorld().playSound(getLocation(), Sound.FIZZ, 3, 2F);
}
_tick++;
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getVelocity().length() < 0.05 || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
if (UtilBlock.airFoliage(block) || block.getType() == Material.WEB)
{
Bukkit.broadcastMessage("Setting Web");
getBoss().getEvent().setBlock(block, Material.WEB);
}
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
}
}
}

View File

@ -0,0 +1,90 @@
package mineplex.minecraft.game.core.boss.broodmother.attacks;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.broodmother.SpiderCreature;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.entity.Spider;
/**
* A attack where webs appear all around the spider in a kinda maze formation, making it hard to approach it.
*/
public class SpiderWebStomp extends BossAbility<SpiderCreature, Spider>
{
private int _tick;
public SpiderWebStomp(SpiderCreature creature)
{
super(creature);
}
@Override
public int getCooldown()
{
return 120;
}
@Override
public boolean canMove()
{
return true;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return _tick > 40;
}
@Override
public void setFinished()
{
}
public Player getTarget()
{
if (!UtilEnt.isGrounded(getEntity()))
{
return null;
}
return super.getTarget();
}
@Override
public void tick()
{
if (_tick++ == 0)
{
int amount = UtilMath.r(60) + 60;
for (int i = 0; i < amount; i++)
{
Block block = getLocation().getBlock().getRelative((int) UtilMath.rr(UtilMath.r(16) + 4, true), 0,
(int) UtilMath.rr(UtilMath.r(16) + 4, true));
if (block.getType() != Material.AIR)
{
continue;
}
Bukkit.broadcastMessage("Setting Web");
getBoss().getEvent().setBlock(block, Material.WEB);
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.WEB);
}
}
}
}

View File

@ -0,0 +1,61 @@
package mineplex.minecraft.game.core.boss.ironwizard;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.common.util.F;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.EventState;
import mineplex.minecraft.game.core.boss.WorldEvent;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
public class GolemBoss extends WorldEvent
{
public GolemBoss(DisguiseManager disguiseManager, DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, ProjectileManager projectileManager, Location cornerLocation)
{
super(disguiseManager, projectileManager, damageManager, blockRestore, conditionManager, "Iron Wizard", cornerLocation);
}
@Override
protected void customStart()
{
Bukkit.broadcastMessage(F.main(getName(), "The mighty " + getName() + " challenges you to face him!"));
spawnGolem(getCenterLocation());
setState(EventState.LIVE);
announceStart();
}
/**
* Check if this golem boss has been defeated
*/
private void checkDeath()
{
if (getCreatures().size() == 0)
{
setState(EventState.COMPLETE);
Bukkit.broadcastMessage(F.main(getName(), "The mighty " + getName() + " has fallen!"));
}
}
@Override
public void removeCreature(EventCreature creature)
{
super.removeCreature(creature);
if (creature instanceof GolemCreature)
{
checkDeath();
}
}
private GolemCreature spawnGolem(Location location)
{
GolemCreature golemCreature = new GolemCreature(this, location, 3000);
registerCreature(golemCreature);
return golemCreature;
}
}

View File

@ -0,0 +1,627 @@
package mineplex.minecraft.game.core.boss.ironwizard;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Random;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemBlockHail;
import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemBlockShot;
import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemDeadlyTremor;
import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemEarthquake;
import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemExplodingAura;
import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemIronHook;
import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemMeleeAttack;
import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemRupture;
import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemSlam;
import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemSpike;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.util.Vector;
public class GolemCreature extends EventCreature<IronGolem>
{
//private static final double HEALTH_PER_REGEN = 5;
//private static final long HEALTH_REGEN_DELAY = 1000;
//private static final long REGEN_SAFE_TIME_NEED = 10000;
//private static final double CROWD_CONTROL_DAMAGE_REDUCTION = .70;
//private final double MAX_HEALTH;
private GolemBoss _boss;
// private GolemAbility _currentAbility;
private int _lastAbility;
private long _lastWalked;
private Location _standing;
private long _spawnDelay = System.currentTimeMillis();
private long _reverseWalk;
private HashMap<Class, Class[]> _preferedCombos = new HashMap<Class, Class[]>();
private Class _lastAttack;
private boolean _usedFinalAttack;
private ArrayList<BossAbility> _currentAbilities = new ArrayList<BossAbility>();
private double _canDeadlyTremor = 225;
private Vector _afkWalk = new Vector();
private long _lastSlam;
//private long _lastHit;
//private long _lastRegenerate;
public GolemCreature(GolemBoss boss, Location location, double maxHealth)
{
super(boss, location, "Iron Wizard", true, maxHealth, IronGolem.class);
//MAX_HEALTH = maxHealth;
//_lastRegenerate = System.currentTimeMillis() + 20000;
_boss = boss;
spawnEntity();
_preferedCombos.put(GolemEarthquake.class, new Class[]
{
GolemBlockHail.class, GolemRupture.class
});
_preferedCombos.put(GolemMeleeAttack.class, new Class[]
{
GolemEarthquake.class, GolemRupture.class
});
_preferedCombos.put(GolemDeadlyTremor.class, new Class[]
{
GolemMeleeAttack.class
});
_preferedCombos.put(GolemBlockShot.class, new Class[]
{
GolemEarthquake.class
});
_preferedCombos.put(GolemRupture.class, new Class[]
{
GolemBlockShot.class
});
_preferedCombos.put(GolemBlockHail.class, new Class[]
{
GolemDeadlyTremor.class
});
}
private boolean hasFurther(HashMap<Player, Double> distances, double range)
{
for (Player player : distances.keySet())
{
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
Double dist = distances.get(player);
if (dist >= range)
{
return true;
}
}
return false;
}
@Override
protected void spawnCustom()
{
UtilEnt.vegetate(getEntity());
// EntityInsentient creature = (EntityInsentient) ((CraftEntity) getEntity()).getHandle();
// creature.Vegetated = false;
_standing = getEntity().getLocation();
}
@EventHandler
public void abilityTick(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
if (!UtilTime.elapsed(_spawnDelay, 5000))
{
_standing = getEntity().getLocation();
return;
}
/*if (UtilTime.elapsed(_lastHit, REGEN_SAFE_TIME_NEED) && UtilTime.elapsed(_lastRegenerate, HEALTH_REGEN_DELAY))
{
_lastRegenerate = System.currentTimeMillis();
super.setHealth(Math.min(MAX_HEALTH, getHealth() + HEALTH_PER_REGEN));
setHealth(getHealth() + HEALTH_PER_REGEN);
}*/
// if (_currentAbility == null || _currentAbility.hasFinished())
// {
Iterator<BossAbility> itel = _currentAbilities.iterator();
boolean canDoNew = _currentAbilities.size() < 3;
while (itel.hasNext())
{
BossAbility ability = itel.next();
if (ability.hasFinished())
{
itel.remove();
ability.setFinished();
_lastAbility = 20;// _currentAbility.getCooldown();
HandlerList.unregisterAll(ability);
System.out.print("Unregistered golem ability " + ability.getClass().getSimpleName());
}
else if (!ability.inProgress())
{
canDoNew = false;
}
}
if (_lastAbility-- <= 0 && canDoNew && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN)))
{
HashMap<Class, Integer> weight = new HashMap<Class, Integer>();
HashMap<Player, Double> dist = new HashMap<Player, Double>();
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
{
if (player.hasLineOfSight(getEntity()))
{
dist.put(player, player.getLocation().distance(getEntity().getLocation()));
}
}
if (!dist.isEmpty())
{
double hp = getHealthPercent();
{ // Melee
ArrayList<Player> players = getPlayers(dist, UtilMath.r(10) == 0 ? 4 : 3);
if (!players.isEmpty())
{
if (players.size() >= 4)
{
weight.put(GolemEarthquake.class, 999);
}
else
{
weight.put(GolemMeleeAttack.class, 999);
}
}
}
if (hasFurther(dist, 15))
{ // Iron Hook
weight.put(GolemIronHook.class, 6); //6
}
if (hp < 0.7)
{ // Earthquake
ArrayList<Player> players = getPlayers(dist, 10);
double score = 0;
for (Player player : players)
{
score += (8 - dist.get(player)) / 2;
}
if (players.size() >= 3)
{
score += 7;
}
if (score > 0)
{
weight.put(GolemEarthquake.class, (int) Math.ceil(score));
}
}
{ // Wall explode
if (!getPlayers(dist, 20).isEmpty() && getPlayers(dist, 4).isEmpty())
{
weight.put(GolemSpike.class, 8);
}
}
{ // Block Shot
ArrayList<Player> players = getPlayers(dist, 30);
for (Player player : players)
{
if (dist.get(player) > 4)
{
weight.put(GolemBlockShot.class, 6);
break;
}
}
}
{ // Rupture
ArrayList<Player> players = getPlayers(dist, 30);
if (!players.isEmpty())
{
weight.put(GolemRupture.class, (int) Math.min(5, dist.get(players.get(0))));
}
}
{ // Slam
ArrayList<Player> players = getPlayers(dist, 30);
if (!players.isEmpty() && UtilTime.elapsed(_lastSlam, 20000))
{
weight.put(GolemSlam.class, 6);
}
}
if (_canDeadlyTremor <= 0) // Deadly Tremor
{
ArrayList<Player> players = getPlayers(dist, 80);
for (BossAbility ability : _currentAbilities)
{
if (ability instanceof GolemExplodingAura)
{
players.clear();
}
}
if (!players.isEmpty())
{
// weight.put(GolemCaveIn.class, (int) Math.min(players.size() * 2, 7));
weight.put(GolemDeadlyTremor.class, (int) 30);
}
}
{// Block Hail
ArrayList<Player> players = getPlayers(dist, 30);
if (!players.isEmpty())
{
int we = _lastAttack == GolemEarthquake.class ? 20 : UtilMath.r(15) - 2;
if (we > 0)
{
weight.put(GolemBlockHail.class, we);
}
}
}
if (!_usedFinalAttack && getHealth() < 90)
{
_usedFinalAttack = true;
weight.clear();
weight.put(GolemExplodingAura.class, 999);
}
if (_lastAttack != null && _preferedCombos.containsKey(_lastAttack))
{
weight.remove(_lastAttack);
for (Class c : _preferedCombos.get(_lastAttack))
{
if (weight.containsKey(c))
{
weight.put(c, weight.get(c) * 4);
}
}
}
for (BossAbility ability : _currentAbilities)
{
weight.remove(ability.getClass());
}
BossAbility ability = null;
if (!weight.isEmpty())
{
int i = 0;
for (Integer entry : weight.values())
{
i += entry;
}
for (int a = 0; a < 10; a++)
{
int luckyNumber = UtilMath.r(i);
for (Entry<Class, Integer> entry : weight.entrySet())
{
luckyNumber -= entry.getValue();
if (luckyNumber <= 0)
{
try
{
ability = (BossAbility) entry.getKey().getConstructor(GolemCreature.class).newInstance(this);
if (ability.getTarget() == null)
{
ability = null;
}
else
{
break;
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
break;
}
}
}
}
if (ability != null && ability.getTarget() != null)
{
_lastAttack = ability.getClass();
if (ability instanceof GolemDeadlyTremor)
{
_canDeadlyTremor = 225;
}
else if (ability instanceof GolemSlam)
{
_lastSlam = System.currentTimeMillis();
}
Bukkit.getPluginManager().registerEvents(ability, _boss.getPlugin());
// Bukkit.broadcastMessage("Prepare fair maidens for " + ability.getClass().getSimpleName() + "!");
System.out.print("Golem boss is using " + ability.getClass().getSimpleName());
_currentAbilities.add(ability);
}
_lastAbility = 10;
}
_lastAttack = null;
}
boolean canMove = true;
for (BossAbility ability : _currentAbilities)
{
try
{
ability.tick();
}
catch (Exception e)
{
e.printStackTrace(); //Keeps the boss from getting stuck if one of the moves throws an error in progression
}
if (!ability.canMove())
{
canMove = false;
}
}
if (canMove)
{
Player target = null;
double dist = 0;
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
double d = player.getLocation().distance(getEntity().getLocation());
if (d > 1.5 && (d < 7 || d > 15) && (target == null || (d < 50 && dist > d)))
{
target = player;
dist = d;
}
}
Vector vec = null;
boolean superWalk = false;
if (target != null)
{
vec = target.getLocation().subtract(getEntity().getLocation()).toVector();
vec.setY(getEntity().getLocation().getY());
double len = vec.length();
vec.setX(vec.getX() * (UtilMath.random.nextDouble() / 3D));
vec.setZ(vec.getZ() * (UtilMath.random.nextDouble() / 3D));
vec.multiply(len);
if (target != null && dist < 8)
{
vec.multiply(-1);
superWalk = true;
}
if (!UtilAlg.HasSight(getEntity().getLocation(),
getEntity().getLocation().add(vec.clone().normalize().multiply(2))))
{
_reverseWalk = System.currentTimeMillis();
}
if (!UtilTime.elapsed(_reverseWalk, 4000))
{
vec.multiply(-1);
}
}
else if (!UtilTime.elapsed(_lastWalked, 7000))
{
vec = _afkWalk;
}
else if (UtilTime.elapsed(_lastWalked, 12000))
{
_afkWalk = new Vector();
for (int i = 0; i < 10; i++)
{
Vector vector = new Vector(UtilMath.r(20) - 10, 0, UtilMath.r(20) - 10);
if (UtilAlg.HasSight(getEntity().getLocation(),
getEntity().getLocation().add(vector.clone().normalize().multiply(2))))
{
vec = _afkWalk = vector;
break;
}
}
_lastWalked = System.currentTimeMillis();
}
if (vec != null)
{
// if (vec.length() > 1)
{
UtilEnt.CreatureMoveFast(getEntity(), getEntity().getLocation().add(vec),
(target != null ? 1.8F : 1.1F) + (superWalk ? 0.4F : 0));
}
}
_standing = getEntity().getLocation();
}
else
{
Location l = getEntity().getLocation();
_standing.setYaw(l.getYaw());
_standing.setPitch(l.getPitch());
_standing.setY(l.getY());
getEntity().teleport(_standing);
}
}
private ArrayList<Player> getPlayers(final HashMap<Player, Double> map, double maxDist)
{
ArrayList<Player> list = new ArrayList<Player>();
for (Player p : map.keySet())
{
if (map.get(p) <= maxDist)
{
list.add(p);
}
}
Collections.sort(list, new Comparator<Player>()
{
@Override
public int compare(Player o1, Player o2)
{
return Double.compare(map.get(o2), map.get(o1));
}
});
return list;
}
@EventHandler
public void onGolemDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().equals(getEntity()))
{
event.AddKnockback("Heavy Golem", 0.3);
//_lastHit = System.currentTimeMillis();
/*if (UtilPlayer.getInRadius(getEntity().getLocation(), 10).size() >= 3)
{
event.AddMult(getEntity().getName(), "Level Field", CROWD_CONTROL_DAMAGE_REDUCTION, false);
}*/
}
}
@EventHandler
public void onRangedAttack(CustomDamageEvent event)
{
if (event.GetDamageeEntity().equals(getEntity()))
{
if (event.GetDamageePlayer() != null)
{
if (event.GetProjectile() != null && event.GetProjectile() instanceof Arrow)
{
if (new Random().nextDouble() <= .5)
{
event.SetCancelled("Iron Skin Reflection");
getEntity().getWorld().playSound(getEntity().getLocation(), Sound.ZOMBIE_METAL, 0.5f, 1.6f);
return;
}
}
double dist = event.GetDamageePlayer().getLocation().distance(getEntity().getLocation());
double maxRange = _usedFinalAttack ? 20 : 45;
double modifier = (maxRange - dist) / maxRange;
if (modifier > 0)
{
event.AddMod("Ranged Resistance", 1 - modifier);
}
else
{
event.SetCancelled("Range too far");
}
}
}
}
@Override
public void dieCustom()
{
endAbility();
}
private void endAbility()
{
for (BossAbility ability : _currentAbilities)
{
ability.setFinished();
HandlerList.unregisterAll(ability);
}
_currentAbilities.clear();
}
@Override
public void setHealth(double health)
{
_canDeadlyTremor -= getHealth() - health;
super.setHealth(health);
if (getHealth() <= 100 && !_usedFinalAttack)
{
endAbility();
}
}
}

View File

@ -0,0 +1,87 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import mineplex.core.common.util.UtilEnt;
import net.minecraft.server.v1_8_R3.DataWatcher;
import net.minecraft.server.v1_8_R3.Entity;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.IronGolem;
public class BlockHailBlock
{
private int _block = UtilEnt.getNewEntityId();
private int _silverfish = UtilEnt.getNewEntityId();
private Location _location;
private Material _mat;
public BlockHailBlock(Location loc, Material mat)
{
_location = loc;
_mat = mat;
}
public Packet getDestroyPacket()
{
return new PacketPlayOutEntityDestroy(new int[]
{
_silverfish, _block
});
}
public Location getLocation()
{
return _location;
}
public Material getMaterial()
{
return _mat;
}
public Packet[] getSpawnPackets(IronGolem entity)
{
Packet[] packets = new Packet[3];
PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving();
DataWatcher watcher = new DataWatcher(null);
watcher.a(0, (byte) 32, Entity.META_ENTITYDATA, (byte) 0);
watcher.a(1, 0, Entity.META_AIR, 0);
packet1.a = _silverfish;
packet1.b = EntityType.SILVERFISH.getTypeId();
packet1.c = (int) Math.floor(_location.getX() * 32);
packet1.d = (int) Math.floor(_location.getY() * 32);
packet1.e = (int) Math.floor(_location.getZ() * 32);
packet1.l = watcher;
packets[0] = packet1;
PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, _mat.getId());
packet2.a = _block;
packet2.b = (int) Math.floor(_location.getX() * 32);
packet2.c = (int) Math.floor(entity.getLocation().getY() * 32);
packet2.d = (int) Math.floor(_location.getZ() * 32);
packets[1] = packet2;
PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity();
packet3.b = _block;
packet3.c = _silverfish;
packets[2] = packet3;
return packets;
}
}

View File

@ -0,0 +1,477 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilShapes;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.Vec3D;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
/**
* Rumble is where the golem picks a target then starts playing a animation for a second where its obviously preparing to use it.
* Copy this from Wizards
*/
public class GolemBlockHail extends BossAbility<GolemCreature, IronGolem>
{
private int _currentBlock;
private int _currentLevel;
private ArrayList<FallingBlock> _fallingBlocks = new ArrayList<FallingBlock>();
private HashMap<Integer, ArrayList<BlockHailBlock>> _floatingBlocks = new HashMap<Integer, ArrayList<BlockHailBlock>>();
private HashMap<String, Integer> _blocks = new HashMap<String, Integer>();
private int _levelToReach;
private boolean _spawned;
private ArrayList<Location> _spawnLocs = new ArrayList<Location>();
private Player _target;
private Location _center;
private int _ticks;
public GolemBlockHail(GolemCreature creature)
{
super(creature);
_center = getLocation();
if (creature.getHealthPercent() > 0.75)
{
_levelToReach = 1;
}
else if (creature.getHealthPercent() > 0.5)
{
_levelToReach = 2;
}
else
{
_levelToReach = 3;
}
_target = getTarget();
}
@Override
public Player getTarget()
{
Player target = null;
double dist = 0;
if (inProgress())
{
for (Player player : UtilPlayer.getNearby(_center, 40, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
if (target != null && _blocks.containsKey(player.getName()) && _blocks.get(player.getName()) > 8)
{
continue;
}
double d = player.getLocation().distance(_center);
if (target == null || dist > d)
{
target = player;
dist = d;
}
}
}
return target;
}
@Override
public boolean canMove()
{
return _spawned && _floatingBlocks.isEmpty();
}
@Override
public boolean hasFinished()
{
return _target == null || !_target.isValid() || ((_fallingBlocks.isEmpty() && _spawned) && _ticks >= 8 * 9)
|| _center.distance(_target.getLocation()) > 100;
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
continue;
// Creative or Spec
if (ent instanceof Player)
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
continue;
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
// if (canDamage(victim))
{
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Block Hail",
"Iron Wizard Block Hail");
}
if (victim instanceof Player)
{
getBoss().getEvent().getCondition().Factory().Slow("Iron Wizard Block Hail", (LivingEntity) victim,
getEntity(), 3, 2, false, false, false, false);
}
fallingIterator.remove();
cur.remove();
}
else if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
fallingIterator.remove();
cur.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
@Override
public void setFinished()
{
for (ArrayList<BlockHailBlock> floatingBlocks : _floatingBlocks.values())
{
for (BlockHailBlock falling : floatingBlocks)
{
Packet packet = falling.getDestroyPacket();
for (Player player : UtilServer.getPlayers())
{
UtilPlayer.sendPacket(player, packet);
}
}
}
for (FallingBlock block : _fallingBlocks)
{
block.remove();
}
}
@Override
public void tick()
{
if (inProgress())
{
for (Player player : UtilPlayer.getNearby(_center, 5, true))
{
Location loc = player.getLocation();
if (Math.abs(loc.getY() - (_center.getY() + 1)) <= 1)
{
loc.setY(_center.getY());
if (loc.distance(_center) < 2.8 + (_currentLevel * 0.75))
{
if (canDamage(player))
{
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null,
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false,
"Iron Wizard Protection", "Iron Wizard Protection");
loc.getWorld().playEffect(player.getLocation(), Effect.STEP_SOUND, Material.OBSIDIAN.getId());
loc.getWorld().playEffect(player.getEyeLocation(), Effect.STEP_SOUND, Material.OBSIDIAN.getId());
}
}
}
}
}
if (!_spawned)
{
if (_currentBlock >= _spawnLocs.size())
{
if (_currentLevel + 1 <= _levelToReach)
{
_currentLevel++;
_currentBlock = 0;
_spawnLocs = UtilShapes.getDistancedCircle(_center.clone().add(0, 2.8 + (_currentLevel * 0.75), 0), 1.3,
1 + (_currentLevel * 1.3));
for (int i = UtilMath.r(_spawnLocs.size()); i > 0; i--)
{
_spawnLocs.add(_spawnLocs.remove(0));
}
}
}
if (_currentBlock < _spawnLocs.size())
{
if (_ticks % 2 == 0)
{
IronGolem entity = getEntity();
Location loc = _spawnLocs.get(_currentBlock++);
ArrayList<BlockHailBlock> floatingBlocks = new ArrayList<BlockHailBlock>();
if (_floatingBlocks.containsKey(_currentLevel))
{
floatingBlocks = _floatingBlocks.get(_currentLevel);
}
else
{
_floatingBlocks.put(_currentLevel, floatingBlocks);
}
if (loc.getBlock().getType() == Material.AIR && UtilAlg.HasSight(entity.getLocation(), loc))
{
BlockHailBlock floating = new BlockHailBlock(loc, Material.STONE);
UtilEnt.CreatureLook(entity, _target);
floatingBlocks.add(floating);
Packet[] packets = floating.getSpawnPackets(entity);
for (Player player : UtilPlayer.getNearby(loc, 100))
{
UtilPlayer.sendPacket(player, packets);
}
entity.getWorld().playSound(entity.getLocation(), Sound.DIG_GRASS, 3, 0.9F);
}
if (_floatingBlocks.size() % 2 == 0)
{
Collections.reverse(floatingBlocks);
}
}
}
else
{
_spawned = true;
_ticks = -20;
}
}
else if (_ticks > 0 && _ticks % 2 == 0 && !_floatingBlocks.isEmpty())
{
IronGolem entity = getEntity();
if (_ticks % 16 == 0)
{
_target = getTarget();
if (_target == null)
return;
}
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
UtilEnt.CreatureLook(entity, _target);
BlockHailBlock floatingBlock = null;
for (int i = 1; i <= _currentLevel; i++)
{
if (_floatingBlocks.containsKey(i) && !_floatingBlocks.get(i).isEmpty())
{
floatingBlock = _floatingBlocks.get(i).remove(0);
if (_floatingBlocks.get(i).isEmpty())
{
_floatingBlocks.remove(i);
}
break;
}
}
Packet packet = floatingBlock.getDestroyPacket();
for (Player player : UtilServer.getPlayers())
{
UtilPlayer.sendPacket(player, packet);
}
Location loc = floatingBlock.getLocation();
FallingBlock b = loc.getWorld().spawnFallingBlock(loc, floatingBlock.getMaterial(), (byte) 0);
b.setDropItem(false);
Vector vec = UtilAlg.calculateVelocity(loc.toVector(),
_target.getLocation().toVector().add(new Vector(UtilMath.r(6 + (_currentLevel * 2)) - (2 + _currentLevel), 0,
UtilMath.r(6 + (_currentLevel * 2)) - (2 + _currentLevel))),
6);
b.setVelocity(vec);
_fallingBlocks.add(b);
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F);
_blocks.put(_target.getName(), _blocks.containsKey(_target.getName()) ? _blocks.get(_target.getName()) + 1 : 1);
}
ArrayList<Location> points = new ArrayList<Location>();
for (int i = _currentLevel; i <= _currentLevel; i++)
{
points.addAll(UtilShapes.getDistancedCircle(_center.clone().add(0, 3.3 + (i * 0.75), 0), 0.3, 1 + (i * 1.3)));
}
for (int i = 0; i < points.size(); i++)
{
if (_spawned || i < _ticks)
{
Location loc = points.get(i);
UtilParticle.PlayParticle(
ParticleType.BLOCK_DUST.getParticle(_spawned && i < _ticks ? Material.STONE : Material.DIRT, 0), loc, 0,
0, 0, 0, 0, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
}
}
_ticks++;
}
@Override
public boolean inProgress()
{
return !_spawned || !_floatingBlocks.isEmpty();
}
}

View File

@ -0,0 +1,442 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityVelocity;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R3.Vec3D;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
public class GolemBlockShot extends BossAbility<GolemCreature, IronGolem>
{
private HashMap<Integer, Location> _blockLoc = new HashMap<Integer, Location>();
private HashMap<Integer, Material> _blockType = new HashMap<Integer, Material>();
private ArrayList<FallingBlock> _current = new ArrayList<FallingBlock>();
private HashMap<Integer, Long> _preshoot = new HashMap<Integer, Long>();
private Player _target;
private HashMap<Integer, Player> _targetBlock = new HashMap<Integer, Player>();
private HashMap<UUID, Integer> _shotAt = new HashMap<UUID, Integer>();
private int _thrown;
private int _tick;
private int _toThrow;
public GolemBlockShot(GolemCreature creature)
{
super(creature);
if (creature.getHealthPercent() > 0.75)
{
_toThrow = 3;
}
else if (creature.getHealthPercent() > 0.5)
{
_toThrow = 6;
}
else
{
_toThrow = 9;
}
_target = getTarget();
}
@Override
public boolean canMove()
{
return _current.isEmpty() && _thrown == _toThrow;
}
@Override
public Player getTarget()
{
Player target = null;
double dist = 0;
Location loc1 = getLocation();
Location loc2 = loc1.clone().add(loc1.getDirection().setY(0).normalize());
List<Player> players = UtilPlayer.getNearby(getLocation(), 40, true);
for (Player player : players)
{
if (_shotAt.containsKey(player.getUniqueId()) && _shotAt.get(player.getUniqueId()) >= 3)
{
continue;
}
double dist1 = player.getLocation().distance(loc1);
double dist2 = player.getLocation().distance(loc2);
double dist3 = dist1 - dist2;
if (dist3 < 0.6 || dist1 > 30 || (target != null && dist3 < dist))
{
continue;
}
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
target = player;
dist = dist3;
}
return target;
}
@Override
public boolean hasFinished()
{
return _current.isEmpty() && _preshoot.isEmpty() && (_target == null || _thrown >= _toThrow);
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _current.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
continue;
// Creative or Spec
if (ent instanceof Player)
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
continue;
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Block Shot",
"Iron Wizard Block Shot");
cur.remove();
fallingIterator.remove();
Vector vec = UtilAlg.getTrajectory(getEntity(), victim);
vec.setY(0).normalize();
double strength = 1;
if (!(victim instanceof Player) || !((Player) victim).isBlocking())
{
strength = 1.3;
}
UtilAction.velocity(victim, vec, strength, true, 0, 0.2, 1, true);
}
else if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
cur.remove();
fallingIterator.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
@Override
public void setFinished()
{
for (FallingBlock falling : _current)
{
falling.remove();
}
int[] ids = new int[_preshoot.size()];
int a = 0;
for (int id : _preshoot.keySet())
{
ids[a++] = id;
}
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids);
for (Player player : Bukkit.getOnlinePlayers())
{
UtilPlayer.sendPacket(player, packet);
}
}
@Override
public void tick()
{
if (_target == null || _target.getLocation().distance(getLocation()) > 30 || !_target.hasLineOfSight(getEntity()))
{
_target = getTarget();
}
Entity entity = getEntity();
if (_tick++ % 16 == 0 && _target != null && _thrown < _toThrow)
{
_thrown++;
UtilEnt.CreatureLook(entity, _target);
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 2, 1);
Location loc = entity.getLocation();
loc.setYaw(loc.getYaw() + (UtilMath.r(150) - 75));
loc.add(loc.getDirection().setY(0).normalize());
Block block = loc.getBlock();
if (block.getType() == Material.AIR)
{
block = block.getRelative(BlockFace.DOWN);
}
Material mat = block.getType();
if (!UtilBlock.solid(block))
{
mat = Material.STONE;
}
int id = UtilEnt.getNewEntityId();
_preshoot.put(id, System.currentTimeMillis());
_blockType.put(id, mat);
_blockLoc.put(id, loc.clone().add(0, 0.6, 0));
_targetBlock.put(id, _target);
PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, mat.getId());
packet.a = id;
packet.b = (int) Math.floor(loc.getX() * 32);
packet.c = (int) Math.floor(loc.getY() * 32);
packet.d = (int) Math.floor(loc.getZ() * 32);
packet.g = (int) ((0.45) * 8000);
PacketPlayOutEntityVelocity packet2 = new PacketPlayOutEntityVelocity(id, 0, 0.45D, 0);
for (Player player : UtilPlayer.getNearby(loc, 70))
{
UtilPlayer.sendPacket(player, packet, packet2);
}
_shotAt.put(_target.getUniqueId(),
(_shotAt.containsKey(_target.getUniqueId()) ? _shotAt.get(_target.getUniqueId()) : 0) + 1);
_target = getTarget();
}
else
{
Iterator<Entry<Integer, Long>> itel = _preshoot.entrySet().iterator();
while (itel.hasNext())
{
Entry<Integer, Long> entry = itel.next();
if (UtilTime.elapsed(entry.getValue(), 920))
{
itel.remove();
int id = entry.getKey();
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[]
{
id
});
for (Player player : Bukkit.getOnlinePlayers())
{
UtilPlayer.sendPacket(player, packet);
}
Location loc = _blockLoc.get(id);
FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, _blockType.get(id), (byte) 0);
falling.setDropItem(false);
_current.add(falling);
Player target = _targetBlock.get(id);
UtilEnt.CreatureLook(entity, target);
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 2, 1.2F);
entity.getWorld().playEffect(falling.getLocation(), Effect.STEP_SOUND, falling.getBlockId());
Location l = falling.getLocation();
l.setY(entity.getLocation().getY());
Location loc1 = target.getEyeLocation();
if (loc1.getY() - l.getY() > 1)
{
loc1.setY(l.getY() + 1);
}
int dist = (int) Math.ceil(loc1.toVector().setY(0).distance(l.toVector().setY(0)));
Vector vector = UtilAlg.calculateVelocity(l.toVector(), loc1.toVector(), dist / 13);
falling.setVelocity(vector);// .multiply(0.5 + (l.distance(target.getEyeLocation()) / 10)).multiply(0.7));
}
}
}
if (_thrown >= 3 && !UtilPlayer.getNearby(
getLocation(), 10, true).isEmpty())
{
_thrown = 99;
}
}
@Override
public boolean inProgress()
{
return _thrown < _toThrow || !_current.isEmpty();
}
}

View File

@ -0,0 +1,337 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilShapes;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Vec3D;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
public class GolemCaveIn extends BossAbility<GolemCreature, IronGolem>
{
private ArrayList<Block> _blocks = new ArrayList<Block>();
private ArrayList<FallingBlock> _fallingBlocks = new ArrayList<FallingBlock>();
private int _tick;
public GolemCaveIn(GolemCreature creature)
{
super(creature);
}
@Override
public boolean canMove()
{
return false;
}
@Override
public Player getTarget()
{
if (getTarget(4) == null)
{
return getTarget(40);
}
return null;
}
@Override
public boolean hasFinished()
{
return _tick > 60 && _fallingBlocks.isEmpty();
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
continue;
// Creative or Spec
if (ent instanceof Player)
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
continue;
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
if (canDamage(victim))
{
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Cave In",
"Iron Wizard Cave In");
}
cur.remove();
fallingIterator.remove();
}
else if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
cur.remove();
fallingIterator.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
@Override
public void setFinished()
{
for (FallingBlock block : _fallingBlocks)
{
block.remove();
}
for (Block block : _blocks)
{
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
block.setType(Material.AIR);
}
}
@Override
public void tick()
{
if (_tick++ == 0)
{
Location l = getLocation();
ArrayList<Location> blocks = UtilShapes.getSphereBlocks(l, 3, 3, true);
for (Location loc : blocks)
{
if (loc.getBlockY() >= l.getBlockY())
{
Block b = loc.getBlock();
if (b.getType() == Material.AIR)
{
_blocks.add(b);
loc.setY(l.getY() - 1);
b.setType(loc.getBlock().getType());
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, loc.getBlock().getTypeId());
}
}
}
}
if (_tick % 5 == 0)
{
for (Player player : UtilPlayer.getNearby(getLocation(), 2.5, true))
{
player.teleport(player.getLocation().add(0, 4, 0));
UtilAction.velocity(player, new Vector(UtilMath.r(10) - 5, 3, UtilMath.r(10) - 5).normalize());
}
}
if (_tick < 200)
{
Location loc = getLocation();
loc.setY(loc.getY() + 4);
for (int i = 0; i < 30; i++)
{
loc.setY(loc.getY() + 1);
Block b = loc.getBlock();
if (UtilBlock.solid(b))
{
break;
}
}
if (!UtilBlock.solid(loc.getBlock()))
{
return;
}
List<Player> players = UtilPlayer.getNearby(getLocation(), 50, true);
for (int i = 0; i < players.size() * 2; i++)
{
int dist = UtilMath.r(10);
if (dist < 3)
{
dist = 2;
}
else if (dist < 5)
{
dist = 5;
}
else
{
dist = 10;
}
Location l = players.get(UtilMath.r(players.size())).getLocation().add(UtilMath.r(dist * 2) - dist, 0,
UtilMath.r(dist * 2) - dist);
l.setY(loc.getY());
Block b = l.getBlock();
l.subtract(0, 1, 0);
if (UtilBlock.solid(b))
{
if (l.getBlock().getType() == Material.AIR)
{
if (UtilAlg.HasSight(l, getLocation().add(0, 4, 0)))
{
FallingBlock block = b.getWorld().spawnFallingBlock(b.getLocation().add(0.5, -1, 0.5), b.getTypeId(),
b.getData());
block.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, block.getBlockId());
block.setDropItem(false);
_fallingBlocks.add(block);
}
}
}
}
}
}
@Override
public boolean inProgress()
{
return true;
}
}

View File

@ -0,0 +1,89 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.recharge.Recharge;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import org.bukkit.Effect;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
public class GolemDeadlyTremor extends BossAbility<GolemCreature, IronGolem>
{
private static final long ATTACK_DURATION = 10000;
private long _start;
public GolemDeadlyTremor(GolemCreature creature)
{
super(creature);
_start = System.currentTimeMillis();
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, ATTACK_DURATION);
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - ATTACK_DURATION;
}
@Override
public void tick()
{
for (Player player : UtilPlayer.getInRadius(getLocation(), 30).keySet())
{
player.playSound(player.getLocation(), Sound.MINECART_BASE, 0.2f, 0.2f);
if (UtilEnt.isGrounded(player))
{
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getBoss().getEntity(), null, DamageCause.CUSTOM, (1 + 2 * Math.random()) * getBoss().getDifficulty(), false, false, false, getBoss().getEntity().getName(), "Deadly Tremor");
if (Recharge.Instance.use(player, "Deadly Tremor Hit", 400, false, false))
{
UtilAction.velocity(player, new Vector(Math.random() - 0.5, Math.random() * 0.2, Math.random() - 0.5),
Math.random() * 1 + 1, false, 0, 0.1 + Math.random() * 0.2, 2, true);
}
}
for (Block block : UtilBlock.getInRadius(player.getLocation(), 5).keySet())
{
if (Math.random() < 0.98)
continue;
if (!UtilBlock.solid(block))
continue;
if (!UtilBlock.airFoliage(block.getRelative(BlockFace.UP)))
continue;
player.playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
}
}
}
}

View File

@ -0,0 +1,167 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.UUID;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilServer;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Entity;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
public class GolemEarthquake extends BossAbility<GolemCreature, IronGolem>
{
private Location _center;
private float _range;
private int _tick;
private ArrayList<UUID> _damaged = new ArrayList<UUID>();
private boolean _earthquake;
public GolemEarthquake(GolemCreature creature)
{
super(creature);
_center = getLocation();
}
@Override
public boolean canMove()
{
return !UtilEnt.isGrounded(getEntity()) && _tick > 1;
}
@Override
public Player getTarget()
{
return getTarget(7);
}
@Override
public boolean hasFinished()
{
return _range > 19;
}
@Override
public void setFinished()
{
}
@Override
public void tick()
{
Entity entity = getEntity();
if (_tick == 0)
{
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 4, 0);
entity.setVelocity(new Vector(0, 1, 0));
}
else if (!_earthquake)
{
_earthquake = _tick > 10 && UtilEnt.isGrounded(entity);
}
if (_earthquake)
{
_range += 0.7;
for (float range = _range - 2; range <= _range; range++)
{
if (range <= 0)
{
continue;
}
for (int x = -1; x <= 1; x++)
{
for (int z = -1; z <= 1; z++)
{
if ((x != 0) == (z != 0))
{
continue;
}
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
_center.clone().add(x * range, 0.1, z * range), (x != 0) ? 0 : (range / 2), 0.1F,
(z != 0) ? 0 : (range / 2), 0, (int) (range * 4), UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
_center.getWorld().playSound(_center, Sound.DIG_STONE, 2, 0.8F);
HashSet<Player> toDamage = new HashSet<Player>();
Location cornerA = _center.clone().add(-_range, -1, -_range);
Location cornerB = _center.clone().add(_range, 1, _range);
Location cornerA1 = _center.clone().add(-(_range - 1.5), -1, -(_range - 1.5));
Location cornerB1 = _center.clone().add(_range - 1.5, 1, _range - 1.5);
for (Player player : Bukkit.getOnlinePlayers())
{
Location pLoc = player.getLocation();
if (_damaged.contains(player.getUniqueId()))
{
continue;
}
if (!UtilAlg.inBoundingBox(pLoc, cornerA, cornerB))
{
continue;
}
if (UtilAlg.inBoundingBox(pLoc, cornerA1, cornerB1))
{
continue;
}
toDamage.add(player);
}
for (Player player : toDamage)
{
_damaged.add(player.getUniqueId());
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) player, getEntity(), null,
DamageCause.CONTACT, 14 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Earthquake",
"Iron Wizard Earthquake");
getBoss().getEvent().getCondition().Factory().Slow("Earthquake", (LivingEntity) player, getEntity(), 3, 1, false,
false, false, false);
// Velocity
UtilAction.velocity(player, UtilAlg.getTrajectory2d(getLocation().toVector(), player.getLocation().toVector()),
1.8, true, 0, 0.5, 0.5, true);
// Condition
getBoss().getEvent().getCondition().Factory().Falling("Earthquake", player, getEntity(), 10, false, true);
}
}
_tick++;
}
@Override
public boolean inProgress()
{
return !_earthquake;
}
}

View File

@ -0,0 +1,406 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.DataWatcher;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
import net.minecraft.server.v1_8_R3.Vec3D;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class GolemExplodingAura extends BossAbility<GolemCreature, IronGolem>
{
private HashMap<Integer, Integer> _blocks = new HashMap<Integer, Integer>();
private HashMap<Integer, Location> _blocksLoc = new HashMap<Integer, Location>();
private ArrayList<FallingBlock> _fallingBlocks = new ArrayList<FallingBlock>();
// private HashMap<Integer, Long> _blocksExplode = new HashMap<Integer, Long>();
private HashMap<Integer, Material> _blockMaterial = new HashMap<Integer, Material>();
private int _tick;
public GolemExplodingAura(GolemCreature creature)
{
super(creature);
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean hasFinished()
{
return _tick > 20 * 30 && _blocks.isEmpty() && _fallingBlocks.isEmpty();
}
@Override
public void setFinished()
{
for (FallingBlock block : _fallingBlocks)
{
block.remove();
}
int[] ids = new int[_blocks.size() * 2];
int i = 0;
for (Entry<Integer, Integer> id : _blocks.entrySet())
{
ids[i] = id.getKey();
ids[i + 1] = id.getValue();
i += 2;
}
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids);
for (Player player : UtilServer.getPlayers())
{
UtilPlayer.sendPacket(player, packet);
}
}
@Override
public void tick()
{
if (_tick < 25 * 25 && getBoss().getHealth() > 30)
{
double angle = (2 * Math.PI) / UtilMath.random.nextDouble();
double x = 1.7 * Math.cos(angle);
double z = 1.7 * Math.sin(angle);
Location loc = getLocation().add(x, 1 + (UtilMath.random.nextDouble() * 1.6), z);
loc.getWorld().playEffect(loc, Effect.STEP_SOUND, Material.DIRT.getId());
for (Player player : UtilPlayer.getNearby(getLocation(), 3, true))
{
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, DamageCause.CONTACT,
6 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Protection", "Iron Wizard Protection");
UtilAction.velocity(player, UtilAlg.getTrajectory(getEntity(), player), 1, true, 0.3, 0, 0.3, false);
}
}
if (_tick < 20 * 30)
{
int key = UtilEnt.getNewEntityId();
int value = UtilEnt.getNewEntityId();
Location loc = null;
for (int i = 0; i < 30; i++)
{
double angle = (2 * Math.PI) / UtilMath.random.nextDouble();
double x = 1.7 * Math.cos(angle);
double z = 1.7 * Math.sin(angle);
loc = getLocation().add(x, 1 + (UtilMath.random.nextDouble() * 1.6), z);
boolean found = false;
for (Location l : _blocksLoc.values())
{
if (l.distance(loc) < 0.3)
{
found = true;
break;
}
}
if (found)
{
loc = null;
}
else
{
break;
}
}
if (loc != null)
{
_blocks.put(key, value);
_blocksLoc.put(key, loc);
// _blocksExplode.put(key, System.currentTimeMillis() + UtilMath.r(800) + 100);
_blockMaterial.put(key, UtilMath.random.nextBoolean() ? Material.DIRT : Material.STONE);
Packet[] packets = new Packet[3];
PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving();
DataWatcher watcher = new DataWatcher(null);
watcher.a(0, (byte) 32, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0);
watcher.a(1, 0, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0);
packet1.a = key;
packet1.b = EntityType.SILVERFISH.getTypeId();
packet1.c = (int) Math.floor(loc.getX() * 32);
packet1.d = (int) Math.floor((loc.getY() - 0.125) * 32);
packet1.e = (int) Math.floor(loc.getZ() * 32);
packet1.l = watcher;
packets[0] = packet1;
PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) getEntity()).getHandle(), 70,
_blockMaterial.get(key).getId());
packet2.a = value;
packet2.b = (int) Math.floor(loc.getX() * 32);
packet2.c = (int) Math.floor(loc.getY() * 32);
packet2.d = (int) Math.floor(loc.getZ() * 32);
packets[1] = packet2;
PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity();
packet3.b = value;
packet3.c = key;
packets[2] = packet3;
for (Player player : UtilPlayer.getNearby(getLocation(), 70))
{
UtilPlayer.sendPacket(player, packets);
}
}
}
/*Iterator<Integer> itel = _blocksExplode.keySet().iterator();
while (itel.hasNext())
{
int key = itel.next();
if (_blocksExplode.get(key) < System.currentTimeMillis())
{
itel.remove();*/
if (_tick % 25 == 0)
{
for (int i = 0; i < 3; i++)
getLocation().getWorld().playSound(getLocation(), Sound.DIG_GRASS, 3, 2);
for (int key : new ArrayList<Integer>(_blocksLoc.keySet()))
{
PacketPlayOutEntityDestroy destroyPacket = new PacketPlayOutEntityDestroy(new int[]
{
key, _blocks.remove(key)
});
for (Player player : UtilServer.getPlayers())
{
UtilPlayer.sendPacket(player, destroyPacket);
}
Location loc = _blocksLoc.remove(key);
FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, _blockMaterial.remove(key), (byte) 0);
_fallingBlocks.add(falling);
Vector vec = UtilAlg.getTrajectory(getLocation().add(0, 1, 0), loc);
vec.setY(Math.max(0.05, vec.getY()));
falling.setVelocity(vec);
loc.getWorld().playEffect(loc, Effect.STEP_SOUND, Material.DIRT.getId());
}
}
_tick++;
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
continue;
// Creative or Spec
if (ent instanceof Player)
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
continue;
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
// if (canDamage(victim))
{
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
DamageCause.CONTACT, 6 * getBoss().getDifficulty(), true, true, false, "Blocky Iron Wizard Aura",
"Blocky Iron Wizard Aura");
}
fallingIterator.remove();
cur.remove();
Vector vec = UtilAlg.getTrajectory(getEntity(), victim);
vec.setY(0).normalize();
double strength = 1;
if (!(victim instanceof Player) || !((Player) victim).isBlocking())
{
strength = 1.3;
}
UtilAction.velocity(victim, vec, strength, true, 0, 0.2, 1, true);
}
else if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
fallingIterator.remove();
cur.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
@Override
public boolean inProgress()
{
return false;
}
}

View File

@ -0,0 +1,590 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.DataWatcher;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
import net.minecraft.server.v1_8_R3.Vec3D;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.util.Vector;
public class GolemExplosiveBlock extends BossAbility<GolemCreature, IronGolem>
{
private HashMap<Integer, Vector> _blocksLocation = new HashMap<Integer, Vector>();
private Location _center;
private int _explosionsLeft;
private FallingBlock _fallingBlock;
private HashMap<Integer, Integer> _fallingBlocks = new HashMap<Integer, Integer>();
private ArrayList<Item> _items = new ArrayList<Item>();
private int _strength;
private Player _target;
private int _tick;
public GolemExplosiveBlock(GolemCreature creature, int strength)
{
super(creature);
_strength = strength;
_center = getLocation().add(0, 3, 0);
_target = getTarget();
if (_target != null)
{
UtilEnt.CreatureLook(getEntity(), _target);
}
}
@Override
public boolean canMove()
{
return _fallingBlock != null;
}
private int clamp(int value)
{
if (value < -127)
return -127;
if (value > 127)
return 127;
return value;
}
@Override
public Player getTarget()
{
HashMap<Player, Double> locs = new HashMap<Player, Double>();
for (Player player : UtilServer.getPlayers())
{
double dist = player.getLocation().distance(_center);
if (dist < 30)
{
double score = (dist > 10 ? 30 - dist : 10);
for (Player p : UtilServer.getPlayers())
{
if (player.getLocation().distance(p.getLocation()) < 4)
{
score += 7;
}
}
if (player.hasLineOfSight(getEntity()))
{
score += 10;
}
locs.put(player, score);
}
}
Player lowest = null;
for (Entry<Player, Double> entry : locs.entrySet())
{
if (lowest == null || locs.get(lowest) > locs.get(entry.getKey()))
{
lowest = entry.getKey();
}
}
return lowest;
}
@Override
public boolean hasFinished()
{
return _target == null || (_fallingBlock != null && !_fallingBlock.isValid() && _explosionsLeft == 0);
}
@EventHandler
public void onDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().equals(getEntity()))
{
if (_tick >= 40 + (40 * _strength) && _tick <= 50 + (40 * _strength))
{
event.SetCancelled("Iron Wizard charging bomb");
}
event.SetKnockback(false);
}
}
public void onExplode(final Location loc)
{
for (int i = 0; i < _strength * 2; i++)
{
if (i == 0)
{
onSubExplode(loc);
}
else
{
_explosionsLeft++;
Bukkit.getScheduler().scheduleSyncDelayedTask(getBoss().getEvent().getPlugin(), new Runnable()
{
public void run()
{
onSubExplode(loc);
_explosionsLeft--;
}
}, 2 * i);
}
}
}
public void onSubExplode(Location loc)
{
for (int i = 0; i < 2; i++)
{
Location l = loc.clone().add(UtilMath.r(_strength * 4) - (_strength * 2), UtilMath.r(_strength * 2),
UtilMath.r(_strength * 4) - (_strength * 2));
/* CustomExplosion explosion = new CustomExplosion(getGolem().getEvent().getDamageManager(), getGolem().getEvent()
.getEventManager().getClans().getExplosion(), l, _strength * 0.8F, "Golem Explosive Block");
explosion.setPlayer(getEntity(), false);
explosion.setDamageBlocks(false);
explosion.explode();*/
UtilParticle.PlayParticle(ParticleType.LARGE_EXPLODE, l, _strength * 3, 1, _strength * 3, 0, _strength * 4,
ViewDist.LONG, UtilServer.getPlayers());
}
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
if (_fallingBlock == null)
{
return;
}
if (_fallingBlock.isDead()
|| !_fallingBlock.isValid()
|| _fallingBlock.getTicksLived() > 400
|| !_fallingBlock.getWorld().isChunkLoaded(_fallingBlock.getLocation().getBlockX() >> 4,
_fallingBlock.getLocation().getBlockZ() >> 4))
{
Block block = _fallingBlock.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
_fallingBlock.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, _fallingBlock.getBlockId());
// Expire
if (_fallingBlock.getTicksLived() > 400
|| !_fallingBlock.getWorld().isChunkLoaded(_fallingBlock.getLocation().getBlockX() >> 4,
_fallingBlock.getLocation().getBlockZ() >> 4))
{
_fallingBlock.remove();
return;
}
_fallingBlock.remove();
return;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) _fallingBlock).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) _fallingBlock.getWorld()).getHandle().getEntities(
((CraftEntity) _fallingBlock).getHandle(),
((CraftEntity) _fallingBlock).getHandle().getBoundingBox().a(((CraftEntity) _fallingBlock).getHandle().motX,
((CraftEntity) _fallingBlock).getHandle().motY, ((CraftEntity) _fallingBlock).getHandle().motZ).grow(2,
2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
continue;
// Creative or Spec
if (ent instanceof Player)
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
continue;
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
onExplode(victim.getEyeLocation());
_fallingBlock.remove();
}
else if (finalObjectPosition != null)
{
Block block = _fallingBlock.getWorld()
.getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ
* nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
onExplode(block.getLocation().add(0.5, 0.5, 0.5));
_fallingBlock.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
_fallingBlock.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
@Override
public void setFinished()
{
int[] ids = new int[_fallingBlocks.size() * 2];
int index = 0;
for (Entry<Integer, Integer> entry : _fallingBlocks.entrySet())
{
ids[index] = entry.getKey();
ids[index + 1] = entry.getValue();
index += 2;
}
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids);
for (Player player : Bukkit.getOnlinePlayers())
{
UtilPlayer.sendPacket(player, packet);
}
for (Item item : _items)
{
item.remove();
}
if (_fallingBlock != null)
{
_fallingBlock.remove();
}
}
@Override
public void tick()
{
IronGolem entity = getEntity();
Iterator<Item> itel = _items.iterator();
while (itel.hasNext())
{
Item item = itel.next();
Vector vec = item.getVelocity();
Location loc = item.getLocation();
if (item.getTicksLived() > 100 || vec.getY() <= 0 || loc.distance(_center) > loc.add(vec).distance(_center)
|| UtilEnt.isGrounded(item))
{
itel.remove();
}
}
// This spawns a floating block
if (_tick >= 20 && _tick % 60 == 0 && _fallingBlocks.size() < _strength)
{
int id = UtilEnt.getNewEntityId();
int id2 = UtilEnt.getNewEntityId();
_fallingBlocks.put(id, id2);
_blocksLocation.put(id, _center.toVector());
Packet[] packets = new Packet[3];
PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving();
DataWatcher watcher = new DataWatcher(null);
watcher.a(0, (byte) 32, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0);
watcher.a(1, 0, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0);
packet1.a = id;
packet1.b = EntityType.SILVERFISH.getTypeId();
packet1.c = (int) Math.floor(_center.getX() * 32);
packet1.d = (int) Math.floor((_center.getY() - 0.125) * 32);
packet1.e = (int) Math.floor(_center.getZ() * 32);
packet1.l = watcher;
packets[0] = packet1;
PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70,
Material.DIRT.getId());
packet2.a = id2;
packet2.b = (int) Math.floor(_center.getX() * 32);
packet2.c = (int) Math.floor(_center.getY() * 32);
packet2.d = (int) Math.floor(_center.getZ() * 32);
packets[1] = packet2;
PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity();
packet3.b = id2;
packet3.c = id;
packets[2] = packet3;
for (Player player : UtilServer.getPlayers())
{
if (player.getLocation().distance(_center) < 80)
{
UtilPlayer.sendPacket(player, packets);
}
}
}
// This spawns a item that flies above the golem's head and disappears
if (UtilMath.r(6) == 0 && _tick < 40 + (_strength * 40))
{
double angle = ((2 * Math.PI) / 30) * UtilMath.r(30);
double x = 5 * Math.cos(angle);
double z = 5 * Math.sin(angle);
Location loc = _center.clone().add(x, -3, z);
Material mat = null;
switch (UtilMath.r(3))
{
case 0:
mat = Material.DIRT;
break;
case 1:
mat = Material.STONE;
break;
case 2:
mat = Material.COBBLESTONE;
break;
default:
break;
}
Item item = loc.getWorld().dropItem(loc, new ItemBuilder(mat).setTitle(System.currentTimeMillis() + "").build());
item.setPickupDelay(999999);
Vector vec = UtilAlg.getTrajectory(_center, item.getLocation());
vec.normalize().multiply(5);
item.setVelocity(vec);
// TODO Fix velocity
_items.add(item);
}
// 10 being when items no longer fly in, 0 being when its shot.
int ticksTillFired = (60 + (40 * _strength)) - _tick;
if (ticksTillFired > 20)
{
int strength = (int) Math.floor(_tick / 20D);
int nine = 8 - strength;
if (_tick % nine == 0)
{
_center.getWorld().playSound(_center, Sound.DIG_GRASS, strength + 1, 1F);
}
}
else if (ticksTillFired < 0)
{
if (_tick % 3 == 0)
{
_center.getWorld().playSound(_fallingBlock.getLocation(), Sound.WOOD_CLICK, _strength + 1, 0.4F);
}
}
// The location the falling blocks need to stick by
Vector blockCenter = _center.toVector();
if (ticksTillFired >= 0 && ticksTillFired <= 20)
{
Vector vec = entity.getLocation().add(entity.getLocation().getDirection().setY(0).normalize().multiply(1.2))
.add(0, 1, 0).toVector();
blockCenter = UtilAlg.getTrajectory(_center.toVector(), blockCenter);
vec.multiply(ticksTillFired / 10D);
_center.getWorld().playSound(_center, Sound.DIG_SNOW, _strength + 1, 0);
}
else if (_fallingBlock != null)
{
blockCenter = _fallingBlock.getLocation().add(0, 0.5, 0).toVector();
}
// Move the fake floating blocks
for (Entry<Integer, Integer> entry : _fallingBlocks.entrySet())
{
int id = entry.getKey();
Vector vec = _blocksLocation.get(id);
int x = clamp((int) ((blockCenter.getX() - vec.getX()) * 32) + (UtilMath.r(8) - 4));
int y = clamp((int) ((blockCenter.getY() - vec.getY()) * 32) + (UtilMath.r(8) - 4));
int z = clamp((int) ((blockCenter.getZ() - vec.getZ()) * 32) + (UtilMath.r(8) - 4));
vec.add(new Vector(x, y, z));
PacketPlayOutEntity.PacketPlayOutRelEntityMove packet = new PacketPlayOutEntity.PacketPlayOutRelEntityMove();
packet.a = id;
packet.b = (byte) x;
packet.c = (byte) y;
packet.d = (byte) z;
for (Player player : UtilServer.getPlayers())
{
if (player.getLocation().distance(_center) < 70)
{
UtilPlayer.sendPacket(player, packet);
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
vec.toLocation(_center.getWorld()), 0.7F, 0.7F, 0.7F, 0, 11, ViewDist.NORMAL, player);
}
}
}
if (ticksTillFired == 0)
{
int id = _fallingBlocks.keySet().iterator().next();
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[]
{
id, _fallingBlocks.get(id)
});
for (Player player : Bukkit.getOnlinePlayers())
{
UtilPlayer.sendPacket(player, packet);
}
_fallingBlocks.remove(id);
_fallingBlock = _center.getWorld().spawnFallingBlock(_blocksLocation.get(id).toLocation(_center.getWorld()),
Material.STONE, (byte) 0);
Vector vec1 = _fallingBlock.getLocation().toVector();
Vector vec2 = _target.getLocation().toVector();
Vector vec = UtilAlg.calculateVelocity(vec1, vec2, (int) (vec1.distanceSquared(vec2) / 4));
_fallingBlock.setVelocity(vec);
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
}
_tick++;
}
@Override
public boolean inProgress()
{
// TODO Auto-generated method stub
return false;
}
}

View File

@ -0,0 +1,170 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.updater.UpdateType;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Sound;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import com.google.common.collect.Lists;
//2-3 people
//5 impact damage
//High pull velocity
//40 block range
public class GolemIronHook extends BossAbility<GolemCreature, IronGolem>
{
private static final Integer MAX_TARGETS = 3;
private boolean _shot, _complete;
private List<Item> _hooks = Lists.newArrayList();
public GolemIronHook(GolemCreature creature)
{
super(creature);
_shot = false;
_complete = false;
}
private int getPosition(Player toAdd, LinkedList<Player> ordered, HashMap<Player, Double> distances)
{
int position = ordered.size();
int index = 0;
for (Player player : ordered)
{
if (distances.get(player) < distances.get(toAdd))
{
position = index;
}
index++;
}
return position;
}
private void shoot()
{
IronGolem wizard = getBoss().getEntity();
LinkedList<Player> selections = new LinkedList<>();
List<Player> targeted = Lists.newArrayList();
HashMap<Player, Double> near = UtilPlayer.getInRadius(wizard.getLocation(), 40D);
for (Player nearby : near.keySet())
{
if (nearby.getGameMode() == GameMode.CREATIVE || nearby.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
if (selections.isEmpty())
{
selections.addFirst(nearby);
}
else
{
selections.add(getPosition(nearby, selections, near), nearby);
}
}
for (int i = 0; i < MAX_TARGETS; i++)
{
if (i < selections.size())
{
targeted.add(selections.get(i));
}
}
if (targeted.isEmpty())
{
_complete = true;
setFinished();
return;
}
for (Player target : targeted)
{
Item item = wizard.getWorld().dropItem(wizard.getEyeLocation().add(UtilAlg.getTrajectory(wizard, target)), ItemStackFactory.Instance.CreateStack(131));
UtilAction.velocity(item, UtilAlg.getTrajectory(wizard, target).normalize(),
2, false, 0, 0.2, 20, false);
getBoss().getEvent().getProjectileManager().AddThrow(item, getBoss().getEntity(), new IronHook(getBoss().getEvent()), -1, true, true, true, true,
Sound.FIRE_IGNITE, 1.4f, 0.8f, ParticleType.CRIT, UpdateType.TICK, 1f);
item.getWorld().playSound(item.getLocation(), Sound.IRONGOLEM_THROW, 2f, 0.8f);
_hooks.add(item);
}
}
@Override
public int getCooldown()
{
return 10;
}
@Override
public boolean canMove()
{
return true;
}
@Override
public boolean inProgress()
{
return false;
}
@Override
public boolean hasFinished()
{
return _complete;
}
@Override
public void setFinished()
{
for (Item hook : _hooks)
{
if (!hook.isDead() && hook.isValid())
{
getBoss().getEvent().getProjectileManager().deleteThrown(hook);
hook.remove();
}
}
_hooks.clear();
}
@Override
public void tick()
{
if (_shot)
{
return;
}
shoot();
_shot = true;
Bukkit.getScheduler().runTaskLater(getBoss().getEvent().getPlugin(), new Runnable()
{
public void run()
{
_complete = true;
setFinished();
}
}, 2 * 20);
}
}

View File

@ -0,0 +1,93 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
public class GolemMeleeAttack extends BossAbility<GolemCreature, IronGolem>
{
private boolean _attacked;
public GolemMeleeAttack(GolemCreature creature)
{
super(creature);
}
@Override
public boolean canMove()
{
return true;
}
@Override
public int getCooldown()
{
return 20;
}
@Override
public Player getTarget()
{
return getTarget(4);
}
@Override
public boolean hasFinished()
{
return _attacked;
}
@Override
public void setFinished()
{
}
@Override
public void tick()
{
_attacked = true;
for (Player target : UtilPlayer.getNearby(getLocation(), 4, true))
{
if (target.getVelocity().length() > 0.5)
{
continue;
}
UtilEnt.CreatureLook(getEntity(), target);
getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.ENTITY_ATTACK,
10 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Melee Attack", "Iron Wizard Melee Attack");
Vector vec = getLocation().getDirection();
vec.setY(0).normalize().setY(0.5).multiply(2.4);
UtilAction.velocity(target, vec);
getBoss().getEvent().getCondition().Factory().Falling("Iron Wizard Throw", target, getEntity(), 3, false, false);
target.getWorld().playSound(target.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F);
EntityIronGolem golem = ((CraftIronGolem) getEntity()).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
}
}
@Override
public boolean inProgress()
{
return _attacked;
}
}

View File

@ -0,0 +1,242 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.ArrayList;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.Damageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
/**
* Rumble is where the golem picks a target then starts playing a animation for a second where its obviously preparing to use it.
* Copy this from Wizards
*/
public class GolemRumble extends BossAbility<GolemCreature, IronGolem>
{
private Location _loc;
private int _ticks;
private int _travelled;
private Vector _vec;
private int _width = 1;
private Location _target;
public GolemRumble(GolemCreature creature)
{
super(creature);
Player target = getTarget();
if (target != null)
{
_target = target.getLocation();
UtilEnt.CreatureLook(getEntity(), _target);
}
}
@Override
public boolean canMove()
{
return _ticks >= 20;
}
@Override
public boolean hasFinished()
{
return _travelled > 35;
}
@Override
public void setFinished()
{
}
@Override
public void tick()
{
if (_ticks++ < 14)
{
IronGolem entity = getEntity();
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
if (_ticks % 2 == 0)
{
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 2F);
}
}
else if (_ticks % 2 == 0)
{
int oldWidth = _width;
if ((_width <= 3 || _ticks % 4 == 0) && _width <= 6)
{
_width++;
}
Location newLoc;
boolean validBlock = false;
ArrayList<Block> current = new ArrayList<Block>();
if (_vec == null)
{
_vec = _target.subtract(getLocation()).toVector().setY(0).normalize();// .multiply(0.5);
_loc = getLocation().subtract(0, 1, 0).getBlock().getLocation().add(0, 0.99, 0);
newLoc = _loc;
current.add(_loc.getBlock());
validBlock = true;
}
else
{ // Move rumble
newLoc = _loc.clone().add(_vec);
// Check if the rumble needs to go up or drop a block or two
for (int y : new int[]
{
0, 1, -1
})
{
for (int a = 1; a <= 2; a++)
{
Block b = newLoc.clone().add(_vec.clone().multiply(a)).getBlock().getRelative(0, y, 0);
if (UtilBlock.solid(b) && !UtilBlock.solid(b.getRelative(0, 1, 0)))
{
validBlock = true;
newLoc.add(0, y, 0);
break;
}
}
if (validBlock)
{
break;
}
}
for (int width = -_width; width <= _width; width++)
{
if (Math.abs(width) <= oldWidth)
{
Block b = _loc.clone().add(UtilAlg.getRight(_vec).multiply(width)).getBlock();
if (!current.contains(b))
{
current.add(b);
}
}
if (validBlock)
{
Block b = newLoc.clone().add(UtilAlg.getRight(_vec).multiply(width)).getBlock();
if (!current.contains(b))
{
current.add(b);
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getTypeId());
}
}
}
}
UtilEnt.CreatureLook(getEntity(), _loc);
for (Entity entity : getEntity().getWorld().getEntities())
{
if (entity instanceof Damageable && !UtilPlayer.isSpectator(entity) && entity != getEntity())
{
Block b = entity.getLocation().getBlock();
boolean canDamage = false;
for (int y = -1; y <= 0; y++)
{
if (current.contains(b.getRelative(0, y, 0)))
{
canDamage = true;
break;
}
}
if (!canDamage)
{
continue;
}
if (canDamage(entity))
{
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) entity, getEntity(), null,
DamageCause.CONTACT, 8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Rumble",
"Iron Wizard Rumble");
}
UtilAction.velocity(entity, _vec.clone(), 1.5, true, 0, 0.2, 1, true);
if (entity instanceof Player)
{
getBoss().getEvent().getCondition().Factory().Slow("Rumble", (LivingEntity) entity, getEntity(), 3, 1,
false, false, false, false);
}
}
}
if (_travelled++ > 35 || !validBlock)
{
_travelled = 100;
}
_loc = newLoc;
}
}
public Player getTarget()
{
Player target = null;
double dist = 0;
for (Player player : UtilPlayer.getNearby(getLocation(), 30, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
double d = player.getLocation().distance(getLocation());
if (d > 2 && (target == null || dist > d))
{
target = player;
dist = d;
}
}
return target;
}
@Override
public boolean inProgress()
{
return _ticks < 14;
}
}

View File

@ -0,0 +1,358 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.common.util.UtilTime;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.EntityIronGolem;
public class GolemRupture extends BossAbility<GolemCreature, IronGolem>
{
private ArrayList<Entry<Location, Location>> _ruptures = new ArrayList<Entry<Location, Location>>();
private HashMap<Location, Long> _ruptureTime = new HashMap<Location, Long>();
private ArrayList<String> _targetted = new ArrayList<String>();
private int _rupturesLeft;
private int _tick;
private ArrayList<Item> _items = new ArrayList<Item>();
private int _ticksFinished;
public GolemRupture(GolemCreature creature)
{
super(creature);
if (creature.getHealthPercent() > 0.75)
{
_rupturesLeft = 2;
}
else if (creature.getHealthPercent() > 0.5)
{
_rupturesLeft = 5;
}
else
{
_rupturesLeft = 10;
}
}
@Override
public boolean canMove()
{
return false;
}
@EventHandler
public void HopperPickup(InventoryPickupItemEvent event)
{
if (_items.contains(event.getItem()))
event.setCancelled(true);
}
@EventHandler
public void ItemDestroy(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
if (_items.isEmpty())
return;
Iterator<Item> itemIterator = _items.iterator();
while (itemIterator.hasNext())
{
Item item = itemIterator.next();
if (item.isDead() || !item.isValid())
{
item.remove();
itemIterator.remove();
}
else if (UtilEnt.isGrounded(item) || item.getTicksLived() > 60)
{
item.getWorld().playEffect(item.getLocation(), Effect.STEP_SOUND, item.getItemStack().getTypeId());
item.remove();
itemIterator.remove();
}
}
}
@Override
public boolean inProgress()
{
return false;
}
@Override
public boolean hasFinished()
{
return _rupturesLeft <= 0 && _ruptures.isEmpty() && --_ticksFinished <= 0;
}
@Override
public void setFinished()
{
for (Item item : _items)
{
item.remove();
}
}
@Override
public void tick()
{
Iterator<Entry<Location, Location>> itel = _ruptures.iterator();
while (itel.hasNext())
{
Entry<Location, Location> entry = itel.next();
if (entry.getKey().distance(entry.getValue()) > 0)
{
Vector vec = entry.getValue().toVector().subtract(entry.getKey().toVector());
if (vec.length() > 1)
{
vec = vec.normalize();
}
entry.getKey().add(vec);
}
if (entry.getKey().distance(entry.getValue()) < 0.1)
{
if (!_ruptureTime.containsKey(entry.getKey()))
{
_ruptureTime.put(entry.getKey(), System.currentTimeMillis());
}
else if (UtilTime.elapsed(_ruptureTime.get(entry.getKey()), 150))
{
itel.remove();
explodeRupture(entry.getKey());
}
}
}
if (_tick % 10 == 0 && _rupturesLeft > 0)
{
_rupturesLeft--;
Location loc = getLocation().add(UtilMath.random.nextFloat() - 0.5, 0, UtilMath.random.nextFloat() - 0.5);
loc.setY(loc.getBlockY());
for (int y = 0; y > -3; y--)
{
if (!UtilBlock.airFoliage(loc.getBlock().getRelative(0, y, 0)))
{
loc.setY(loc.getY() + y);
break;
}
}
Player player = getTarget();
if (player != null)
{
_targetted.add(player.getName());
Location target = player.getLocation();
target.setY(loc.getY());
_ruptures.add(new HashMap.SimpleEntry(loc, target));
UtilEnt.CreatureLook(getEntity(), player.getLocation());
EntityIronGolem golem = ((CraftIronGolem) getEntity()).getHandle();
golem.world.broadcastEntityEffect(golem, (byte) 4);
}
else
{
_rupturesLeft = 0;
}
}
for (Entry<Location, Location> entry : _ruptures)
{
entry.getKey().getWorld().playSound(entry.getKey(), Sound.DIG_GRAVEL, 2.5F, 0.9F);
// if (_tick % 3 == 0)
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
entry.getKey().clone().add(0, 1.1, 0), 1F, 0, 1F, 0, 70, ViewDist.NORMAL, UtilServer.getPlayers());
}
}
_tick++;
}
@Override
public Player getTarget()
{
Player target = null;
double dist = 0;
for (Player player : UtilPlayer.getNearby(getLocation(), 30, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
if (_targetted.contains(player.getName()))
{
continue;
}
double d = player.getLocation().distance(getLocation());
if (d < 7)
{
continue;
}
boolean valid = true;
for (Entry<Location, Location> loc : _ruptures)
{
if (loc.getValue().distance(player.getLocation()) < 1.5)
{
valid = false;
break;
}
}
if (!valid)
{
continue;
}
if (target == null || dist > d)
{
target = player;
dist = d;
}
}
return target;
}
private void explodeRupture(Location loc)
{
loc.add(0, 1.1, 0);
loc.setX(loc.getBlockX() + 0.5);
loc.setZ(loc.getBlockZ() + 0.5);
// Fling
HashMap<LivingEntity, Double> targets = UtilEnt.getInRadius(loc, 3.5);
for (LivingEntity cur : targets.keySet())
{
// Velocity
UtilAction.velocity(cur,
UtilAlg.getTrajectory2d(loc.toVector().add(new Vector(0.5, 0, 0.5)), cur.getLocation().toVector()),
0.8 + 0.8 * targets.get(cur), true, 0, 0.4 + 1.0 * targets.get(cur), 1.4, true);
// Condition
getBoss().getEvent().getCondition().Factory().Falling("Rupture", cur, getEntity(), 10, false, true);
// Damage Event
getBoss().getEvent().getDamageManager().NewDamageEvent(cur, getEntity(), null, DamageCause.CUSTOM,
8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard", "Rupture");
}
ArrayList<Block> blocks = new ArrayList<Block>();
for (int x = -3; x <= 3; x++)
{
for (int z = -3; z <= 3; z++)
{
for (int y = 0; y <= 1; y++)
{
for (int i = 0; i < 2; i++)
{
if (Math.sqrt(x * x + z * z + y * y) <= 3)
{
blocks.add(loc.clone().add(x, y, z).getBlock());
}
}
}
}
}
Collections.shuffle(blocks);
// Blocks
int done = 0;
Iterator<Block> itel = blocks.iterator();
while (done < 30 && itel.hasNext())
{
Block block = itel.next();
Vector vec = new Vector(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize();
if (!UtilBlock.airFoliage(block))
continue;
// Add Directional
vec.add(UtilAlg.getTrajectory(loc.getBlock().getLocation(), block.getLocation().add(0.5, 0, 0.5)));
// Add Up
vec.add(new Vector(0, 1.6, 0));
vec.normalize();
// Scale
vec.multiply(0.1 + 0.3 * Math.random() + 0.6);
// Block!
Item item = loc.getWorld().dropItem(block.getLocation().add(0.5, 0, 0.5), new ItemStack(Material.DIRT.getId(), 0));
item.setVelocity(vec);
item.setPickupDelay(50000);
_items.add(item);
// Effect
loc.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.STONE.getId());
done++;
}
_ticksFinished = 20;
}
}

View File

@ -0,0 +1,261 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
public class GolemSlam extends BossAbility<GolemCreature, IronGolem>
{
private ArrayList<Item> _items = new ArrayList<Item>();
private int _ticksFinished;
private int _stage;
private Vector _target;
private int _ticksJumped;
public GolemSlam(GolemCreature creature)
{
super(creature);
Player target = getTarget();
if (target != null)
{
_target = UtilAlg.calculateVelocity(getLocation().toVector(),
target.getLocation().toVector().setY(getLocation().getY()), 2, getEntity());
}
}
@Override
public boolean canMove()
{
return !UtilEnt.isGrounded(getEntity()) && _stage == 1;
}
@Override
public boolean hasFinished()
{
return _stage == 2 && --_ticksFinished <= 0;
}
@Override
public void setFinished()
{
for (Item item : _items)
{
item.remove();
}
}
@Override
public void tick()
{
Entity entity = getEntity();
if (_stage == 0)
{
UtilEnt.CreatureLook(getEntity(), getLocation().add(_target));
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 4, 0);
entity.setVelocity(_target);
_stage++;
}
else if (_stage == 1)
{
_ticksJumped++;
if (_ticksJumped > 4 && getLocation().subtract(0, 0.2, 0).getBlock().getType() != Material.AIR)
{
explodeRupture(getLocation());
_stage = 2;
}
}
}
@EventHandler
public void HopperPickup(InventoryPickupItemEvent event)
{
if (_items.contains(event.getItem()))
event.setCancelled(true);
}
@EventHandler
public void ItemDestroy(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
if (_items.isEmpty())
return;
Iterator<Item> itemIterator = _items.iterator();
while (itemIterator.hasNext())
{
Item item = itemIterator.next();
if (item.isDead() || !item.isValid())
{
item.remove();
itemIterator.remove();
}
else if (UtilEnt.isGrounded(item) || item.getTicksLived() > 60)
{
item.getWorld().playEffect(item.getLocation(), Effect.STEP_SOUND, item.getItemStack().getTypeId());
item.remove();
itemIterator.remove();
}
}
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public Player getTarget()
{
Player target = null;
double dist = 0;
for (Player player : UtilPlayer.getNearby(getLocation(), 30, true))
{
if (!player.hasLineOfSight(getEntity()))
{
continue;
}
double d = player.getLocation().distance(getLocation());
if (d < 10)
{
continue;
}
if (target == null || dist > d)
{
target = player;
dist = d;
}
}
return target;
}
private void explodeRupture(Location loc)
{
loc.add(0, 1.1, 0);
loc.setX(loc.getBlockX() + 0.5);
loc.setZ(loc.getBlockZ() + 0.5);
// Fling
HashMap<LivingEntity, Double> targets = UtilEnt.getInRadius(loc, 3.5);
for (LivingEntity cur : targets.keySet())
{
if (cur.equals(getEntity()))
{
continue;
}
// Velocity
UtilAction.velocity(cur,
UtilAlg.getTrajectory2d(loc.toVector().add(new Vector(0.5, 0, 0.5)), cur.getLocation().toVector()),
0.8 + 0.8 * targets.get(cur), true, 0, 0.4 + 1.0 * targets.get(cur), 1.4, true);
// Condition
getBoss().getEvent().getCondition().Factory().Falling("Rupture", cur, getEntity(), 10, false, true);
// Damage Event
getBoss().getEvent().getDamageManager().NewDamageEvent(cur, getEntity(), null, DamageCause.CUSTOM,
8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard", "Rupture");
}
ArrayList<Block> blocks = new ArrayList<Block>();
for (int x = -3; x <= 3; x++)
{
for (int z = -3; z <= 3; z++)
{
for (int y = 0; y <= 1; y++)
{
for (int i = 0; i < 2; i++)
{
if (Math.sqrt(x * x + z * z + y * y) <= 3)
{
blocks.add(loc.clone().add(x, y, z).getBlock());
}
}
}
}
}
Collections.shuffle(blocks);
// Blocks
int done = 0;
Iterator<Block> itel = blocks.iterator();
while (done < 30 && itel.hasNext())
{
Block block = itel.next();
Vector vec = new Vector(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize();
if (!UtilBlock.airFoliage(block))
continue;
// Add Directional
vec.add(UtilAlg.getTrajectory(loc.getBlock().getLocation(), block.getLocation().add(0.5, 0, 0.5)));
// Add Up
vec.add(new Vector(0, 1.6, 0));
vec.normalize();
// Scale
vec.multiply(0.1 + 0.3 * Math.random() + 0.6);
// Block!
Item item = loc.getWorld().dropItem(block.getLocation().add(0.5, 0, 0.5), new ItemStack(Material.DIRT.getId(), 0));
item.setVelocity(vec);
item.setPickupDelay(50000);
_items.add(item);
// Effect
loc.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.DIRT.getId());
done++;
}
_ticksFinished = 20;
}
}

View File

@ -0,0 +1,105 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.List;
import java.util.Random;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import org.bukkit.Sound;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
public class GolemSpike extends BossAbility<GolemCreature, IronGolem>
{
private static final int SPIKE_HEIGHT = 2;
private static final long ATTACK_DURATION = 1000 + (500 * SPIKE_HEIGHT * 2);
private static final long SPIKE_REMAIN = 1000;
private long _start;
private List<GroundSpike> _spikes;
public GolemSpike(GolemCreature creature)
{
super(creature);
_start = System.currentTimeMillis();
_spikes = Lists.newArrayList();
}
@Override
public int getCooldown()
{
return 15;
}
@Override
public boolean canMove()
{
return true;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, ATTACK_DURATION) && _spikes.isEmpty();
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - ATTACK_DURATION;
for (GroundSpike spike : _spikes)
{
spike.finish();
}
_spikes.clear();
}
@Override
public void tick()
{
if (_spikes.isEmpty())
{
for (Player player : UtilPlayer.getInRadius(getLocation(), 20).keySet())
{
if (UtilEnt.isGrounded(player))
{
player.playSound(player.getLocation(), Sound.STEP_STONE, 0.2f, 0.2f);
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getBoss().getEntity(), null, DamageCause.CUSTOM, 5 * getBoss().getDifficulty(), false, false, false, getBoss().getEntity().getName(), "Stone Spike");
player.teleport(player.getLocation().add(0, SPIKE_HEIGHT, 0));
UtilAction.velocity(player, player.getLocation().toVector().normalize().add(new Vector(0, 0.02, 0)).normalize());
_spikes.add(new GroundSpike(player.getLocation().getBlock(), player.getLocation().getBlock().getRelative(0, -1, 0).getType(), new Random().nextInt(SPIKE_HEIGHT) + 2, SPIKE_REMAIN));
}
}
}
else
{
List<GroundSpike> toRemove = Lists.newArrayList();
for (GroundSpike spike : _spikes)
{
spike.tick();
if (spike.isFinished())
{
toRemove.add(spike);
}
}
for (GroundSpike remove : toRemove)
{
_spikes.remove(remove);
}
}
}
}

View File

@ -0,0 +1,416 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilShapes;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
import net.minecraft.server.v1_8_R3.Vec3D;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.util.Vector;
public class GolemWallExplode extends BossAbility<GolemCreature, IronGolem>
{
private HashMap<BlockFace, ArrayList<Block>> _blockWalls = new HashMap<BlockFace, ArrayList<Block>>();
private ArrayList<String> _dontTarget = new ArrayList<String>();
private ArrayList<FallingBlock> _fallingBlocks = new ArrayList<FallingBlock>();
private int _maxTimes = UtilMath.r(2) + 1;
private int _tick;
private int _timesDone;
private HashMap<BlockFace, Long> _wallTimers = new HashMap<BlockFace, Long>();
public GolemWallExplode(GolemCreature creature)
{
super(creature);
}
@Override
public boolean canMove()
{
return true;
}
@Override
public int getCooldown()
{
return 20;
}
private float getMod(int div)
{
return UtilMath.random.nextFloat() / div;
}
@Override
public Player getTarget()
{
for (Player player : UtilPlayer.getNearby(getLocation(), 15, true))
{
if (_dontTarget.contains(player.getName()))
{
continue;
}
if (player.getLocation().distance(getLocation()) <= 4)
{
continue;
}
return player;
}
return null;
}
@Override
public boolean hasFinished()
{
return _wallTimers.isEmpty() && _fallingBlocks.isEmpty() && _timesDone >= _maxTimes;
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
while (fallingIterator.hasNext())
{
FallingBlock cur = fallingIterator.next();
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
fallingIterator.remove();
Block block = cur.getLocation().getBlock();
block.setTypeIdAndData(0, (byte) 0, true);
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
// Expire
if (cur.getTicksLived() > 400
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
{
cur.remove();
continue;
}
cur.remove();
continue;
}
double distanceToEntity = 0.0D;
LivingEntity victim = null;
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
nmsEntity.locZ + nmsEntity.motZ);
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
if (finalObjectPosition != null)
{
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
}
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
{
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
if (bukkitEntity instanceof LivingEntity)
{
LivingEntity ent = (LivingEntity) bukkitEntity;
// Avoid Self
if (ent.equals(getEntity()))
continue;
// Creative or Spec
if (ent instanceof Player)
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
continue;
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
if (entityCollisionPosition != null)
{
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
{
victim = ent;
distanceToEntity = d1;
}
}
}
}
if (victim != null)
{
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
if (canDamage(victim))
{
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Wall Explosion",
"Iron Wizard Wall Explosion");
}
cur.remove();
fallingIterator.remove();
Vector vec = cur.getVelocity();
UtilAction.velocity(victim, vec, 1.5, true, 0, 0.2, 1, true);
}
else if (finalObjectPosition != null)
{
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
{
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
float f2 = MathHelper.sqrt(
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
cur.remove();
fallingIterator.remove();
}
}
else
{
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
UtilServer.getPlayers());
}
}
}
@Override
public void setFinished()
{
for (FallingBlock block : _fallingBlocks)
{
block.remove();
}
for (ArrayList<Block> list : _blockWalls.values())
{
for (Block b : list)
{
b.setType(Material.AIR);
}
}
}
@Override
public void tick()
{
if (_tick++ % 30 == 0 && _timesDone < _maxTimes)
{
_dontTarget.clear();
_timesDone++;
for (int i = 0; i < 10; i++)
{
Player target = getTarget();
if (target == null)
{
if (_dontTarget.isEmpty())
{
_timesDone = _maxTimes;
}
}
else
{
_dontTarget.add(target.getName());
UtilEnt.CreatureLook(getEntity(), target);
BlockFace face = UtilShapes.getFacing(getLocation().getYaw());
if (_wallTimers.containsKey(face))
{
continue;
}
ArrayList<Block> blocks = new ArrayList<Block>();
Location loc = getLocation().getBlock().getLocation().add(0.5, 0, 0.5);
int mul = (face.getModX() != 0 && face.getModZ() != 0) ? 2 : 3;
loc.add(face.getModX() * mul, 0, face.getModZ() * mul);
Block b = loc.getBlock();
BlockFace sideFace = UtilShapes.getSideBlockFaces(face, true)[0];
boolean invalid = false;
for (int mult = -3; mult <= 3; mult++)
{
Block block = b;
if (Math.abs(mult) < 3)
{
block = block.getRelative(face);
}
block = block.getRelative(sideFace, mult);
if (Math.abs(mult) == 3 && face.getModX() != 0 && face.getModZ() != 0)
{
block = block.getRelative(UtilShapes.getSideBlockFaces(face, false)[mult < 0 ? 0 : 1]);
}
if (!UtilAlg.HasSight(getLocation(), block.getLocation()))
{
invalid = true;
break;
}
Block under = block.getRelative(0, -1, 0);
if (!UtilBlock.solid(under))
{
continue;
}
for (int y = 0; y <= 1; y++)
{
block = block.getRelative(0, y, 0);
if (block.getType() != Material.AIR)
{
invalid = true;
break;
}
blocks.add(block);
}
if (invalid)
{
break;
}
}
if (invalid)
{
continue;
}
for (Block block : blocks)
{
block.setType(block.getWorld().getBlockAt(block.getX(), b.getY() - 1, block.getZ()).getType());
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
}
_blockWalls.put(face, blocks);
_wallTimers.put(face, System.currentTimeMillis());
break;
}
}
}
Iterator<Entry<BlockFace, ArrayList<Block>>> itel = _blockWalls.entrySet().iterator();
boolean doExplode = false;
while (itel.hasNext())
{
Entry<BlockFace, ArrayList<Block>> entry = itel.next();
BlockFace face = entry.getKey();
if (UtilTime.elapsed(_wallTimers.get(face), 1000))
{
doExplode = true;
itel.remove();
_wallTimers.remove(face);
for (Block b : entry.getValue())
{
FallingBlock block = getEntity().getWorld().spawnFallingBlock(b.getLocation().add(0.5, 0, 0.5), b.getType(),
(byte) 0);
block.setDropItem(false);
int index = entry.getValue().indexOf(b);
BlockFace f = index == 8 || index == 9 ? BlockFace.SELF
: UtilShapes.getSideBlockFaces(face, true)[index > 6 ? 0 : 1];
block.setVelocity(new Vector((face.getModX() * 0.6) + (f.getModX() * (0.05 + getMod(10))), 0.2 + getMod(15),
(face.getModZ() * 0.6) + (f.getModZ() * (0.05 + getMod(10)))));
_fallingBlocks.add(block);
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getTypeId());
b.setType(Material.AIR);
}
}
}
if (doExplode)
{
onUpdate(new UpdateEvent(UpdateType.TICK));
}
}
@Override
public boolean inProgress()
{
return false;
}
}

View File

@ -0,0 +1,116 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import java.util.LinkedList;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
public class GroundSpike
{
private Block _initial;
private Material _type;
private int _max, _height;
private long _lastTick, _remain;
private LinkedList<Block> _blocks;
private boolean _shrinking, _finished;
public GroundSpike(Block first, Material type, int maxHeight, long remainDuration)
{
_initial = first;
_type = type;
_height = 0;
_max = maxHeight;
_remain = remainDuration;
_lastTick = System.currentTimeMillis();
_blocks = new LinkedList<>();
_shrinking = false;
_finished = false;
}
@SuppressWarnings("deprecation")
private void raise()
{
if ((_height + 1) < _max)
{
_lastTick = System.currentTimeMillis();
Block b = _initial.getRelative(0, _height, 0);
for (Player player : UtilServer.getPlayers())
{
player.sendBlockChange(b.getLocation(), _type, (byte)0);
}
_blocks.add(b);
_height++;
}
else
{
if (UtilTime.elapsed(_lastTick, _remain))
{
_shrinking = true;
lower();
}
}
}
@SuppressWarnings("deprecation")
private void lower()
{
_height = Math.min(_blocks.size() - 1, _height);
if ((_height - 1) >= 0)
{
_lastTick = System.currentTimeMillis();
for (Player player : UtilServer.getPlayers())
{
player.sendBlockChange(_blocks.get(_height).getLocation(), Material.AIR, (byte)0);
}
_blocks.remove(_height);
_height--;
}
else
{
finish();
}
}
public boolean isFinished()
{
if (!_blocks.isEmpty())
return false;
return _finished;
}
@SuppressWarnings("deprecation")
public void finish()
{
_finished = true;
for (Block block : _blocks)
{
for (Player player : UtilServer.getPlayers())
{
player.sendBlockChange(block.getLocation(), Material.AIR, (byte)0);
}
}
_blocks.clear();
}
public void tick()
{
if (isFinished())
return;
if (!UtilTime.elapsed(_lastTick, 500))
return;
if (_shrinking)
{
lower();
}
else
{
raise();
}
}
}

View File

@ -0,0 +1,60 @@
package mineplex.minecraft.game.core.boss.ironwizard.abilities;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.projectile.IThrown;
import mineplex.core.projectile.ProjectileUser;
import mineplex.minecraft.game.core.boss.WorldEvent;
import org.bukkit.block.Block;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
public class IronHook implements IThrown
{
private WorldEvent _host;
public IronHook(WorldEvent event)
{
_host = event;
}
@Override
public void Collide(LivingEntity target, Block block, ProjectileUser data)
{
data.getThrown().remove();
if (!(data.getThrower() instanceof IronGolem))
return;
IronGolem wizard = (IronGolem)data.getThrower();
if (target == null)
return;
UtilAction.velocity(target, UtilAlg.getTrajectory(target.getLocation(), wizard.getLocation()), 5, false, 0, 0.7, 1.2, true);
_host.getCondition().Factory().Falling("Iron Hook", target, wizard, 10, false, true);
_host.getDamageManager().NewDamageEvent(target, wizard, null, DamageCause.CUSTOM, 5, false, true, false, wizard.getName(), "Iron Hook");
}
@Override
public void Idle(ProjectileUser data)
{
data.getThrown().remove();
}
@Override
public void Expire(ProjectileUser data)
{
data.getThrown().remove();
}
@Override
public void ChunkUnload(ProjectileUser data)
{
data.getThrown().remove();
}
}

View File

@ -0,0 +1,102 @@
package mineplex.minecraft.game.core.boss.skeletonking;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.common.util.F;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.EventState;
import mineplex.minecraft.game.core.boss.WorldEvent;
import mineplex.minecraft.game.core.boss.skeletonking.minion.MinionType;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
public class SkeletonBoss extends WorldEvent
{
protected boolean canMove = false;
public SkeletonBoss(DisguiseManager disguiseManager, DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, ProjectileManager projectileManager, Location cornerLocation)
{
super(disguiseManager, projectileManager, damageManager, blockRestore, conditionManager, "Skeleton King", cornerLocation);
}
@Override
protected void customStart()
{
Bukkit.broadcastMessage(F.main(getName(), "The evils of the world have manifested in the form of the " + getName() + "! Become the champion of Light and destroy him!"));
spawnNecromancer(getCenterLocation());
setState(EventState.LIVE);
announceStart();
}
/**
* Check if this skeleton boss has been defeated
*/
private void checkDeath()
{
if (getBossesAlive() == 0)
{
setState(EventState.COMPLETE);
Bukkit.broadcastMessage(F.main(getName(), "The demonic " + getName() + " has been slain!"));
}
}
@Override
public void removeCreature(EventCreature creature)
{
super.removeCreature(creature);
if (creature instanceof SkeletonCreature)
{
checkDeath();
}
}
@Override
protected void setState(EventState state)
{
super.setState(state);
if (state == EventState.LIVE)
{
Bukkit.getScheduler().runTaskLater(getPlugin(), () ->
{
canMove = true;
}, 20 * 3);
}
}
public EventCreature spawnMinion(MinionType type, Location location)
{
EventCreature minionCreature = type.getNewInstance(this, location);
if (minionCreature != null)
{
registerCreature(minionCreature);
}
return minionCreature;
}
private SkeletonCreature spawnNecromancer(Location location)
{
SkeletonCreature necromancerCreature = new SkeletonCreature(this, location, 2500);
registerCreature(necromancerCreature);
return necromancerCreature;
}
private int getBossesAlive()
{
int alive = 0;
for (EventCreature creature : getCreatures())
{
if (creature instanceof SkeletonCreature)
{
alive++;
}
}
return alive;
}
}

View File

@ -0,0 +1,478 @@
package mineplex.minecraft.game.core.boss.skeletonking;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Random;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonArcherShield;
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonPassive;
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonPulse;
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonSmite;
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonStrike;
import mineplex.minecraft.game.core.boss.skeletonking.abilities.SkeletonWraithSummon;
import mineplex.minecraft.game.core.boss.skeletonking.minion.UndeadArcherCreature;
import mineplex.minecraft.game.core.boss.skeletonking.minion.UndeadWarriorCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
public class SkeletonCreature extends EventCreature<Skeleton>
{
private ArrayList<BossAbility> _currentAbilities = Lists.newArrayList();
private SkeletonPassive _passive;
private int _lastAbility;
private HashMap<Class, Long> _cooldowns = new HashMap<>();
private LinkedList<Double> _wraithTriggers = new LinkedList<>();
private List<Location> _movePoints = Lists.newArrayList();
private Location _movingTo;
private boolean _moving;
private long _lastMoved;
private long _lastUsedPassive;
public List<UndeadArcherCreature> Archers = Lists.newArrayList();
public List<UndeadWarriorCreature> Warriors = Lists.newArrayList();
public SkeletonCreature(SkeletonBoss boss, Location location, double maxHealth)
{
super(boss, location, "Skeleton King", true, maxHealth, Skeleton.class);
spawnEntity();
_passive = new SkeletonPassive(this);
_wraithTriggers.add(1500D);
_wraithTriggers.add(1000D);
_wraithTriggers.add(500D);
_wraithTriggers.add(100D);
getEntity().getWorld().setThunderDuration(10000000);
getEntity().getWorld().setThundering(true);
}
@Override
protected void spawnCustom()
{
UtilEnt.vegetate(getEntity());
getEntity().setSkeletonType(SkeletonType.WITHER);
getEntity().getEquipment().setItemInHand(new ItemStack(Material.RECORD_6)); //Meridian Scepter
getEntity().getEquipment().setItemInHandDropChance(0.f);
}
@Override
public void dieCustom()
{
HandlerList.unregisterAll(_passive);
_passive = null;
endAbility();
getEntity().getWorld().setThunderDuration(0);
getEntity().getWorld().setThundering(false);
}
private void endAbility()
{
for (BossAbility ability : _currentAbilities)
{
ability.setFinished();
HandlerList.unregisterAll(ability);
}
_currentAbilities.clear();
}
@EventHandler
public void onTick(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
if (_passive != null && ((SkeletonBoss)getEvent()).canMove)
{
if (UtilTime.elapsed(_lastUsedPassive, _passive.getCooldown() * 20) || _passive.isProgressing())
{
_lastUsedPassive = System.currentTimeMillis();
_passive.tick();
}
}
Iterator<BossAbility> itel = _currentAbilities.iterator();
boolean canDoNew = _currentAbilities.size() < 3;
while (itel.hasNext())
{
BossAbility ability = itel.next();
if (ability.hasFinished())
{
itel.remove();
ability.setFinished();
_lastAbility = 20;// _currentAbility.getCooldown();
HandlerList.unregisterAll(ability);
System.out.print("Unregistered necromancer ability " + ability.getClass().getSimpleName());
_cooldowns.put(ability.getClass(), System.currentTimeMillis() + (ability.getCooldown() * 1000));
}
else if (ability.inProgress())
{
canDoNew = false;
_lastAbility = 20;// _currentAbility.getCooldown();
}
}
if (_lastAbility-- <= 0 && canDoNew && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN)))
{
HashMap<Class<? extends BossAbility>, Integer> weight = new HashMap<>();
HashMap<Player, Double> dist = new HashMap<>();
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
{
if (player.hasLineOfSight(getEntity()))
{
dist.put(player, player.getLocation().distance(getEntity().getLocation()));
}
}
if (!dist.isEmpty())
{
{// Pulse & Strike
ArrayList<Player> players = getPlayers(dist, UtilMath.r(10) == 0 ? 25 : 20);
ArrayList<Player> near = getPlayers(dist, 5);
if (!players.isEmpty())
{
if (!near.isEmpty() && near.size() >= 4 && new Random().nextDouble() <= .45)
{
weight.put(SkeletonPulse.class, 999);
}
else
{
weight.put(SkeletonStrike.class, 6);
}
}
}
{// Smite
ArrayList<Player> players = getPlayers(dist, 15);
if (!players.isEmpty())
{
weight.put(SkeletonSmite.class, 6);
}
}
{//Archer Shield
ArrayList<Player> players = getPlayers(dist, 20);
double score = 0;
for (Player player : players)
{
score += (18 - dist.get(player)) / 2;
}
if (players.size() >= 4)
{
score += 17;
}
if (score > 0)
{
weight.put(SkeletonArcherShield.class, (int) Math.ceil(score));
}
}
Double wraithUse = null;
for (Double test : _wraithTriggers)
{
if (wraithUse == null)
{
if (getHealth() <= test)
{
wraithUse = test;
break;
}
}
}
if (wraithUse != null)
{// Wraith Summon
_wraithTriggers.remove(wraithUse);
weight.clear();
weight.put(SkeletonWraithSummon.class, 999);
}
}
for (BossAbility ability : _currentAbilities)
{
weight.remove(ability.getClass());
}
for (Class c : _cooldowns.keySet())
{
if (_cooldowns.get(c) > System.currentTimeMillis())
{
weight.remove(c);
}
}
if (_moving)
{
Iterator<Class<? extends BossAbility>> trying = weight.keySet().iterator();
while (trying.hasNext())
{
Class<? extends BossAbility> abilityClass = trying.next();
try
{
BossAbility ability = abilityClass.newInstance();
if (!ability.canMove())
{
trying.remove();
}
}
catch (Exception e) {}
}
}
BossAbility ability = null;
if (!weight.isEmpty())
{
int i = 0;
for (Integer entry : weight.values())
{
i += entry;
}
loop: for (int a = 0; a < 10; a++)
{
int luckyNumber = UtilMath.r(i);
for (Entry<Class<? extends BossAbility>, Integer> entry : weight.entrySet())
{
luckyNumber -= entry.getValue();
if (luckyNumber <= 0)
{
try
{
ability = entry.getKey().getConstructor(SkeletonCreature.class).newInstance(this);
if (ability.getTarget() == null || ability.hasFinished())
{
ability = null;
}
else
{
break loop;
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
break;
}
}
}
}
if (ability != null && ability.getTarget() != null)
{
Bukkit.getPluginManager().registerEvents(ability, getEvent().getPlugin());
System.out.print("Necromancer is using " + ability.getClass().getSimpleName());
_currentAbilities.add(ability);
}
_lastAbility = 10;
}
for (BossAbility ability : _currentAbilities)
{
try
{
ability.tick();
}
catch (Exception e)
{
e.printStackTrace();
}
}
boolean canMove = true;
for (BossAbility ability : _currentAbilities)
{
if (!ability.canMove())
{
canMove = false;
}
}
if (!((SkeletonBoss)getEvent()).canMove)
{
return;
}
if (_moving)
{
if (_movingTo == null)
{
_movingTo = selectWalkTarget();
}
if (UtilMath.offset(getEntity().getLocation(), _movingTo) <= 1.3)
{
_lastMoved = System.currentTimeMillis();
_movingTo = null;
_moving = false;
return;
}
UtilEnt.LookAt(getEntity(), _movingTo);
Vector walk = UtilAlg.getTrajectory(getEntity().getLocation(), _movingTo);
walk.multiply(walk.length());
walk.multiply(.2);
getEntity().setVelocity(walk);
}
else
{
if (!UtilTime.elapsed(_lastMoved, 7000) || !canMove)
{
return;
}
_movingTo = selectWalkTarget();
_moving = true;
}
}
private Location selectWalkTarget()
{
if (_movePoints.isEmpty())
{
Location base = getSpawnLocation().clone();
base.setY(getEntity().getLocation().getY());
generateWalkPoints(base);
}
Location selected = _movePoints.get(new Random().nextInt(_movePoints.size()));
_movePoints.remove(selected);
return selected;
}
private void generateWalkPoints(Location base)
{
_movePoints.add(base.clone().add(5 + UtilMath.random(1, 3), 0, 5 + UtilMath.random(1, 3)));
_movePoints.add(base.clone().add(-5 + UtilMath.random(1, 3), 0, 5 + UtilMath.random(1, 3)));
_movePoints.add(base.clone().add(5 + UtilMath.random(1, 3), 0, -5 + UtilMath.random(1, 3)));
_movePoints.add(base.clone().add(-5 + UtilMath.random(1, 3), 0, -5 + UtilMath.random(1, 3)));
}
private ArrayList<Player> getPlayers(HashMap<Player, Double> map, double maxDist)
{
return getPlayers(map, 0, maxDist);
}
private ArrayList<Player> getPlayers(final HashMap<Player, Double> map, double minDist, double maxDist)
{
ArrayList<Player> list = new ArrayList<Player>();
for (Player p : map.keySet())
{
if (map.get(p) >= minDist && map.get(p) <= maxDist)
{
list.add(p);
}
}
Collections.sort(list, new Comparator<Player>()
{
@Override
public int compare(Player o1, Player o2)
{
return Double.compare(map.get(o2), map.get(o1));
}
});
return list;
}
@EventHandler
public void onSkeletonDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId())
{
event.SetKnockback(false);
}
}
@EventHandler
public void noFallDamage(CustomDamageEvent event)
{
if (getEntity() == null)
return;
if (event.GetDamageeEntity().getEntityId() != getEntity().getEntityId())
return;
DamageCause cause = event.GetCause();
if (cause == DamageCause.FALL)
{
event.SetCancelled("Boss Invulnerability");
}
}
@EventHandler(priority = EventPriority.HIGH)
public void protect(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damagee))
{
if (!(damager instanceof Player))
{
event.SetCancelled("Allied Attacker");
}
}
}
}

View File

@ -0,0 +1,186 @@
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
import mineplex.minecraft.game.core.boss.skeletonking.minion.UndeadArcherCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftSkeleton;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
public class SkeletonArcherShield extends BossAbility<SkeletonCreature, Skeleton>
{
private static long ATTACK_DURATION = 10000;
private static long ARROW_DELAY = 100;
private static long ARROW_WARMUP = 2000;
private static double PULL_RANGE = 12;
private long _start;
private long _lastShoot;
private boolean _teleported;
public SkeletonArcherShield(SkeletonCreature creature)
{
super(creature);
_start = System.currentTimeMillis();
}
@Override
public int getCooldown()
{
return 20;
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return false;
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, ATTACK_DURATION);
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - ATTACK_DURATION;
for (UndeadArcherCreature creature : getBoss().Archers)
{
creature.getEntity().remove();
}
}
private void run(boolean initial)
{
for (int i = 0; i < getBoss().Archers.size(); i++)
{
Skeleton archer = getBoss().Archers.get(i).getEntity();
UtilEnt.vegetate(archer);
((CraftSkeleton)archer).setVegetated(false);
double lead = i * ((2d * Math.PI)/getBoss().Archers.size());
double sizeMod = 2;
//Orbit
double speed = 10d;
double oX = -Math.sin(getEntity().getTicksLived()/speed + lead) * 2 * sizeMod;
double oY = 0;
double oZ = Math.cos(getEntity().getTicksLived()/speed + lead) * 2 * sizeMod;
if (initial)
{
archer.teleport(getEntity().getLocation().add(oX, oY, oZ));
UtilEnt.vegetate(archer);
}
else
{
Location to = getEntity().getLocation().add(oX, oY, oZ);
UtilEnt.LookAt(archer, to);
UtilAction.velocity(archer, UtilAlg.getTrajectory(archer.getLocation(), to), 0.4, false, 0, 0.1, 1, true);
}
}
}
private void shoot()
{
if (UtilTime.elapsed(_start, ARROW_WARMUP) && UtilTime.elapsed(_lastShoot, ARROW_DELAY))
{
_lastShoot = System.currentTimeMillis();
for (UndeadArcherCreature archer : getBoss().Archers)
{
Location spawn = archer.getEntity().getEyeLocation().add(UtilAlg.getTrajectory(getEntity().getEyeLocation(), archer.getEntity().getEyeLocation()).normalize());
Vector vector = UtilAlg.getTrajectory(getEntity().getEyeLocation(), spawn);
Arrow arrow = archer.getEntity().getWorld().spawnArrow(spawn, vector, 0.6f, 12f);
arrow.setMetadata("SHIELD_SHOT", new FixedMetadataValue(getBoss().getEvent().getPlugin(), true));
arrow.setMetadata("BARBED_ARROW", new FixedMetadataValue(getBoss().getEvent().getPlugin(), 10));
arrow.setShooter(archer.getEntity());
}
}
}
@Override
public void tick()
{
if (!_teleported)
{
run(true);
_teleported = true;
for (Player near : UtilPlayer.getInRadius(getEntity().getLocation(), PULL_RANGE).keySet())
{
Vector velocity = UtilAlg.getTrajectory(near, getEntity());
UtilAction.velocity(near, velocity, 2, false, 0, 0, 1, true);
near.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 5 * 20, -2));
for (int i = 0; i < 6; i++)
{
Vector random = new Vector(Math.random() * 4 - 2, Math.random() * 4 - 2, Math.random() * 4 - 2);
Location origin = getEntity().getLocation().add(0, 1.3, 0);
origin.add(velocity.clone().multiply(10));
origin.add(random);
Vector vel = UtilAlg.getTrajectory(origin, getEntity().getLocation().add(0, 1.3, 0));
vel.multiply(7);
UtilParticle.PlayParticleToAll(ParticleType.MAGIC_CRIT, origin, (float)vel.getX(), (float)vel.getY(), (float)vel.getZ(), 1, 0, ViewDist.LONG);
}
}
}
else
{
run(false);
shoot();
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().equals(getBoss().getEntity()))
{
if (!hasFinished())
{
event.SetCancelled("Wraiths Alive");
}
}
}
@EventHandler
public void onArrowHit(ProjectileHitEvent event)
{
if (event.getEntity().hasMetadata("SHIELD_SHOT"))
{
Bukkit.getScheduler().runTaskLater(getBoss().getEvent().getPlugin(), () ->
{
event.getEntity().remove();
}, 20L);
}
}
}

View File

@ -0,0 +1,118 @@
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilTime;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonBoss;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
import mineplex.minecraft.game.core.boss.skeletonking.minion.MinionType;
import org.bukkit.Location;
import org.bukkit.entity.Skeleton;
public class SkeletonHellishFlood extends BossAbility<SkeletonCreature, Skeleton>
{
private static final int WAVE_COUNT = 3;
private static final int WAVE_SIZE = 5;
private static final MinionType[] POSSIBLE_MINIONS = new MinionType[] {MinionType.WARRIOR, MinionType.ARCHER};
private static final long WAVE_DELAY = 1000;
private ConcurrentHashMap<String, MinionType[]> _waves = new ConcurrentHashMap<>();
private long _lastSpawned;
private int _current;
private int _ticks;
public SkeletonHellishFlood(SkeletonCreature creature)
{
super(creature);
if (WAVE_COUNT > 0)
{
for (int i = 1; i <= WAVE_COUNT; i++)
{
createWave(i);
}
}
_lastSpawned = System.currentTimeMillis();
_current = 1;
}
private void createWave(int number)
{
int length = POSSIBLE_MINIONS.length;
if (length <= 0 || WAVE_SIZE <= 0)
{
return;
}
MinionType[] wave = new MinionType[WAVE_SIZE];
for (int i = 0; i < WAVE_SIZE; i++)
{
wave[i] = POSSIBLE_MINIONS[new Random().nextInt(length)];
}
_waves.put("Wave " + number, wave);
}
@Override
public int getCooldown()
{
return 30;
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return _waves.isEmpty() && _ticks > ((WAVE_DELAY / 1000) * 20 * (WAVE_COUNT - 1));
}
@Override
public void setFinished()
{
_waves.clear();
_ticks = 60;
}
@Override
public void tick()
{
_ticks++;
if (UtilTime.elapsed(_lastSpawned, WAVE_DELAY))
{
if (_current <= WAVE_COUNT)
{
for (MinionType type : _waves.get("Wave " + _current))
{
Location toSpawn = getLocation().clone();
toSpawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6));
((SkeletonBoss)getBoss().getEvent()).spawnMinion(type, toSpawn);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, toSpawn, null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, toSpawn, null, 0, 2, ViewDist.MAX);
}
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
_waves.remove("Wave " + _current);
_current++;
_lastSpawned = System.currentTimeMillis();
}
}
}
}

View File

@ -0,0 +1,121 @@
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
import java.util.List;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilTime;
import mineplex.minecraft.game.core.boss.BossPassive;
import mineplex.minecraft.game.core.boss.EventCreatureDeathEvent;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonBoss;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
import mineplex.minecraft.game.core.boss.skeletonking.minion.MinionType;
import mineplex.minecraft.game.core.boss.skeletonking.minion.UndeadArcherCreature;
import mineplex.minecraft.game.core.boss.skeletonking.minion.UndeadWarriorCreature;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import com.google.common.collect.Lists;
public class SkeletonPassive extends BossPassive<SkeletonCreature, Skeleton>
{
private static final int MAX_ARCHERS = 10;
private static final int MAX_WARRIORS = 8;
private static final long SPAWN_RATE = 5000;
private List<Location> _queuedArchers = Lists.newArrayList();
private List<Location> _queuedWarriors = Lists.newArrayList();
private long _lastASpawned;
private long _lastWSpawned;
public SkeletonPassive(SkeletonCreature creature)
{
super(creature);
}
@Override
public int getCooldown()
{
return 20;
}
@Override
public boolean isProgressing()
{
return !_queuedArchers.isEmpty() || !_queuedWarriors.isEmpty();
}
@Override
public void tick()
{
if (getBoss().Archers.size() < MAX_ARCHERS && _queuedArchers.isEmpty())
{
for (int i = 0; i < (MAX_ARCHERS - getBoss().Archers.size()); i++)
{
Location spawn = getLocation().clone();
spawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6));
_queuedArchers.add(spawn);
}
}
if (getBoss().Warriors.size() < MAX_WARRIORS && _queuedWarriors.isEmpty())
{
for (int i = 0; i < (MAX_WARRIORS - getBoss().Warriors.size()); i++)
{
Location spawn = getLocation().clone();
spawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6));
_queuedWarriors.add(spawn);
}
}
for (Location animate : _queuedArchers)
{
UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
animate.clone().add(0, 0.2, 0), null, 0, 4, ViewDist.NORMAL);
}
for (Location animate : _queuedWarriors)
{
UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
animate.clone().add(0, 0.2, 0), null, 0, 4, ViewDist.NORMAL);
}
if (!_queuedArchers.isEmpty() && UtilTime.elapsed(_lastASpawned, SPAWN_RATE))
{
_lastASpawned = System.currentTimeMillis();
Location spawn = _queuedArchers.remove(0);
getBoss().Archers.add((UndeadArcherCreature) ((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.ARCHER, spawn));
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, spawn, null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, spawn, null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
}
if (!_queuedWarriors.isEmpty() && UtilTime.elapsed(_lastWSpawned, SPAWN_RATE))
{
_lastWSpawned = System.currentTimeMillis();
Location spawn = _queuedWarriors.remove(0);
getBoss().Warriors.add((UndeadWarriorCreature) ((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.WARRIOR, spawn));
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, spawn, null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, spawn, null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
}
}
@EventHandler
public void onArcherDeath(EventCreatureDeathEvent event)
{
if (event.getCreature() instanceof UndeadArcherCreature)
{
getBoss().Archers.remove(event.getCreature());
}
if (event.getCreature() instanceof UndeadWarriorCreature)
{
getBoss().Warriors.remove(event.getCreature());
}
}
}

View File

@ -0,0 +1,108 @@
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.recharge.Recharge;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
public class SkeletonPulse extends BossAbility<SkeletonCreature, Skeleton>
{
private static final long TOTAL_ATTACK_DURATION = 8000;
private static final long TOTAL_ATTACK_PROGRESS = 3000;
private long _start, _lastIncrement;
private int _radius;
private Location _center;
public SkeletonPulse(SkeletonCreature creature)
{
super(creature);
_start = System.currentTimeMillis();
_radius = 2;
_lastIncrement = System.currentTimeMillis();
_center = creature.getEntity().getLocation();
}
private int getRadius()
{
return Math.min(8, _radius);
}
@Override
public int getCooldown()
{
return 7;
}
@Override
public boolean canMove()
{
return UtilTime.elapsed(_start, TOTAL_ATTACK_PROGRESS);
}
@Override
public boolean inProgress()
{
return UtilTime.elapsed(_start, TOTAL_ATTACK_PROGRESS);
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, TOTAL_ATTACK_DURATION);
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - TOTAL_ATTACK_DURATION;
}
@Override
public void tick()
{
if (UtilTime.elapsed(_lastIncrement, 500))
{
_lastIncrement = System.currentTimeMillis();
_radius++;
}
for (double token = 0; token <= (2 * Math.PI); token += .2)
{
double x = getRadius() * Math.cos(token);
double z = getRadius() * Math.sin(token);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, _center.clone().add(x, 1.5, z), null, 0, 1, ViewDist.MAX);
}
for (Player player : UtilPlayer.getInRadius(getEntity().getLocation(), getRadius()).keySet())
{
if (player.isDead() || !player.isValid() || !player.isOnline())
{
continue;
}
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
if (!Recharge.Instance.use(player, "Pulse Knockback", 400, false, false, false))
{
continue;
}
player.playSound(player.getLocation(), Sound.AMBIENCE_THUNDER, 1f, 1f);
UtilAction.velocity(player, UtilAlg.getTrajectory2d(getEntity(), player), 2, false, 0.6, 0, 1.4, true);
}
}
}

View File

@ -0,0 +1,104 @@
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
import java.math.BigDecimal;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
public class SkeletonSmite extends BossAbility<SkeletonCreature, Skeleton>
{
private static final long TOTAL_ATTACK_DURATION = 8000;
private long _start;
private int _ticks;
private boolean _shot;
public SkeletonSmite(SkeletonCreature creature)
{
super(creature);
_start = System.currentTimeMillis();
_ticks = 0;
_shot = false;
}
@Override
public int getCooldown()
{
return 15;
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, TOTAL_ATTACK_DURATION) && _shot;
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - TOTAL_ATTACK_DURATION;
_shot = true;
}
@Override
public void tick()
{
if (_shot)
return;
if (_ticks < (6 * 20))
{
_ticks++;
double maxHeight = Math.min(_ticks / 20, 6);
int radius = Math.max(6 - (new BigDecimal(_ticks).divide(new BigDecimal(20)).intValue()), 0);
for (double y = 0; y < maxHeight; y += 0.5)
{
double cos = radius * Math.cos(y);
double sin = radius * Math.sin(y);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation().add(cos, y, sin), null, 0, 1, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation().add(sin, y, cos), null, 0, 1, ViewDist.MAX);
}
}
else
{
_shot = true;
for (Player player : UtilPlayer.getInRadius(getEntity().getLocation(), 15).keySet())
{
if (player.isDead() || !player.isValid() || !player.isOnline())
{
continue;
}
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
player.getWorld().strikeLightningEffect(player.getLocation());
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, DamageCause.LIGHTNING, 15 * getBoss().getDifficulty(), false, true, false, getEntity().getName(), "Lightning Strike");
}
}
}
}

View File

@ -0,0 +1,168 @@
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import com.google.common.collect.Lists;
public class SkeletonStrike extends BossAbility<SkeletonCreature, Skeleton>
{
private static final double MAX_RANGE = 25;
private static final Integer MAX_TARGETS = 1;
private boolean _shot;
public SkeletonStrike(SkeletonCreature creature)
{
super(creature);
_shot = false;
}
private int getPosition(Player toAdd, LinkedList<Player> ordered)
{
int position = ordered.size();
int index = 0;
for (Player player : ordered)
{
if (player.getHealth() < toAdd.getHealth())
{
position = index;
return position;
}
index++;
}
return position;
}
private List<Player> getTargets()
{
Skeleton necromancer = getBoss().getEntity();
LinkedList<Player> selections = new LinkedList<>();
List<Player> targeted = Lists.newArrayList();
HashMap<Player, Double> near = UtilPlayer.getInRadius(necromancer.getLocation(), MAX_RANGE);
for (Player nearby : near.keySet())
{
if (nearby.getGameMode() == GameMode.CREATIVE || nearby.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
if (selections.isEmpty())
{
selections.addFirst(nearby);
}
else
{
selections.add(getPosition(nearby, selections), nearby);
}
}
for (int i = 0; i < MAX_TARGETS; i++)
{
if (i < selections.size())
{
targeted.add(selections.get(i));
}
}
return targeted;
}
private void shootAt(Player target)
{
double curRange = 0;
boolean canHit = false;
while (curRange <= MAX_RANGE)
{
Location newTarget = getEntity().getEyeLocation().add(UtilAlg.getTrajectory(getEntity(), target).multiply(curRange));
if (!UtilBlock.airFoliage(newTarget.getBlock()))
{
canHit = false;
break;
}
if (UtilMath.offset(newTarget, target.getLocation()) <= 0.9)
{
canHit = true;
break;
}
curRange += 0.2;
UtilParticle.PlayParticle(ParticleType.WITCH_MAGIC, newTarget, 0, 0, 0, 0, 1,
ViewDist.MAX, UtilServer.getPlayers());
canHit = true;
}
if (canHit)
{
getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.CUSTOM, 12 * getBoss().getDifficulty(), true, true, false, getEntity().getName(), "Mystical Energy");
}
}
@Override
public int getCooldown()
{
return 15;
}
@Override
public boolean canMove()
{
return true;
}
@Override
public boolean inProgress()
{
return false;
}
@Override
public boolean hasFinished()
{
return _shot;
}
@Override
public void setFinished()
{
_shot = true;
}
@Override
public void tick()
{
if (_shot)
return;
_shot = true;
for (Player target : getTargets())
{
shootAt(target);
}
}
}

View File

@ -0,0 +1,230 @@
package mineplex.minecraft.game.core.boss.skeletonking.abilities;
import java.math.BigDecimal;
import java.util.concurrent.ConcurrentHashMap;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilPlayer;
import mineplex.minecraft.game.core.boss.BossAbility;
import mineplex.minecraft.game.core.boss.EventCreatureDeathEvent;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonBoss;
import mineplex.minecraft.game.core.boss.skeletonking.SkeletonCreature;
import mineplex.minecraft.game.core.boss.skeletonking.minion.MinionType;
import mineplex.minecraft.game.core.boss.skeletonking.minion.WraithCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.util.Vector;
public class SkeletonWraithSummon extends BossAbility<SkeletonCreature, Skeleton>
{
private static final int WRAITH_AMOUNT = 4;
private static final double DISTANCE_FROM_KING = 4;
private static final double FINAL_SKELETON_HEALTH = 100;
private static final double FINAL_WRAITH_MULTIPLIER = 2;
private final int WRAITH_AMOUNT_THIS_USE;
private ConcurrentHashMap<WraithCreature, String> _wraiths = new ConcurrentHashMap<>();
private Location[] _spawns;
private int _ticks;
public SkeletonWraithSummon(SkeletonCreature creature)
{
super(creature);
_spawns = new Location[]
{
getEntity().getLocation().add(DISTANCE_FROM_KING, 0, DISTANCE_FROM_KING),
getEntity().getLocation().add(DISTANCE_FROM_KING * -1, 0, DISTANCE_FROM_KING),
getEntity().getLocation().add(DISTANCE_FROM_KING, 0, DISTANCE_FROM_KING * -1),
getEntity().getLocation().add(DISTANCE_FROM_KING * -1, 0, DISTANCE_FROM_KING * -1),
getEntity().getLocation().add(DISTANCE_FROM_KING / 2, 0, DISTANCE_FROM_KING / 2),
getEntity().getLocation().add((DISTANCE_FROM_KING / 2) * -1, 0, DISTANCE_FROM_KING / 2),
getEntity().getLocation().add(DISTANCE_FROM_KING / 2, 0, (DISTANCE_FROM_KING / 2) * -1),
getEntity().getLocation().add((DISTANCE_FROM_KING / 2) * -1, 0, (DISTANCE_FROM_KING / 2) * -1)
};
if (creature.getHealth() <= FINAL_SKELETON_HEALTH)
{
WRAITH_AMOUNT_THIS_USE = (int)(WRAITH_AMOUNT * FINAL_WRAITH_MULTIPLIER);
}
else
{
WRAITH_AMOUNT_THIS_USE = WRAITH_AMOUNT;
}
}
private String getNumberString(Integer number)
{
String num = number.toString();
char last = num.toCharArray()[num.length() - 1];
String formatted = number.toString();
String ending = "";
if (last == '1' && !num.equals("1" + last))
{
ending = "st";
}
if (last == '2' && !num.equals("1" + last))
{
ending = "nd";
}
if (last == '3' && !num.equals("1" + last))
{
ending = "rd";
}
if (ending.equals(""))
{
ending = "th";
}
return formatted + ending;
}
private void spawnWraith(Location loc, int number)
{
WraithCreature wraith = (WraithCreature)((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.WRAITH, loc);
_wraiths.put(wraith, getNumberString(number));
}
@Override
public int getCooldown()
{
return 0;
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return _wraiths.isEmpty() && _ticks > 40;
}
@Override
public void setFinished()
{
for (WraithCreature wraith : _wraiths.keySet())
{
wraith.remove();
}
_wraiths.clear();
_ticks = 41;
}
@Override
public void tick()
{
if (_ticks == 0)
{
if (WRAITH_AMOUNT > 0)
{
for (int i = 0; i < WRAITH_AMOUNT_THIS_USE; i++)
{
int spawnIndex = i;
if (spawnIndex >= _spawns.length)
{
spawnIndex = spawnIndex % _spawns.length;
}
spawnWraith(_spawns[spawnIndex], i + 1);
}
for (Player player : UtilPlayer.getInRadius(getEntity().getLocation(), 80).keySet())
{
if (player.isDead() || !player.isValid() || !player.isOnline())
{
continue;
}
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
player.sendMessage(F.main(getBoss().getEvent().getName(), "You must slay all " + WRAITH_AMOUNT_THIS_USE + " wraiths before continuing to fight the " + getBoss().getEvent().getName() + "!"));
}
}
}
_ticks++;
if (!hasFinished())
{
int ticks = 10;
int hticks = 40;
boolean up = getEntity().getTicksLived() % (hticks * 2) < hticks;
int tick = getEntity().getTicksLived() % ticks;
double htick = getEntity().getTicksLived() % hticks;
int splits = 4;
Location loc = getEntity().getLocation().add(0, 2, 0);
for (double d = tick * (Math.PI * 2 / splits) / ticks; d < Math.PI * 2; d += Math.PI * 2 / splits)
{
Vector v = new Vector(Math.sin(d), 0, Math.cos(d));
v.normalize().multiply(Math.max(0.2, Math.sin((htick / hticks) * Math.PI) * 1.0));
v.setY((htick / hticks) * -2);
if (up) v.setY(-2 + 2 * (htick / hticks));
Location lloc = loc.clone().add(v);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, lloc, null, 0f, 2, ViewDist.MAX);
}
}
}
@EventHandler
public void onWraithDie(EventCreatureDeathEvent event)
{
if (event.getCreature() instanceof WraithCreature)
{
String number = _wraiths.remove(event.getCreature());
if (number != null)
{
double remainPercent = new BigDecimal(_wraiths.size()).divide(new BigDecimal(WRAITH_AMOUNT_THIS_USE)).doubleValue();
ChatColor remainColor = ChatColor.GREEN;
if (remainPercent < .66)
{
remainColor = ChatColor.YELLOW;
}
if (remainPercent < .33)
{
remainColor = ChatColor.RED;
}
Bukkit.broadcastMessage(F.main(getBoss().getEvent().getName(), "A wraith has been slain!" + " (" + remainColor + _wraiths.size() + "/" + WRAITH_AMOUNT_THIS_USE + C.cGray + ") wraiths remaining!"));
System.out.println(F.main(getBoss().getEvent().getName(), "The " + number + " wraith has been slain!"));
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().equals(getBoss().getEntity()))
{
if (!hasFinished())
{
event.SetCancelled("Wraiths Alive");
}
}
}
}

View File

@ -0,0 +1,36 @@
package mineplex.minecraft.game.core.boss.skeletonking.minion;
import java.lang.reflect.InvocationTargetException;
import org.bukkit.Location;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.WorldEvent;
public enum MinionType
{
WARRIOR(UndeadWarriorCreature.class),
ARCHER(UndeadArcherCreature.class),
WRAITH(WraithCreature.class);
private Class<? extends EventCreature> _code;
private MinionType(Class<? extends EventCreature> code)
{
_code = code;
}
public EventCreature getNewInstance(WorldEvent event, Location spawn)
{
try
{
return _code.getConstructor(WorldEvent.class, Location.class).newInstance(event, spawn);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,233 @@
package mineplex.minecraft.game.core.boss.skeletonking.minion;
import mineplex.core.common.util.UtilMath;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.WorldEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class UndeadArcherCreature extends EventCreature<Skeleton>
{
private static final int BARBED_LEVEL = 1;
private static final int LIFETIME = -1;
public UndeadArcherCreature(WorldEvent event, Location spawnLocation)
{
super(event, spawnLocation, "Undead Archer", true, 25, Skeleton.class);
spawnEntity();
}
@Override
protected void spawnCustom()
{
Skeleton entity = getEntity();
EntityEquipment eq = entity.getEquipment();
eq.setItemInHand(new ItemStack(Material.BOW));
eq.setHelmet(new ItemStack(Material.CHAINMAIL_HELMET));
eq.setChestplate(new ItemStack(Material.CHAINMAIL_CHESTPLATE));
eq.setLeggings(new ItemStack(Material.CHAINMAIL_LEGGINGS));
eq.setBoots(new ItemStack(Material.CHAINMAIL_BOOTS));
eq.setItemInHandDropChance(0.f);
eq.setHelmetDropChance(0.f);
eq.setChestplateDropChance(0.f);
eq.setLeggingsDropChance(0.f);
eq.setBootsDropChance(0.f);
entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0));
}
@Override
public void dieCustom()
{
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
return;
}
if (Math.random() > 0.97)
{
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_HELMET));
}
if (Math.random() > 0.97)
{
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_CHESTPLATE));
}
if (Math.random() > 0.97)
{
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_LEGGINGS));
}
if (Math.random() > 0.97)
{
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_BOOTS));
}
if (Math.random() > 0.90)
{
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.BOW));
}
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.ARROW, UtilMath.r(12) + 1));
}
@EventHandler(priority = EventPriority.MONITOR)
public void bowShoot(EntityShootBowEvent event)
{
if (BARBED_LEVEL == 0)
{
return;
}
if (!(event.getProjectile() instanceof Arrow))
{
return;
}
if (event.getEntity().getEntityId() != getEntity().getEntityId())
{
return;
}
event.getProjectile().setMetadata("BARBED_ARROW", new FixedMetadataValue(getEvent().getPlugin(), 2));
}
@EventHandler(priority = EventPriority.HIGH)
public void damage(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
if (event.GetCause() != DamageCause.PROJECTILE)
{
return;
}
Projectile projectile = event.GetProjectile();
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(true);
if (projectile == null)
{
return;
}
if (!projectile.hasMetadata("BARBED_ARROW"))
{
return;
}
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (!getEntity().equals(damager))
{
return;
}
// Level
if (BARBED_LEVEL == 0)
{
return;
}
Player damageePlayer = event.GetDamageePlayer();
if (damageePlayer != null)
{
damageePlayer.setSprinting(false);
}
// Damage
event.AddMod(damager.getName(), "Barbed Arrows", projectile.getMetadata("BARBED_ARROW").get(0).asDouble(), false);
// Condition
getEvent().getCondition().Factory().Slow("Barbed Arrows", damagee, damager, (projectile.getVelocity().length() / 3) * (2 + BARBED_LEVEL), 0, false, true, true, true);
}
@EventHandler
public void clean(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
{
return;
}
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
remove();
return;
}
}
@EventHandler
public void onTarget(EntityTargetLivingEntityEvent event)
{
if (getEntity().equals(event.getEntity()))
{
if (!(event.getTarget() instanceof Player))
{
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void protect(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damagee))
{
if (!(damager instanceof Player))
{
event.SetCancelled("Allied Attacker");
}
}
}
}

View File

@ -0,0 +1,186 @@
package mineplex.minecraft.game.core.boss.skeletonking.minion;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.WorldEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class UndeadWarriorCreature extends EventCreature<Zombie>
{
private static final int LIFETIME = -1;
public UndeadWarriorCreature(WorldEvent event, Location spawnLocation)
{
super(event, spawnLocation, "Undead Warrior", true, 30, Zombie.class);
spawnEntity();
}
@Override
protected void spawnCustom()
{
Zombie entity = getEntity();
EntityEquipment eq = entity.getEquipment();
eq.setHelmet(new ItemStack(Material.IRON_HELMET));
eq.setChestplate(new ItemStack(Material.IRON_CHESTPLATE));
eq.setLeggings(new ItemStack(Material.IRON_LEGGINGS));
eq.setBoots(new ItemStack(Material.IRON_BOOTS));
eq.setItemInHand(new ItemStack(Material.STONE_SWORD));
eq.setHelmetDropChance(0.f);
eq.setChestplateDropChance(0.f);
eq.setLeggingsDropChance(0.f);
eq.setBootsDropChance(0.f);
eq.setItemInHandDropChance(0.f);
entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0));
}
@Override
public void dieCustom()
{
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
return;
}
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_HELMET));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_CHESTPLATE));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_LEGGINGS));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_BOOTS));
}
@EventHandler
public void leap(UpdateEvent event)
{
if (getEntity() == null)
return;
if (event.getType() != UpdateType.FAST)
return;
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
remove();
return;
}
if (Math.random() < 0.9)
return;
Zombie zombie = getEntity();
if (zombie.getTarget() == null)
return;
double dist = UtilMath.offset(zombie.getTarget(), zombie);
if (dist <= 3 || dist > 16)
return;
double power = 0.8 + (1.2 * ((dist-3)/13d));
//Leap
UtilAction.velocity(zombie, UtilAlg.getTrajectory(zombie, zombie.getTarget()),
power, false, 0, 0.2, 1, true);
//Effect
zombie.getWorld().playSound(zombie.getLocation(), Sound.ZOMBIE_HURT, 1f, 2f);
}
@EventHandler
public void onTarget(EntityTargetLivingEntityEvent event)
{
if (getEntity().equals(event.getEntity()))
{
if (!(event.getTarget() instanceof Player))
{
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void attack(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(false);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damager))
{
if (damagee instanceof Player)
{
((Player)damagee).setFoodLevel(((Player)damagee).getFoodLevel() - 1);
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void protect(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damagee))
{
if (!(damager instanceof Player))
{
event.SetCancelled("Allied Attacker");
}
}
}
}

View File

@ -0,0 +1,190 @@
package mineplex.minecraft.game.core.boss.skeletonking.minion;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.WorldEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class WraithCreature extends EventCreature<Zombie>
{
private static final int LIFETIME = -1;
public WraithCreature(WorldEvent event, Location spawnLocation)
{
super(event, spawnLocation, "Wraith", true, 200, Zombie.class);
spawnEntity();
}
@Override
protected void spawnCustom()
{
Zombie entity = getEntity();
EntityEquipment eq = entity.getEquipment();
eq.setHelmet(new ItemStack(Material.SKULL_ITEM, 1, (short)1));
eq.setChestplate(new ItemBuilder(Material.LEATHER_CHESTPLATE).setColor(Color.BLACK).build());
eq.setLeggings(new ItemBuilder(Material.LEATHER_LEGGINGS).setColor(Color.BLACK).build());
eq.setBoots(new ItemBuilder(Material.LEATHER_BOOTS).setColor(Color.BLACK).build());
eq.setItemInHand(new ItemStack(Material.IRON_SWORD));
eq.setHelmetDropChance(0.f);
eq.setChestplateDropChance(0.f);
eq.setLeggingsDropChance(0.f);
eq.setBootsDropChance(0.f);
eq.setItemInHandDropChance(0.f);
entity.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 999999, 0));
entity.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 999999, 0));
entity.addPotionEffect(new PotionEffect(PotionEffectType.WATER_BREATHING, 999999, 0));
entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 1));
}
@Override
public void dieCustom()
{
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
return;
}
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_HELMET));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_CHESTPLATE));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_LEGGINGS));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_BOOTS));
}
@EventHandler(priority = EventPriority.HIGH)
public void damage(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(false);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damager))
{
event.AddMult(damager.getName(), "Mystical Darkness", 2, false);
}
}
@EventHandler
public void blink(UpdateEvent event)
{
if (getEntity() == null)
return;
if (event.getType() != UpdateType.FAST)
return;
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
remove();
return;
}
if (Math.random() < 0.6)
return;
Zombie zombie = getEntity();
if (zombie.getTarget() == null)
return;
double dist = UtilMath.offset(zombie.getTarget(), zombie);
if (dist <= 10 || dist > 25)
return;
Location teleport = zombie.getTarget().getLocation().add(Math.random() + 1, 0, Math.random() + 1);
if (UtilMath.offset(getSpawnLocation(), teleport) > 30)
{
return;
}
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, zombie.getLocation(), 0, 0, 0, 0, 5, ViewDist.MAX);
zombie.getWorld().playSound(zombie.getLocation(), Sound.ENDERMAN_TELEPORT, 1f, 2f);
zombie.teleport(teleport);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, zombie.getLocation(), 0, 0, 0, 0, 5, ViewDist.MAX);
zombie.getWorld().playSound(zombie.getLocation(), Sound.ENDERMAN_TELEPORT, 1f, 2f);
}
@EventHandler
public void onTarget(EntityTargetLivingEntityEvent event)
{
if (getEntity().equals(event.getEntity()))
{
if (!(event.getTarget() instanceof Player))
{
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void protect(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damagee))
{
if (!(damager instanceof Player))
{
event.SetCancelled("Allied Attacker");
}
}
}
}

View File

@ -0,0 +1,109 @@
package mineplex.minecraft.game.core.boss.slimeking;
import java.io.File;
import java.io.IOException;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.common.block.schematic.Schematic;
import mineplex.core.common.block.schematic.UtilSchematic;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.EventMap;
import mineplex.minecraft.game.core.boss.EventState;
import mineplex.minecraft.game.core.boss.WorldEvent;
import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.util.Vector;
public class SlimeBoss extends WorldEvent
{
private static final int MAX_SIZE = 16;
private static final int MIN_SIZE = 2;
public SlimeBoss(DisguiseManager disguiseManager, DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, ProjectileManager projectileManager, Location cornerLocation)
{
super(disguiseManager, projectileManager, damageManager, blockRestore, conditionManager, "Slime King", cornerLocation, "schematic/ClansSlime.schematic");
}
@Override
protected void customStart()
{
Bukkit.broadcastMessage("Custom Start");
spawnSlime(getCenterLocation(), MAX_SIZE);
setState(EventState.LIVE);
announceStart();
}
/**
* Check if this slime boss has been defeated
*/
private void checkDeath()
{
if (getCreatures().size() == 0)
{
setState(EventState.COMPLETE);
Bukkit.broadcastMessage("FINISHED!");
}
}
@Override
public void removeCreature(EventCreature creature)
{
super.removeCreature(creature);
if (creature instanceof SlimeCreature)
{
splitSlime(((SlimeCreature) creature));
checkDeath();
}
}
private int getSplitSize(int slimeSize)
{
return slimeSize / 2;
}
private int getSplitCount(int slimeSize)
{
return slimeSize <= 8 ? 4 : 2;
}
private double getMaxSlimeHealth(int slimeSize)
{
return slimeSize * 20;
}
private int getEnrageTicks(int slimeSize)
{
return 40 * slimeSize;
}
public void splitSlime(SlimeCreature slime)
{
int splitCount = getSplitCount(slime.getSize());
int splitSize = getSplitSize(slime.getSize());
if (splitSize >= MIN_SIZE)
{
for (int i = 0; i < splitCount; i++)
{
Location location = slime.getEntity().getLocation();
SlimeCreature creature = spawnSlime(location, splitSize);
creature.getEntity().setVelocity(new Vector(Math.random(), 0.1, Math.random()).multiply(0.5));
}
}
}
private SlimeCreature spawnSlime(Location location, int size)
{
SlimeCreature slimeCreature = new SlimeCreature(this, location, size, getMaxSlimeHealth(size), getEnrageTicks(size));
registerCreature(slimeCreature);
return slimeCreature;
}
}

View File

@ -0,0 +1,69 @@
package mineplex.minecraft.game.core.boss.slimeking.ability;
import java.util.HashMap;
import java.util.Map;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilPlayer;
import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.util.Vector;
public class AbsorbAbility extends SlimeAbility
{
private int _ticksPerPulse;
private int _pulseMax;
private int _pulseCount;
private int _maxDistance;
public AbsorbAbility(SlimeCreature slime)
{
super(slime);
_ticksPerPulse = 20;
_pulseMax = 10;
_pulseCount = 0;
_maxDistance = 20;
}
@Override
public void tickCustom()
{
if (getTicks() % _ticksPerPulse == 0)
{
pulse();
_pulseCount++;
if (_pulseCount >= _pulseMax)
{
setIdle(true);
}
}
}
private void pulse()
{
HashMap<Player, Double> playerMap = UtilPlayer.getInRadius(getSlime().getEntity().getLocation(), _maxDistance);
for (Map.Entry<Player, Double> entry : playerMap.entrySet())
{
Player player = entry.getKey();
double distance = entry.getValue();
Vector dir = UtilAlg.getTrajectory2d(player, getSlime().getEntity());
dir.multiply(0.4);
dir.setY(0.1);
player.setVelocity(dir);
getSlime().getEvent().getDamageManager().NewDamageEvent(player, getSlime().getEntity(), null,
EntityDamageEvent.DamageCause.MAGIC, getDamage(distance), false, false, false, getSlime().getEvent().getName(), "Absorb");
}
}
private double getDamage(double distance)
{
double mult = _maxDistance - distance;
return mult * 0.25;
}
}

View File

@ -0,0 +1,63 @@
package mineplex.minecraft.game.core.boss.slimeking.ability;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilPlayer;
import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
public class LeapAbility extends SlimeAbility
{
private Player _target;
private int _jumpTick;
public LeapAbility(SlimeCreature slime)
{
super(slime);
_target = UtilPlayer.getRandomTarget(slime.getEntity().getLocation(), 30);
_jumpTick = 20;
// Only attempt to find a target once for this ability!
if (_target == null)
{
setIdle(true);
}
}
@Override
public void tickCustom()
{
if (_target != null)
{
if (getTicks() == _jumpTick)
{
// Jump
Vector dir = UtilAlg.getTrajectory2d(getSlime().getEntity(), _target);
UtilAction.velocity(getSlime().getEntity(), dir, 2, false, 0, 0.5, 0.5, true);
}
else if (getTicks() > _jumpTick)
{
if (getSlime().getEntity().isOnGround())
{
setIdle(true);
}
else if (getSlime().isEnraged())
{
World world = getSlime().getEntity().getWorld();
Block block = world.getHighestBlockAt(getSlime().getEntity().getLocation()).getRelative(BlockFace.UP);
if (block.getType() == Material.AIR)
{
block.setType(Material.FIRE);
}
}
}
}
}
}

View File

@ -0,0 +1,163 @@
package mineplex.minecraft.game.core.boss.slimeking.ability;
import java.util.Iterator;
import java.util.LinkedList;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.projectile.IThrown;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.projectile.ProjectileUser;
import mineplex.core.updater.UpdateType;
import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Slime;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.util.Vector;
public class RocketAbility extends SlimeAbility implements IThrown
{
private int _rocketCount;
private int _rocketsFired;
private int _rocketsHit;
private LinkedList<ShotData> _shots;
public RocketAbility(SlimeCreature slime)
{
this(slime, 5);
}
public RocketAbility(SlimeCreature slime, int rocketCount)
{
super(slime);
_rocketCount = rocketCount;
_rocketsFired = 0;
_rocketsHit = 0;
_shots = new LinkedList<ShotData>();
}
@Override
public void tickCustom()
{
if (_rocketsHit >= _rocketCount)
{
// We're done here!
setIdle(true);
return;
}
if (_rocketsFired < _rocketCount && getTicks() % 20 == 0)
{
Player target = UtilPlayer.getRandomTarget(getSlime().getEntity().getLocation(), 20);
if (target == null && getTicks() > 20 * (_rocketCount + 10))
{
// Give up on firing more rockets
_rocketCount = _rocketsFired;
}
if (target != null) fireRocket(target);
}
tickRockets();
}
private void tickRockets()
{
Iterator<ShotData> it = _shots.iterator();
while (it.hasNext())
{
ShotData next = it.next();
if (next.getEntity().isDead())
{
it.remove();
}
else
{
Vector v = UtilAlg.getTrajectory(next.getEntity(), next.getTarget());
next.getEntity().setVelocity(v.multiply(new Vector(0.3, 0.1, 0.3)));
}
}
}
private void fireRocket(Player target)
{
Location loc = getSlime().getEntity().getEyeLocation();
loc.add(UtilAlg.getTrajectory2d(loc, target.getLocation()).multiply(2));
Slime projectile = loc.getWorld().spawn(loc, Slime.class);
projectile.setSize(1);
_shots.add(new ShotData(projectile, target));
ProjectileManager pm = getSlime().getProjectileManager();
pm.AddThrow(projectile, getSlime().getEntity(), this, -1, true, true, true, false, null, 0, 0, UtilParticle.ParticleType.SLIME, UpdateType.FASTEST, 1F);
// Bukkit.broadcastMessage("Shot Slime at target " + target);
_rocketsFired++;
}
@Override
public void Collide(LivingEntity target, Block block, ProjectileUser data)
{
// Bukkit.broadcastMessage("COLLIDE " + target);
UtilParticle.PlayParticle(UtilParticle.ParticleType.LARGE_EXPLODE, data.getThrown().getLocation(), 0, 0, 0, 0, 1, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
target.getLocation().getWorld().playSound(target.getLocation(), Sound.SPLASH, 1, 2);
getSlime().getEvent().getDamageManager().NewDamageEvent(target, getSlime().getEntity(), null,
EntityDamageEvent.DamageCause.PROJECTILE, 3 + getSlime().getSize() * 3, true, true, false,
getSlime().getName(), "Slime Rocket");
data.getThrown().remove();
_rocketsHit++;
}
@Override
public void Idle(ProjectileUser data)
{
data.getThrown().remove();
_rocketsHit++;
}
@Override
public void Expire(ProjectileUser data)
{
data.getThrown().remove();
_rocketsHit++;
}
@Override
public void ChunkUnload(ProjectileUser data)
{
data.getThrown().remove();
}
private static class ShotData
{
private LivingEntity _entity;
private LivingEntity _target;
public ShotData(LivingEntity entity, LivingEntity target)
{
_entity = entity;
_target = target;
}
public LivingEntity getEntity()
{
return _entity;
}
public LivingEntity getTarget()
{
return _target;
}
}
}

View File

@ -0,0 +1,158 @@
package mineplex.minecraft.game.core.boss.slimeking.ability;
import java.util.LinkedList;
import java.util.List;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
public class SlamAbility extends SlimeAbility
{
private int _findAttempts;
private boolean _hasTarget;
private int _foundTicks;
private Player _target;
private Location _targetLocation;
// Timings
private final int _lockTick;
private final int _jumpTick;
private final int _diveTick;
public SlamAbility(SlimeCreature slime)
{
this(slime, 40, 60, 80);
}
public SlamAbility(SlimeCreature slime, int lockTick, int jumpTick, int diveTick)
{
super(slime);
_hasTarget = false;
_findAttempts = 0;
_foundTicks = 0;
assert (jumpTick > lockTick && diveTick > jumpTick);
_lockTick = lockTick;
_jumpTick = jumpTick;
_diveTick = diveTick;
}
@Override
public void tickCustom()
{
if (!_hasTarget)
{
if (getTicks() % 20 == 0)
{
searchForTarget();
}
}
else
{
int ticks = getTicks() - _foundTicks;
if (ticks < _lockTick)
{
// Follow Target
displayTarget(_target.getLocation());
}
else if (ticks == _lockTick)
{
// Lock on
Bukkit.broadcastMessage("Target Locked");
_targetLocation = _target.getLocation();
}
else if (ticks < _jumpTick)
{
// Target still locked
displayTarget(_targetLocation);
}
else if (ticks == _jumpTick)
{
// Target starts jump
Bukkit.broadcastMessage("Start Jump");
}
else if (ticks < _diveTick)
{
// Target in air
displayTarget(_targetLocation);
Vector direction = UtilAlg.getTrajectory2d(getSlime().getEntity().getLocation(), _targetLocation);
direction.multiply(0.4);
direction.setY(2 * (1 - ((getTicks() - 100.0) / 60.0)));
getSlime().getEntity().setVelocity(direction);
}
else if (ticks == _diveTick)
{
displayTarget(_targetLocation);
// Time to go down!
getSlime().getEntity().setVelocity(new Vector(0, -3, 0));
getSlime().getEntity().setFallDistance(0);
}
else if (ticks > _diveTick)
{
displayTarget(_targetLocation);
// Check for hitting ground
if (getSlime().getEntity().isOnGround())
{
// We're done here!
setIdle(true);
damageArea(getSlime().getEntity().getLocation());
}
}
}
}
private void damageArea(Location location)
{
// TODO Deal more damage based on how close you are to the slime?
List<Player> nearPlayers = UtilPlayer.getNearby(location, 4);
for (Player player : nearPlayers)
{
player.damage(4);
player.setVelocity(UtilAlg.getTrajectory2d(location, player.getLocation()).setY(0.2));
}
UtilParticle.PlayParticle(UtilParticle.ParticleType.LAVA, location, 2, 0.5F, 2, 0, 100, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
location.getWorld().playSound(location, Sound.ANVIL_LAND, 10, 0.5F);
}
private void displayTarget(Location location)
{
UtilParticle.PlayParticle(UtilParticle.ParticleType.LAVA, location, 0, 0, 0, 0, 1, UtilParticle.ViewDist.NORMAL, UtilServer.getPlayers());
}
private void searchForTarget()
{
if (_findAttempts >= 10)
{
// Just give up! THERE'S NO HOPE
setIdle(true);
return;
}
Player target = UtilPlayer.getRandomTarget(getSlime().getEntity().getLocation(), 15);
if (target != null)
{
_target = target;
_hasTarget = true;
_foundTicks = getTicks();
Bukkit.broadcastMessage("Target placed on " + _target);
}
_findAttempts++;
}
}

View File

@ -0,0 +1,56 @@
package mineplex.minecraft.game.core.boss.slimeking.ability;
import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature;
public abstract class SlimeAbility
{
private SlimeCreature _slime;
private boolean _idle;
private int _ticks;
private int _idleTicks;
public SlimeAbility(SlimeCreature slime)
{
_slime = slime;
}
public final void tick()
{
if (isIdle())
{
_idleTicks++;
}
else
{
_ticks++;
tickCustom();
}
}
public int getTicks()
{
return _ticks;
}
public int getIdleTicks()
{
return _idleTicks;
}
public boolean isIdle()
{
return _idle;
}
public SlimeCreature getSlime()
{
return _slime;
}
public abstract void tickCustom();
protected void setIdle(boolean idle)
{
_idle = idle;
}
}

View File

@ -0,0 +1,135 @@
package mineplex.minecraft.game.core.boss.slimeking.creature;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.slimeking.SlimeBoss;
import mineplex.minecraft.game.core.boss.slimeking.ability.AbsorbAbility;
import mineplex.minecraft.game.core.boss.slimeking.ability.LeapAbility;
import mineplex.minecraft.game.core.boss.slimeking.ability.RocketAbility;
import mineplex.minecraft.game.core.boss.slimeking.ability.SlamAbility;
import mineplex.minecraft.game.core.boss.slimeking.ability.SlimeAbility;
import org.bukkit.Location;
import org.bukkit.entity.MagmaCube;
import org.bukkit.entity.Slime;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.SlimeSplitEvent;
public class SlimeCreature extends EventCreature<Slime>
{
private SlimeBoss _boss;
private SlimeAbility _currentAbility;
private boolean _enraged;
// Storing size here incase one of the slime states decide to change the slime size
private int _size;
private int _ticksLived;
private int _enrageTicks;
public SlimeCreature(SlimeBoss boss, Location location, int size, double maxHealth, int enrageTicks)
{
super(boss, location, "Slime King", true, maxHealth, Slime.class);
_boss = boss;
_enraged = false;
_size = size;
_ticksLived = 0;
_enrageTicks = enrageTicks;
spawnEntity();
}
@Override
protected void spawnCustom()
{
getEntity().setSize(_size);
}
public ProjectileManager getProjectileManager()
{
return _boss.getProjectileManager();
}
@EventHandler
public void abilityTick(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
_ticksLived++;
if (_currentAbility == null || (_currentAbility.isIdle() && _currentAbility.getIdleTicks() > 80))
{
double rand = Math.random();
if (rand <= 0.25)
{
_currentAbility = new SlamAbility(this);
}
else if (rand <= 0.50 && getSize() >= 8)
{
_currentAbility = new AbsorbAbility(this);
}
else if (rand <= 0.75 && getSize() >= 4)
{
_currentAbility = new RocketAbility(this);
}
else
{
_currentAbility = new LeapAbility(this);
}
}
// Disable Enrage
// if (!_enraged && _ticksLived >= _enrageTicks)
// {
// setEnraged(true);
// }
_currentAbility.tick();
}
@EventHandler
public void onSplit(SlimeSplitEvent event)
{
if (event.getEntity().equals(getEntity()))
event.setCancelled(true);
}
// @EventHandler
// public void target(EntityTargetEvent event)
// {
// if (event.getEntity().equals(getEntity()))
// {
// Bukkit.broadcastMessage("Target Event");
// Player player = UtilPlayer.getRandomTarget(getEntity().getLocation(), 30);
// Bukkit.broadcastMessage("Targetting: " + player);
// event.setTarget(player);
// }
// }
public void setEnraged(boolean enraged)
{
if (enraged != _enraged)
{
_enraged = enraged;
setEntityClass(_enraged ? MagmaCube.class : Slime.class);
spawnEntity();
}
}
public boolean isEnraged()
{
return _enraged;
}
public int getSize()
{
return _size;
}
@Override
public void dieCustom()
{
}
}

View File

@ -0,0 +1,64 @@
package mineplex.minecraft.game.core.boss.snake;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.EventState;
import mineplex.minecraft.game.core.boss.WorldEvent;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
public class SnakeBoss extends WorldEvent
{
public SnakeBoss(DisguiseManager disguiseManager, ProjectileManager projectileManager, DamageManager damageManager,
BlockRestore blockRestore, ConditionManager conditionManager, Location cornerLocation)
{
super(disguiseManager, projectileManager, damageManager, blockRestore, conditionManager, "Snaaaake", cornerLocation,
"schematic/Golem.schematic");
}
@Override
protected void customStart()
{
Bukkit.broadcastMessage("Custom Start");
spawn(getCenterLocation());
setState(EventState.LIVE);
announceStart();
}
/**
* Check if this slime boss has been defeated
*/
private void checkDeath()
{
if (getCreatures().size() == 0)
{
setState(EventState.COMPLETE);
Bukkit.broadcastMessage("FINISHED!");
}
}
@Override
public void removeCreature(EventCreature creature)
{
super.removeCreature(creature);
if (creature instanceof SnakeCreature)
{
checkDeath();
}
}
private SnakeCreature spawn(Location location)
{
SnakeCreature slimeCreature = new SnakeCreature(this, location);
registerCreature(slimeCreature);
return slimeCreature;
}
}

View File

@ -0,0 +1,231 @@
package mineplex.minecraft.game.core.boss.snake;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.entity.Silverfish;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.boss.EventCreature;
import mineplex.minecraft.game.core.boss.WorldEvent;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
public class SnakeCreature extends EventCreature<Silverfish>
{
private ArrayList<SnakeSegment> _segments = new ArrayList<SnakeSegment>();
private double _seperator = 0.5;
private ArrayList<Player> _canSee = new ArrayList<Player>();
private Location _waypoint;
private Vector _velocity = new Vector(0, 0, 0);
private boolean _enabled = true;
private double _speed = 0.75;
private int _ticks = 0;
public SnakeCreature(WorldEvent event, Location spawnLocation)
{
super(event, spawnLocation, "Serpent Lord", false, 2000, Silverfish.class);
}
@Override
protected void spawnCustom()
{
getEntity().addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 10000, 0));
UtilEnt.vegetate(getEntity());
UtilEnt.ghost(getEntity(), true, false);
Vector dir = new Vector(UtilMath.rr(1, true), 0, UtilMath.rr(1, true)).normalize().multiply(_seperator);
getNewWaypoint();
for (int i = 0; i < getHealth() / 50; i++)
{
SnakeSegment tail = new SnakeSegment(getSpawnLocation().toVector().subtract(dir.clone().multiply(-i)),
new ItemStack(i == 0 ? Material.DROPPER : Material.BEDROCK));
_segments.add(tail);
}
}
private void getNewWaypoint()
{
// Bukkit.broadcastMessage("NEW WAYPOINT!");
_waypoint = getSpawnLocation().clone().add(Math.random() * 60 - 30, Math.random() * 24 - 16, Math.random() * 60 - 30);
}
@EventHandler
public void onSecond(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
Location loc = _segments.get(0).getLocation().toLocation(getSpawnLocation().getWorld());
ArrayList<Player> canSee = new ArrayList<Player>();
for (Player player : loc.getWorld().getPlayers())
{
if (player.getLocation().distance(loc) < 120)
{
canSee.add(player);
}
}
Iterator<Player> iter2 = _canSee.iterator();
int[] ids = new int[_segments.size()];
for (int a = 0; a < _segments.size(); a++)
{
ids[a] = _segments.get(a).getId();
}
Packet destroy = new PacketPlayOutEntityDestroy(ids);
while (iter2.hasNext())
{
Player player = iter2.next();
if (!canSee.contains(player))
{
iter2.remove();
UtilPlayer.sendPacket(player, destroy);
}
}
for (Player player : canSee)
{
if (!_canSee.contains(player))
{
_canSee.add(player);
for (SnakeSegment tail : _segments)
{
UtilPlayer.sendPacket(player, tail.getSpawn());
}
}
}
}
@Override
public void dieCustom()
{
int[] ids = new int[_segments.size()];
for (int a = 0; a < _segments.size(); a++)
{
ids[a] = _segments.get(a).getId();
}
Packet destroy = new PacketPlayOutEntityDestroy(ids);
for (Player player : _canSee)
{
UtilPlayer.sendPacket(player, destroy);
}
}
@EventHandler
public void onTickMove(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK || !_enabled)
{
return;
}
ArrayList<Packet> packets = new ArrayList<Packet>();
for (int i = 0 ; i < _segments.size() ; i++)
{
SnakeSegment seg = _segments.get(i);
Vector vec = seg.getLocation().clone();
if (i == 0)
{
Vector direction = UtilAlg.getTrajectory(vec, _waypoint.toVector());
_velocity.add(direction.multiply(0.1 * _speed));
if (_velocity.length() > _speed)
_velocity.normalize().multiply(_speed);
// Bukkit.broadcastMessage("Loc: " + UtilWorld.vecToStrClean(moveTo));
vec.add(_velocity);
// Bukkit.broadcastMessage("Loc: " + UtilWorld.vecToStrClean(vec));
if (UtilMath.offset(vec, _waypoint.toVector()) < 6)
{
getNewWaypoint();
}
}
else
{
Vector infront = _segments.get(i - 1).getLocation();
Vector behind = _segments.get(i - 1).getLastLocation();
vec = infront.clone().add(UtilAlg.getTrajectory(infront, behind).multiply(_seperator));
}
Block block = _waypoint.getWorld().getBlockAt(seg.getLocation().getBlockX(),seg.getLocation().getBlockY(),seg.getLocation().getBlockZ()).getRelative(BlockFace.UP);
if (block.getType() != Material.AIR && UtilBlock.isVisible(block))
{
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
}
packets.addAll(Arrays.asList(seg.moveEntity(vec)));
}
Packet[] packetArray = packets.toArray(new Packet[0]);
for (Player player : _canSee)
{
UtilPlayer.sendPacket(player, packetArray);
}
}
@EventHandler
public void command(PlayerCommandPreprocessEvent event)
{
if (event.getMessage().contains("speed"))
{
try
{
_speed = Double.parseDouble(event.getMessage().split(" ")[1]);
Bukkit.broadcastMessage("SPEED " + _speed);
}
catch (Exception e)
{
}
}
}
}

View File

@ -0,0 +1,178 @@
package mineplex.minecraft.game.core.boss.snake;
import java.util.UUID;
import net.minecraft.server.v1_8_R3.DataWatcher;
import net.minecraft.server.v1_8_R3.EntityArmorStand;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
import net.minecraft.server.v1_8_R3.Vector3f;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
public class SnakeSegment
{
private int _entityId = UtilEnt.getNewEntityId();
private Vector _entityLocation;
private Vector _entityLastLocation;
private ItemStack _item;
private Vector _prevDir = new Vector();
public SnakeSegment(Vector location, ItemStack item)
{
_entityLocation = location.clone();
_item = item;
}
public int getId()
{
return _entityId;
}
public Packet[] moveEntity(Vector newLocation)
{
_entityLastLocation = _entityLocation.clone();
Vector toMove = newLocation.clone().subtract(_entityLocation);
Packet packet1;
int x = (int) Math.floor(32 * toMove.getX());
int y = (int) Math.floor(32 * toMove.getY());
int z = (int) Math.floor(32 * toMove.getZ());
if (x >= -128 && x <= 127 && y >= -128 && y <= 127 && z >= -128 && z <= 127)
{
_entityLocation.add(new Vector(x / 32D, y / 32D, z / 32D));
PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook relMove = new PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook();
relMove.a = getId();
relMove.b = (byte) x;
relMove.c = (byte) y;
relMove.d = (byte) z;
// relMove.e = (byte) (int) (UtilAlg.GetYaw(toMove) * 256.0F / 360.0F);
// relMove.f = (byte) (int) (UtilAlg.GetPitch(toMove) * 256.0F / 360.0F);
packet1 = relMove;
}
else
{
_entityLocation = newLocation.clone();
x = (int) Math.floor(_entityLocation.getX() * 32);
y = (int) Math.floor(_entityLocation.getY() * 32);
z = (int) Math.floor(_entityLocation.getZ() * 32);
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport();
teleportPacket.a = getId();
teleportPacket.b = x;
teleportPacket.c = y;
teleportPacket.d = z;
// teleportPacket.e = (byte) (int) (UtilAlg.GetYaw(toMove) * 256.0F / 360.0F);
// teleportPacket.f = (byte) (int) (UtilAlg.GetPitch(toMove) * 256.0F / 360.0F);
packet1 = teleportPacket;
}
Vector vec = new Vector(UtilAlg.GetPitch(toMove), UtilAlg.GetYaw(toMove), 0);
if (vec.equals(_prevDir))
{
return new Packet[]
{
packet1
};
}
_prevDir = vec;
DataWatcher watcher = new DataWatcher(null);
watcher.a(0, (byte) 32, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0);
watcher.a(1, 0, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0);
watcher.a(10, (byte) 0, EntityArmorStand.META_ARMOR_OPTION, (byte) 0);
watcher.a(11, new Vector3f(0, 0, 0), EntityArmorStand.META_HEAD_POSE,
new Vector3f((float) vec.getX(), (float) vec.getY(), (float) vec.getZ()));
watcher.a(12, new Vector3f(0, 0, 0), EntityArmorStand.META_BODY_POSE, new Vector3f(0, 0, 0));
watcher.a(13, new Vector3f(0, 0, 0), EntityArmorStand.META_LEFT_ARM_POSE, new Vector3f(0, 0, 0));
watcher.a(14, new Vector3f(0, 0, 0), EntityArmorStand.META_RIGHT_ARM_POSE, new Vector3f(0, 0, 0));
watcher.a(15, new Vector3f(0, 0, 0), EntityArmorStand.META_LEFT_LEG_POSE, new Vector3f(0, 0, 0));
watcher.a(16, new Vector3f(0, 0, 0), EntityArmorStand.META_RIGHT_LEG_POSE, new Vector3f(0, 0, 0));
PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(getId(), watcher, true);
return new Packet[]
{
packet1, meta
};
}
public Vector getLocation()
{
return _entityLocation.clone();
}
public Vector getLastLocation()
{
return _entityLastLocation.clone();
}
public Packet[] getSpawn()
{
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving();
DataWatcher watcher = new DataWatcher(null);
watcher.a(1, 0, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0);
packet.a = getId();
packet.c = (int) Math.floor(_entityLocation.getX() * 32);
packet.d = (int) Math.floor(_entityLocation.getY() * 32);
packet.e = (int) Math.floor(_entityLocation.getZ() * 32);
packet.l = watcher;
packet.uuid = UUID.randomUUID();
if (_item != null)
{
watcher.a(0, (byte) 32, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 32);
watcher.a(10, (byte) 0, EntityArmorStand.META_ARMOR_OPTION, (byte) 0);
watcher.a(11, new Vector3f(0, 0, 0), EntityArmorStand.META_HEAD_POSE, new Vector3f(0, 0, 0));
watcher.a(12, new Vector3f(0, 0, 0), EntityArmorStand.META_BODY_POSE, new Vector3f(0, 0, 0));
watcher.a(13, new Vector3f(0, 0, 0), EntityArmorStand.META_LEFT_ARM_POSE, new Vector3f(0, 0, 0));
watcher.a(14, new Vector3f(0, 0, 0), EntityArmorStand.META_RIGHT_ARM_POSE, new Vector3f(0, 0, 0));
watcher.a(15, new Vector3f(0, 0, 0), EntityArmorStand.META_LEFT_LEG_POSE, new Vector3f(0, 0, 0));
watcher.a(16, new Vector3f(0, 0, 0), EntityArmorStand.META_RIGHT_LEG_POSE, new Vector3f(0, 0, 0));
packet.b = 30;
PacketPlayOutEntityEquipment packet2 = new PacketPlayOutEntityEquipment();
packet2.a = getId();
packet2.b = 4;
packet2.c = CraftItemStack.asNMSCopy(_item);
return new Packet[]
{
packet, packet2
};
}
else
{
watcher.a(0, (byte) 0, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0);
packet.b = EntityType.MAGMA_CUBE.getTypeId();
return new Packet[]
{
packet
};
}
}
}

View File

@ -0,0 +1,85 @@
package mineplex.minecraft.game.core.combat;
import java.util.LinkedList;
import java.util.Map;
import java.util.WeakHashMap;
import mineplex.core.common.util.UtilTime;
import org.bukkit.entity.LivingEntity;
public class ClientCombat
{
private final LinkedList<CombatLog> _kills = new LinkedList<>();
private final LinkedList<CombatLog> _assists = new LinkedList<>();
private final LinkedList<CombatLog> _deaths = new LinkedList<>();
private final Map<LivingEntity, Long> _lastHurt = new WeakHashMap<>();
private final Map<LivingEntity, Long> _lastHurtBy = new WeakHashMap<>();
private long _lastHurtByWorld = 0;
public LinkedList<CombatLog> GetKills()
{
return _kills;
}
public LinkedList<CombatLog> GetAssists()
{
return _assists;
}
public LinkedList<CombatLog> GetDeaths()
{
return _deaths;
}
public boolean CanBeHurtBy(LivingEntity damager)
{
if (damager == null)
{
if (UtilTime.elapsed(_lastHurtByWorld, 250))
{
_lastHurtByWorld = System.currentTimeMillis();
return true;
}
else
{
return false;
}
}
if (!_lastHurtBy.containsKey(damager))
{
_lastHurtBy.put(damager, System.currentTimeMillis());
return true;
}
if (System.currentTimeMillis() - _lastHurtBy.get(damager) > 400)
{
_lastHurtBy.put(damager, System.currentTimeMillis());
return true;
}
return false;
}
public boolean CanHurt(LivingEntity damagee)
{
if (damagee == null)
return true;
if (!_lastHurt.containsKey(damagee))
{
_lastHurt.put(damagee, System.currentTimeMillis());
return true;
}
if (System.currentTimeMillis() - _lastHurt.get(damagee) > 400)
{
_lastHurt.put(damagee, System.currentTimeMillis());
return true;
}
return false;
}
}

View File

@ -0,0 +1,162 @@
package mineplex.minecraft.game.core.combat;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.minecraft.game.core.damage.DamageChange;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
public class CombatComponent
{
private boolean _player = false;
private LinkedList<CombatDamage> _damage;
protected String EntityName;
protected long LastDamage = 0;
private UUID _entityUUID;
public CombatComponent(String name, LivingEntity ent)
{
EntityName = name;
if (ent != null)
{
_entityUUID = ent.getUniqueId();
if (ent instanceof Player)
{
_player = true;
}
}
}
public void AddDamage(String source, double dmg, List<DamageChange> mod, Map<String, Object> metadata)
{
if (source == null)
source = "-";
GetDamage().addFirst(new CombatDamage(source, dmg, mod, metadata));
LastDamage = System.currentTimeMillis();
}
public String GetName()
{
if (EntityName.equals("Null"))
return "World";
return EntityName;
}
public UUID getUniqueIdOfEntity()
{
if (_entityUUID == null)
{
return UUID.nameUUIDFromBytes(GetName().getBytes(StandardCharsets.UTF_8));
}
return _entityUUID;
}
public LinkedList<CombatDamage> GetDamage()
{
if (_damage == null)
_damage = new LinkedList<>();
return _damage;
}
public String GetReason()
{
if (_damage.isEmpty())
return null;
return _damage.get(0).GetName();
}
public long GetLastDamage()
{
return LastDamage;
}
public int GetTotalDamage()
{
int total = 0;
for (CombatDamage cur : GetDamage())
total += cur.GetDamage();
return total;
}
public String GetBestWeapon()
{
HashMap<String, Integer> cumulative = new HashMap<String, Integer>();
String weapon = null;
int best = 0;
for (CombatDamage cur : _damage)
{
int dmg = 0;
if (cumulative.containsKey(cur.GetName()))
dmg = cumulative.get(cur.GetName());
cumulative.put(cur.GetName(), dmg);
if (dmg >= best)
weapon = cur.GetName();
}
return weapon;
}
public String Display(long _deathTime)
{
// Time
String time = "";
if (_deathTime == 0)
time = UtilTime.convertString(System.currentTimeMillis()
- LastDamage, 1, TimeUnit.FIT)
+ " Ago";
else
time = UtilTime.convertString(_deathTime - LastDamage, 1,
TimeUnit.FIT) + " Prior";
return F.name(EntityName) + " ["
+ F.elem(GetTotalDamage() + "dmg") + "" + "] ["
+ F.elem(GetBestWeapon()) + "] [" + F.time(time) + "]";
}
public String Display(long _deathTime, CombatDamage damage)
{
// Time
String time = "";
if (_deathTime == 0)
time = UtilTime.convertString(System.currentTimeMillis()
- damage.GetTime(), 1, TimeUnit.FIT)
+ " Ago";
else
time = UtilTime.convertString(_deathTime - damage.GetTime(), 1,
TimeUnit.FIT) + " Prior";
//String
return F.name(EntityName) + " ["
+ F.elem(damage.GetDamage() + " dmg") + "" + "] ["
+ F.elem(damage.GetName()) + "] [" + F.time(time) + "]";
}
public boolean IsPlayer()
{
return _player;
}
public String GetLastDamageSource()
{
return _damage.getFirst().GetName();
}
}

View File

@ -0,0 +1,57 @@
package mineplex.minecraft.game.core.combat;
import java.util.List;
import java.util.Map;
import mineplex.minecraft.game.core.damage.DamageChange;
public class CombatDamage
{
private final String _name;
private final double _dmg;
private final long _time;
private final List<DamageChange> _mod;
private final Map<String, Object> _metadata;
CombatDamage(String name, double dmg, List<DamageChange> mod, Map<String, Object> metadata)
{
_name = name;
_dmg = dmg;
_time = System.currentTimeMillis();
_mod = mod;
_metadata = metadata;
}
public String GetName()
{
return _name;
}
public double GetDamage()
{
return _dmg;
}
public long GetTime()
{
return _time;
}
public List<DamageChange> getDamageMod()
{
return _mod;
}
/**
* Retrieves metadata that was associated with this damage via
* {@link mineplex.minecraft.game.core.damage.CustomDamageEvent#setMetadata(String, Object)}.
* <p/>
* There is no standardized metadata that should be expected. Metadata is meant to be used
* on a per-minigame basis to store additional information about the damage.
* @return a non-null map containing the metadata
*/
public Map<String, Object> getMetadata()
{
return _metadata;
}
}

View File

@ -0,0 +1,251 @@
package mineplex.minecraft.game.core.combat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilTime;
import mineplex.minecraft.game.core.damage.DamageChange;
public class CombatLog
{
private final LinkedList<CombatComponent> _damager = new LinkedList<>();
private final CombatComponent _player;
private final long _expireTime;
private long _deathTime = 0;
private CombatComponent _killer;
private int _assistants;
private String _killedColor = C.cYellow;
private String _killerColor = C.cYellow;
private CombatComponent LastDamager;
private long _lastDamaged;
private long _lastCombat;
private long _lastCombatEngaged;
public CombatLog(Player player, long expireTime)
{
_expireTime = expireTime;
_player = new CombatComponent(player.getName(), player);
_lastCombatEngaged = 0; // Just so taunts can be used before pvp
}
public LinkedList<CombatComponent> GetAttackers()
{
return _damager;
}
public CombatComponent GetPlayer()
{
return _player;
}
public void Attacked(String damagerName, double damage, LivingEntity damagerEnt, String attackName, List<DamageChange> mod)
{
Attacked(damagerName, damage, damagerEnt, attackName, mod, new HashMap<>());
}
public void Attacked(String damagerName, double damage, LivingEntity damagerEnt, String attackName, List<DamageChange> mod, Map<String, Object> metadata)
{
// Add Attacked
CombatComponent comp = GetEnemy(damagerName, damagerEnt);
comp.AddDamage(attackName, damage, mod, metadata);
// Set Last
LastDamager = comp;
_lastDamaged = System.currentTimeMillis();
}
public CombatComponent GetEnemy(String name, LivingEntity ent)
{
ExpireOld();
CombatComponent component = null;
for (CombatComponent cur : _damager)
{
if (cur.GetName().equals(name))
{
component = cur;
}
}
// Player has attacked in past
if (component != null)
{
_damager.remove(component);
_damager.addFirst(component);
return component;
}
component = new CombatComponent(name, ent);
_damager.addFirst(component);
return component;
}
public void ExpireOld()
{
int expireFrom = -1;
for (int i = 0; i < _damager.size(); i++)
{
if (UtilTime.elapsed(_damager.get(i).GetLastDamage(), _expireTime))
{
expireFrom = i;
break;
}
}
if (expireFrom != -1)
{
while (_damager.size() > expireFrom)
{
_damager.remove(expireFrom);
}
}
}
public LinkedList<String> Display()
{
LinkedList<String> out = new LinkedList<>();
for (int i = 0; i < 8; i++)
{
if (i < _damager.size())
{
out.add(F.desc("#" + (i + 1), _damager.get(i).Display(_deathTime)));
}
}
return out;
}
public LinkedList<String> DisplayAbsolute()
{
Map<Long, String> components = new HashMap<>();
for (CombatComponent cur : _damager)
{
for (CombatDamage dmg : cur.GetDamage())
{
components.put(dmg.GetTime(), cur.Display(_deathTime, dmg));
}
}
int id = components.size();
LinkedList<String> out = new LinkedList<>();
while (!components.isEmpty())
{
long bestTime = 0;
String bestString = null;
for (long time : components.keySet())
{
if (time > bestTime || bestString == null)
{
bestTime = time;
bestString = components.get(time);
}
}
components.remove(bestTime);
out.addFirst(F.desc("#" + id, bestString));
id--;
}
return out;
}
public CombatComponent GetKiller()
{
return _killer;
}
public void SetKiller(CombatComponent killer)
{
_killer = killer;
}
public int GetAssists()
{
return _assistants;
}
public void SetAssists(int assistants)
{
_assistants = assistants;
}
public CombatComponent GetLastDamager()
{
return LastDamager;
}
public long GetLastDamaged()
{
return _lastDamaged;
}
public long GetLastCombat()
{
return _lastCombat;
}
public long GetLastCombatEngaged()
{
return _lastCombatEngaged;
}
public void SetLastCombatEngaged(long time)
{
_lastCombatEngaged = time;
}
public void SetLastCombat(long time)
{
_lastCombat = time;
}
public long GetDeathTime()
{
return _deathTime;
}
public void SetDeathTime(long deathTime)
{
_deathTime = deathTime;
}
public String GetKilledColor()
{
return _killedColor;
}
public void SetKilledColor(String color)
{
_killedColor = color;
}
public String GetKillerColor()
{
return _killerColor;
}
public void SetKillerColor(String color)
{
_killerColor = color;
}
}

View File

@ -0,0 +1,563 @@
package mineplex.minecraft.game.core.combat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import net.minecraft.server.v1_8_R3.ItemStack;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import mineplex.core.MiniClientPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.Pair;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.incognito.events.IncognitoStatusChangeEvent;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.combat.event.CombatDeathEvent;
import mineplex.minecraft.game.core.combat.event.CombatQuitEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
@ReflectivelyCreateMiniPlugin
public class CombatManager extends MiniClientPlugin<ClientCombat>
{
public enum AttackReason
{
Attack,
CustomWeaponName,
DefaultWeaponName
}
private static final long EXPIRE_TIME = TimeUnit.SECONDS.toMillis(15);
private final Map<UUID, CombatLog> _active = new HashMap<>();
private final Set<UUID> _removeList = new HashSet<>();
private AttackReason _attackReason;
public CombatManager()
{
super("Death");
_attackReason = AttackReason.CustomWeaponName;
}
@Override
protected ClientCombat addPlayer(UUID uuid)
{
return new ClientCombat();
}
//This is a backup, for when CustomDamageEvent is disabled (manually)
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void AddAttack(EntityDamageEvent event)
{
if (event.getEntity() == null || !(event.getEntity() instanceof Player))
{
return;
}
Player damagee = (Player) event.getEntity();
LivingEntity damagerEnt = UtilEvent.GetDamagerEntity(event, true);
//Attacked by Entity
if (damagerEnt != null)
{
if (damagerEnt instanceof Player)
{
getLog((Player) damagerEnt).SetLastCombat(System.currentTimeMillis());
}
String cause;
switch (event.getCause())
{
case ENTITY_ATTACK:
cause = "Attack";
break;
case ENTITY_EXPLOSION:
cause = "Explosion";
break;
case MAGIC:
cause = "Thrown Potion";
break;
case PROJECTILE:
cause = "Ranged Weapon";
break;
case THORNS:
cause = "Thorns Enchantment";
break;
default:
cause = event.getCause() + "";
break;
}
if (UtilEvent.isBowDamage(event))
{
cause = "Bow";
}
if (damagerEnt instanceof Player)
{
if (event.getCause() == DamageCause.ENTITY_ATTACK)
{
Player player = (Player) damagerEnt;
if (player.getItemInHand() == null)
{
cause = "Fists";
}
else if (player.getItemInHand().getType() == Material.AIR)
{
cause = "Fists";
}
else
{
cause = ItemStackFactory.Instance.GetName(player.getItemInHand(), false);
}
}
}
getLog(damagee).Attacked(UtilEnt.getName(damagerEnt), event.getDamage(), damagerEnt, cause, null);
}
// Damager is WORLD
else
{
DamageCause cause = event.getCause();
Pair<String, String> source = getSourceAndReason(cause);
getLog(damagee).Attacked(source.getLeft(), event.getDamage(), null, source.getRight(), null);
}
}
public void AddAttack(CustomDamageEvent event)
{
// Not Player > No Log
if (event.GetDamageePlayer() == null)
{
return;
}
// Damager is ENTITY
if (event.GetDamagerEntity(true) != null)
{
String reason = event.GetReason();
if (reason == null)
{
if (event.GetDamagerPlayer(false) != null)
{
Player damager = event.GetDamagerPlayer(false);
reason = "Attack";
if (_attackReason == AttackReason.DefaultWeaponName)
{
reason = "Fists";
if (damager.getItemInHand() != null)
{
byte data = 0;
if (damager.getItemInHand().getData() != null)
{
data = damager.getItemInHand().getData().getData();
}
reason = ItemStackFactory.Instance.GetName(damager.getItemInHand().getType(), data, false);
}
}
else if (_attackReason == AttackReason.CustomWeaponName)
{
reason = "Fists";
if (damager.getItemInHand() != null)
{
ItemStack itemStack = CraftItemStack.asNMSCopy(damager
.getItemInHand());
if (itemStack != null)
{
reason = CraftItemStack.asNMSCopy(
damager.getItemInHand()).getName();
}
}
}
}
else if (event.GetProjectile() != null)
{
if (event.GetProjectile() instanceof Arrow)
{
reason = "Archery";
}
else if (event.GetProjectile() instanceof Fireball)
{
reason = "Fireball";
}
}
}
if (event.GetDamagerEntity(true) instanceof Player)
{
getLog(event.GetDamagerPlayer(true)).SetLastCombat(System.currentTimeMillis());
getLog(event.GetDamagerPlayer(true)).SetLastCombatEngaged(System.currentTimeMillis());
getLog(event.GetDamageePlayer()).SetLastCombatEngaged(System.currentTimeMillis());
}
getLog(event.GetDamageePlayer()).Attacked(UtilEnt.getName(event.GetDamagerEntity(true)), (int) event.GetDamage(), event.GetDamagerEntity(true), reason, event.GetDamageMod(), event.getMetadata());
}
// Damager is WORLD
else
{
DamageCause cause = event.GetCause();
Pair<String, String> source = getSourceAndReason(cause);
if (event.GetReason() != null)
{
source.setRight(event.GetReason());
}
getLog(event.GetDamageePlayer()).Attacked(source.getLeft(), (int) event.GetDamage(), null, source.getRight(), event.GetDamageMod(), event.getMetadata());
}
}
private Pair<String, String> getSourceAndReason(DamageCause cause)
{
String source = "?";
String reason = "-";
switch (cause)
{
case BLOCK_EXPLOSION:
source = "Explosion";
break;
case CONTACT:
source = "Cactus";
break;
case CUSTOM:
source = "Custom";
break;
case DROWNING:
source = "Water";
break;
case ENTITY_ATTACK:
source = "Entity";
reason = "Attack";
break;
case ENTITY_EXPLOSION:
source = "Explosion";
break;
case FALL:
source = "Fall";
break;
case FALLING_BLOCK:
source = "Falling Block";
break;
case FIRE:
source = "Fire";
break;
case FIRE_TICK:
source = "Fire";
break;
case LAVA:
source = "Lava";
break;
case LIGHTNING:
source = "Lightning";
break;
case MAGIC:
source = "Magic";
break;
case MELTING:
source = "Melting";
break;
case POISON:
source = "Poison";
break;
case PROJECTILE:
source = "Projectile";
break;
case STARVATION:
source = "Starvation";
break;
case SUFFOCATION:
source = "Suffocation";
break;
case SUICIDE:
source = "Suicide";
break;
case VOID:
source = "Void";
break;
case WITHER:
source = "Wither";
break;
}
return Pair.create(source, reason);
}
@EventHandler(priority = EventPriority.LOW)
public void playerQuit(PlayerQuitEvent event)
{
fakeDeath(event.getPlayer());
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void vanishStatus(IncognitoStatusChangeEvent event)
{
if (!event.getNewState())
{
return;
}
fakeDeath(event.getPlayer());
}
private void fakeDeath(Player player)
{
CombatLog log = _active.get(player.getUniqueId());
if (log == null)
{
return;
}
log.ExpireOld();
if (log.GetAttackers().isEmpty())
{
return;
}
CombatQuitEvent combatQuitEvent = new CombatQuitEvent(player);
// Cancelled by default
combatQuitEvent.setCancelled(true);
UtilServer.CallEvent(combatQuitEvent);
if (combatQuitEvent.isCancelled())
{
return;
}
playerDeath(new PlayerDeathEvent(player, null, 0, null));
}
@EventHandler(priority = EventPriority.LOW)
public void playerDeath(PlayerDeathEvent event)
{
event.setDeathMessage(null);
CombatLog log = _active.remove(event.getEntity().getUniqueId());
if (log == null)
{
return;
}
log.SetDeathTime(System.currentTimeMillis());
log.ExpireOld();
// Save Death
ClientCombat client = Get(event.getEntity());
client.GetDeaths().addFirst(log);
// Add Kill/Assist
int assists = 0;
for (int i = 0; i < log.GetAttackers().size(); i++)
{
CombatComponent attacker = log.GetAttackers().get(i);
if (!attacker.IsPlayer())
{
continue;
}
if (log.GetKiller() == null)
{
log.SetKiller(attacker);
ClientCombat killerClient = Get(attacker.getUniqueIdOfEntity());
if (killerClient != null)
{
killerClient.GetKills().addFirst(log);
}
}
else
{
assists++;
ClientCombat assistClient = Get(attacker.getUniqueIdOfEntity());
if (assistClient != null)
{
assistClient.GetAssists().addFirst(log);
}
}
}
log.SetAssists(assists);
// Event
CombatDeathEvent combatEvent = new CombatDeathEvent(event, client, log, "killed");
UtilServer.CallEvent(combatEvent);
DeathMessageType messageType = combatEvent.GetBroadcastType();
//Death Message
if (messageType == DeathMessageType.Detailed || messageType == DeathMessageType.Absolute)
{
// Killed
String killedColor = log.GetKilledColor();
String deadPlayer = killedColor + event.getEntity().getName();
String message;
// Killer
if (log.GetKiller() != null)
{
String killerColor = log.GetKillerColor();
String killPlayer = killerColor + log.GetKiller().GetName();
if (log.GetAssists() > 0)
{
killPlayer += " + " + log.GetAssists();
}
String weapon = (String) log.GetKiller().GetDamage().getFirst().getMetadata().get("customWeapon");
weapon = weapon == null ? log.GetKiller().GetLastDamageSource() : weapon;
message = F.main(getName(), deadPlayer + C.mBody + " " + combatEvent.getKilledWord() + " by " + killPlayer + C.mBody + " with " + F.item(weapon) + ".");
}
// No Killer
else
{
if (log.GetAttackers().isEmpty())
{
message = F.main(getName(), deadPlayer + C.mBody + " has died.");
}
else
{
if (log.GetLastDamager() != null && log.GetLastDamager().GetReason() != null && log.GetLastDamager().GetReason().length() > 1)
{
message = F.main(getName(), deadPlayer + C.mBody + " " + combatEvent.getKilledWord() + " by " + F.name(log.GetLastDamager().GetReason())) + C.mBody + ".";
}
else
{
message = F.main(getName(), deadPlayer + C.mBody + " " + combatEvent.getKilledWord() + " by " + F.name(log.GetAttackers().getFirst().GetName())) + C.mBody + ".";
}
}
}
String finalMessage = message + combatEvent.getSuffix();
// Tell all players simple info
combatEvent.getPlayersToInform().forEach(player -> player.sendMessage(finalMessage));
// Tell the player who died it all
event.getEntity().sendMessage(messageType == DeathMessageType.Absolute ? log.DisplayAbsolute().toArray(new String[0]) : log.Display().toArray(new String[0]));
}
else if (combatEvent.GetBroadcastType() == DeathMessageType.Simple)
{
//Simple
if (log.GetKiller() != null)
{
//Killer
String killerColor = log.GetKillerColor();
String killPlayer = killerColor + log.GetKiller().GetName();
// Killed
String killedColor = log.GetKilledColor();
String deadPlayer = killedColor + event.getEntity().getName();
if (log.GetAssists() > 0)
{
killPlayer += " + " + log.GetAssists();
}
String weapon = log.GetKiller().GetLastDamageSource();
Player killer = UtilPlayer.searchExact(log.GetKiller().GetName());
if (killer != null)
{
killer.sendMessage(F.main(getName(), "You " + combatEvent.getKilledWord() + " " + F.elem(deadPlayer) + " with " + F.item(weapon) + "." + combatEvent.getSuffix()));
}
event.getEntity().sendMessage(F.main(getName(), killPlayer + C.mBody + " " + combatEvent.getKilledWord() + " you with " + F.item(weapon) + "." + combatEvent.getSuffix()));
}
else
{
if (log.GetAttackers().isEmpty())
{
UtilPlayer.message(event.getEntity(), F.main(getName(), "You have died." + combatEvent.getSuffix()));
}
else
{
UtilPlayer.message(event.getEntity(), F.main(getName(), "You were " + combatEvent.getKilledWord() + " by " + F.name(log.GetAttackers().getFirst().GetName())) + C.mBody + "." + combatEvent.getSuffix());
}
}
}
}
public CombatLog getLog(Player player)
{
return _active.computeIfAbsent(player.getUniqueId(), k -> new CombatLog(player, EXPIRE_TIME));
}
@EventHandler(priority = EventPriority.HIGHEST)
public void ClearInactives(UpdateEvent event)
{
if (event.getType() == UpdateType.MIN_02)
{
// Remove already marked inactives if still offline
Iterator<UUID> removeIterator = _removeList.iterator();
while (removeIterator.hasNext())
{
UUID uuid = removeIterator.next();
Player player = Bukkit.getPlayer(uuid);
if (player == null)
_active.remove(uuid);
removeIterator.remove();
}
// Mark inactives for cleanup next go around
for (UUID player : _active.keySet())
{
if (Bukkit.getPlayer(player) == null)
_removeList.add(player);
}
}
}
public void setUseWeaponName(AttackReason var)
{
_attackReason = var;
}
}

View File

@ -0,0 +1,9 @@
package mineplex.minecraft.game.core.combat;
public enum DeathMessageType
{
Absolute,
Detailed,
Simple,
None
}

View File

@ -0,0 +1,96 @@
package mineplex.minecraft.game.core.combat.event;
import java.util.ArrayList;
import java.util.List;
import mineplex.minecraft.game.core.combat.ClientCombat;
import mineplex.minecraft.game.core.combat.CombatLog;
import mineplex.minecraft.game.core.combat.DeathMessageType;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.PlayerDeathEvent;
public class CombatDeathEvent extends Event
{
private static final HandlerList HANDLER_LIST = new HandlerList();
private final PlayerDeathEvent _event;
private final ClientCombat _clientCombat;
private final CombatLog _log;
private final List<Player> _playersToInform;
private DeathMessageType _messageType = DeathMessageType.Detailed;
private String _killedWord, _suffix;
public CombatDeathEvent(PlayerDeathEvent event, ClientCombat clientCombat, CombatLog log, String killedWord)
{
_event = event;
_clientCombat = clientCombat;
_log = log;
_killedWord = killedWord;
_suffix = "";
_playersToInform = new ArrayList<>(event.getEntity().getWorld().getPlayers());
}
public HandlerList getHandlers()
{
return HANDLER_LIST;
}
public static HandlerList getHandlerList()
{
return HANDLER_LIST;
}
public ClientCombat GetClientCombat()
{
return _clientCombat;
}
public CombatLog GetLog()
{
return _log;
}
public PlayerDeathEvent GetEvent()
{
return _event;
}
public List<Player> getPlayersToInform()
{
return _playersToInform;
}
public void SetBroadcastType(DeathMessageType value)
{
_messageType = value;
}
public DeathMessageType GetBroadcastType()
{
return _messageType;
}
public String getKilledWord()
{
return _killedWord;
}
public void setKilledWord(String killedWord)
{
_killedWord = killedWord;
}
public void setSuffix(String suffix)
{
_suffix = suffix;
}
public String getSuffix()
{
return _suffix;
}
}

View File

@ -0,0 +1,42 @@
package mineplex.minecraft.game.core.combat.event;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class CombatQuitEvent extends PlayerEvent implements Cancellable
{
private static final HandlerList HANDLER_LIST = new HandlerList();
public static HandlerList getHandlerList()
{
return HANDLER_LIST;
}
private boolean _cancelled;
public CombatQuitEvent(Player who)
{
super(who);
}
@Override
public void setCancelled(boolean cancelled)
{
_cancelled = cancelled;
}
@Override
public boolean isCancelled()
{
return _cancelled;
}
@Override
public HandlerList getHandlers()
{
return HANDLER_LIST;
}
}

View File

@ -0,0 +1,133 @@
package mineplex.minecraft.game.core.combat.itemstack;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.minecraft.game.core.combat.CombatComponent;
import mineplex.minecraft.game.core.combat.event.CombatDeathEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.inventory.ItemStack;
public class Stats implements Listener
{
@EventHandler(priority = EventPriority.HIGHEST)
public void StatsKill(CombatDeathEvent event)
{
if (event.GetLog().GetAttackers().isEmpty())
return;
CombatComponent kill = event.GetLog().GetAttackers().getFirst();
if (!kill.IsPlayer()) return;
Player killer = UtilPlayer.searchExact(kill.GetName());
if (killer == null) return;
if (killer.isBlocking())
return;
ItemStack item = killer.getItemInHand();
if (item == null)
return;
if (item.getMaxStackSize() > 1)
return;
int kills = 1 + ItemStackFactory.Instance.GetLoreVar(item, "Player Kills", 0);
ItemStackFactory.Instance.SetLoreVar(item, "Player Kills", "" + kills);
}
@EventHandler(priority = EventPriority.MONITOR)
public void StatsArmor(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() == DamageCause.SUICIDE)
return;
Player damagee = event.GetDamageePlayer();
if (damagee == null) return;
ItemStackFactory.Instance.StatsArmorRename(damagee.getInventory().getHelmet(), (int)event.GetDamage());
ItemStackFactory.Instance.StatsArmorRename(damagee.getInventory().getChestplate(), (int)event.GetDamage());
ItemStackFactory.Instance.StatsArmorRename(damagee.getInventory().getLeggings(), (int)event.GetDamage());
ItemStackFactory.Instance.StatsArmorRename(damagee.getInventory().getBoots(), (int)event.GetDamage());
}
@EventHandler(priority = EventPriority.HIGHEST)
public void StatsDamage(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
Player damager = event.GetDamagerPlayer(true);
if (damager == null)
return;
if (damager.isBlocking())
return;
if (event.GetCause() == DamageCause.FIRE_TICK)
return;
ItemStack item = damager.getItemInHand();
if (item == null)
return;
if (item.getMaxStackSize() > 1)
return;
int damage = (int)event.GetDamage() + ItemStackFactory.Instance.GetLoreVar(item, "Damage Dealt", 0);
ItemStackFactory.Instance.SetLoreVar(item, "Damage Dealt", "" + damage);
if (damage >= 10000)
item.addEnchantment(Enchantment.DURABILITY, 1);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void StatsBowHit(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
Player damager = event.GetDamagerPlayer(true);
if (damager == null) return;
Projectile proj = event.GetProjectile();
if (proj == null) return;
ItemStack item = damager.getItemInHand();
if (item == null)
return;
if (item.getType() != Material.BOW)
return;
int hits = 1 + ItemStackFactory.Instance.GetLoreVar(item, "Arrows Hit", 0);
ItemStackFactory.Instance.SetLoreVar(item, "Arrows Hit", "" + hits);
int shots = ItemStackFactory.Instance.GetLoreVar(item, "Arrows Shot", 0);
double acc = UtilMath.trim(1, ((double)hits/(double)shots)*100);
ItemStackFactory.Instance.SetLoreVar(item, "Accuracy", acc + "%");
}
}

View File

@ -0,0 +1,351 @@
package mineplex.minecraft.game.core.condition;
import net.minecraft.server.v1_8_R3.MobEffect;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.events.AddConditionEvent;
public class Condition
{
public enum ConditionType
{
CLOAK,
UNTRUE_CLOAK,
SHOCK,
POISON_SHOCK,
SILENCE,
BURNING,
FALLING,
LIGHTNING,
INVULNERABLE,
EXPLOSION,
FIRE_ITEM_IMMUNITY,
ARCADE_HUNGER_DISABLE,
CUSTOM,
ABSORBTION,
BLINDNESS,
CONFUSION,
DAMAGE_RESISTANCE,
FAST_DIGGING,
FIRE_RESISTANCE,
HARM,
HEAL,
HEALTH_BOOST,
HUNGER,
INCREASE_DAMAGE,
INVISIBILITY,
JUMP,
NIGHT_VISION,
POISON,
REGENERATION,
SLOW,
SLOW_DIGGING,
SPEED,
WATER_BREATHING,
WEAKNESS,
WITHER;
}
protected ConditionManager Manager;
protected long _time;
protected String _reason;
protected String _informOn;
protected String _informOff;
protected LivingEntity _ent;
protected LivingEntity _source;
protected ConditionType _type;
protected int _mult;
protected int _ticks;
protected int _ticksTotal;
protected boolean _ambient;
protected Material _indicatorType;
protected byte _indicatorData;
protected boolean _add = false;
protected boolean _live = false;
protected boolean _cancelPotion;
protected boolean _showIndicator = true;
public Condition(ConditionManager manager, String reason, LivingEntity ent, LivingEntity source,
ConditionType type, int mult, int ticks, boolean add, Material visualType, byte visualData, boolean showIndicator, boolean ambient)
{
Manager = manager;
_time = System.currentTimeMillis();
_reason = reason;
_ent = ent;
_source = source;
_type = type;
_mult = mult;
_ticks = ticks;
_ticksTotal = ticks;
_ambient = ambient;
_indicatorType = visualType;
_indicatorData = visualData;
_showIndicator = showIndicator;
_add = add;
//Live if NOT Additive
_live = !add;
}
public Condition(ConditionManager manager, String reason, LivingEntity ent, LivingEntity source,
ConditionType type, int mult, int ticks, boolean add, Material visualType, byte visualData, boolean showIndicator, boolean ambient, boolean cancelPotion)
{
Manager = manager;
_time = System.currentTimeMillis();
_reason = reason;
_ent = ent;
_source = source;
_type = type;
_mult = mult;
_ticks = ticks;
_ticksTotal = ticks;
_ambient = ambient;
_indicatorType = visualType;
_indicatorData = visualData;
_showIndicator = showIndicator;
_cancelPotion = cancelPotion;
_add = add;
//Live if NOT Additive
_live = !add;
}
public Condition(ConditionManager manager, AddConditionEvent event)
{
this(manager, event.getReason(), event.getEnt(), event.getSource(), ConditionType.valueOf(event.getType().name()),
event.getMult(), event.getTicks(), event.isAdd(), event.getIndicatorType(), event.getIndicatorData(),
event.isShowIndicator(), event.isAmbient(), event.isCancelPotion());
}
public boolean Tick()
{
if (_live && _ticks > 0)
_ticks--;
return IsExpired();
}
public void OnConditionAdd()
{
}
public void Apply()
{
_live = true;
Add();
}
public void Add()
{
if (_cancelPotion)
{
return;
}
try
{
PotionEffectType type = PotionEffectType.getByName(_type.toString());
boolean remove = false;
for (PotionEffect effect : _ent.getActivePotionEffects())
{
if (effect.getType() == type && effect.getAmplifier() != _mult)
remove = true;
}
// Remove
if (remove)
_ent.removePotionEffect(type);
//Add
PotionEffect effect = new PotionEffect(type, _ticks, _mult, _ambient, _showIndicator);
if (_ticks == -1)
_ent.addPotionEffect(new PotionEffect(type, 72000, _mult, _ambient, _showIndicator), true);
else
((CraftLivingEntity) _ent).getHandle().addEffect(new MobEffect(effect.getType().getId(), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), _showIndicator));
}
catch (Exception e)
{
}
}
public void Remove()
{
PotionEffectType type = PotionEffectType.getByName(_type.toString());
if (type != null)
{
_ent.removePotionEffect(type);
}
}
public Material GetIndicatorMaterial()
{
return _indicatorType;
}
public byte GetIndicatorData()
{
return _indicatorData;
}
public LivingEntity GetEnt()
{
return _ent;
}
public LivingEntity GetSource()
{
return _source;
}
public boolean IsAdd()
{
return _add;
}
public ConditionType GetType()
{
return _type;
}
public int GetMult()
{
return _mult;
}
public void SetLive(boolean live)
{
_live = live;
}
public int GetTicks()
{
return _ticks;
}
public int GetTicksTotal()
{
return _ticksTotal;
}
public String GetReason()
{
return _reason;
}
public long GetTime()
{
return _time;
}
public void Expire()
{
_ticks = 0;
Remove();
}
public void Restart()
{
_ticks = _ticksTotal;
}
public boolean IsBetterOrEqual(Condition other, boolean additive)
{
if (this.GetMult() > other.GetMult())
return true;
if (this.GetMult() < other.GetMult())
return false;
if (additive)
return true;
if (this.GetTicks() >= other.GetTicks())
return true;
return false;
}
public boolean IsVisible()
{
return _showIndicator;
}
public boolean IsExpired()
{
if (_ticks == -1)
return false;
return _ticks <= 0;
}
public boolean needsForceRemove()
{
return false;
}
public ConditionManager GetManager()
{
return Manager;
}
public String GetInformOn()
{
return _informOn;
}
public String GetInformOff()
{
return _informOff;
}
public void ModifyTicks(int amount)
{
_ticks += amount;
_ticksTotal += amount;
}
public void ModifyMult(int i)
{
_mult = Math.max(0, _mult + i);
}
@Override
public String toString()
{
return getClass().getSimpleName() + "[ent=" + _ent + "]";
}
}

View File

@ -0,0 +1,22 @@
package mineplex.minecraft.game.core.condition;
public class ConditionActive
{
private Condition _condition;
public ConditionActive(Condition condition)
{
SetCondition(condition);
}
public Condition GetCondition()
{
return _condition;
}
public void SetCondition(Condition newCon)
{
_condition = newCon;
newCon.Apply();
}
}

View File

@ -0,0 +1,237 @@
package mineplex.minecraft.game.core.condition;
import java.util.ArrayList;
import java.util.HashMap;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import org.bukkit.ChatColor;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class ConditionApplicator
{
//Types
private HashMap<String, PotionEffectType> _effectMap;
public ConditionApplicator()
{
_effectMap = new HashMap<String, PotionEffectType>();
_effectMap.put("Blindness", PotionEffectType.BLINDNESS);
_effectMap.put("Confusion", PotionEffectType.CONFUSION);
_effectMap.put("DamageResist", PotionEffectType.DAMAGE_RESISTANCE);
_effectMap.put("FastDig", PotionEffectType.FAST_DIGGING);
_effectMap.put("FireResist", PotionEffectType.FIRE_RESISTANCE);
_effectMap.put("Harm", PotionEffectType.HARM);
_effectMap.put("Heal", PotionEffectType.HEAL);
_effectMap.put("Hunger", PotionEffectType.HUNGER);
_effectMap.put("Strength", PotionEffectType.INCREASE_DAMAGE);
_effectMap.put("Jump", PotionEffectType.JUMP);
_effectMap.put("Poison", PotionEffectType.POISON);
_effectMap.put("Regeneration", PotionEffectType.REGENERATION);
_effectMap.put("Slow", PotionEffectType.SLOW);
_effectMap.put("SlowDig", PotionEffectType.SLOW_DIGGING);
_effectMap.put("Speed", PotionEffectType.SPEED);
_effectMap.put("Breathing", PotionEffectType.WATER_BREATHING);
_effectMap.put("Weakness", PotionEffectType.WEAKNESS);
_effectMap.put("Invisibility", PotionEffectType.INVISIBILITY);
_effectMap.put("NightVision", PotionEffectType.NIGHT_VISION);
}
public void clearEffects(Player player)
{
for (PotionEffectType cur : _effectMap.values())
player.removePotionEffect(cur);
}
public void listEffect(Player caller)
{
caller.sendMessage(ChatColor.RED + "[C] " + ChatColor.YELLOW + "Listing Potion Effects;");
caller.sendMessage(ChatColor.DARK_GREEN + "Health Effects: " + ChatColor.AQUA +
"Harm, Heal, Poison, Regeneration, Hunger");
caller.sendMessage(ChatColor.DARK_GREEN + "Damage Effects: " + ChatColor.AQUA +
"Strength, Weakness, DamageResist, FireResist");
caller.sendMessage(ChatColor.DARK_GREEN + "Movement Effects: " + ChatColor.AQUA +
"Slow, Speed, Jump, FireResist");
caller.sendMessage(ChatColor.DARK_GREEN + "Vision Effects: " + ChatColor.AQUA +
"Blindness, Confusion, NightVision");
caller.sendMessage(ChatColor.DARK_GREEN + "Misc Effects: " + ChatColor.AQUA +
"FastDig, SlowDig, Breathing, Invisibility");
}
public HashMap<String, PotionEffectType> readEffect(Player caller, String eString)
{
HashMap<String, PotionEffectType> eList = new HashMap<String, PotionEffectType>();
ArrayList<String> errorList = new ArrayList<String>();
String[] eToken = eString.split(",");
for (String eCur : eToken)
{
for (String cur : _effectMap.keySet())
{
if (cur.equalsIgnoreCase(eCur))
{
eList.put(cur, _effectMap.get(cur));
}
else
{
errorList.add(eCur);
}
}
}
if (!errorList.isEmpty())
{
String out = ChatColor.RED + "[C] " + ChatColor.YELLOW + "Invalid Effects:" + ChatColor.AQUA;
for (String cur : errorList)
{
out += " '" + cur + "'";
}
caller.sendMessage(out);
}
return eList;
}
public void doEffect(Player caller, String name, HashMap<String, PotionEffectType> eMap, String durationString, String strengthString, boolean extend)
{
//All Players
ArrayList<Player> targetList = new ArrayList<Player>();
ArrayList<String> invalidList = new ArrayList<String>();
if (name.equalsIgnoreCase("all"))
{
for (Player cur : UtilServer.getPlayers())
targetList.add(cur);
}
//Listed Players
else
{
String[] playerTokens = name.split(",");
for (String curName : playerTokens)
{
Player target = (Player)UtilPlayer.matchOnline(null, name, false);
if (target != null)
{
targetList.add(target);
}
else
{
invalidList.add(curName);
}
}
}
if (!invalidList.isEmpty())
{
String out = ChatColor.RED + "[C] " + ChatColor.YELLOW + "Invalid Targets:";
for (String cur : invalidList)
{
out += " '" + cur + "'";
}
caller.sendMessage(out);
}
if (targetList.isEmpty())
{
caller.sendMessage(ChatColor.RED + "[C] " + ChatColor.YELLOW + "No Valid Targets Listed.");
return;
}
//Parse Effects
if (eMap.isEmpty())
{
caller.sendMessage(ChatColor.RED + "[C] " + ChatColor.YELLOW + "No Valid Effects Listed.");
return;
}
//Parse Duration and Strength
double duration;
int strength;
try
{
duration = Double.parseDouble(durationString);
strength = Integer.parseInt(strengthString);
if (duration <= 0)
{
caller.sendMessage(ChatColor.RED + "[C] " + ChatColor.YELLOW + "Invalid Effect Duration.");
return;
}
if (strength < 0)
{
caller.sendMessage(ChatColor.RED + "[C] " + ChatColor.YELLOW + "Invalid Effect Strength.");
return;
}
}
catch (Exception ex)
{
caller.sendMessage(ChatColor.RED + "[C] " + ChatColor.YELLOW + "Invalid Effect Duration/Strength.");
return;
}
caller.sendMessage(ChatColor.RED + "[C] " + ChatColor.YELLOW + "Applying Effect(s) to Target(s).");
for (Player curPlayer : targetList)
{
for (String cur : _effectMap.keySet())
{
addEffect(curPlayer, cur, _effectMap.get(cur), duration, strength, true, extend);
}
}
}
public boolean addEffect(LivingEntity target, String effectName, PotionEffectType type, double duration, int strength, boolean inform, boolean extend)
{
//Duration of Previous
int oldDur = 0;
if (target.hasPotionEffect(type))
{
for (PotionEffect cur : target.getActivePotionEffects())
{
if (cur.getType().equals(type))
{
if (cur.getAmplifier() > strength)
return true;
else if (extend)
oldDur += cur.getDuration();
}
}
//Remove Old
target.removePotionEffect(type);
}
//Create & Add
target.addPotionEffect(new PotionEffect(type, (int)(duration*20) + oldDur, strength), true);
if (inform && target instanceof Player)
{
Player tPlayer = (Player)target;
UtilPlayer.message(tPlayer, F.main("Condition", "You received " +
F.elem(effectName + " " + (strength+1)) +
" for " + F.time(""+UtilMath.trim(1, duration * 20d)) + " Seconds."));
}
return false;
}
}

View File

@ -0,0 +1,514 @@
package mineplex.minecraft.game.core.condition;
import java.util.Iterator;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity.PacketPlayOutEntityLook;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity.PacketPlayOutRelEntityMove;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.EntityEffect;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.Managers;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilTime;
import mineplex.core.packethandler.IPacketHandler;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.packethandler.PacketInfo;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.visibility.VisibilityManager;
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class ConditionEffect implements Listener, IPacketHandler
{
protected final ConditionManager Manager;
public ConditionEffect(ConditionManager manager)
{
Manager = manager;
Manager.getPlugin().getServer().getPluginManager().registerEvents(this, Manager.getPlugin());
Managers.require(PacketHandler.class).addPacketHandler(this,
PacketPlayOutEntityLook.class,
PacketPlayOutRelEntityMove.class,
PacketPlayOutRelEntityMoveLook.class,
PacketPlayOutEntityTeleport.class
);
}
@EventHandler(priority = EventPriority.LOW)
public void Invulnerable(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
LivingEntity ent = event.GetDamageeEntity();
if (ent == null) return;
if (!Manager.IsInvulnerable(ent))
return;
//Set Damage
event.SetCancelled("Invulnerable");
}
@EventHandler(priority = EventPriority.LOW)
public void Cloak(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.ENTITY_ATTACK)
return;
LivingEntity ent = event.GetDamageeEntity();
if (ent == null) return;
if (!Manager.IsCloaked(ent) && !Manager.isUntrueCloaked(ent))
return;
//Set Damage
event.SetCancelled("Cloak");
}
@EventHandler
public void Cloak(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
return;
VisibilityManager vm = Managers.require(VisibilityManager.class);
for (LivingEntity ent : Manager.GetActiveConditions().keySet())
{
if (!(ent instanceof Player))
continue;
Player player = (Player)ent;
//Hide
if (Manager.IsCloaked(ent))
{
for (Player other : Bukkit.getOnlinePlayers())
{
vm.hidePlayer(other, player, "Cloaking");
}
}
//Show
else
{
for (Player other : Bukkit.getOnlinePlayers())
{
vm.showPlayer(other, player, "Cloaking");
}
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void Cloak(EntityTargetEvent event)
{
if (!(event.getTarget() instanceof Player))
return;
if (!Manager.HasCondition((LivingEntity)event.getTarget(), ConditionType.CLOAK, null))
return;
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.HIGH)
public void Protection(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.ENTITY_ATTACK)
return;
Player damagee = event.GetDamageePlayer();
if (damagee == null) return;
if (!damagee.hasPotionEffect(PotionEffectType.DAMAGE_RESISTANCE))
return;
mineplex.minecraft.game.core.condition.Condition cond = Manager.GetActiveCondition(damagee, ConditionType.DAMAGE_RESISTANCE);
if (cond == null) return;
event.AddMod(UtilEnt.getName(cond.GetSource()), cond.GetReason(), -1 * (cond.GetMult()+1), false);
}
@EventHandler(priority = EventPriority.HIGH)
public void VulnerabilityDamagee(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.ENTITY_ATTACK)
return;
Player damagee = event.GetDamageePlayer();
if (damagee == null) return;
if (!damagee.hasPotionEffect(PotionEffectType.WITHER))
return;
mineplex.minecraft.game.core.condition.Condition cond = Manager.GetActiveCondition(damagee, ConditionType.WITHER);
if (cond == null) return;
event.AddMod(UtilEnt.getName(cond.GetSource()), cond.GetReason(), cond.GetMult()+1, false);
}
@EventHandler(priority = EventPriority.HIGH)
public void VulnerabilityDamager(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.ENTITY_ATTACK)
return;
Player damager = event.GetDamagerPlayer(false);
if (damager == null) return;
if (!damager.hasPotionEffect(PotionEffectType.WITHER))
return;
mineplex.minecraft.game.core.condition.Condition cond = Manager.GetActiveCondition(damager, ConditionType.WITHER);
if (cond == null) return;
event.AddMod(UtilEnt.getName(cond.GetSource()), cond.GetReason(), -1 * (cond.GetMult()+1), false);
}
@EventHandler
public void VulnerabilityEffect(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER)
return;
for (LivingEntity ent : Manager.GetActiveConditions().keySet())
{
if (ent.isDead())
continue;
if (!ent.hasPotionEffect(PotionEffectType.WITHER))
continue;
if (Manager.HasCondition(ent, ConditionType.CLOAK, null))
continue;
ent.getWorld().playEffect(ent.getLocation(), Effect.SMOKE, 1);
ent.getWorld().playEffect(ent.getLocation(), Effect.SMOKE, 3);
ent.getWorld().playEffect(ent.getLocation(), Effect.SMOKE, 5);
ent.getWorld().playEffect(ent.getLocation(), Effect.SMOKE, 7);
}
}
@EventHandler(priority = EventPriority.LOW)
public void VulnerabilityWitherCancel(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() == DamageCause.WITHER)
event.SetCancelled("Vulnerability Wither");
}
@EventHandler(priority = EventPriority.HIGH)
public void Strength(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.ENTITY_ATTACK)
return;
Player damager = event.GetDamagerPlayer(true);
if (damager == null) return;
if (!damager.hasPotionEffect(PotionEffectType.INCREASE_DAMAGE))
return;
mineplex.minecraft.game.core.condition.Condition cond = Manager.GetActiveCondition(damager, ConditionType.INCREASE_DAMAGE);
if (cond == null) return;
event.AddMod(damager.getName(), cond.GetReason(), cond.GetMult() + 1, true);
}
@EventHandler
public void Shock(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
for (LivingEntity ent : Manager.GetActiveConditions().keySet())
for (ConditionActive ind : Manager.GetActiveConditions().get(ent))
if (ind.GetCondition().GetType() == ConditionType.SHOCK)
ent.playEffect(EntityEffect.HURT);
}
@EventHandler(priority = EventPriority.LOWEST)
public void Lightning(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.LIGHTNING)
return;
LivingEntity ent = event.GetDamageeEntity();
if (ent == null) return;
Condition condition = Manager.GetActiveCondition(ent, ConditionType.LIGHTNING);
if (condition == null) return;
if (event.GetDamageePlayer() != null)
{
if (!Recharge.Instance.use(event.GetDamageePlayer(), "Lightning by " + UtilEnt.getName(condition.GetSource()), 1000, false, false))
{
event.SetCancelled("Lightning Rate");
return;
}
}
//Damage
event.SetDamager(condition.GetSource());
event.AddMod(UtilEnt.getName(condition.GetSource()), condition.GetReason(), 0, true);
if (condition.GetMult() != 0)
event.AddMod("Lightning Modifier", UtilEnt.getName(condition.GetSource()), condition.GetMult(), false);
event.SetKnockback(false);
}
@EventHandler
public void Explosion(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.ENTITY_EXPLOSION && event.GetCause() != DamageCause.BLOCK_EXPLOSION)
return;
LivingEntity ent = event.GetDamageeEntity();
if (ent == null) return;
Condition condition = Manager.GetActiveCondition(ent, ConditionType.EXPLOSION);
if (condition == null) return;
//Damage
event.SetDamager(condition.GetSource());
event.AddMod("Negate", condition.GetReason(), -event.GetDamageInitial(), false);
event.AddMod(UtilEnt.getName(condition.GetSource()), condition.GetReason(), Math.min(event.GetDamageInitial(), condition.GetMult()), true);
event.SetKnockback(false);
}
@EventHandler
public void Fire(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.FIRE_TICK)
return;
LivingEntity ent = event.GetDamageeEntity();
if (ent == null) return;
//Limit
if (ent.getFireTicks() > 160)
ent.setFireTicks(160);
Condition condition = Manager.GetActiveCondition(ent, ConditionType.BURNING);
if (condition == null) return;
//Damage
event.SetDamager(condition.GetSource());
event.AddMod(UtilEnt.getName(condition.GetSource()), condition.GetReason(), 0, true);
event.SetIgnoreArmor(true);
event.SetKnockback(false);
}
@EventHandler
public void FireDouse(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER)
return;
for (LivingEntity ent : Manager.GetActiveConditions().keySet())
if (ent.getFireTicks() <= 0)
Manager.EndCondition(ent, ConditionType.BURNING, null);
}
@EventHandler
public void Poison(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.POISON)
return;
LivingEntity ent = event.GetDamageeEntity();
if (ent == null) return;
//Ignore Poison Shock
Condition poisonShock = Manager.GetActiveCondition(ent, ConditionType.POISON_SHOCK);
if (poisonShock != null)
{
event.SetCancelled("Poison Shock - Poison Cancel");
return;
}
Condition condition = Manager.GetActiveCondition(ent, ConditionType.POISON);
if (condition == null)
return;
//Damage
event.SetDamager(condition.GetSource());
event.AddMod(UtilEnt.getName(condition.GetSource()), condition.GetReason(), 0, true);
event.SetIgnoreArmor(true);
event.SetKnockback(false);
}
@EventHandler
public void PoisonShock(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
Iterator<LivingEntity> ents = Manager.GetActiveConditions().keySet().iterator();
while (ents.hasNext())
{
LivingEntity ent = ents.next();
Condition condition = Manager.GetActiveCondition(ent, ConditionType.POISON_SHOCK);
if (condition == null || condition.GetSource() == null)
continue;
try
{
Manager.getDamagerManager().NewDamageEvent(ent, condition.GetSource(), null,
DamageCause.CUSTOM, 0.1, false, true, false,
condition.GetSource() != null ? condition.GetSource().getName() : "The Mighty Defek7", "Poison");
}
catch (Exception exception)
{
System.out.println("__+Poison error+__");
System.out.println("Manager null? : " + Manager == null);
System.out.println("Manager.getDamagerManager null? : " + Manager.getDamagerManager() == null);
System.out.println("condition.GetSource() null? : " + condition.GetSource() == null);
System.out.println("condition.GetSource().getName() null? : " + condition.GetSource().getName() == null);
throw exception;
}
}
}
@EventHandler
public void Fall(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.FALL)
return;
LivingEntity ent = event.GetDamageeEntity();
if (ent == null) return;
Condition condition = Manager.GetActiveCondition(ent, ConditionType.FALLING);
if (condition == null) return;
//Damage
event.SetDamager(condition.GetSource());
event.AddMod(UtilEnt.getName(condition.GetSource()), condition.GetReason(), 0, true);
event.SetIgnoreArmor(true);
event.SetKnockback(false);
}
@EventHandler
public void Fall(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
return;
for (LivingEntity ent : Manager.GetActiveConditions().keySet())
{
if (!UtilEnt.isGrounded(ent))
continue;
Condition condition = Manager.GetActiveCondition(ent, ConditionType.FALLING);
if (condition == null) return;
if (!UtilTime.elapsed(condition.GetTime(), 250))
continue;
Manager.EndCondition(ent, ConditionType.FALLING , null);
}
}
@Override
public void handle(PacketInfo packetInfo)
{
Player player = packetInfo.getPlayer();
Packet packet = packetInfo.getPacket();
Player packetPlayer = null;
if (packet instanceof PacketPlayOutEntity)
{
PacketPlayOutEntity entityPacket = (PacketPlayOutEntity) packet;
for (Player other : player.getWorld().getPlayers())
{
if (entityPacket.a == other.getEntityId())
{
packetPlayer = other;
break;
}
}
if (packetPlayer == null || !Manager.isUntrueCloaked(packetPlayer))
{
return;
}
packetInfo.setCancelled(true);
}
else if (packet instanceof PacketPlayOutEntityTeleport)
{
PacketPlayOutEntityTeleport entityPacket = (PacketPlayOutEntityTeleport) packet;
for (Player other : player.getWorld().getPlayers())
{
if (entityPacket.a == other.getEntityId())
{
packetPlayer = other;
break;
}
}
if (packetPlayer == null || !Manager.isUntrueCloaked(packetPlayer))
{
return;
}
packetInfo.setCancelled(true);
}
}
}

View File

@ -0,0 +1,306 @@
package mineplex.minecraft.game.core.condition;
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
import mineplex.minecraft.game.core.condition.conditions.*;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.util.Vector;
public class ConditionFactory
{
public ConditionManager Manager;
public ConditionFactory(ConditionManager manager)
{
Manager = manager;
}
public Condition Custom(String reason, LivingEntity ent, LivingEntity source,
ConditionType type, double duration, int mult, boolean extend,
Material indMat, byte indData, boolean showIndicator)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
type, mult, (int)(20 * duration), extend,
indMat, indData, showIndicator, false));
}
public Condition Invulnerable(String reason, LivingEntity ent, LivingEntity source,
double duration, boolean extend, boolean showIndicator)
{
showIndicator = false;
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.INVULNERABLE, 0, (int)(20 * duration), extend,
Material.GHAST_TEAR, (byte)0, showIndicator, false));
}
public Condition FireItemImmunity(String reason, LivingEntity ent, LivingEntity source,
double duration, boolean extend)
{
return Manager.AddCondition(new FireItemImmunity(Manager, reason, ent, source,
ConditionType.FIRE_ITEM_IMMUNITY, 0, (int)(20 * duration), extend,
Material.GHAST_TEAR, (byte)0, false));
}
public Condition Cloak(String reason, LivingEntity ent, LivingEntity source,
double duration, boolean extend, boolean inform)
{
return Manager.AddCondition(new Cloak(Manager, reason, ent, source,
ConditionType.CLOAK, 0, (int)(20 * duration), extend,
Material.GHAST_TEAR, (byte)0, false));
}
public Condition untrueCloak(String reason, LivingEntity ent, LivingEntity source, double duration, boolean extend)
{
return Manager.AddCondition(new UntrueCloak(Manager, reason, ent, source, ConditionType.UNTRUE_CLOAK, 0, (int)(20 * duration), extend, Material.GHAST_TEAR, (byte)0, false));
}
public Condition Explosion(String reason, LivingEntity ent, LivingEntity source,
int mult, double duration, boolean extend, boolean showIndicator)
{
//Never Show
showIndicator = false;
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.EXPLOSION, mult, (int)(20 * duration), extend,
Material.GHAST_TEAR, (byte)0, showIndicator, false));
}
public Condition Lightning(String reason, LivingEntity ent, LivingEntity source,
int mult, double duration, boolean extend, boolean showIndicator)
{
showIndicator = false;
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.LIGHTNING, mult, (int)(20 * duration), extend,
Material.GHAST_TEAR, (byte)0, showIndicator, false));
}
public Condition Falling(String reason, LivingEntity ent, LivingEntity source,
double duration, boolean extend, boolean showIndicator)
{
showIndicator = false;
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.FALLING, 0, (int)(20 * duration), extend,
Material.GHAST_TEAR, (byte)0, showIndicator, false));
}
public Condition Silence(String reason, LivingEntity ent, LivingEntity source,
double duration, boolean extend, boolean showIndicator)
{
return Manager.AddCondition(new Silence(Manager, reason, ent, source,
ConditionType.SILENCE, 0, (int)(20 * duration), extend,
Material.WATCH, (byte)0, showIndicator));
}
public Condition Speed(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.SPEED, mult, (int)(20 * duration), extend,
Material.FEATHER, (byte)0, showIndicator, ambient));
}
public Condition Strength(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.INCREASE_DAMAGE, mult, (int)(20 * duration), extend,
Material.IRON_SWORD, (byte)0, showIndicator, ambient));
}
public Condition Hunger(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
showIndicator = false;
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.HUNGER, mult, (int)(20 * duration), extend,
Material.ROTTEN_FLESH, (byte)0, showIndicator, ambient));
}
public Condition Regen(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.REGENERATION, mult, (int)(20 * duration), extend,
Material.INK_SACK, (byte)1, showIndicator, ambient));
}
public Condition Weakness(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.WEAKNESS, mult, (int)(20 * duration), extend,
Material.INK_SACK, (byte)15, showIndicator, ambient));
}
public Condition Protection(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.DAMAGE_RESISTANCE, mult, (int)(20 * duration), extend,
Material.IRON_CHESTPLATE, (byte)0, showIndicator, ambient));
}
public Condition FireResist(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.FIRE_RESISTANCE, mult, (int)(20 * duration), extend,
Material.BLAZE_POWDER, (byte)0, showIndicator, ambient));
}
public Condition Breath(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.WATER_BREATHING, mult, (int)(20 * duration), extend,
Material.INK_SACK, (byte)4, showIndicator, ambient));
}
public Condition DigFast(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.FAST_DIGGING, mult, (int)(20 * duration), extend,
Material.GLOWSTONE_DUST, (byte)0, showIndicator, ambient));
}
public Condition DigSlow(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.SLOW_DIGGING, mult, (int)(20 * duration), extend,
Material.WOOD_PICKAXE, (byte)0, showIndicator, ambient));
}
public Condition Jump(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.JUMP, mult, (int)(20 * duration), extend,
Material.CARROT_ITEM, (byte)0, showIndicator, ambient));
}
public Condition Invisible(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
showIndicator = false;
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.INVISIBILITY, mult, (int)(20 * duration), extend,
Material.SNOW_BALL, (byte)0, showIndicator, ambient));
}
/*
public Condition Vulnerable(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Vulnerability(Manager, reason, ent, source,
ConditionType.WITHER, mult, (int)(20 * duration), extend,
Material.BONE, (byte)0, showIndicator, ambient));
}
*/
public Condition Shock(String reason, LivingEntity ent, LivingEntity source,
double duration, boolean extend, boolean showIndicator)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.SHOCK, 0, (int)(20 * duration), extend,
Material.DEAD_BUSH, (byte)0, showIndicator, false));
}
public Condition Ignite(String reason, LivingEntity ent, LivingEntity source,
double duration, boolean extend, boolean showIndicator)
{
showIndicator = false;
return Manager.AddCondition(new Burning(Manager, reason, ent, source,
ConditionType.BURNING, 0, (int)(20 * duration), extend,
Material.GHAST_TEAR, (byte)0, showIndicator));
}
public Condition Slow(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean stun, boolean ambient)
{
if (stun)
ent.setVelocity(new Vector(0,0,0));
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.SLOW, mult, (int)(20 * duration), extend,
Material.WEB, (byte)0, showIndicator, ambient));
}
public Condition Wither(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.WITHER, mult, (int)(20 * duration), extend,
Material.SKULL_ITEM, (byte)1, showIndicator, ambient));
}
public Condition Poison(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Poison(reason, ent, source, duration, mult, extend, showIndicator, ambient, false);
}
public Condition Poison(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient, boolean cancelPotion)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.POISON, mult, (int)(20 * duration), extend,
Material.SLIME_BALL, (byte)14, showIndicator, ambient, cancelPotion));
}
public Condition PoisonShock(String reason, LivingEntity ent, LivingEntity source,
double duration, boolean extend)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.POISON_SHOCK, 0, (int)(20 * duration), extend,
Material.SLIME_BALL, (byte)14, false, false));
}
public Condition Confuse(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.CONFUSION, mult, (int)(20 * duration), extend,
Material.ENDER_PEARL, (byte)0, showIndicator, ambient));
}
public Condition Blind(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.BLINDNESS, mult, (int)(20 * duration), extend,
Material.EYE_OF_ENDER, (byte)0, showIndicator, ambient));
}
public Condition NightVision(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.NIGHT_VISION, mult, (int)(20 * duration), extend,
Material.EYE_OF_ENDER, (byte)0, showIndicator, ambient));
}
public Condition HealthBoost(String reason, LivingEntity ent, LivingEntity source,
double duration, int mult, boolean extend, boolean showIndicator, boolean ambient)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.HEALTH_BOOST, mult, (int)(20 * duration), extend,
Material.APPLE, (byte)0, showIndicator, ambient));
}
public Condition ArcadeHungerDisable(String reason, LivingEntity ent, LivingEntity source,
double duration, boolean extend)
{
return Manager.AddCondition(new Condition(Manager, reason, ent, source,
ConditionType.ARCADE_HUNGER_DISABLE, 0, (int)(20 * duration), extend,
Material.COAL, (byte)0, false, false));
}
}

View File

@ -0,0 +1,582 @@
package mineplex.minecraft.game.core.condition;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.WeakHashMap;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
import mineplex.minecraft.game.core.condition.events.ConditionApplyEvent;
import mineplex.minecraft.game.core.condition.events.ConditionExpireEvent;
import mineplex.minecraft.game.core.damage.DamageManager;
public class ConditionManager extends MiniPlugin
{
static class ConditionMap<T> extends WeakHashMap<LivingEntity, LinkedList<T>>
{
@Override
public LinkedList<T> put(LivingEntity key, LinkedList<T> value)
{
if (key == null)
throw new NullPointerException("Key cannot be null!");
return super.put(key, value);
}
}
private ConditionFactory _factory;
private ConditionApplicator _applicator;
protected ConditionEffect Effect;
private DamageManager _damageManager;
private WeakHashMap<LivingEntity, LinkedList<Condition>> _conditions = new ConditionMap<>();
private WeakHashMap<LivingEntity, LinkedList<ConditionActive>> _activeConditions = new ConditionMap<>();
private HashSet<Entity> _items = new HashSet<>();
public ConditionManager(JavaPlugin plugin)
{
super("Condition Manager", plugin);
Factory();
Applicator();
Effect();
}
public void setDamageManager(DamageManager damageManager)
{
_damageManager = damageManager;
}
public DamageManager getDamagerManager()
{
return _damageManager;
}
public ConditionFactory Factory()
{
if (_factory == null)
_factory = new ConditionFactory(this);
return _factory;
}
public ConditionApplicator Applicator()
{
if (_applicator == null)
_applicator = new ConditionApplicator();
return _applicator;
}
public ConditionEffect Effect()
{
if (Effect == null)
Effect = new ConditionEffect(this);
return Effect;
}
private void validate(Condition condition)
{
if (condition == null)
throw new NullPointerException("Provided condition was null");
if (condition.GetEnt() == null)
throw new NullPointerException("Entity in condition " + condition);
}
public Condition AddCondition(Condition newCon)
{
validate(newCon);
//Event
ConditionApplyEvent condEvent = new ConditionApplyEvent(newCon);
getPlugin().getServer().getPluginManager().callEvent(condEvent);
if (condEvent.isCancelled())
return null;
//Add Condition
if (!_conditions.containsKey(newCon.GetEnt()))
_conditions.put(newCon.GetEnt(), new LinkedList<>());
_conditions.get(newCon.GetEnt()).add(newCon);
//Condition Add
newCon.OnConditionAdd();
//Indicator
HandleIndicator(newCon);
return newCon;
}
public void HandleIndicator(Condition newCon)
{
ConditionActive ind = GetIndicatorType(newCon);
//New Condition
if (ind == null)
{
AddIndicator(newCon);
}
//Condition Exists
else
{
UpdateActive(ind, newCon);
}
}
public ConditionActive GetIndicatorType(Condition newCon)
{
validate(newCon);
if (!_activeConditions.containsKey(newCon.GetEnt()))
_activeConditions.put(newCon.GetEnt(), new LinkedList<>());
for (ConditionActive ind : _activeConditions.get(newCon.GetEnt()))
if (ind.GetCondition().GetType() == newCon.GetType())
return ind;
return null;
}
public void AddIndicator(Condition newCon)
{
validate(newCon);
//Create
ConditionActive newInd = new ConditionActive(newCon);
//Get Inds
if (!_activeConditions.containsKey(newCon.GetEnt()))
_activeConditions.put(newCon.GetEnt(), new LinkedList<>());
LinkedList<ConditionActive> entInds = _activeConditions.get(newCon.GetEnt());
//Add
entInds.addFirst(newInd);
//Inform
if (newCon.GetInformOn() != null)
UtilPlayer.message(newCon.GetEnt(), F.main("Condition", newCon.GetInformOn()));
}
public void UpdateActive(ConditionActive active, Condition newCon)
{
validate(newCon);
//Not Additive
if (!active.GetCondition().IsExpired())
{
if (active.GetCondition().IsBetterOrEqual(newCon, newCon.IsAdd()))
{
return;
}
}
if (active.GetCondition().needsForceRemove())
{
active.GetCondition().Remove();
}
active.SetCondition(newCon);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void ExpireConditions(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
/** Conditions **/
for (LivingEntity ent : _conditions.keySet())
{
if (ent == null)
{
_conditions.remove(null);
continue;
}
Iterator<Condition> conditionIterator = _conditions.get(ent).iterator();
while (conditionIterator.hasNext())
{
Condition cond = conditionIterator.next();
if (cond.Tick())
{
ConditionExpireEvent conditionExpireEvent = new ConditionExpireEvent(cond);
UtilServer.CallEvent(conditionExpireEvent);
conditionIterator.remove();
if (cond.needsForceRemove())
{
cond.Remove();
}
}
}
}
/** Indicators **/
for (LivingEntity ent : _activeConditions.keySet())
{
if (ent == null)
{
_activeConditions.remove(null);
continue;
}
Iterator<ConditionActive> conditionIndicatorIterator = _activeConditions.get(ent).iterator();
while (conditionIndicatorIterator.hasNext())
{
ConditionActive conditionIndicator = conditionIndicatorIterator.next();
if (conditionIndicator.GetCondition().IsExpired())
{
Condition replacement = GetBestCondition(ent, conditionIndicator.GetCondition().GetType());
if (replacement == null)
{
conditionIndicatorIterator.remove();
if (conditionIndicator.GetCondition().needsForceRemove())
{
conditionIndicator.GetCondition().Remove();
}
//Inform
if (conditionIndicator.GetCondition().GetInformOff() != null)
{
UtilPlayer.message(conditionIndicator.GetCondition().GetEnt(), F.main("Condition", conditionIndicator.GetCondition().GetInformOff()));
}
}
else
{
UpdateActive(conditionIndicator, replacement);
}
}
}
}
}
public Condition GetBestCondition(LivingEntity ent, ConditionType type)
{
if (!_conditions.containsKey(ent))
return null;
Condition best = null;
for (Condition con : _conditions.get(ent))
{
if (con.GetType() != type)
continue;
if (con.IsExpired())
continue;
if (best == null)
{
best = con;
continue;
}
if (con.IsBetterOrEqual(best, false))
best = con;
}
return best;
}
public Condition GetActiveCondition(LivingEntity ent, ConditionType type)
{
if (!_activeConditions.containsKey(ent))
return null;
for (ConditionActive ind : _activeConditions.get(ent))
{
if (ind.GetCondition().GetType() != type)
continue;
if (ind.GetCondition().IsExpired())
continue;
return ind.GetCondition();
}
return null;
}
@EventHandler
public void Remove(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
HashSet<Entity> expired = new HashSet<Entity>();
for (Entity cur : _items)
if (UtilEnt.isGrounded(cur) || cur.isDead() || !cur.isValid())
expired.add(cur);
for (Entity cur : expired)
{
_items.remove(cur);
cur.remove();
}
}
@EventHandler
public void Respawn(PlayerRespawnEvent event)
{
Clean(event.getPlayer());
}
@EventHandler
public void Quit(PlayerQuitEvent event)
{
Clean(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
public void Death(EntityDeathEvent event)
{
//Still Alive - SHOULD IGNORE DEATHS FROM DOMINATE
if (event.getEntity() instanceof Player)
if (event.getEntity().getHealth() > 0)
return;
Clean(event.getEntity());
}
public void Clean(LivingEntity ent)
{
//Wipe Conditions
_conditions.remove(ent);
_activeConditions.remove(ent);
}
@EventHandler
public void Debug(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
return;
for (LivingEntity ent : _activeConditions.keySet())
{
if (!(ent instanceof Player))
continue;
Player player = (Player)ent;
if (player.getItemInHand() == null)
continue;
if (player.getItemInHand().getType() != Material.PAPER)
continue;
if (!player.isOp())
continue;
UtilPlayer.message(player, C.cGray + _activeConditions.get(ent).size() + " Indicators ----------- " + _conditions.get(ent).size() + " Conditions");
for (ConditionActive ind : _activeConditions.get(ent))
UtilPlayer.message(player,
F.elem(ind.GetCondition().GetType() + " " + (ind.GetCondition().GetMult()+1)) + " for " +
F.time(UtilTime.convertString(ind.GetCondition().GetTicks()*50L, 1, TimeUnit.FIT)) + " via " +
F.skill(ind.GetCondition().GetReason()) + " from " +
F.name(UtilEnt.getName(ind.GetCondition().GetSource())) + ".");
}
}
@EventHandler
public void Pickup(PlayerPickupItemEvent event)
{
if (event.isCancelled())
return;
if (_items.contains(event.getItem()))
event.setCancelled(true);
}
@EventHandler
public void HopperPickup(InventoryPickupItemEvent event)
{
if (event.isCancelled())
return;
if (_items.contains(event.getItem()))
event.setCancelled(true);
}
public void EndCondition(LivingEntity target, ConditionType type, String reason)
{
if (!_conditions.containsKey(target))
return;
for (Condition cond : _conditions.get(target))
{
if (reason == null || cond.GetReason().equals(reason))
{
if (type == null || cond.GetType() == type)
{
cond.Expire();
Condition best = GetBestCondition(target, cond.GetType());
if (best != null) best.Apply();
}
}
}
}
public boolean HasCondition(LivingEntity target, ConditionType type, String reason)
{
if (!_conditions.containsKey(target))
return false;
for (Condition cond : _conditions.get(target))
{
if (reason == null || cond.GetReason().equals(reason))
{
if (type == null || cond.GetType() == type)
{
return true;
}
}
}
return false;
}
public boolean HasCondition(LivingEntity target, ConditionType type)
{
if (!_conditions.containsKey(target))
return false;
for (Condition cond : _conditions.get(target))
if (type == null || cond.GetType() == type)
return true;
return false;
}
public WeakHashMap<LivingEntity, LinkedList<ConditionActive>> GetActiveConditions()
{
return _activeConditions;
}
public boolean IsSilenced(LivingEntity ent, String ability)
{
if (!_activeConditions.containsKey(ent))
return false;
for (ConditionActive ind : _activeConditions.get(ent))
if (ind.GetCondition().GetType() == ConditionType.SILENCE)
{
if (ability != null)
{
if (ent instanceof Player)
{
if (Recharge.Instance.use((Player)ent, "Silence Feedback", 200, false, false))
{
//Inform
UtilPlayer.message(ent, F.main("Condition", "Cannot use " + F.skill(ability) + " while silenced."));
//Effect
((Player)ent).playSound(ent.getLocation(), Sound.BAT_HURT, 0.8f, 0.8f);
}
}
}
return true;
}
return false;
}
public boolean IsInvulnerable(LivingEntity ent)
{
if (!_activeConditions.containsKey(ent))
return false;
for (ConditionActive ind : _activeConditions.get(ent))
if (ind.GetCondition().GetType() == ConditionType.INVULNERABLE)
return true;
return false;
}
public boolean IsCloaked(LivingEntity ent)
{
if (!_activeConditions.containsKey(ent))
return false;
for (ConditionActive ind : _activeConditions.get(ent))
if (ind.GetCondition().GetType() == ConditionType.CLOAK)
if (!ind.GetCondition().IsExpired())
return true;
return false;
}
public boolean isUntrueCloaked(LivingEntity ent)
{
return _activeConditions.containsKey(ent) && _activeConditions.get(ent).stream().anyMatch(condition -> condition.GetCondition().GetType() == ConditionType.UNTRUE_CLOAK);
}
@EventHandler
public void CleanUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
return;
Iterator<Entry<LivingEntity, LinkedList<ConditionActive>>> conditionIndIterator = _activeConditions.entrySet().iterator();
while (conditionIndIterator.hasNext())
{
Entry<LivingEntity, LinkedList<ConditionActive>> entry = conditionIndIterator.next();
LivingEntity ent = entry.getKey();
if (ent.isDead() || !ent.isValid() || (ent instanceof Player && !((Player)ent).isOnline()))
{
ent.remove();
conditionIndIterator.remove();
}
}
Iterator<Entry<LivingEntity, LinkedList<Condition>>> conditionIterator = _conditions.entrySet().iterator();
while (conditionIterator.hasNext())
{
Entry<LivingEntity, LinkedList<Condition>> entry = conditionIterator.next();
LivingEntity ent = entry.getKey();
if (ent.isDead() || !ent.isValid() || (ent instanceof Player && !((Player)ent).isOnline()))
{
ent.remove();
conditionIterator.remove();
}
}
}
}

View File

@ -0,0 +1,39 @@
package mineplex.minecraft.game.core.condition.conditions;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import mineplex.minecraft.game.core.condition.Condition;
import mineplex.minecraft.game.core.condition.ConditionManager;
public class Burning extends Condition
{
public Burning(ConditionManager manager, String reason, LivingEntity ent,
LivingEntity source, ConditionType type, int mult, int ticks,
boolean add, Material visualType, byte visualData,
boolean showIndicator)
{
super(manager, reason, ent, source, type, mult, ticks, add, visualType,
visualData, showIndicator, false);
}
@Override
public void Add()
{
}
@Override
public void Remove()
{
}
@Override
public void OnConditionAdd()
{
if (_ent.getFireTicks() > 0 && IsAdd())
_ent.setFireTicks(_ent.getFireTicks() + _ticksTotal);
else if (_ent.getFireTicks() < _ticksTotal)
_ent.setFireTicks(_ticksTotal);
}
}

View File

@ -0,0 +1,74 @@
package mineplex.minecraft.game.core.condition.conditions;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.visibility.VisibilityManager;
import mineplex.minecraft.game.core.condition.Condition;
import mineplex.minecraft.game.core.condition.ConditionManager;
public class Cloak extends Condition
{
public Cloak(ConditionManager manager, String reason, LivingEntity ent,
LivingEntity source, ConditionType type, int mult, int ticks,
boolean add, Material visualType, byte visualData,
boolean showIndicator)
{
super(manager, reason, ent, source, type, mult, ticks, add, visualType,
visualData, showIndicator, false);
_informOn = "You are now invisible.";
_informOff = "You are no longer invisible.";
}
@Override
public boolean needsForceRemove()
{
return true;
}
@Override
public void Add()
{
if (!(_ent instanceof Player))
return;
VisibilityManager vm = Managers.require(VisibilityManager.class);
Bukkit.getOnlinePlayers().forEach(player ->
{
vm.hidePlayer(player, (Player)_ent, "Cloaking " + _reason);
});
for (Entity ent : _ent.getWorld().getEntities())
{
if (!(ent instanceof Creature))
continue;
Creature creature = (Creature)ent;
if (creature.getTarget() != null && !creature.getTarget().equals(_ent))
continue;
creature.setTarget(null);
}
}
@Override
public void Remove()
{
super.Remove();
VisibilityManager vm = Managers.require(VisibilityManager.class);
Bukkit.getOnlinePlayers().forEach(player ->
{
vm.showPlayer(player, (Player)_ent, "Cloaking " + _reason);
});
}
}

View File

@ -0,0 +1,19 @@
package mineplex.minecraft.game.core.condition.conditions;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import mineplex.minecraft.game.core.condition.Condition;
import mineplex.minecraft.game.core.condition.ConditionManager;
public class FireItemImmunity extends Condition
{
public FireItemImmunity(ConditionManager manager, String reason, LivingEntity ent,
LivingEntity source, ConditionType type, int mult, int ticks,
boolean add, Material visualType, byte visualData,
boolean showIndicator)
{
super(manager, reason, ent, source, type, mult, ticks, add, visualType,
visualData, showIndicator, false);
}
}

View File

@ -0,0 +1,34 @@
package mineplex.minecraft.game.core.condition.conditions;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import mineplex.minecraft.game.core.condition.Condition;
import mineplex.minecraft.game.core.condition.ConditionManager;
public class Silence extends Condition
{
public Silence(ConditionManager manager, String reason, LivingEntity ent,
LivingEntity source, ConditionType type, int mult, int ticks,
boolean add, Material visualType, byte visualData,
boolean showIndicator)
{
super(manager, reason, ent, source, type, mult, ticks, add, visualType,
visualData, showIndicator, false);
}
@Override
public void Add()
{
if (_ent instanceof Player)
((Player)_ent).playSound(_ent.getLocation(), Sound.BAT_HURT, 0.8f, 0.8f);
}
@Override
public void Remove()
{
}
}

View File

@ -0,0 +1,82 @@
package mineplex.minecraft.game.core.condition.conditions;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import mineplex.core.common.util.UtilPlayer;
import mineplex.minecraft.game.core.condition.Condition;
import mineplex.minecraft.game.core.condition.ConditionManager;
public class UntrueCloak extends Condition
{
public UntrueCloak(ConditionManager manager, String reason, LivingEntity ent,
LivingEntity source, ConditionType type, int mult, int ticks,
boolean add, Material visualType, byte visualData,
boolean showIndicator)
{
super(manager, reason, ent, source, type, mult, ticks, add, visualType,
visualData, showIndicator, false);
_informOn = "You are now invisible.";
_informOff = "You are no longer invisible.";
}
@Override
public boolean needsForceRemove()
{
return true;
}
@Override
public void Add()
{
if (!(_ent instanceof Player))
{
return;
}
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport(((CraftPlayer) _ent).getHandle());
Location location = _ent.getLocation();
packet.b = location.getBlockX() * 32;
packet.c = location.getWorld().getMaxHeight() * 32;
packet.d = location.getBlockZ() * 32;
packet.g = false;
for (Player player : _ent.getWorld().getPlayers())
{
if (player.equals(_ent))
{
continue;
}
UtilPlayer.sendPacket(player, packet);
}
}
@Override
public void Remove()
{
if (!(_ent instanceof Player))
{
return;
}
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport(((CraftPlayer) _ent).getHandle());
for (Player player : _ent.getWorld().getPlayers())
{
if (player.equals(_ent))
{
continue;
}
UtilPlayer.sendPacket(player, packet);
}
}
}

View File

@ -0,0 +1,26 @@
package mineplex.minecraft.game.core.condition.conditions;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import mineplex.core.common.util.F;
import mineplex.minecraft.game.core.condition.Condition;
import mineplex.minecraft.game.core.condition.ConditionManager;
public class Vulnerability extends Condition
{
public Vulnerability(ConditionManager manager, String reason, LivingEntity ent,
LivingEntity source, ConditionType type, int mult, int ticks,
boolean add, Material visualType, byte visualData,
boolean showIndicator, boolean ambient)
{
super(manager, reason, ent, source, type, mult, ticks, add, visualType,
visualData, showIndicator, ambient);
_showIndicator = false;
_informOn = F.elem("Vulnerability " + (mult+1)) + " makes you take " + F.elem("+" + (mult+1) + " Damage") +
" and deal " + F.elem("-" + (mult+1) + " Damage") + ".";
}
}

View File

@ -0,0 +1,48 @@
package mineplex.minecraft.game.core.condition.events;
import mineplex.minecraft.game.core.condition.Condition;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class ConditionApplyEvent extends Event implements Cancellable
{
private static final HandlerList handlers = new HandlerList();
private boolean _cancelled = false;
private Condition _cond;
public ConditionApplyEvent(Condition cond)
{
_cond = cond;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
@Override
public boolean isCancelled()
{
return _cancelled;
}
@Override
public void setCancelled(boolean cancel)
{
_cancelled = cancel;
}
public Condition GetCondition()
{
return _cond;
}
}

View File

@ -0,0 +1,33 @@
package mineplex.minecraft.game.core.condition.events;
import mineplex.minecraft.game.core.condition.Condition;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class ConditionExpireEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Condition _cond;
public ConditionExpireEvent(Condition cond)
{
_cond = cond;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
public Condition getCondition()
{
return _cond;
}
}

View File

@ -0,0 +1,426 @@
package mineplex.minecraft.game.core.damage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import mineplex.core.common.util.C;
public class CustomDamageEvent extends Event implements Cancellable
{
private static final HandlerList handlers = new HandlerList();
private DamageCause _eventCause;
private double _initialDamage;
private ArrayList<DamageChange> _damageMult = new ArrayList<DamageChange>();
private ArrayList<DamageChange> _damageMod = new ArrayList<DamageChange>();
private ArrayList<String> _cancellers = new ArrayList<String>();
private HashMap<String, Double> _knockbackMod = new HashMap<String, Double>();
private Map<String, Object> _metadata = new HashMap<>();
//Ents
private LivingEntity _damageeEntity;
private Player _damageePlayer;
private LivingEntity _damagerEntity;
private Player _damagerPlayer;
private Projectile _projectile;
private Location _knockbackOrigin = null;
//Flags
private boolean _ignoreArmor = false;
private boolean _ignoreRate = false;
private boolean _knockback = true;
private boolean _damageeBrute = false;
private boolean _damageToLevel = true;
private boolean _arrowShow = true;
private boolean _projectileDamageSelf = false;
public CustomDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile projectile, Location knockbackOrigin,
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor, String initialSource,
String initialReason, boolean cancelled)
{
_eventCause = cause;
//if (initialSource == null || initialReason == null)
_initialDamage = damage;
_damageeEntity = damagee;
if (_damageeEntity != null && _damageeEntity instanceof Player) _damageePlayer = (Player)_damageeEntity;
_damagerEntity = damager;
if (_damagerEntity != null && _damagerEntity instanceof Player) _damagerPlayer = (Player)_damagerEntity;
_projectile = projectile;
_knockback = knockback;
_ignoreRate = ignoreRate;
_ignoreArmor = ignoreArmor;
if (initialSource != null && initialReason != null)
AddMod(initialSource, initialReason, 0, true);
if (_eventCause == DamageCause.FALL)
_ignoreArmor = true;
if (cancelled)
SetCancelled("Pre-Cancelled");
_knockbackOrigin = knockbackOrigin;
}
@Override
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
public void AddMult(String source, String reason, double mod, boolean useAttackName)
{
_damageMult.add(new DamageChange(source, reason, mod, useAttackName));
}
public void AddMod(String source, double mod)
{
AddMod(source, "", mod, false);
}
public void AddMod(String source, String reason, double mod, boolean useAttackName)
{
_damageMod.add(new DamageChange(source, reason, mod, useAttackName));
}
public void AddKnockback(String reason, double d)
{
_knockbackMod.put(reason, d);
}
public boolean IsCancelled()
{
return !_cancellers.isEmpty();
}
public void SetCancelled(String reason)
{
_cancellers.add(reason);
}
public double GetDamage()
{
double damage = GetDamageInitial();
for (DamageChange mult : _damageMod)
damage += mult.GetDamage();
for (DamageChange mult : _damageMult)
damage *= mult.GetDamage();
return damage;
}
public LivingEntity GetDamageeEntity()
{
return _damageeEntity;
}
public Player GetDamageePlayer()
{
return _damageePlayer;
}
public LivingEntity GetDamagerEntity(boolean ranged)
{
if (ranged)
return _damagerEntity;
else if (_projectile == null)
return _damagerEntity;
return null;
}
public Player GetDamagerPlayer(boolean passthroughRanged)
{
if (passthroughRanged)
return _damagerPlayer;
else if (_projectile == null)
return _damagerPlayer;
return null;
}
public Projectile GetProjectile()
{
return _projectile;
}
public boolean getProjectileDamageSelf()
{
return _projectileDamageSelf;
}
public void setProjectileDamageSelf(boolean projectileDamageSelf)
{
_projectileDamageSelf = projectileDamageSelf;
if(!projectileDamageSelf)
{
_cancellers.remove("Self Projectile Damage");
}
else
{
if(!_cancellers.contains("Self Projectile Damage"))
{
_cancellers.add("Self Projectile Damage");
}
}
}
public void setShowArrows(boolean show)
{
_arrowShow = show;
}
public boolean getShowArrows()
{
return _arrowShow;
}
public DamageCause GetCause()
{
return _eventCause;
}
public double GetDamageInitial()
{
return _initialDamage;
}
public void SetIgnoreArmor(boolean ignore)
{
if (ignore)
{
_cancellers.removeIf(reason -> reason.equals("World/Monster Damage Rate"));
}
_ignoreArmor = ignore;
}
/**
* A warning to those using this method, the {@link DamageManager} cancels for rate on {@link org.bukkit.event.EventPriority#LOW}, which is a problem.
* So only call this on {@link org.bukkit.event.EventPriority#LOWEST} otherwise it will not work. It's stupid but there you go.
*/
public void SetIgnoreRate(boolean ignore)
{
_ignoreRate = ignore;
}
public void SetKnockback(boolean knockback)
{
_knockback = knockback;
}
public void SetBrute()
{
_damageeBrute = true;
}
public boolean IsBrute()
{
return _damageeBrute;
}
public String GetReason()
{
StringBuilder reason = new StringBuilder();
//Get Reason
for (DamageChange change : _damageMod)
{
if (change.UseReason())
{
reason
.append(C.mSkill)
.append(change.GetReason())
.append(C.mBody)
.append(", ");
}
}
//Trim Reason
if (reason.length() > 0)
{
return reason.substring(0, reason.length() - 2);
}
return null;
}
public boolean IsKnockback()
{
return _knockback;
}
public boolean IgnoreRate()
{
return _ignoreRate;
}
public boolean IgnoreArmor()
{
return _ignoreArmor;
}
public void SetDamager(LivingEntity ent)
{
if (ent == null)
return;
_damagerEntity = ent;
_damagerPlayer = null;
if (ent instanceof Player)
_damagerPlayer = (Player)ent;
}
public void setDamagee(LivingEntity ent)
{
_damageeEntity = ent;
_damageePlayer = ent instanceof Player ? (Player) ent : null;
}
public void setDamager(LivingEntity ent)
{
_damagerEntity = ent;
_damagerPlayer = ent instanceof Player ? (Player) ent : null;
}
public void setKnockbackOrigin(Location loc)
{
_knockbackOrigin = loc;
}
public Location getKnockbackOrigin()
{
return _knockbackOrigin;
}
public ArrayList<DamageChange> GetDamageMod()
{
return _damageMod;
}
public ArrayList<DamageChange> GetDamageMult()
{
return _damageMult;
}
public HashMap<String, Double> GetKnockback()
{
return _knockbackMod;
}
public double getKnockbackValue()
{
double value = 0.0d;
for (double knockback : _knockbackMod.values())
{
value += knockback;
}
return value;
}
/**
* Invert knockback modifier values to their negative counterparts.
*/
public void invertKnockback()
{
for (String key : _knockbackMod.keySet())
{
double value = _knockbackMod.get(key);
_knockbackMod.put(key, -value);
}
}
public ArrayList<String> GetCancellers()
{
return _cancellers;
}
public void SetDamageToLevel(boolean val)
{
_damageToLevel = val;
}
public boolean DisplayDamageToLevel()
{
return _damageToLevel;
}
@Override
public boolean isCancelled()
{
return IsCancelled();
}
/**
* Associates the provided metadata key with the provided value.
* Metadata can later be retrieved from individual {@link
* mineplex.minecraft.game.core.combat.CombatDamage} instances acquired
* from the {@link mineplex.minecraft.game.core.combat.CombatLog}.
*
* @param key non-null key to associate the value with
* @param value nullable value
* @throws IllegalArgumentException if key is null
*/
public void setMetadata(String key, Object value)
{
Validate.notNull(key);
_metadata.put(key, value);
}
/**
* Gets all Metadata associated with this event. There is
* no standardized metadata that should be expected.
*
* @see #setMetadata(String, Object)
* @return non-null map of metadata
*/
public Map<String, Object> getMetadata()
{
return _metadata;
}
@Override
@Deprecated
/**
* Don't call this method. Use SetCancelled(String) instead.
*
* You will be made the butt of jokes if you use this method.
*/
public void setCancelled(boolean isCancelled)
{
SetCancelled("No reason given because SOMEONE IS AN IDIOT");
}
}

View File

@ -0,0 +1,38 @@
package mineplex.minecraft.game.core.damage;
public class DamageChange
{
private final String _source;
private final String _reason;
private final double _modifier;
private final boolean _useReason;
DamageChange(String source, String reason, double modifier, boolean useReason)
{
_source = source;
_reason = reason;
_modifier = modifier;
_useReason = useReason;
}
public String GetSource()
{
return _source;
}
public String GetReason()
{
return _reason;
}
public double GetDamage()
{
return _modifier;
}
public boolean UseReason()
{
return _useReason;
}
}

View File

@ -0,0 +1,858 @@
package mineplex.minecraft.game.core.damage;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import mineplex.core.MiniPlugin;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilGear;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.npc.NpcManager;
import mineplex.minecraft.game.core.combat.CombatManager;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.compatibility.NpcProtectListener;
import net.minecraft.server.v1_8_R3.DamageSource;
import net.minecraft.server.v1_8_R3.EntityHuman;
import net.minecraft.server.v1_8_R3.EntityLiving;
import org.bukkit.EntityEffect;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Fish;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
public class DamageManager extends MiniPlugin
{
private CombatManager _combatManager;
private DisguiseManager _disguiseManager;
private ConditionManager _conditionManager;
protected Field _lastDamageByPlayerTime;
protected Method _k;
public boolean UseSimpleWeaponDamage = false;
public boolean DisableDamageChanges = false;
/**
* The value of knockback that is applied when a player is attacked.
* If 0, the value is calculated from log10(damage).
*/
private double _constantKnockback;
private boolean _enabled = true;
private final HashMap<String, Integer> _protectionTypeModifiers = new HashMap<>();
private final HashMap<String, DamageCause[]> _protectionCauses = new HashMap<>();
public DamageManager(JavaPlugin plugin, CombatManager combatManager, NpcManager npcManager, DisguiseManager disguiseManager, ConditionManager conditionManager)
{
super("Damage Manager", plugin);
_combatManager = combatManager;
_disguiseManager = disguiseManager;
_conditionManager = conditionManager;
try
{
_lastDamageByPlayerTime = EntityLiving.class.getDeclaredField("lastDamageByPlayerTime");
_lastDamageByPlayerTime.setAccessible(true);
_k = EntityLiving.class.getDeclaredMethod("damageArmor", float.class);
_k.setAccessible(true);
}
catch (final Exception e)
{
System.out.println("Problem getting access to EntityLiving: " + e.getMessage());
}
if (npcManager != null)
{
registerEvents(new NpcProtectListener(npcManager));
}
_protectionTypeModifiers.put(Enchantment.PROTECTION_ENVIRONMENTAL.getName(), 1);
_protectionTypeModifiers.put(Enchantment.PROTECTION_FIRE.getName(), 2);
_protectionTypeModifiers.put(Enchantment.PROTECTION_EXPLOSIONS.getName(), 2);
_protectionTypeModifiers.put(Enchantment.PROTECTION_PROJECTILE.getName(), 2);
_protectionTypeModifiers.put(Enchantment.PROTECTION_FALL.getName(), 3);
_protectionCauses.put(Enchantment.PROTECTION_ENVIRONMENTAL.getName(), new DamageCause[] {DamageCause.BLOCK_EXPLOSION, DamageCause.CONTACT, DamageCause.CUSTOM, DamageCause.DROWNING, DamageCause.ENTITY_ATTACK, DamageCause.ENTITY_EXPLOSION, DamageCause.FALL, DamageCause.FALLING_BLOCK, DamageCause.FIRE, DamageCause.FIRE_TICK, DamageCause.LAVA, DamageCause.LIGHTNING, DamageCause.PROJECTILE, DamageCause.SUFFOCATION, DamageCause.THORNS});
_protectionCauses.put(Enchantment.PROTECTION_FIRE.getName(), new DamageCause[] {DamageCause.FIRE, DamageCause.FIRE_TICK, DamageCause.LAVA});
_protectionCauses.put(Enchantment.PROTECTION_EXPLOSIONS.getName(), new DamageCause[] {DamageCause.BLOCK_EXPLOSION, DamageCause.ENTITY_EXPLOSION});
_protectionCauses.put(Enchantment.PROTECTION_PROJECTILE.getName(), new DamageCause[] {DamageCause.PROJECTILE});
_protectionCauses.put(Enchantment.PROTECTION_FALL.getName(), new DamageCause[] {DamageCause.FALL});
}
private int getHighestLevel(Enchantment ench, ItemStack[] items)
{
int level = 0;
for (ItemStack item : items)
{
if (item == null && item.getType() == Material.AIR)
{
continue;
}
if (!item.containsEnchantment(ench))
{
continue;
}
if (item.getEnchantmentLevel(ench) <= level)
{
continue;
}
level = item.getEnchantmentLevel(ench);
}
return level;
}
private int getTotalEPF(Enchantment ench, ItemStack[] items)
{
if (!_protectionTypeModifiers.containsKey(ench.getName()))
{
return 0;
}
if (!_protectionCauses.containsKey(ench.getName()))
{
return 0;
}
int epf = 0;
for (ItemStack item : items)
{
if (item == null || item.getType() == Material.AIR)
{
continue;
}
if (!item.containsEnchantment(ench))
{
continue;
}
if (item.getEnchantmentLevel(ench) <= 0)
{
continue;
}
epf += (item.getEnchantmentLevel(ench) * _protectionTypeModifiers.get(ench.getName()));
}
return Math.min(20, epf);
}
private double getTotalEnchantReduction(ItemStack[] armor, DamageCause cause)
{
int epf = 0;
for (Enchantment ench : Enchantment.values())
{
if (!_protectionTypeModifiers.containsKey(ench.getName()))
{
continue;
}
if (!_protectionCauses.containsKey(ench.getName()))
{
continue;
}
if (!Arrays.asList(_protectionCauses.get(ench.getName())).contains(cause))
{
continue;
}
epf += getTotalEPF(ench, armor);
}
epf = Math.max(0, Math.min(20, epf));
return new BigDecimal(1).subtract(new BigDecimal(epf).divide(new BigDecimal(25))).doubleValue();
}
@EventHandler(priority = EventPriority.HIGHEST)
public void StartDamageEvent(EntityDamageEvent event)
{
if (!_enabled)
return;
boolean preCancel = false;
if (event.isCancelled())
preCancel = true;
if (!(event.getEntity() instanceof LivingEntity))
return;
//Get Data
LivingEntity damagee = GetDamageeEntity(event);
LivingEntity damager = UtilEvent.GetDamagerEntity(event, true);
Projectile projectile = GetProjectile(event);
/*
* Fishing rods are disabled because of their custom properties
* we want them to behave like default MC.
*/
if (projectile instanceof Fish)
return;
//Pre-Event Modifications
if (!DisableDamageChanges)
WeaponDamage(event, damager);
double damage = event.getDamage();
//Consistent Arrow Damage
if (projectile != null && projectile instanceof Arrow)
{
damage = projectile.getVelocity().length() * 3;
}
//New Event
NewDamageEvent(damagee, damager, projectile, event.getCause(), damage, true, false, false, null, null, preCancel);
//System.out.println(UtilEnt.getName(damagee) + " by " + event.getCause() + " at " + UtilWorld.locToStr(damagee.getLocation()));
event.setCancelled(true);
}
@EventHandler
public void onEntityCombust(EntityCombustByEntityEvent event)
{
if (!_enabled)
return;
if (!(event.getCombuster() instanceof Player || event.getCombuster() instanceof Arrow))
return;
event.setCancelled(true);
}
/**
* Removes arrows after hit, especially in cases where arrows may bounce, like if the damage was cancelled.
*/
@EventHandler(priority = EventPriority.MONITOR)
public void removeArrows(EntityDamageEvent event)
{
Projectile projectile = GetProjectile(event);
if (projectile instanceof Arrow)
{
projectile.teleport(new Location(projectile.getWorld(), 0, 0, 0));
projectile.remove();
}
}
/**
* Removes arrows after hit, especially in cases where arrows may bounce, like if the damage was cancelled.
*/
@EventHandler(priority = EventPriority.MONITOR)
public void removeArrows(CustomDamageEvent event)
{
Projectile projectile = event.GetProjectile();
if (projectile instanceof Arrow)
{
projectile.teleport(new Location(projectile.getWorld(), 0, 0, 0));
projectile.remove();
}
}
public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj,
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
String source, String reason)
{
return NewDamageEvent(damagee, damager, proj,
cause, damage, knockback, ignoreRate, ignoreArmor,
source, reason, false);
}
public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj,
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
String source, String reason, boolean cancelled)
{
return NewDamageEvent(damagee, damager, proj, null, cause, damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled);
}
public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, Location knockbackOrigin,
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
String source, String reason)
{
return NewDamageEvent(damagee, damager, proj, knockbackOrigin, cause, damage, knockback, ignoreRate, ignoreArmor, source,
reason, false);
}
public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, Location knockbackOrigin,
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
String source, String reason, boolean cancelled)
{
CustomDamageEvent customDamageEvent = new CustomDamageEvent(damagee, damager, proj, knockbackOrigin, cause,
damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled);
_plugin.getServer().getPluginManager().callEvent(customDamageEvent);
return customDamageEvent;
}
@EventHandler(priority = EventPriority.LOW)
public void CancelDamageEvent(CustomDamageEvent event)
{
if (event.GetDamageeEntity().getHealth() <= 0)
{
event.SetCancelled("0 Health");
return;
}
if (event.GetProjectile() != null && event.GetDamageeEntity().equals(event.GetProjectile().getShooter()) && !event.getProjectileDamageSelf())
{
event.SetCancelled("Self Projectile Damage");
return;
}
if (event.GetDamageePlayer() != null)
{
Player damagee = event.GetDamageePlayer();
//Not Survival
if (damagee.getGameMode() != GameMode.SURVIVAL && damagee.getGameMode() != GameMode.ADVENTURE)
{
event.SetCancelled("Damagee in Creative");
return;
}
if (UtilPlayer.isSpectator(damagee))
{
event.SetCancelled("Damagee in Spectator");
return;
}
//Limit Mob/World Damage Rate
if (!event.IgnoreRate())
{
if (!_combatManager.Get(damagee.getUniqueId()).CanBeHurtBy(event.GetDamagerEntity(true)))
{
event.SetCancelled("World/Monster Damage Rate");
return;
}
}
}
if (event.GetDamagerPlayer(true) != null)
{
Player damager = event.GetDamagerPlayer(true);
//Not Survival
if (damager.getGameMode() != GameMode.SURVIVAL && damager.getGameMode() != GameMode.ADVENTURE)
{
event.SetCancelled("Damager in Creative");
return;
}
//Damage Rate
if (!event.IgnoreRate())
if (!_combatManager.Get(damager.getUniqueId()).CanHurt(event.GetDamageeEntity()))
{
event.SetCancelled("PvP Damage Rate");
return;
}
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void handleEnchants(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
//Defensive
Player damagee = event.GetDamageePlayer();
if (damagee != null)
{
if (event.GetDamage() <= 0)
{
return;
}
if (getTotalEnchantReduction(damagee.getInventory().getArmorContents(), event.GetCause()) > 0)
{
event.AddMult("Ench Prot", damagee.getName(), getTotalEnchantReduction(damagee.getInventory().getArmorContents(), event.GetCause()), false);
}
}
//Offensive
Player damager = event.GetDamagerPlayer(true);
if (damager != null)
{
ItemStack stack = damager.getItemInHand();
if (stack == null)
return;
Map<Enchantment, Integer> enchants = stack.getEnchantments();
for (Enchantment e : enchants.keySet())
{
if (e.equals(Enchantment.ARROW_KNOCKBACK) || e.equals(Enchantment.KNOCKBACK))
event.AddKnockback("Ench Knockback", 1 + (0.5 * (double)enchants.get(e)));
else if (e.equals(Enchantment.ARROW_DAMAGE) || e.equals(Enchantment.DAMAGE_ALL))
event.AddMod("Enchant", "Ench Damage", 0.5 * (double)enchants.get(e), false);
else if (e.equals(Enchantment.FIRE_ASPECT))
if (_conditionManager != null)
{
double reduce = 0;
if (damagee != null)
{
reduce = (15 * getHighestLevel(Enchantment.PROTECTION_FIRE, damagee.getInventory().getArmorContents())) * (4 * (double)enchants.get(e));
}
_conditionManager.Factory().Ignite("Ench Fire", event.GetDamageeEntity(), damager,
(4 * (double)enchants.get(e)) - reduce, false, false);
}
}
}
if (event.GetProjectile() instanceof Arrow && event.GetProjectile().getFireTicks() > 0)
{
if (_conditionManager != null)
_conditionManager.Factory().Ignite("Arrow Fire", event.GetDamageeEntity(), damager, 5, false, false);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void EndDamageEvent(CustomDamageEvent event)
{
if (!event.IsCancelled() && event.GetDamage() > 0)
{
Damage(event);
//DING ARROW
if (event.GetProjectile() != null && event.GetProjectile() instanceof Arrow)
{
Player player = event.GetDamagerPlayer(true);
if (player != null)
{
if (player.equals(event.GetDamageeEntity()) && !event.getProjectileDamageSelf()) return;
player.playSound(player.getLocation(), Sound.ORB_PICKUP, 0.5f, 0.5f);
}
}
}
}
/*
* Should only be used to debug the damage event
* No modification of the event should take place
*/
@EventHandler (priority = EventPriority.MONITOR)
public void debugDamageEvent(CustomDamageEvent event)
{
DisplayDamage(event);
}
private void Damage(CustomDamageEvent event)
{
if (event.GetDamageeEntity() == null)
return;
if (event.GetDamageeEntity().getHealth() <= 0)
return;
if (event.GetProjectile() != null &&
event.GetDamageeEntity().equals(event.GetProjectile().getShooter()) &&
!event.getProjectileDamageSelf())
return;
//Player Conditions
if (event.GetDamageePlayer() != null)
{
//Register Damage (must happen before damage)
_combatManager.AddAttack(event);
}
if (event.GetDamagerPlayer(true) != null && event.DisplayDamageToLevel())
{
//Display Damage to Damager
if (event.GetCause() != DamageCause.THORNS)
event.GetDamagerPlayer(true).setLevel((int)event.GetDamage());
}
try
{
double bruteBonus = 0;
if (event.IsBrute() &&
(
event.GetCause() == DamageCause.ENTITY_ATTACK ||
event.GetCause() == DamageCause.PROJECTILE ||
event.GetCause() == DamageCause.CUSTOM
))// && event.GetDamage() > 2)
bruteBonus = Math.min(8, event.GetDamage()*2);
//Do Damage
HandleDamage(event.GetDamageeEntity(), event.GetDamagerEntity(true), event.GetCause(), (float)(event.GetDamage() + bruteBonus), event.IgnoreArmor());
//Effect
event.GetDamageeEntity().playEffect(EntityEffect.HURT);
//Sticky Arrow
if (event.GetCause() == DamageCause.PROJECTILE && event.GetProjectile() != null && event.GetProjectile() instanceof Arrow && event.getShowArrows())
((CraftLivingEntity)event.GetDamageeEntity()).getHandle().o(((CraftLivingEntity)event.GetDamageeEntity()).getHandle().bv() + 1);
//Knockback
if (event.IsKnockback() && (event.getKnockbackOrigin() != null || event.GetDamagerEntity(true) != null))
{
//Base
double knockback = _constantKnockback;
if (_constantKnockback == 0)
{
knockback = Math.log10(Math.max(event.GetDamage(), 2));
}
//Mults
for (double cur : event.GetKnockback().values())
{
knockback *= cur;
}
//Origin
Location origin = null;
if (event.GetDamagerEntity(true) != null)
origin = event.GetDamagerEntity(true).getLocation();
if (event.getKnockbackOrigin() != null)
origin = event.getKnockbackOrigin();
//Vec
Vector trajectory = UtilAlg.getTrajectory2d(origin, event.GetDamageeEntity().getLocation());
trajectory.multiply(0.6 * knockback);
trajectory.setY(Math.abs(trajectory.getY()));
if (event.GetProjectile() != null && event.getKnockbackOrigin() == null)
{
trajectory = event.GetProjectile().getVelocity();
trajectory.setY(0);
trajectory.multiply(0.37 * knockback / trajectory.length());
trajectory.setY(0.06);
}
//Apply
double vel = 0.2 + trajectory.length() * 0.8;
UtilAction.velocity(event.GetDamageeEntity(), trajectory, vel,
false, 0, Math.abs(0.2 * knockback), 0.4 + (0.04 * knockback), true);
}
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
e.printStackTrace();
}
}
private void DisplayDamage(CustomDamageEvent event)
{
for (Player player : UtilServer.getPlayers())
{
if (!UtilGear.isMat(player.getItemInHand(), Material.COMMAND))
continue;
UtilPlayer.message(player, " ");
UtilPlayer.message(player, "=====================================");
UtilPlayer.message(player, F.elem("Reason ") + event.GetReason());
UtilPlayer.message(player, F.elem("Cause ") + event.GetCause());
UtilPlayer.message(player, F.elem("Damager ") + UtilEnt.getName(event.GetDamagerEntity(true)));
UtilPlayer.message(player, F.elem("Damagee ") + UtilEnt.getName(event.GetDamageeEntity()));
UtilPlayer.message(player, F.elem("Projectile ") + UtilEnt.getName(event.GetProjectile()));
UtilPlayer.message(player, F.elem("Damage ") + event.GetDamage());
UtilPlayer.message(player, F.elem("Damage Initial ") + event.GetDamageInitial());
for (DamageChange cur : event.GetDamageMod())
UtilPlayer.message(player, F.elem("Mod ") + cur.GetDamage() + " - " + cur.GetReason() + " by " + cur.GetSource());
for (DamageChange cur : event.GetDamageMult())
UtilPlayer.message(player, F.elem("Mult ") + cur.GetDamage() + " - " + cur.GetReason() + " by " + cur.GetSource());
for (String cur : event.GetKnockback().keySet())
UtilPlayer.message(player, F.elem("Knockback ") + cur + " = " + event.GetKnockback().get(cur));
for (String cur : event.GetCancellers())
UtilPlayer.message(player, F.elem("Cancel ") + cur);
}
}
private void HandleDamage(LivingEntity damagee, LivingEntity damager, DamageCause cause, float damage, boolean ignoreArmor) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
EntityLiving entityDamagee = ((CraftLivingEntity)damagee).getHandle();
EntityLiving entityDamager = null;
if (damager != null)
entityDamager= ((CraftLivingEntity)damager).getHandle();
entityDamagee.aC = 1.5F;
if ((float) entityDamagee.noDamageTicks > (float) entityDamagee.maxNoDamageTicks / 2.0F)
{
if (damage <= entityDamagee.lastDamage)
{
return;
}
ApplyDamage(entityDamagee, damage - entityDamagee.lastDamage, ignoreArmor);
entityDamagee.lastDamage = damage;
}
else
{
entityDamagee.lastDamage = damage;
//entityDamagee.aw = entityDamagee.getHealth();
//entityDamagee.noDamageTicks = entityDamagee.maxNoDamageTicks;
ApplyDamage(entityDamagee, damage, ignoreArmor);
//entityDamagee.hurtTicks = entityDamagee.aW = 10;
}
if (entityDamager != null)
entityDamagee.b(entityDamager);
if (entityDamager != null)
if (entityDamager instanceof EntityHuman)
{
_lastDamageByPlayerTime.setInt(entityDamagee, 100);
entityDamagee.killer = (EntityHuman)entityDamager;
}
if (entityDamagee.getHealth() <= 0)
{
if (entityDamager != null)
{
if (entityDamager instanceof EntityHuman) entityDamagee.die(DamageSource.playerAttack((EntityHuman)entityDamager));
else if (entityDamager instanceof EntityLiving) entityDamagee.die(DamageSource.mobAttack((EntityLiving)entityDamager));
else entityDamagee.die(DamageSource.GENERIC);
}
else
entityDamagee.die(DamageSource.GENERIC);
}
}
@EventHandler (priority = EventPriority.MONITOR)
public void DamageSound(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.ENTITY_ATTACK && event.GetCause() != DamageCause.PROJECTILE)
return;
//Damagee
LivingEntity damagee = event.GetDamageeEntity();
if (damagee == null) return;
if (_disguiseManager.isDisguised(damagee))
{
_disguiseManager.getDisguise(damagee).playHurtSound();
return;
}
//Sound
Sound sound = Sound.HURT_FLESH;
float vol = 1f;
float pitch = 1f;
//Armor Sound
if (damagee instanceof Player)
{
Player player = (Player)damagee;
double r = Math.random();
ItemStack stack = null;
if (r > 0.50) stack = player.getInventory().getChestplate();
else if (r > 0.25) stack = player.getInventory().getLeggings();
else if (r > 0.10) stack = player.getInventory().getHelmet();
else stack = player.getInventory().getBoots();
if (stack != null)
{
if (stack.getType().toString().contains("LEATHER_"))
{
sound = Sound.SHOOT_ARROW;
pitch = 2f;
}
else if (stack.getType().toString().contains("CHAINMAIL_"))
{
sound = Sound.ITEM_BREAK;
pitch = 1.4f;
}
else if (stack.getType().toString().contains("GOLD_"))
{
sound = Sound.ITEM_BREAK;
pitch = 1.8f;
}
else if (stack.getType().toString().contains("IRON_"))
{
sound = Sound.BLAZE_HIT;
pitch = 0.7f;
}
else if (stack.getType().toString().contains("DIAMOND_"))
{
sound = Sound.BLAZE_HIT;
pitch = 0.9f;
}
}
}
//Animal Sound
else
{
UtilEnt.PlayDamageSound(damagee);
return;
}
damagee.getWorld().playSound(damagee.getLocation(), sound, vol, pitch);
}
private void ApplyDamage(EntityLiving entityLiving, float damage, boolean ignoreArmor) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
if (!ignoreArmor)
{
int j = 25 - entityLiving.br();
float k = damage * (float)j;
_k.invoke(entityLiving, damage);
damage = k / 25.0f;
}
/**
if (entityLiving.hasEffect(MobEffectList.RESISTANCE))
{
int j = (entityLiving.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5;
int k = 25 - j;
int l = damage * k + _aS.getInt(entityLiving);
damage = l / 25;
_aS.setInt(entityLiving, l % 25);
}
**/
entityLiving.setHealth(entityLiving.getHealth() - damage);
}
private void WeaponDamage(EntityDamageEvent event, LivingEntity ent)
{
if (!(ent instanceof Player))
return;
if (event.getCause() != DamageCause.ENTITY_ATTACK)
return;
Player damager = (Player)ent;
if (UseSimpleWeaponDamage)
{
if (event.getDamage() > 1)
event.setDamage(event.getDamage() - 1);
if (UtilGear.isWeapon(damager.getItemInHand()) && damager.getItemInHand().getType().name().contains("GOLD_"))
event.setDamage(event.getDamage() + 2);
return;
}
if (damager.getItemInHand() == null || !UtilGear.isWeapon(damager.getItemInHand()))
{
event.setDamage(1);
return;
}
Material mat = damager.getItemInHand().getType();
int damage = 6;
if (mat.name().contains("WOOD")) damage -= 3;
else if (mat.name().contains("STONE")) damage -= 2;
else if (mat.name().contains("DIAMOND")) damage += 1;
else if (mat.name().contains("GOLD")) damage += 0;
event.setDamage(damage);
}
public LivingEntity GetDamageeEntity(EntityDamageEvent event)
{
if (event.getEntity() instanceof LivingEntity)
return (LivingEntity)event.getEntity();
return null;
}
public Projectile GetProjectile(EntityDamageEvent event)
{
if (!(event instanceof EntityDamageByEntityEvent))
return null;
EntityDamageByEntityEvent eventEE = (EntityDamageByEntityEvent)event;
if (eventEE.getDamager() instanceof Projectile)
return (Projectile)eventEE.getDamager();
return null;
}
public boolean IsEnabled()
{
return _enabled;
}
public void SetEnabled(boolean var)
{
_enabled = var;
}
/**
* Sets the value of {@link #_constantKnockback}.
**/
public void setConstantKnockback(double constantKnockback)
{
_constantKnockback = constantKnockback;
}
/**
* Resets the configuration of damage manager and ensures it is enabled.
*/
public void resetConfiguration()
{
DisableDamageChanges = false;
_constantKnockback = 0;
SetEnabled(true);
}
public CombatManager GetCombatManager()
{
return _combatManager;
}
public void setConditionManager(ConditionManager cm)
{
_conditionManager = cm;
}
}

View File

@ -0,0 +1,39 @@
package mineplex.minecraft.game.core.damage.compatibility;
import mineplex.core.Managers;
import mineplex.core.newnpc.NewNPCManager;
import mineplex.core.npc.NpcManager;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
public class NpcProtectListener implements Listener
{
private NpcManager _npcManager;
public NpcProtectListener(NpcManager npcManager)
{
_npcManager = npcManager;
}
@EventHandler(priority = EventPriority.LOWEST)
public void CustomDamage(CustomDamageEvent event)
{
if (_npcManager.isNpc(event.GetDamageeEntity()))
{
event.SetCancelled("NPC");
}
else
{
// This is bad but /shrug
NewNPCManager manager = Managers.get(NewNPCManager.class);
if (manager != null && manager.isNPC(event.GetDamageeEntity()))
{
event.SetCancelled("New NPC");
}
}
}
}

View File

@ -0,0 +1,449 @@
package mineplex.minecraft.game.core.explosion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_8_R3.event.CraftEventFactory;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.explosion.ExplosionEvent;
import mineplex.minecraft.game.core.damage.DamageManager;
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
import net.minecraft.server.v1_8_R3.Block;
import net.minecraft.server.v1_8_R3.BlockPosition;
import net.minecraft.server.v1_8_R3.Blocks;
import net.minecraft.server.v1_8_R3.DamageSource;
import net.minecraft.server.v1_8_R3.EnchantmentProtection;
import net.minecraft.server.v1_8_R3.Entity;
import net.minecraft.server.v1_8_R3.EntityHuman;
import net.minecraft.server.v1_8_R3.EnumParticle;
import net.minecraft.server.v1_8_R3.Explosion;
import net.minecraft.server.v1_8_R3.IBlockData;
import net.minecraft.server.v1_8_R3.Material;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.PacketPlayOutExplosion;
import net.minecraft.server.v1_8_R3.Vec3D;
import net.minecraft.server.v1_8_R3.World;
public class CustomExplosion extends Explosion
{
private org.bukkit.entity.LivingEntity _owner;
private boolean _damageOwner;
private World _world;
private DamageManager _manager;
private String _damageReason;
private boolean _dropItems = true;
private boolean _damageBlocksEqually;
private boolean _createFire;
private boolean _ignoreRate = true;
private float _blockExplosionSize;
private boolean _fallingBlockExplosion;
private mineplex.core.explosion.Explosion _explosion;
private float _damage;
private boolean _useCustomDamage;
private int _maxFallingBlocks = 0;
private float _maxDamage = 1000;
private float _size;
private boolean _damageBlocks = true;
private double posX, posY, posZ;
private boolean _ignoreNonLiving;
public CustomExplosion(DamageManager manager, mineplex.core.explosion.Explosion explosion, Location loc, float explosionSize,
String deathCause)
{
super(((CraftWorld) loc.getWorld()).getHandle(), null, loc.getX(), loc.getY(), loc.getZ(), explosionSize, false, false);
posX = loc.getX();
posY = loc.getY();
posZ = loc.getZ();
_world = ((CraftWorld) loc.getWorld()).getHandle();
_manager = manager;
_damageReason = deathCause;
_blockExplosionSize = explosionSize;
_explosion = explosion;
_size = explosionSize;
}
/**
* Center of explosion does this much damage
*/
public CustomExplosion setExplosionDamage(float damage)
{
_damage = damage;
_useCustomDamage = true;
return this;
}
public CustomExplosion setIgnoreNonLiving(boolean ignoreNonLiving)
{
_ignoreNonLiving = ignoreNonLiving;
return this;
}
public CustomExplosion setMaxDamage(float maxDamage)
{
_maxDamage = maxDamage;
return this;
}
public CustomExplosion setBlockExplosionSize(float explosionSize)
{
_blockExplosionSize = explosionSize;
return this;
}
public CustomExplosion setIgnoreRate(boolean ignoreRate)
{
_ignoreRate = ignoreRate;
return this;
}
public CustomExplosion setFallingBlockExplosion(boolean fallingBlockExplosion)
{
_fallingBlockExplosion = fallingBlockExplosion;
return this;
}
public CustomExplosion setFallingBlockExplosionAmount(int maxFallingBlocks)
{
_maxFallingBlocks = maxFallingBlocks;
return this;
}
public CustomExplosion setDamageBlocks(boolean damageBlocks)
{
_damageBlocks = damageBlocks;
return this;
}
public CustomExplosion setBlocksDamagedEqually(boolean damageEqually)
{
_damageBlocksEqually = damageEqually;
return this;
}
public CustomExplosion explode()
{
// Explode the explosion
a();
a(true);
return this;
}
public CustomExplosion setDropItems(boolean dropItems)
{
_dropItems = dropItems;
return this;
}
public CustomExplosion setPlayer(org.bukkit.entity.LivingEntity player, boolean damageExplosionOwner)
{
_owner = player;
_damageOwner = damageExplosionOwner;
return this;
}
@Override
public void a()
{
if (Math.max(_blockExplosionSize, this._size) < 0.1F)
{
return;
}
HashSet hashset = new HashSet();
for (int k = 0; k < 16; k++)
{
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
if ((k == 0) || (k == 15) || (i == 0) || (i == 15) || (j == 0) || (j == 15))
{
double d0 = k / 15.0F * 2.0F - 1.0F;
double d1 = i / 15.0F * 2.0F - 1.0F;
double d2 = j / 15.0F * 2.0F - 1.0F;
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
d0 /= d3;
d1 /= d3;
d2 /= d3;
float f1 = this._blockExplosionSize * (0.7F + this._world.random.nextFloat() * 0.6F);
double d4 = this.posX;
double d5 = this.posY;
double d6 = this.posZ;
for (; f1 > 0.0F; f1 -= 0.225F)
{
BlockPosition blockposition = new BlockPosition(d4, d5, d6);
IBlockData iblockdata = this._world.getType(blockposition);
if (iblockdata.getBlock().getMaterial() != Material.AIR)
{
float f2 = this.source != null ? this.source.a(this, this._world, blockposition, iblockdata)
: (_damageBlocksEqually ? Blocks.DIRT : iblockdata.getBlock()).a((Entity) null);
f1 -= (f2 + 0.3F) * 0.3F;
}
if ((f1 > 0.0F)
&& ((this.source == null) || (this.source.a(this, this._world, blockposition, iblockdata, f1)))
&& (blockposition.getY() < 256) && (blockposition.getY() >= 0))
{
hashset.add(blockposition);
}
d4 += d0 * 0.300000011920929D;
d5 += d1 * 0.300000011920929D;
d6 += d2 * 0.300000011920929D;
}
}
}
}
}
this.getBlocks().addAll(hashset);
float f3 = _size * 2F;
int i = MathHelper.floor(this.posX - f3 - 1.0D);
int j = MathHelper.floor(this.posX + f3 + 1.0D);
int k = MathHelper.floor(this.posY - f3 - 1.0D);
int k1 = MathHelper.floor(this.posY + f3 + 1.0D);
int l1 = MathHelper.floor(this.posZ - f3 - 1.0D);
int i2 = MathHelper.floor(this.posZ + f3 + 1.0D);
List list = this._world.getEntities(this.source, new AxisAlignedBB(i, k, l1, j, k1, i2));
Vec3D vec3d = new Vec3D(this.posX, this.posY, this.posZ);
for (int j2 = 0; j2 < list.size(); j2++)
{
Entity entity = (Entity) list.get(j2);
if (entity.getBukkitEntity() == _owner && !_damageOwner)
continue;
if (!(entity.getBukkitEntity() instanceof LivingEntity) && _ignoreNonLiving)
continue;
double d7 = entity.f(this.posX, this.posY, this.posZ) / this._size; // XXX
if (d7 <= 1.0D)
{
double d0 = entity.locX - this.posX;
double d1 = entity.locY + entity.getHeadHeight() - this.posY;
double d2 = entity.locZ - this.posZ;
double d8 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
if (d8 != 0.0D)
{
d0 /= d8;
d1 /= d8;
d2 /= d8;
// Performs a raytrace that determines the percentage of solid blocks between the two
double d9 = this._world.a(vec3d, entity.getBoundingBox()); // XXX
double d10 = (1.0D - d7) * d9;
float damage;
if (_useCustomDamage)
{
damage = Math.max(0, (int) ((_damage * d9) * (d8 / _size)));
}
else
{
damage = (int) ((d10 * d10 + d10) / 2.0D * 8.0D * this._size + 1.0D);
damage = Math.min(damage, _maxDamage);
}
if (entity.getBukkitEntity() instanceof LivingEntity)
{
_manager.NewDamageEvent((LivingEntity) entity.getBukkitEntity(), _owner, null, new Location(_world.getWorld(), posX, posY, posZ),
DamageCause.ENTITY_EXPLOSION, damage, true, _ignoreRate, false, _damageReason, _damageReason, false);
}
else
{
CraftEventFactory.entityDamage = this.source;
entity.damageEntity(DamageSource.explosion(this), damage);
CraftEventFactory.entityDamage = null;
}
double d11 = EnchantmentProtection.a(entity, d10); // XXX
/*entity.motX += d0 * d11;
entity.motY += d1 * d11;
entity.motZ += d2 * d11;*/
if (((entity instanceof EntityHuman)) && (!((EntityHuman) entity).abilities.isInvulnerable))
{
this.b().put((EntityHuman) entity, new Vec3D(d0 * d10, d1 * d10, d2 * d10));
}
}
}
}
}
@Override
public void a(boolean flag)
{
this._world.makeSound(this.posX, this.posY, this.posZ, "random.explode", 4.0F,
(1.0F + (this._world.random.nextFloat() - this._world.random.nextFloat()) * 0.2F) * 0.7F);
if ((this._blockExplosionSize >= 2.0F) && (this._damageBlocks))
this._world.addParticle(EnumParticle.EXPLOSION_HUGE, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D, new int[0]);
else {
this._world.addParticle(EnumParticle.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D, new int[0]);
}
if (_damageBlocks)
{
org.bukkit.World bworld = this._world.getWorld();
List blockList = new ArrayList();
for (int i1 = this.getBlocks().size() - 1; i1 >= 0; i1--)
{
BlockPosition cpos = this.getBlocks().get(i1);
org.bukkit.block.Block bblock = bworld.getBlockAt(cpos.getX(), cpos.getY(), cpos.getZ());
if (bblock.getType() != org.bukkit.Material.AIR)
{
blockList.add(bblock);
}
}
ExplosionEvent event = _owner == null || !(_owner instanceof Player) ? new ExplosionEvent(blockList) : new ExplosionEvent(blockList, (Player) _owner);
this._world.getServer().getPluginManager().callEvent(event);
this.getBlocks().clear();
for (org.bukkit.block.Block bblock : event.GetBlocks())
{
BlockPosition coords = new BlockPosition(bblock.getX(), bblock.getY(), bblock.getZ());
this.getBlocks().add(coords);
}
if (event.GetBlocks().isEmpty())
{
this.wasCanceled = true;
return;
}
if (_fallingBlockExplosion)
{
List<org.bukkit.block.Block> blocks = new ArrayList<>(event.GetBlocks());
if (blocks.size() > _maxFallingBlocks && _maxFallingBlocks >= 0)
{
Collections.shuffle((ArrayList) blocks);
int toRemove = blocks.size() - _maxFallingBlocks;
for (int i = 0; i < toRemove; i++)
{
blocks.remove(0);
}
}
_explosion.BlockExplosion(blocks, new Location(_world.getWorld(), posX, posY, posZ), false, false);
}
Iterator iterator = this.getBlocks().iterator();
while (iterator.hasNext())
{
BlockPosition blockposition = (BlockPosition) iterator.next();
Block block = this._world.getType(blockposition).getBlock();
this._world.spigotConfig.antiXrayInstance.updateNearbyBlocks(this._world, blockposition);
if (flag)
{
double d0 = blockposition.getX() + this._world.random.nextFloat();
double d1 = blockposition.getY() + this._world.random.nextFloat();
double d2 = blockposition.getZ() + this._world.random.nextFloat();
double d3 = d0 - this.posX;
double d4 = d1 - this.posY;
double d5 = d2 - this.posZ;
double d6 = MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
d3 /= d6;
d4 /= d6;
d5 /= d6;
double d7 = 0.5D / (d6 / this._blockExplosionSize + 0.1D);
d7 *= (this._world.random.nextFloat() * this._world.random.nextFloat() + 0.3F);
d3 *= d7;
d4 *= d7;
d5 *= d7;
this._world.addParticle(EnumParticle.EXPLOSION_NORMAL, (d0 + this.posX * 1.0D) / 2.0D,
(d1 + this.posY * 1.0D) / 2.0D, (d2 + this.posZ * 1.0D) / 2.0D, d3, d4, d5, new int[0]);
this._world.addParticle(EnumParticle.SMOKE_NORMAL, d0, d1, d2, d3, d4, d5, new int[0]);
}
if (block.getMaterial() != Material.AIR)
{
if (block.a(this) && _dropItems)
{
block.dropNaturally(this._world, blockposition, this._world.getType(blockposition), _blockExplosionSize,
0);
}
this._world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3);
block.wasExploded(this._world, blockposition, this);
}
}
}
if (this._createFire)
{
Iterator iterator = this.getBlocks().iterator();
while (iterator.hasNext())
{
BlockPosition blockposition = (BlockPosition) iterator.next();
if ((this._world.getType(blockposition).getBlock().getMaterial() == Material.AIR)
&& (this._world.getType(blockposition.down()).getBlock().o()) && (UtilMath.r(3) == 0))
{
if (!CraftEventFactory.callBlockIgniteEvent(this._world, blockposition.getX(), blockposition.getY(),
blockposition.getZ(), this).isCancelled())
this._world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData());
}
}
}
PacketPlayOutExplosion explosion = new PacketPlayOutExplosion(this.posX, this.posY, this.posZ, this._blockExplosionSize,
new ArrayList(), null);
for (Player p : Bukkit.getOnlinePlayers())
UtilPlayer.sendPacket(p, explosion);
}
public float getSize()
{
return _size;
}
}

View File

@ -0,0 +1,233 @@
package mineplex.minecraft.game.core.fire;
import java.util.HashMap;
import java.util.HashSet;
import mineplex.core.MiniPlugin;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
import org.bukkit.Effect;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.potion.PotionEffectType;
public class Fire extends MiniPlugin
{
private ConditionManager _conditionManager;
private DamageManager _damageManager;
private HashMap<Item, FireData> _fire = new HashMap<Item, FireData>();
public Fire(JavaPlugin plugin, ConditionManager conditionManager, DamageManager damageManager)
{
super("Fire", plugin);
_conditionManager = conditionManager;
_damageManager = damageManager;
}
public void Add(Item item, LivingEntity owner, double expireTime, double delayTime, double burnTime, double damage, String skillName, boolean hitSelf)
{
_fire.put(item, new FireData(owner, expireTime, delayTime, burnTime, damage, skillName, hitSelf));
item.setPickupDelay(0);
}
@EventHandler
public void IgniteCollide(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
HashMap<Item, LivingEntity> collided = new HashMap<Item, LivingEntity>();
for (Item fire : _fire.keySet())
{
if (!_fire.get(fire).IsPrimed())
continue;
if (fire.getLocation().getBlock().isLiquid())
{
collided.put(fire, null);
continue;
}
for (LivingEntity ent : fire.getWorld().getEntitiesByClass(LivingEntity.class))
{
if (UtilPlayer.isSpectator(ent) || ent.hasPotionEffect(PotionEffectType.FIRE_RESISTANCE))
{
continue;
}
if (ent.getLocation().getBlock().getTypeId() == 8 || ent.getLocation().getBlock().getTypeId() == 9)
continue;
if (!_fire.get(fire).canHitOwner() && ent.equals(_fire.get(fire).GetOwner()))
continue;
if (_conditionManager.HasCondition(ent, ConditionType.FIRE_ITEM_IMMUNITY, null))
{
continue;
}
if (!UtilEnt.hitBox(fire.getLocation(), ent, 1.5, null))
continue;
collided.put(fire, ent);
}
}
for (Item fire : collided.keySet())
{
FireData fireData = _fire.remove(fire);
fire.remove();
Ignite(collided.get(fire), fireData);
}
}
@EventHandler(priority = EventPriority.LOW)
public void IgnitePickup(PlayerPickupItemEvent event)
{
Player player = event.getPlayer();
Item fire = event.getItem();
if (!_fire.containsKey(fire))
return;
event.setCancelled(true);
if (!_fire.get(fire).canHitOwner() && _fire.get(fire).GetOwner().equals(player))
return;
if (UtilPlayer.isSpectator(player))
return;
if (player.hasPotionEffect(PotionEffectType.FIRE_RESISTANCE))
return;
if (player.getLocation().getBlock().getTypeId() == 8 || player.getLocation().getBlock().getTypeId() == 9)
return;
if (!_fire.get(fire).IsPrimed())
return;
if (_conditionManager.HasCondition(player, ConditionType.FIRE_ITEM_IMMUNITY, null))
{
return;
}
if (!UtilEnt.hitBox(fire.getLocation(), player, 1.5, null))
return;
//Remove
FireData fireData = _fire.remove(fire);
fire.remove();
Ignite(player, fireData);
}
@EventHandler
public void HopperPickup(InventoryPickupItemEvent event)
{
if (_fire.containsKey(event.getItem()))
event.setCancelled(true);
}
public void Ignite(LivingEntity ent, FireData fireData)
{
if (ent == null)
return;
_conditionManager.Factory().Ignite(fireData.GetName(), ent, fireData.GetOwner(), fireData.GetBurnTime(), true, true);
//Damage
if (fireData.GetDamage() > 0)
{
//Inferno Negate
if (fireData.GetDamage() == 1)
if (ent instanceof Player)
if (!Recharge.Instance.use((Player)ent, "Fire Damage", 150, false, false))
{
ent.playEffect(EntityEffect.HURT);
return;
}
//Damage Event
_damageManager.NewDamageEvent(ent, fireData.GetOwner(), null,
DamageCause.CUSTOM, fireData.GetDamage(), false, true, false,
UtilEnt.getName(fireData.GetOwner()), fireData.GetName());
}
}
@EventHandler
public void Expire(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
HashSet<Item> expire = new HashSet<Item>();
for (Item cur : _fire.keySet())
{
if (!cur.isValid() || _fire.get(cur).Expired())
expire.add(cur);
}
for (Item cur : expire)
{
_fire.remove(cur);
cur.remove();
}
}
public void Remove(LivingEntity owner, String cause)
{
HashSet<Item> remove = new HashSet<Item>();
for (Item cur : _fire.keySet())
if (owner == null || _fire.get(cur).GetOwner().equals(owner))
if (cause == null || _fire.get(cur).GetName().equals(cause))
remove.add(cur);
for (Item cur : remove)
{
_fire.remove(cur);
cur.remove();
}
}
public void RemoveNear(Location loc, double range)
{
HashSet<Item> remove = new HashSet<Item>();
for (Item cur : _fire.keySet())
if (UtilMath.offset(loc, cur.getLocation()) < range)
remove.add(cur);
for (Item cur : remove)
{
_fire.remove(cur);
cur.getWorld().playEffect(cur.getLocation(), Effect.EXTINGUISH, 0);
cur.remove();
}
}
}

View File

@ -0,0 +1,60 @@
package mineplex.minecraft.game.core.fire;
import org.bukkit.entity.LivingEntity;
public class FireData
{
private LivingEntity _owner;
private long _expireTime;
private long _delayTime;
private double _burnTime;
private double _damage;
private String _skillName;
private boolean _hitOwner;
public FireData(LivingEntity owner, double expireTime, double delayTime, double burnTime, double damage, String skillName, boolean hitSelf)
{
_owner = owner;
_expireTime = System.currentTimeMillis() + (long)(1000 * expireTime);
_delayTime = System.currentTimeMillis() + (long)(1000 * delayTime);
_burnTime = burnTime;
_damage = damage;
_skillName = skillName;
_hitOwner = hitSelf;
}
public LivingEntity GetOwner()
{
return _owner;
}
public double GetBurnTime()
{
return _burnTime;
}
public double GetDamage()
{
return _damage;
}
public String GetName()
{
return _skillName;
}
public boolean IsPrimed()
{
return System.currentTimeMillis() > _delayTime;
}
public boolean Expired()
{
return System.currentTimeMillis() > _expireTime;
}
public boolean canHitOwner()
{
return _hitOwner;
}
}

View File

@ -0,0 +1,120 @@
package mineplex.minecraft.game.core.mechanics;
import java.util.HashMap;
import java.util.HashSet;
import mineplex.core.MiniPlugin;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.updater.UpdateType;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilTime;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.material.PistonBaseMaterial;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
public class PistonJump extends MiniPlugin
{
private HashMap<Block, Long> _pistonExtend = new HashMap<Block, Long>();
public PistonJump(JavaPlugin plugin)
{
super("Piston Jump", plugin);
}
@EventHandler
public void PistonLaunch(PlayerMoveEvent event)
{
Block below = event.getPlayer().getLocation().getBlock().getRelative(BlockFace.DOWN);
if (below.getTypeId() != 33)
return;
if (below.getData() != 1)
return;
if (below.getRelative(BlockFace.UP).getType() != Material.AIR)
return;
if (_pistonExtend.containsKey(below))
return;
for (Player player : below.getWorld().getPlayers())
{
if (!below.equals(player.getLocation().getBlock().getRelative(BlockFace.DOWN)))
continue;
//Vector
Vector vec = new Vector(0,1.2,0);
UtilAction.velocity(player, vec);
}
final Block block = below;
_plugin.getServer().getScheduler().scheduleSyncDelayedTask(_plugin, new Runnable()
{
public void run()
{
//Extend
BlockState state = block.getState();
PistonBaseMaterial pbm = (PistonBaseMaterial)state.getData();
pbm.setPowered(true);
state.setData(pbm);
state.update(true);
block.getRelative(BlockFace.UP).setTypeIdAndData(34, (byte)1, false);
_pistonExtend.put(block, System.currentTimeMillis());
//Effect
block.getWorld().playSound(block.getLocation(), Sound.PISTON_EXTEND, 1f, 1f);
}
}, 10);
}
@EventHandler
public void PistonExtendUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
return;
HashSet<Block> retract = new HashSet<Block>();
for (Block cur : _pistonExtend.keySet())
{
if (UtilTime.elapsed(_pistonExtend.get(cur), 600))
retract.add(cur);
}
for (Block cur : retract)
{
_pistonExtend.remove(cur);
//Retract
if (cur.getTypeId() == 33)
{
//Extend
BlockState state = cur.getState();
PistonBaseMaterial pbm = (PistonBaseMaterial)state.getData();
pbm.setPowered(false);
state.setData(pbm);
state.update(true);
}
if (cur.getRelative(BlockFace.UP).getTypeId() == 34)
cur.getRelative(BlockFace.UP).setTypeIdAndData(0, (byte)0, true);
//Effect
cur.getWorld().playSound(cur.getLocation(), Sound.PISTON_RETRACT, 1f, 1f);
}
}
}

View File

@ -0,0 +1,149 @@
package mineplex.minecraft.game.core.mechanics;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.potion.PotionEffectType;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import mineplex.core.MiniPlugin;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilGear;
import mineplex.core.common.util.UtilInv;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.energy.Energy;
public class Weapon extends MiniPlugin
{
private Energy _energy;
public Weapon(JavaPlugin plugin, Energy energy)
{
super("Weapon", plugin);
_energy = energy;
}
@EventHandler
public void ShootBow(EntityShootBowEvent event)
{
if (event.getEntity().getLocation().getBlock().isLiquid())
{
UtilPlayer.message(event.getEntity(), F.main("Skill", "You cannot use " + F.item("Bow") + " in water."));
event.setCancelled(true);
return;
}
}
@EventHandler(priority = EventPriority.HIGH)
public void ArrowFix(CustomDamageEvent event)
{
Projectile proj = event.GetProjectile();
if (proj == null) return;
if (!(proj instanceof Arrow))
return;
event.AddMod("Del", "Arrow Fix", -event.GetDamageInitial(), false);
event.AddMod("Add", "Arrow Fix", proj.getVelocity().length() * 3, false);
}
@EventHandler(priority = EventPriority.MONITOR)
public void ArrowDelete(CustomDamageEvent event)
{
if (event.GetCause() != DamageCause.PROJECTILE)
return;
Projectile proj = event.GetProjectile();
if (proj == null) return;
proj.remove();
}
@EventHandler(priority = EventPriority.LOWEST)
public void AttackExhaust(CustomDamageEvent event)
{
if (event.GetCause() != DamageCause.ENTITY_ATTACK)
return;
//No Energy
Player damager = event.GetDamagerPlayer(false);
if (damager == null) return;
if (damager.hasPotionEffect(PotionEffectType.FAST_DIGGING))
return;
if (_energy.Use(damager, "Attack", 1, false, false))
return;
//50%
event.AddMod(damager.getName(), "Exhaustion", -event.GetDamageInitial() + 1, false);
}
@EventHandler(priority = EventPriority.MONITOR)
public void WeaponDurability(CustomDamageEvent event)
{
if (event.IsCancelled())
return;
if (event.GetCause() != DamageCause.ENTITY_ATTACK)
return;
Player damager = event.GetDamagerPlayer(false);
if (damager == null) return;
if (GoldPower(damager))
return;
ItemStack item = damager.getItemInHand();
if (item == null)
return;
if (item.getType().getMaxDurability() == 0)
return;
if (UtilGear.isArmor(item))
return;
// Don't mess with unbreakable items
if (item.getItemMeta() != null && item.getItemMeta().spigot().isUnbreakable())
return;
item.setDurability((short) (item.getDurability() + 1));
if (item.getDurability() >= item.getType().getMaxDurability())
{
UtilPlayer.message(damager, F.main("Weapon", "Your " + F.item(item.getItemMeta().getDisplayName()) + " has broken."));
damager.setItemInHand(null);
UtilInv.Update(damager);
damager.getWorld().playSound(damager.getLocation(), Sound.ANVIL_LAND, 1f, 0.8f);
}
}
private boolean GoldPower(Player damager)
{
try
{
if (!UtilGear.isGold(damager.getItemInHand()))
return false;
if (!damager.getInventory().contains(Material.GOLD_NUGGET))
return false;
UtilInv.remove(damager, Material.GOLD_NUGGET, (byte)0, 1);
return true;
}
catch (Exception e)
{
return false;
}
}
}