Mineplex2018-withcommit/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java
2015-08-16 08:39:03 +02:00

535 lines
15 KiB
Java

package mineplex.hub.modules;
import java.util.ArrayList;
import java.util.HashSet;
import org.bukkit.EntityEffect;
import org.bukkit.FireworkEffect.Type;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Bat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Firework;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Slime;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.WitherSkull;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerVelocityEvent;
import org.bukkit.util.Vector;
import mineplex.core.MiniPlugin;
import mineplex.core.common.util.C;
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.UtilFirework;
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.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.event.GadgetActivateEvent;
import mineplex.core.gadget.gadgets.OutfitTeam;
import mineplex.core.gadget.types.Gadget;
import mineplex.core.gadget.types.GadgetType;
import mineplex.core.mount.event.MountActivateEvent;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.hub.HubManager;
public class SoccerManager extends MiniPlugin
{
public HubManager Manager;
private HashSet<Player> _active = new HashSet<Player>();
private ArrayList<OutfitTeam> _teamArmor = new ArrayList<OutfitTeam>();
private Location _cornerFieldPlayerA;
private Location _cornerFieldPlayerB;
private Location _cornerGoalPlayerA;
private Location _cornerGoalPlayerB;
private Location _cornerFieldA;
private Location _cornerFieldB;
private Location _cornerRedGoalA;
private Location _cornerRedGoalB;
private Location _cornerBlueGoalA;
private Location _cornerBlueGoalB;
int _blueGoals = 0;
int _redGoals = 0;
int _insideGoalTicks = 0;
private Slime _ball;
private Vector _ballVel;
private long _ballDeadTime = -1;
private String _lastKicker = "";
private Color _lastKick = null;
//Item Rebound
protected Vector _vel;
protected Location _lastLoc;
protected ArrayList<Vector> _velHistory = new ArrayList<Vector>();
public SoccerManager(HubManager manager, GadgetManager gadgets)
{
super("Football Manager", manager.getPlugin());
Manager = manager;
_cornerFieldPlayerA = new Location(Manager.GetSpawn().getWorld(), 28.5,70,-27.5);
_cornerFieldPlayerB = new Location(Manager.GetSpawn().getWorld(), 50.5,100,-65.5);
_cornerGoalPlayerA = new Location(Manager.GetSpawn().getWorld(), 35.5,70,-24.5);
_cornerGoalPlayerB = new Location(Manager.GetSpawn().getWorld(), 43.5,100,-68.5);
_cornerFieldA = new Location(Manager.GetSpawn().getWorld(), 29.75,70,-28.75);
_cornerFieldB = new Location(Manager.GetSpawn().getWorld(), 49.25,100,-64.25);
_cornerRedGoalA = new Location(Manager.GetSpawn().getWorld(), 36.75,70,-64.25);
_cornerRedGoalB = new Location(Manager.GetSpawn().getWorld(), 42.25,73.5,-67.25);
_cornerBlueGoalA = new Location(Manager.GetSpawn().getWorld(), 36.75,70,-25.75);
_cornerBlueGoalB = new Location(Manager.GetSpawn().getWorld(), 42.25,73.5,-28.75);
//Store Gadgets
for (Gadget gadget : gadgets.getGadgets(GadgetType.Costume))
{
if (gadget instanceof OutfitTeam)
{
_teamArmor.add((OutfitTeam)gadget);
}
}
}
@EventHandler
public void ballUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
if (_active.size() <= 0)
{
_blueGoals = 0;
_redGoals = 0;
if (_ball != null)
_ball.remove();;
return;
}
//New Ball Needed
if (_ballDeadTime == -1 && (_ball == null || !_ball.isValid()))
{
if (_ball != null)
_ball.remove();
_ballDeadTime = System.currentTimeMillis();
}
//Spawn Ball
if (_ballDeadTime > 0 && UtilTime.elapsed(_ballDeadTime, 4000))
{
Location mid = UtilAlg.getMidpoint(_cornerFieldPlayerA, _cornerFieldPlayerB);
if (!mid.getChunk().isLoaded())
return;
_ball = mid.getWorld().spawn(mid, Slime.class);
_ball.setSize(2);
UtilEnt.Vegetate(_ball);
UtilEnt.ghost(_ball, true, false);
_ballVel = new Vector(0,-0.1,0);
UtilFirework.playFirework(mid, Type.BALL, Color.YELLOW, false, false);
_ballDeadTime = -1;
_vel = new Vector(0,-0.1,0);
_velHistory.add(_vel);
_lastLoc = _ball.getLocation();
}
if (_ball == null)
return;
if (_lastKick == Color.AQUA)
{
for (int i = 0 ; i < 3 ; i++)
UtilParticle.PlayParticle(ParticleType.RED_DUST, _ball.getLocation().add(0.0, 0.5, 0.0), -1, 1, 1, 1, 0,
ViewDist.NORMAL, UtilServer.getPlayers());
}
else
{
for (int i = 0 ; i < 3 ; i++)
UtilParticle.PlayParticle(ParticleType.RED_DUST, _ball.getLocation().add(0.0, 0.5, 0.0), 0, 0, 0, 0, 1,
ViewDist.NORMAL, UtilServer.getPlayers());
}
//Kick
for (Player player : _active)
{
if (UtilMath.offset(player, _ball) < 1.5 ||
UtilMath.offset(player.getEyeLocation(), _ball.getLocation()) < 1.25)
{
if (Recharge.Instance.use(player, "Football Kick", 600, false, false))
{
_ballVel = player.getLocation().getDirection();
_ballVel.setY(_ballVel.getY() + 0.4);
if (UtilEnt.isGrounded(_ball) && _ballVel.getY() <= 0)
_ballVel.setY(0);
_ballVel.setY(Math.min(_ballVel.getY(), 1));
_ball.getWorld().playSound(_ball.getLocation(), Sound.ZOMBIE_WOOD, 0.5f, 1.5f);
UtilParticle.PlayParticle(ParticleType.SLIME,
UtilAlg.getMidpoint(_ball.getLocation(), player.getLocation()),
0, 0, 0, 0, 5, ViewDist.NORMAL, UtilServer.getPlayers());
UtilAction.zeroVelocity(player);
_lastKick = getTeamColor(player);
if (_lastKick == null)
_lastKicker = player.getName();
else if (_lastKick == Color.RED)
_lastKicker = C.cRed + player.getName();
else if (_lastKick == Color.AQUA)
_lastKicker = C.cAqua + player.getName();
}
}
}
//Blue Goal
if (UtilAlg.inBoundingBox(_ball.getLocation(), _cornerRedGoalA, _cornerRedGoalB) &&
!UtilAlg.inBoundingBox(_ball.getLocation(), _cornerFieldA, _cornerFieldB))
{
_insideGoalTicks++;
if (_insideGoalTicks > 3)
{
UtilFirework.playFirework(_ball.getLocation(), Type.BALL, Color.AQUA, true, true);
_blueGoals++;
for (Player player : _active)
UtilTextMiddle.display("Goal! (" + C.cRed + _redGoals + C.cWhite + " : " + C.cBlue + _blueGoals + C.cWhite + ")",
_lastKicker + C.cWhite + " scored for " + C.cAqua + "Blue Team", 0, 70, 20, player);
_ball.remove();
_ball = null;
}
return;
}
//Red Goal
else if (UtilAlg.inBoundingBox(_ball.getLocation(), _cornerBlueGoalA, _cornerBlueGoalB) &&
!UtilAlg.inBoundingBox(_ball.getLocation(), _cornerFieldA, _cornerFieldB))
{
_insideGoalTicks++;
if (_insideGoalTicks > 3)
{
UtilFirework.playFirework(_ball.getLocation(), Type.BALL, Color.RED, true, true);
_redGoals++;
for (Player player : _active)
UtilTextMiddle.display("Goal! (" + C.cRed + _redGoals + C.cWhite + " : " + C.cBlue + _blueGoals + C.cWhite + ")",
_lastKicker + C.cWhite + " scored for " + C.cRed + "Red Team", 0, 70, 20, player);
_ball.remove();
_ball = null;
}
return;
}
else
{
_insideGoalTicks = 0;
}
//Wind Drag
_ballVel = _ballVel.multiply(0.99);
//Ground Drag
if (UtilEnt.isGrounded(_ball))
_ballVel = _ballVel.multiply(0.98);
//Rebound Y
if (UtilEnt.isGrounded(_ball))
{
if (_ballVel.getY() < -0.1)
{
_ballVel.setY(_ballVel.getY() * -0.65);
}
}
//Gravity
if (!UtilEnt.isGrounded(_ball))
_ballVel.setY(_ballVel.getY() - 0.04);
//Rebound X
if ((_ballVel.getX() > 0 && _ball.getLocation().getX() > Math.max(_cornerFieldA.getX(), _cornerFieldB.getX())) ||
(_ballVel.getX() < 0 && _ball.getLocation().getX() < Math.min(_cornerFieldA.getX(), _cornerFieldB.getX())))
{
_ballVel.setX(_ballVel.getX() * -1);
_ballVel = _ballVel.multiply(0.9);
_ball.getWorld().playSound(_ball.getLocation(), Sound.ZOMBIE_WOOD, 0.5f, 1.5f);
UtilParticle.PlayParticle(ParticleType.LARGE_EXPLODE, _ball.getLocation(), 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers());
}
//Rebound Z
if ((_ballVel.getZ() > 0 && _ball.getLocation().getZ() > Math.max(_cornerFieldA.getZ(), _cornerFieldB.getZ())) ||
(_ballVel.getZ() < 0 && _ball.getLocation().getZ() < Math.min(_cornerFieldA.getZ(), _cornerFieldB.getZ())))
{
_ballVel.setZ(_ballVel.getZ() * -1);
_ballVel = _ballVel.multiply(0.9);
_ball.getWorld().playSound(_ball.getLocation(), Sound.ZOMBIE_WOOD, 0.5f, 1.5f);
UtilParticle.PlayParticle(ParticleType.LARGE_EXPLODE, _ball.getLocation(), 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers());
}
//Move Ball
_ball.setVelocity(_ballVel);
}
public Color getTeamColor(Player player)
{
//All peices are always same color!
for (OutfitTeam outfit : _teamArmor)
{
if (outfit.IsActive(player))
return outfit.getTeamColor(player);
}
return null;
}
public boolean inPlayerArena(Entity entity)
{
return UtilAlg.inBoundingBox(entity.getLocation(), _cornerFieldPlayerA, _cornerFieldPlayerB) ||
UtilAlg.inBoundingBox(entity.getLocation(), _cornerGoalPlayerA, _cornerGoalPlayerB);
}
@EventHandler
public void clean(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER)
return;
for (Entity ent : _cornerFieldA.getWorld().getEntities())
{
if (ent instanceof Player)
continue;
if (_ball != null && _ball.equals(ent))
continue;
if (inPlayerArena(ent))
{
if (ent instanceof Bat || ent instanceof WitherSkull || ent instanceof TNTPrimed || ent instanceof Firework)
{
ent.remove();
continue;
}
Location bounce = UtilAlg.getMidpoint(_cornerFieldPlayerA, _cornerFieldPlayerB);
bounce.setY(Math.min(_cornerFieldPlayerA.getY(), _cornerFieldPlayerB.getY()));
Entity bottom = ent;
if (bottom.getVehicle() != null)
bottom = bottom.getVehicle();
UtilAction.velocity(bottom, UtilAlg.getTrajectory(bounce, ent.getLocation()), 1, false, 0, 0.4, 1, true);
}
}
}
@EventHandler
public void joinLeaveGame(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
for (Player player : UtilServer.getPlayers())
{
if (_active.contains(player))
{
if (!inPlayerArena(player))
{
setSoccerMode(player, false, null);
continue;
}
//Took armor off
Color color = getTeamColor(player);
if (color == null || (color != Color.RED && color != Color.AQUA))
{
setSoccerMode(player, false, null);
}
}
else
{
if (inPlayerArena(player))
{
Color color = getTeamColor(player);
//Join
if (color != null && (color == Color.RED || color == Color.AQUA) && _active.size() < 8)
{
setSoccerMode(player, true, color);
}
//Eject
else
{
Location bounce = UtilAlg.getMidpoint(_cornerFieldPlayerA, _cornerFieldPlayerB);
bounce.setY(Math.min(_cornerFieldPlayerA.getY(), _cornerFieldPlayerB.getY()));
Entity bottom = player;
if (bottom.getVehicle() != null)
bottom = bottom.getVehicle();
UtilAction.velocity(bottom, UtilAlg.getTrajectory2d(bounce, player.getLocation()), 1, false, 0, 0.8, 1, true);
if (Recharge.Instance.use(player, "Soccer Eject", 5000, false, false))
{
if (_active.size() < 8)
{
UtilPlayer.message(player, F.main("Slimeball", "You must be wearing Red/Blue Team Outfit."));
UtilPlayer.message(player, F.main("Slimeball", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!"));
}
else
{
UtilPlayer.message(player, F.main("Slimeball", "The game is currently full!"));
}
}
}
}
}
}
}
public void setSoccerMode(Player player, boolean enabled, Color color)
{
if (enabled)
{
_active.add(player);
if (color == null)
UtilPlayer.message(player, F.main("Parkour", "You have entered " + F.elem("Slimeball Mode") + "."));
else if (color == Color.RED)
UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cRed + "Red Slimeball Team") + "."));
else if (color == Color.AQUA)
UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cAqua + "Blue Slimeball Team") + "."));
ArrayList<String> outfit = new ArrayList<String>();
outfit.add("Team Helmet");
outfit.add("Team Shirt");
outfit.add("Team Pants");
outfit.add("Team Boots");
Manager.GetGadget().DisableAll(player, outfit);
Manager.GetMount().DisableAll(player);
Manager.getPetManager().DisableAll(player);
}
else
{
_active.remove(player);
UtilPlayer.message(player, F.main("Parkour", "You have exited " + F.elem("Slimeball Mode") + "."));
}
}
public boolean isSoccerMode(Player player)
{
return _active.contains(player);
}
@EventHandler
public void disableGadgets(GadgetActivateEvent event)
{
if (isSoccerMode(event.getPlayer()))
event.setCancelled(true);
}
@EventHandler
public void disableMounts(MountActivateEvent event)
{
if (isSoccerMode(event.getPlayer()))
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.LOWEST)
public void playerGrabSlime(PlayerInteractEntityEvent event)
{
if (_active.contains(event.getPlayer()))
event.setCancelled(true);
if (_ball != null && event.getRightClicked().equals(_ball))
event.setCancelled(true);
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
_active.remove(event.getPlayer());
}
@EventHandler(priority = EventPriority.HIGHEST)
public void allowDamage(EntityDamageByEntityEvent event)
{
if (!(event.getEntity() instanceof Player) || !(event.getDamager() instanceof Player))
return;
Player damager = (Player)event.getDamager();
Player damagee = (Player)event.getEntity();
if (!_active.contains(damager) || !_active.contains(damagee))
return;
if (getTeamColor(damager) == null || getTeamColor(damagee) == null)
return;
if (getTeamColor(damager) == getTeamColor(damagee))
return;
if (Recharge.Instance.use(damagee, "Football Damage", 800, false, false))
{
UtilAction.velocity(damagee, UtilAlg.getTrajectory2d(damager, damagee), 0.6, false, 0, 0.3, 1, true);
damagee.playEffect(EntityEffect.HURT);
}
}
}