Changes to Slime Boss, ability to drop gold with GoldManager, small KOTH changes. [ALL UNTESTED]
This commit is contained in:
parent
90a7362440
commit
1f92564ea1
@ -4,6 +4,7 @@ import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
@ -22,6 +23,8 @@ import net.minecraft.server.v1_7_R4.PlayerConnection;
|
||||
|
||||
public class UtilPlayer
|
||||
{
|
||||
private static Random RANDOM = new Random();
|
||||
|
||||
private static boolean hasIntersection(Vector3D p1, Vector3D p2, Vector3D min, Vector3D max)
|
||||
{
|
||||
final double epsilon = 0.0001f;
|
||||
@ -530,7 +533,7 @@ public class UtilPlayer
|
||||
continue;
|
||||
|
||||
//Get lower offset (eye to eye, eye to feet)
|
||||
double offset = Math.min(UtilMath.offset(player.getEyeLocation(), cur.getEyeLocation()),
|
||||
double offset = Math.min(UtilMath.offset(player.getEyeLocation(), cur.getEyeLocation()),
|
||||
UtilMath.offset(player.getEyeLocation(), cur.getLocation()));
|
||||
|
||||
if (offset < distance && UtilAlg.isTargetInPlayerPyramid(player, cur, angleLimit))
|
||||
@ -608,6 +611,18 @@ public class UtilPlayer
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random player within maxDist of the target location
|
||||
* @param location The center location to look for the player
|
||||
* @param maxDist The max distance from location that the player can be
|
||||
* @return A random player that is within maxDist of location, or null if no players apply
|
||||
*/
|
||||
public static Player getRandomTarget(Location location, double maxDist)
|
||||
{
|
||||
List<Player> nearby = getNearby(location, maxDist);
|
||||
return nearby.get(RANDOM.nextInt(nearby.size()));
|
||||
}
|
||||
|
||||
public static boolean isSpectator(Entity player)
|
||||
{
|
||||
if (player instanceof Player)
|
||||
|
@ -1,5 +1,7 @@
|
||||
package mineplex.core.reward;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public enum RewardType
|
||||
{
|
||||
//% Chances Mythic Legend Rare Uncommon
|
||||
@ -34,4 +36,43 @@ public enum RewardType
|
||||
|
||||
return rarity;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
int maxCount = Integer.MAX_VALUE;
|
||||
int openCount = 0;
|
||||
RewardType type = RewardType.MythicalChest;
|
||||
ArrayList<RewardTest> data = new ArrayList<RewardTest>();
|
||||
|
||||
for (RewardRarity rarity : RewardRarity.values())
|
||||
{
|
||||
data.add(rarity.ordinal(), new RewardTest(rarity));
|
||||
}
|
||||
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
RewardRarity rarity = type.generateRarity(false);
|
||||
data.get(rarity.ordinal()).Count++;
|
||||
openCount++;
|
||||
if (rarity == RewardRarity.MYTHICAL) break;
|
||||
}
|
||||
|
||||
System.out.printf("Opened %10d rewards using type " + type.name() + "\n", openCount);
|
||||
for (RewardTest test : data)
|
||||
{
|
||||
System.out.printf("Opened %10d of reward type %10s", test.Count, test.Rarity.name());
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private static class RewardTest
|
||||
{
|
||||
public final RewardRarity Rarity;
|
||||
public int Count;
|
||||
|
||||
public RewardTest(RewardRarity rare)
|
||||
{
|
||||
Rarity = rare;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,19 @@
|
||||
package mineplex.game.clans.clans.worldevent.event.boss.slime;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Slime;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.SlimeSplitEvent;
|
||||
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.game.clans.clans.worldevent.WorldEventManager;
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.AbstractBoss;
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.BossState;
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.slime.state.AbsorbState;
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.slime.state.RocketState;
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.slime.state.SlamState;
|
||||
import mineplex.minecraft.game.core.damage.DamageManager;
|
||||
|
||||
public class SlimeBoss extends AbstractBoss
|
||||
@ -28,13 +21,13 @@ public class SlimeBoss extends AbstractBoss
|
||||
private static final int MAX_SIZE = 10;
|
||||
private static final int MIN_SIZE = 1;
|
||||
|
||||
private List<SlimeData> _slimes;
|
||||
private List<SlimePart> _slimes;
|
||||
|
||||
public SlimeBoss(WorldEventManager eventManager, DamageManager damageManager, Location center)
|
||||
{
|
||||
super(eventManager, damageManager, "Slime King", center, 100, 300);
|
||||
|
||||
_slimes = new ArrayList<SlimeData>();
|
||||
_slimes = new LinkedList<SlimePart>();
|
||||
|
||||
spawnSlime(center, MAX_SIZE);
|
||||
}
|
||||
@ -56,34 +49,9 @@ public class SlimeBoss extends AbstractBoss
|
||||
{
|
||||
super.customTick();
|
||||
|
||||
for (SlimeData slimeData : _slimes)
|
||||
for (SlimePart slimePart : _slimes)
|
||||
{
|
||||
if (slimeData.State != null) slimeData.State.tick();
|
||||
}
|
||||
|
||||
if (getTicks() % 80 == 0)
|
||||
{
|
||||
SlimeData data = _slimes.get(getRandom().nextInt(_slimes.size()));
|
||||
|
||||
assert(data != null);
|
||||
|
||||
int num = getRandom().nextInt(3);
|
||||
|
||||
BossState state;
|
||||
|
||||
switch (num)
|
||||
{
|
||||
case 0:
|
||||
state = new AbsorbState(this, data.Entity, 20);
|
||||
break;
|
||||
case 1:
|
||||
state = new RocketState(this, data.Entity);
|
||||
break;
|
||||
default:
|
||||
state = new SlamState(this, data.Entity, getRandomTarget(data.Entity.getLocation(), 10));
|
||||
}
|
||||
|
||||
data.State = state;
|
||||
slimePart.tick();
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,9 +60,9 @@ public class SlimeBoss extends AbstractBoss
|
||||
{
|
||||
if (event.getEntity().getType() == EntityType.SLIME)
|
||||
{
|
||||
for (SlimeData slimeData : _slimes)
|
||||
for (SlimePart slimePart : _slimes)
|
||||
{
|
||||
if (event.getEntity().equals(slimeData.Entity))
|
||||
if (event.getEntity().equals(slimePart.getEntity()))
|
||||
{
|
||||
// slime.setHealth(slime.getMaxHealth());
|
||||
// event.setDamage(0);
|
||||
@ -107,9 +75,9 @@ public class SlimeBoss extends AbstractBoss
|
||||
@EventHandler
|
||||
public void onSplit(SlimeSplitEvent event)
|
||||
{
|
||||
for (SlimeData slimeData : _slimes)
|
||||
for (SlimePart slimeData : _slimes)
|
||||
{
|
||||
if (event.getEntity().equals(slimeData.Entity))
|
||||
if (event.getEntity().equals(slimeData.getEntity()))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -119,37 +87,38 @@ public class SlimeBoss extends AbstractBoss
|
||||
{
|
||||
if (event.getEntity().getType() == EntityType.SLIME)
|
||||
{
|
||||
for (SlimeData slimeData : _slimes)
|
||||
{
|
||||
if (slimeData.Entity.equals(event.getEntity()))
|
||||
{
|
||||
splitSlime(slimeData.Entity);
|
||||
Iterator<SlimePart> slimeIterator = _slimes.iterator();
|
||||
|
||||
checkDeath();
|
||||
while (slimeIterator.hasNext())
|
||||
{
|
||||
SlimePart slimePart = slimeIterator.next();
|
||||
|
||||
if (slimePart.getEntity().equals(event.getEntity()))
|
||||
{
|
||||
splitSlime(slimePart);
|
||||
event.setDroppedExp(0);
|
||||
slimeIterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if our main boss died every time a slime entity dies
|
||||
checkDeath();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this slime boss has been defeated
|
||||
*/
|
||||
private void checkDeath()
|
||||
{
|
||||
if (_slimes.size() == 0)
|
||||
{
|
||||
// SLIME IS DEAD!
|
||||
setHealth(0);
|
||||
}
|
||||
}
|
||||
|
||||
public Player getRandomTarget(Location location, double maxDist)
|
||||
{
|
||||
List<Player> nearby = UtilPlayer.getNearby(location, maxDist);
|
||||
return nearby.get(getRandom().nextInt(nearby.size()));
|
||||
}
|
||||
|
||||
public void rotateState()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public int getSplitSize(int currSize)
|
||||
{
|
||||
return currSize / 2;
|
||||
@ -165,7 +134,7 @@ public class SlimeBoss extends AbstractBoss
|
||||
return slimeSize * 20;
|
||||
}
|
||||
|
||||
private void splitSlime(Slime slime)
|
||||
private void splitSlime(SlimePart slime)
|
||||
{
|
||||
int splitCount = getSplitCount(slime.getSize());
|
||||
int splitSize = getSplitSize(slime.getSize());
|
||||
@ -174,19 +143,16 @@ public class SlimeBoss extends AbstractBoss
|
||||
{
|
||||
for (int i = 0; i < splitCount; i++)
|
||||
{
|
||||
spawnSlime(slime.getLocation(), splitSize);
|
||||
spawnSlime(slime.getEntity().getLocation(), splitSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Slime spawnSlime(Location location, int size)
|
||||
private SlimePart spawnSlime(Location location, int size)
|
||||
{
|
||||
Slime slime = location.getWorld().spawn(location, Slime.class);
|
||||
slime.setSize(size);
|
||||
slime.setMaxHealth(getMaxSlimeHealth(size));
|
||||
slime.setHealth(slime.getMaxHealth());
|
||||
_slimes.add(new SlimeData(slime));
|
||||
return slime;
|
||||
SlimePart slimePart = new SlimePart(this, location, size, getMaxSlimeHealth(size));
|
||||
_slimes.add(slimePart);
|
||||
return slimePart;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -194,15 +160,4 @@ public class SlimeBoss extends AbstractBoss
|
||||
{
|
||||
Bukkit.broadcastMessage("DEATH");
|
||||
}
|
||||
|
||||
private static class SlimeData
|
||||
{
|
||||
private final Slime Entity;
|
||||
private BossState State;
|
||||
|
||||
public SlimeData(Slime slime)
|
||||
{
|
||||
Entity = slime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,110 @@
|
||||
package mineplex.game.clans.clans.worldevent.event.boss.slime;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.MagmaCube;
|
||||
import org.bukkit.entity.Slime;
|
||||
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.slime.ability.AbsorbAbility;
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.slime.ability.RocketAbility;
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.slime.ability.SlamAbility;
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.slime.ability.SlimeAbility;
|
||||
|
||||
public class SlimePart
|
||||
{
|
||||
private SlimeBoss _boss;
|
||||
private Slime _slime;
|
||||
private SlimeAbility _currentAbility;
|
||||
private Location _spawnLocation;
|
||||
private boolean _enraged;
|
||||
// Storing size here incase one of the slime states decide to change the slime size
|
||||
private int _size;
|
||||
private double _maxHealth;
|
||||
private int _ticksLived;
|
||||
|
||||
public SlimePart(SlimeBoss boss, Location location, int size, double maxHealth)
|
||||
{
|
||||
_boss = boss;
|
||||
_spawnLocation = location;
|
||||
_enraged = false;
|
||||
_size = size;
|
||||
_maxHealth = maxHealth;
|
||||
_ticksLived = 0;
|
||||
spawn(location);
|
||||
}
|
||||
|
||||
private void spawn(Location location)
|
||||
{
|
||||
double health = _maxHealth;
|
||||
|
||||
// Remove old slime
|
||||
if (_slime != null)
|
||||
{
|
||||
health = _slime.getHealth();
|
||||
_slime.remove();
|
||||
}
|
||||
|
||||
_slime = location.getWorld().spawn(location, _enraged ? MagmaCube.class : Slime.class);
|
||||
_slime.setMaxHealth(_maxHealth);
|
||||
_slime.setHealth(health);
|
||||
_slime.setSize(_size);
|
||||
}
|
||||
|
||||
public void tick()
|
||||
{
|
||||
_ticksLived++;
|
||||
|
||||
if (_currentAbility == null || (_currentAbility.isIdle() && _currentAbility.getIdleTicks() > 80))
|
||||
{
|
||||
double rand = Math.random();
|
||||
|
||||
if (rand <= 0.33)
|
||||
{
|
||||
_currentAbility = new AbsorbAbility(this);
|
||||
}
|
||||
else if (rand <= 0.66)
|
||||
{
|
||||
_currentAbility = new RocketAbility(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentAbility = new SlamAbility(this);
|
||||
}
|
||||
}
|
||||
|
||||
_currentAbility.tick();
|
||||
}
|
||||
|
||||
public void setEnraged(boolean enraged)
|
||||
{
|
||||
if (enraged != _enraged)
|
||||
{
|
||||
_enraged = enraged;
|
||||
spawn(_slime.getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
public SlimeBoss getBoss()
|
||||
{
|
||||
return _boss;
|
||||
}
|
||||
|
||||
public boolean isEnraged()
|
||||
{
|
||||
return _enraged;
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
public Location getSpawnLocation()
|
||||
{
|
||||
return _spawnLocation;
|
||||
}
|
||||
|
||||
public Slime getEntity()
|
||||
{
|
||||
return _slime;
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package mineplex.game.clans.clans.worldevent.event.boss.slime.ability;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimePart;
|
||||
|
||||
public class AbsorbAbility extends SlimeAbility
|
||||
{
|
||||
private int _ticksPerPulse;
|
||||
private int _pulseMax;
|
||||
private int _pulseCount;
|
||||
private int _maxDistance;
|
||||
|
||||
public AbsorbAbility(SlimePart 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()
|
||||
{
|
||||
Bukkit.broadcastMessage("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.setY(0.4);
|
||||
player.setVelocity(dir);
|
||||
getSlime().getBoss().getDamageManager().NewDamageEvent(player, getSlime().getEntity(), null,
|
||||
EntityDamageEvent.DamageCause.MAGIC, getDamage(distance), false, false, false, getSlime().getBoss().getName(), "Absorb");
|
||||
}
|
||||
}
|
||||
|
||||
private double getDamage(double distance)
|
||||
{
|
||||
double mult = _maxDistance - distance;
|
||||
|
||||
return mult * 0.25;
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
package mineplex.game.clans.clans.worldevent.event.boss.slime.ability;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Slime;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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.game.clans.clans.worldevent.event.boss.slime.SlimePart;
|
||||
|
||||
public class RocketAbility extends SlimeAbility implements IThrown
|
||||
{
|
||||
private int _rocketCount;
|
||||
private int _rocketsFired;
|
||||
private int _rocketsHit;
|
||||
private LinkedList<ShotData> _shots;
|
||||
|
||||
public RocketAbility(SlimePart slime)
|
||||
{
|
||||
this(slime, 5);
|
||||
}
|
||||
|
||||
public RocketAbility(SlimePart 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().getLocation();
|
||||
loc.add(loc.getDirection().normalize().multiply(2));
|
||||
Slime projectile = loc.getWorld().spawn(loc, Slime.class);
|
||||
projectile.setSize(2);
|
||||
_shots.add(new ShotData(projectile, target));
|
||||
|
||||
ProjectileManager pm = getSlime().getBoss().getEventManager().getClans().getProjectile();
|
||||
pm.AddThrow(projectile, getSlime().getEntity(), this, -1, true, true, true, 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());
|
||||
data.GetThrown().remove();
|
||||
_rocketsHit++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Idle(ProjectileUser data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Expire(ProjectileUser data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
package mineplex.game.clans.clans.worldevent.event.boss.slime.ability;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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.game.clans.clans.worldevent.event.boss.slime.SlimePart;
|
||||
|
||||
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(SlimePart slime)
|
||||
{
|
||||
this(slime, 40, 60, 80);
|
||||
}
|
||||
|
||||
public SlamAbility(SlimePart 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 > _jumpTick)
|
||||
{
|
||||
// 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?
|
||||
LinkedList<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;
|
||||
_foundTicks = getTicks();
|
||||
Bukkit.broadcastMessage("Target placed on " + _target);
|
||||
}
|
||||
|
||||
_findAttempts++;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package mineplex.game.clans.clans.worldevent.event.boss.slime.ability;
|
||||
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimePart;
|
||||
|
||||
public abstract class SlimeAbility
|
||||
{
|
||||
private SlimePart _slime;
|
||||
private boolean _idle;
|
||||
private int _ticks;
|
||||
private int _idleTicks;
|
||||
|
||||
public SlimeAbility(SlimePart 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 SlimePart getSlime()
|
||||
{
|
||||
return _slime;
|
||||
}
|
||||
|
||||
public abstract void tickCustom();
|
||||
|
||||
protected void setIdle(boolean idle)
|
||||
{
|
||||
_idle = idle;
|
||||
}
|
||||
}
|
@ -61,23 +61,7 @@ public class RocketState extends BossState implements IThrown
|
||||
// getBoss().setState(new AbsorbState(getBoss(), ((Slime) _shooter), 20 * 2));
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,16 +78,7 @@ public class RocketState extends BossState implements IThrown
|
||||
|
||||
private void fireProjectile(LivingEntity target)
|
||||
{
|
||||
Location loc = _shooter.getEyeLocation();
|
||||
loc.add(loc.getDirection().normalize().multiply(2));
|
||||
Slime projectile = loc.getWorld().spawn(loc, Slime.class);
|
||||
projectile.setSize(2);
|
||||
// projectile.setVelocity(direction);
|
||||
_shots.add(new ShotData(projectile, target));
|
||||
|
||||
ProjectileManager pm = getBoss().getEventManager().getClans().getProjectile();
|
||||
pm.AddThrow(projectile, _shooter, this, -1, true, true, true, null, 0, 0, UtilParticle.ParticleType.SLIME, UpdateType.FASTEST, 1F);
|
||||
Bukkit.broadcastMessage("Shot Slime");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -88,20 +88,7 @@ public class SlamState extends BossState
|
||||
{
|
||||
if (event.getEntity().equals(_entity) && event.getCause() == EntityDamageEvent.DamageCause.FALL)
|
||||
{
|
||||
Location fallLoc = _entity.getLocation();
|
||||
List<Entity> nearby = _entity.getNearbyEntities(4, 4, 4);
|
||||
for (Entity near : nearby)
|
||||
{
|
||||
if (near instanceof LivingEntity)
|
||||
{
|
||||
LivingEntity le = ((LivingEntity) near);
|
||||
le.damage(4);
|
||||
le.setVelocity(UtilAlg.getTrajectory2d(fallLoc, le.getLocation()).setY(0.2));
|
||||
}
|
||||
}
|
||||
|
||||
UtilParticle.PlayParticle(UtilParticle.ParticleType.LAVA, fallLoc, 2, 0.5F, 2, 0, 100, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
|
||||
fallLoc.getWorld().playSound(fallLoc, Sound.ANVIL_LAND, 10, 0.5F);
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
package mineplex.game.clans.clans.worldevent.event.boss.slime.state;
|
||||
|
||||
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimePart;
|
||||
|
||||
public abstract class SlimeState
|
||||
{
|
||||
private SlimePart _slime;
|
||||
private boolean _idle;
|
||||
private int _ticks;
|
||||
private int _idleTicks;
|
||||
|
||||
public SlimeState(SlimePart 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 abstract void tickCustom();
|
||||
|
||||
protected void setIdle(boolean idle)
|
||||
{
|
||||
_idle = idle;
|
||||
}
|
||||
}
|
@ -54,5 +54,12 @@ public class HillData
|
||||
return x > minX && y > minY && z > minZ && x < maxX && y < maxY && z < maxZ;
|
||||
}
|
||||
|
||||
public Location getHillCenter(Location eventLocation)
|
||||
{
|
||||
Location hill = eventLocation.clone();
|
||||
hill.add(_hillX, _hillY, _hillZ);
|
||||
hill.add(_lengthX / 2.0, _lengthY / 2.0, _lengthZ / 2.0);
|
||||
return hill;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import mineplex.game.clans.clans.ClanInfo;
|
||||
import mineplex.game.clans.clans.ClansManager;
|
||||
import mineplex.game.clans.clans.worldevent.WorldEventManager;
|
||||
import mineplex.game.clans.clans.worldevent.event.AbstractWorldEvent;
|
||||
import mineplex.game.clans.economy.GoldManager;
|
||||
import mineplex.minecraft.game.core.damage.DamageManager;
|
||||
|
||||
public class KingHill extends AbstractWorldEvent
|
||||
@ -67,9 +68,6 @@ public class KingHill extends AbstractWorldEvent
|
||||
|
||||
if (getTicks() % 5 == 0)
|
||||
tickHill();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void tickHill()
|
||||
@ -87,19 +85,27 @@ public class KingHill extends AbstractWorldEvent
|
||||
clanCount++;
|
||||
lastClan = playerClan;
|
||||
}
|
||||
|
||||
// Bukkit.broadcastMessage(player.getName() + " IS ON THE HILL");
|
||||
}
|
||||
}
|
||||
|
||||
if (clanCount == 1 && lastClan != null)
|
||||
{
|
||||
Bukkit.broadcastMessage(lastClan.getName() + " owns the hill!");
|
||||
|
||||
CaptureData capData = _scoreMap.get(lastClan);
|
||||
if (capData == null)
|
||||
{
|
||||
capData = new CaptureData();
|
||||
_scoreMap.put(lastClan, capData);
|
||||
}
|
||||
capData.TicksOnHill++;
|
||||
|
||||
GoldManager.getInstance().dropGold(_hill.getHillCenter(getCenterLocation()), 20);
|
||||
}
|
||||
}
|
||||
|
||||
private static class CaptureData
|
||||
{
|
||||
public int Score;
|
||||
public int TicksOnHill;
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +1,31 @@
|
||||
package mineplex.game.clans.economy;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.items.economy.GoldToken;
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.common.CurrencyType;
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.creature.Creature;
|
||||
import mineplex.core.donation.DonationManager;
|
||||
import mineplex.core.donation.Donor;
|
||||
import mineplex.core.energy.Energy;
|
||||
import mineplex.game.clans.Clans;
|
||||
import mineplex.game.clans.fields.repository.FieldRepository;
|
||||
import mineplex.game.clans.items.generation.WeightSet;
|
||||
import mineplex.minecraft.game.core.condition.ConditionFactory;
|
||||
import mineplex.minecraft.game.core.condition.ConditionManager;
|
||||
|
||||
public class GoldManager extends MiniPlugin
|
||||
{
|
||||
@ -39,13 +35,15 @@ public class GoldManager extends MiniPlugin
|
||||
public static GoldManager getInstance() { return _instance; }
|
||||
|
||||
private DonationManager _donationManager;
|
||||
|
||||
private HashSet<Item> _itemSet;
|
||||
|
||||
public GoldManager(JavaPlugin plugin, DonationManager donationManager)
|
||||
{
|
||||
super("Clans Gold", plugin);
|
||||
|
||||
_instance = this;
|
||||
_donationManager = donationManager;
|
||||
_itemSet = new HashSet<Item>();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -75,10 +73,41 @@ public class GoldManager extends MiniPlugin
|
||||
{
|
||||
if (event.getMessage().startsWith("/gold"))
|
||||
{
|
||||
notify(event.getPlayer(), "Your Balance is " + C.cYellow + getGold(event.getPlayer()) + "g");
|
||||
notify(event.getPlayer(), "Your Balance is " + C.cYellow + getGold(event.getPlayer()) + "g");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPickup(PlayerPickupItemEvent event)
|
||||
{
|
||||
if (_itemSet.contains(event.getItem()))
|
||||
{
|
||||
event.setCancelled(true);
|
||||
event.getItem().remove();
|
||||
event.getPlayer().playSound(event.getPlayer().getEyeLocation(), Sound.ORB_PICKUP, 1F, 1F);
|
||||
addGold(event.getPlayer(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void cleanItems(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.SEC) return;
|
||||
|
||||
Iterator<Item> itemIterator = _itemSet.iterator();
|
||||
|
||||
while (itemIterator.hasNext())
|
||||
{
|
||||
Item item = itemIterator.next();
|
||||
|
||||
if (!item.isValid() || item.getTicksLived() >= 12000) // 10 minutes
|
||||
{
|
||||
item.remove();
|
||||
itemIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getGold(Player player)
|
||||
{
|
||||
@ -101,6 +130,25 @@ public class GoldManager extends MiniPlugin
|
||||
addGold(player, value);
|
||||
notify(player, String.format("You have cashed in a gold token worth %dg!", value));
|
||||
}
|
||||
|
||||
public void dropGold(Location location, int amount)
|
||||
{
|
||||
dropGold(location, amount, 1);
|
||||
}
|
||||
|
||||
public void dropGold(Location location, int amount, double mult)
|
||||
{
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
Item item = location.getWorld().dropItem(location, new ItemStack(Material.GOLD_INGOT));
|
||||
item.setPickupDelay(40);
|
||||
|
||||
// Velocity
|
||||
double x = Math.random() * 2 * Math.PI;
|
||||
Vector velocity = new Vector(Math.sin(x), 0, Math.cos(x));
|
||||
UtilAction.velocity(item, velocity, mult, false, 0, 0.2, 0.5, false);
|
||||
}
|
||||
}
|
||||
|
||||
private Donor getDonor(Player player)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user