diff --git a/Plugins/Nautilus.Game.MineKart/.classpath b/Plugins/Nautilus.Game.MineKart/.classpath
new file mode 100644
index 000000000..652a7606a
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/.classpath
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plugins/Nautilus.Game.MineKart/.externalToolBuilders/MineKart Builder.launch b/Plugins/Nautilus.Game.MineKart/.externalToolBuilders/MineKart Builder.launch
new file mode 100644
index 000000000..21979608a
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/.externalToolBuilders/MineKart Builder.launch
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plugins/Nautilus.Game.MineKart/.project b/Plugins/Nautilus.Game.MineKart/.project
new file mode 100644
index 000000000..50f9fe4d1
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/.project
@@ -0,0 +1,26 @@
+
+
+ Nautilus.Game.MineKart
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/MineKart Builder.launch
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/Plugins/Nautilus.Game.MineKart/.settings/org.eclipse.jdt.core.prefs b/Plugins/Nautilus.Game.MineKart/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..7341ab168
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/Plugins/Nautilus.Game.MineKart/plugin.yml b/Plugins/Nautilus.Game.MineKart/plugin.yml
new file mode 100644
index 000000000..e600dfb55
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/plugin.yml
@@ -0,0 +1,3 @@
+name: MineKart
+main: nautilus.game.minekart.MineKart
+version: 1.0
\ No newline at end of file
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/KartFactory.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/KartFactory.java
new file mode 100644
index 000000000..75faca4b3
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/KartFactory.java
@@ -0,0 +1,92 @@
+package nautilus.game.minekart;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import nautilus.game.minekart.kart.KartType;
+import nautilus.game.minekart.repository.KartItemToken;
+import nautilus.game.minekart.repository.KartRepository;
+import nautilus.game.minekart.shop.KartItem;
+
+import org.bukkit.Material;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import mineplex.core.MiniPlugin;
+import mineplex.core.common.util.NautHashMap;
+import mineplex.core.donation.repository.GameSalesPackageToken;
+
+public class KartFactory extends MiniPlugin
+{
+ private KartRepository _repository;
+ private NautHashMap _karts;
+ private List _sortedKarts;
+
+ public KartFactory(JavaPlugin plugin, KartRepository repository)
+ {
+ super("Kart Factory", plugin);
+
+ _repository = repository;
+ _karts = new NautHashMap();
+
+ PopulateKarts();
+ }
+
+ public Collection GetKarts()
+ {
+ return _sortedKarts;
+ }
+
+ private void PopulateKarts()
+ {
+ _karts.put("Chicken", new KartItem(Material.FEATHER, KartType.Chicken));
+ _karts.put("Sheep", new KartItem(Material.WHEAT, KartType.Sheep));
+ _karts.put("Cow", new KartItem(Material.MILK_BUCKET, KartType.Cow));
+ _karts.put("Pig", new KartItem(Material.GRILLED_PORK, KartType.Pig));
+ _karts.put("Spider", new KartItem(Material.STRING, KartType.Spider));
+ _karts.put("Wolf", new KartItem(Material.SUGAR, KartType.Wolf));
+ _karts.put("Enderman", new KartItem(Material.FIREBALL, KartType.Enderman));
+ _karts.put("Blaze", new KartItem(Material.BLAZE_ROD, KartType.Blaze));
+ _karts.put("Golem", new KartItem(Material.IRON_INGOT, KartType.Golem));
+
+ List itemTokens = new ArrayList();
+
+ for (KartItem item : _karts.values())
+ {
+ KartItemToken itemToken = new KartItemToken();
+ itemToken.Name = item.GetName();
+ itemToken.Material = item.GetDisplayMaterial().toString();
+ itemToken.Data = item.GetDisplayData() + "";
+ itemToken.SalesPackage = new GameSalesPackageToken();
+
+ itemTokens.add(itemToken);
+ }
+
+ for (KartItemToken itemToken : _repository.GetKartItems(itemTokens))
+ {
+ if (_karts.containsKey(itemToken.Name))
+ {
+ _karts.get(itemToken.Name).Update(itemToken.SalesPackage);
+ }
+ }
+
+ _sortedKarts = new ArrayList(_karts.values());
+
+ Collections.sort(_sortedKarts, new Comparator()
+ {
+ @Override
+ public int compare(KartItem kartItem1, KartItem kartItem2)
+ {
+ if (kartItem1.GetKartType().GetStability() < kartItem2.GetKartType().GetStability())
+ return -1;
+
+ if (kartItem1.GetKartType().GetStability() == kartItem2.GetKartType().GetStability())
+ return 0;
+
+ return 1;
+ }
+ });
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/MineKart.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/MineKart.java
new file mode 100644
index 000000000..17bb5b3ac
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/MineKart.java
@@ -0,0 +1,309 @@
+package nautilus.game.minekart;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.antistack.AntiStack;
+import mineplex.core.blockrestore.BlockRestore;
+import mineplex.core.command.CommandCenter;
+import mineplex.core.common.CurrencyType;
+import mineplex.core.creature.Creature;
+import mineplex.core.donation.DonationManager;
+import mineplex.core.explosion.Explosion;
+import mineplex.core.fakeEntity.FakeEntity;
+import mineplex.core.fakeEntity.FakeEntityManager;
+import mineplex.core.itemstack.ItemStackFactory;
+import mineplex.core.join.JoinQuit;
+import mineplex.core.memory.MemoryFix;
+import mineplex.core.monitor.LagMeter;
+import mineplex.core.npc.NpcManager;
+import mineplex.core.packethandler.PacketHandler;
+import mineplex.core.punish.Punish;
+import mineplex.core.recharge.Recharge;
+import mineplex.core.server.ServerListener;
+import mineplex.core.spawn.Spawn;
+import mineplex.core.status.ServerStatusManager;
+import mineplex.core.teleport.Teleport;
+import mineplex.core.updater.Updater;
+import nautilus.game.minekart.gp.GPManager;
+import nautilus.game.minekart.kart.KartManager;
+import nautilus.game.minekart.menu.KartMenu;
+import nautilus.game.minekart.repository.KartRepository;
+import nautilus.game.minekart.shop.KartShop;
+import nautilus.game.minekart.track.TrackManager;
+import nautilus.game.minekart.track.TrackProcessor;
+import nautilus.minecraft.core.INautilusPlugin;
+import net.minecraft.server.v1_7_R1.EntityPlayer;
+
+import org.apache.commons.io.FileDeleteStrategy;
+import org.bukkit.GameMode;
+import org.bukkit.Location;
+import org.bukkit.Server;
+import org.bukkit.craftbukkit.v1_7_R1.entity.CraftPlayer;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.BlockBreakEvent;
+import org.bukkit.event.block.BlockBurnEvent;
+import org.bukkit.event.block.BlockFromToEvent;
+import org.bukkit.event.block.BlockGrowEvent;
+import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.event.entity.FoodLevelChangeEvent;
+import org.bukkit.event.player.PlayerBucketEmptyEvent;
+import org.bukkit.event.player.PlayerBucketFillEvent;
+import org.bukkit.event.player.PlayerDropItemEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.plugin.PluginManager;
+import org.bukkit.plugin.java.JavaPlugin;
+
+public class MineKart extends JavaPlugin implements INautilusPlugin, Listener
+{
+ private String WEB_CONFIG = "webServer";
+
+ //Modules
+ private CoreClientManager _clientManager;
+ private DonationManager _donationManager;
+ private BlockRestore _blockRestore;
+ private Creature _creature;
+ private Spawn _spawn;
+ private Teleport _teleport;
+
+ private GPManager _gpManager;
+
+ private ServerListener _serverListener;
+
+ private Location _spawnLocation;
+
+ private FakeEntity _chicken;
+ private FakeEntity _wolf;
+ private FakeEntity _pig;
+ private FakeEntity _spider;
+ private FakeEntity _sheep;
+ private FakeEntity _cow;
+ private FakeEntity _golem;
+ private FakeEntity _blaze;
+ private FakeEntity _enderman;
+
+ @Override
+ public void onEnable()
+ {
+ ClearRaceFolders();
+
+ getConfig().addDefault(WEB_CONFIG, "http://accounts.mineplex.com/");
+ getConfig().set(WEB_CONFIG, getConfig().getString(WEB_CONFIG));
+ saveConfig();
+
+ _spawnLocation = new Location(this.getServer().getWorlds().get(0), 8.5, 17, -22.5, 0f, 0f);
+
+ _clientManager = CoreClientManager.Initialize(this, GetWebServerAddress());
+ CommandCenter.Initialize(this, _clientManager);
+ FakeEntityManager.Initialize(this);
+ Recharge.Initialize(this);
+
+ _donationManager = new DonationManager(this, GetWebServerAddress());
+
+ _creature = new Creature(this);
+
+ new Punish(this, GetWebServerAddress(), _clientManager);
+ new Explosion(this, _blockRestore);
+
+ _teleport = new Teleport(this, _clientManager, _spawn);
+
+ //Unreferenced Modules
+ new AntiStack(this);
+ //new Chat(this, GetClans(), _repository);
+ new JoinQuit();
+ new ServerStatusManager(this, new LagMeter(this, _clientManager));
+
+
+ PacketHandler packetHandler = new PacketHandler(this);
+
+ ItemStackFactory.Initialize(this, true);
+
+ //Kart
+ _gpManager = new GPManager(this, _donationManager, _teleport, Recharge.Instance, new KartManager(this, Recharge.Instance), new TrackManager(this, _teleport));
+ new TrackProcessor();
+
+ //Updates
+ new Updater(this);
+
+ //_serverListener = new ServerListener(GetWebServerAddress(), getServer().getIp(), getServer().getPort() + 1);
+
+ //new TabLobbyList(this, playerNamer.PacketHandler, _clientManager, _donationManager, true);
+
+ FakeEntityManager.Instance.SetPacketHandler(packetHandler);
+ DonationManager donationManager = new DonationManager(this, GetWebServerAddress());
+
+ new NpcManager(this, _creature);
+ KartFactory _kartFactory = new KartFactory(this, new KartRepository(GetWebServerAddress()));
+ new KartShop(_kartFactory, _clientManager, donationManager, CurrencyType.Gems);
+ new KartMenu(_kartFactory, _clientManager, donationManager, _gpManager);
+
+ new MemoryFix(this);
+
+ getServer().getPluginManager().registerEvents(this, this);
+
+ CreateFakeKarts();
+ }
+
+ @EventHandler
+ public void OnPlayerJoin(PlayerJoinEvent event)
+ {
+ event.getPlayer().teleport(_spawnLocation);
+ event.getPlayer().setGameMode(GameMode.SURVIVAL);
+ event.getPlayer().setFoodLevel(20);
+ event.getPlayer().setHealth(20d);
+ ShowFakeKarts(event.getPlayer());
+ }
+
+ @EventHandler
+ public void PreventFoodChange(FoodLevelChangeEvent event)
+ {
+ if (event.getEntity() instanceof Player && !_gpManager.InGame((Player)event.getEntity()))
+ {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void onBlockBreakEvent(BlockBreakEvent event)
+ {
+ if (!event.getPlayer().isOp())
+ {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void onBlockPlaceEvent(BlockPlaceEvent event)
+ {
+ if (!event.getPlayer().isOp())
+ event.setCancelled(true);
+ }
+
+ @EventHandler
+ public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event)
+ {
+ if (!event.getPlayer().isOp())
+ event.setCancelled(true);
+ }
+
+ @EventHandler
+ public void onPlayerBucketFill(PlayerBucketFillEvent event)
+ {
+ if (!event.getPlayer().isOp())
+ event.setCancelled(true);
+ }
+
+ @EventHandler
+ public void PreventDrop(PlayerDropItemEvent event)
+ {
+ event.setCancelled(true);
+ }
+
+ @EventHandler
+ public void BurnCancel(BlockBurnEvent event)
+ {
+ event.setCancelled(true);
+ }
+
+ @EventHandler
+ public void SpreadCancel(BlockFromToEvent event)
+ {
+ event.setCancelled(true);
+ }
+
+ @EventHandler
+ public void GrowCancel(BlockGrowEvent event)
+ {
+ event.setCancelled(true);
+ }
+
+ @Override
+ public void onDisable()
+ {
+ _serverListener.Shutdown();
+ }
+
+ @Override
+ public JavaPlugin GetPlugin()
+ {
+ return this;
+ }
+
+ @Override
+ public String GetWebServerAddress()
+ {
+ return getConfig().getString(WEB_CONFIG);
+ }
+
+ @Override
+ public Server GetRealServer()
+ {
+ return getServer();
+ }
+
+ @Override
+ public PluginManager GetPluginManager()
+ {
+ return GetRealServer().getPluginManager();
+ }
+
+ private void CreateFakeKarts()
+ {
+ _chicken = new FakeEntity(EntityType.CHICKEN, new Location(_spawnLocation.getWorld(), 6.5, 17.5, -39.5, 0f, 0f));
+ _wolf = new FakeEntity(EntityType.WOLF, new Location(_spawnLocation.getWorld(), 8.5, 17.5, -39.5, 0f, 0f));
+ _pig = new FakeEntity(EntityType.PIG, new Location(_spawnLocation.getWorld(), 10.5, 17.5, -39.5, 0f, 0f));
+ _spider = new FakeEntity(EntityType.SPIDER, new Location(_spawnLocation.getWorld(), 6.5, 19.5, -39.5, 0f, 0f));
+ _sheep = new FakeEntity(EntityType.SHEEP, new Location(_spawnLocation.getWorld(), 8.5, 19.5, -39.5, 0f, 0f));
+ _cow = new FakeEntity(EntityType.COW, new Location(_spawnLocation.getWorld(), 10.5, 19.5, -39.5, 0f, 0f));
+ _golem = new FakeEntity(EntityType.IRON_GOLEM, new Location(_spawnLocation.getWorld(), 6.5, 21.5, -39.5, 0f, 0f));
+ _blaze = new FakeEntity(EntityType.BLAZE, new Location(_spawnLocation.getWorld(), 8.5, 21.5, -39.5, 0f, 0f));
+ _enderman = new FakeEntity(EntityType.ENDERMAN, new Location(_spawnLocation.getWorld(), 10.5, 21.5, -39.5, 0f, 0f));
+ }
+
+ private void ShowFakeKarts(Player player)
+ {
+ EntityPlayer mcPlayer = ((CraftPlayer)player).getHandle();
+
+ mcPlayer.playerConnection.sendPacket(_chicken.Spawn());
+ mcPlayer.playerConnection.sendPacket(_wolf.Spawn());
+ mcPlayer.playerConnection.sendPacket(_pig.Spawn());
+ mcPlayer.playerConnection.sendPacket(_spider.Spawn());
+ mcPlayer.playerConnection.sendPacket(_sheep.Spawn());
+ mcPlayer.playerConnection.sendPacket(_cow.Spawn());
+ mcPlayer.playerConnection.sendPacket(_golem.Spawn());
+ mcPlayer.playerConnection.sendPacket(_blaze.Spawn());
+ mcPlayer.playerConnection.sendPacket(_enderman.Spawn());
+ }
+
+ private void ClearRaceFolders()
+ {
+ File mainDirectory = new File(".");
+
+ FileFilter statsFilter = new FileFilter()
+ {
+ @Override
+ public boolean accept(File arg0)
+ {
+ return arg0.isDirectory() && arg0.getName().contains("-");
+ }
+ };
+
+ for (File f : mainDirectory.listFiles(statsFilter))
+ {
+ try
+ {
+ FileDeleteStrategy.FORCE.delete(f);
+
+ }
+ catch (IOException e)
+ {
+ System.out.println("Error deleting " + f.getName() + " on startup.");
+ }
+ }
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GP.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GP.java
new file mode 100644
index 000000000..493a00624
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GP.java
@@ -0,0 +1,416 @@
+package nautilus.game.minekart.gp;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.InputStreamReader;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+import org.bukkit.scoreboard.DisplaySlot;
+import org.bukkit.scoreboard.Objective;
+import org.bukkit.scoreboard.Score;
+import org.bukkit.scoreboard.Scoreboard;
+import org.bukkit.scoreboard.ScoreboardManager;
+import org.fusesource.jansi.Ansi.Color;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.fakeEntity.FakeEntityManager;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartType;
+import nautilus.game.minekart.track.Track;
+import nautilus.game.minekart.track.Track.TrackState;
+
+public class GP
+{
+ public enum GPState
+ {
+ Recruit,
+ Live,
+ Ended
+ }
+
+ public GPManager Manager;
+
+ private GPState _state = GPState.Recruit;
+
+ private int _gpId = 0;
+
+ private HashMap _players = new HashMap();
+
+ private Scoreboard _scoreScoreboard;
+ private Objective _scoreObjective;
+
+ private Scoreboard _posScoreboard;
+ private Objective _posObjective;
+
+ private boolean _switchScoreboards;
+
+ private GPSet _trackSet;
+ private int _trackIndex = -1;
+ private Track[] _trackArray = null;
+
+ private int _maxKarts = 10;
+
+ public GP(GPManager manager, GPSet trackSet)
+ {
+ Manager = manager;
+ _trackSet = trackSet;
+
+ _gpId = GetNewId();
+
+ //Prepare Tracks
+ _trackArray = new Track[_trackSet.GetMapNames().length];
+ for (int i=0 ; i<_trackArray.length ; i++)
+ {
+ _trackArray[i] = new Track(this, Manager.GetTeleport(), Manager.GetRecharge(), _trackSet.GetMapNames()[i], i);
+ }
+ }
+
+ public GPState GetState()
+ {
+ return _state;
+ }
+
+ public int GetId()
+ {
+ return _gpId;
+ }
+
+ public GPSet GetSet()
+ {
+ return _trackSet;
+ }
+
+ public Track GetTrack()
+ {
+ if (_trackIndex == -1)
+ return null;
+
+ if (_trackIndex >= _trackArray.length)
+ return null;
+
+ return _trackArray[_trackIndex];
+ }
+
+ public Track GetTrack(int id)
+ {
+ try
+ {
+ return _trackArray[id];
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ public Track[] GetTracks()
+ {
+ return _trackArray;
+ }
+
+ public int GetMaxKarts()
+ {
+ return _maxKarts;
+ }
+
+ public Collection GetPlayers()
+ {
+ return _players.keySet();
+ }
+
+ public Collection GetKarts()
+ {
+ HashSet _karts = new HashSet();
+
+ for (Player player : GetPlayers())
+ {
+ Kart kart = Manager.KartManager.GetKart(player);
+
+ if (kart != null)
+ _karts.add(kart);
+ }
+
+ return _karts;
+ }
+
+ public void SetState(GPState state)
+ {
+ _state = state;
+ }
+
+ public void NextTrack()
+ {
+ _trackIndex++;
+
+ for (Kart kart : GetKarts())
+ {
+ kart.ClearTrackData();
+
+ kart.SetItemCycles(0);
+ kart.SetItemStored(null);
+ }
+
+ if (_trackIndex < _trackArray.length)
+ {
+ for (Kart kart : GetKarts())
+ {
+ kart.SetItemStored(null);
+ kart.SetItemActive(null);
+
+ kart.GetDriver().eject();
+ kart.GetDriver().leaveVehicle();
+ }
+
+ GetTrack().Initialize();
+ }
+ else
+ {
+ _trackIndex--;
+ //Load Castle
+ Manager.CreateResult(this);
+
+ _trackIndex++;
+
+ for (Kart kart : GetKarts())
+ {
+ Manager.KartManager.RemoveKart(kart.GetDriver());
+ FakeEntityManager.Instance.RemoveForward(kart.GetDriver());
+ FakeEntityManager.Instance.RemoveFakeVehicle(kart.GetDriver(), kart.GetEntity().GetEntityId());
+ }
+
+ Announce(F.main("MK", "Ended Set: " + F.elem(_trackSet.GetName())));
+
+ SetState(GPState.Ended);
+ }
+ }
+
+ public void AddPlayer(Player player, KartType type)
+ {
+ _players.put(player, type);
+
+ Manager.KartManager.AddKart(player, type, this);
+ }
+
+ public void RemovePlayer(Player player, Kart kart)
+ {
+ _players.remove(player);
+
+ if (_scoreScoreboard != null)
+ {
+ _scoreScoreboard.resetScores(Bukkit.getOfflinePlayer(Color.WHITE + player.getName()));
+ }
+
+ if (_posScoreboard != null)
+ {
+ ChatColor col = ChatColor.YELLOW;
+ if (kart != null && kart.GetLap() > 3)
+ col = ChatColor.GREEN;
+
+ _posScoreboard.resetScores(Bukkit.getOfflinePlayer(col + player.getName()));
+ }
+
+ if (kart != null)
+ for (Track track : _trackArray)
+ track.RemoveKart(kart);
+
+ if (this instanceof GPBattle)
+ Announce(F.main("MK", player.getName() + " has left the Battle."));
+ else
+ Announce(F.main("MK", player.getName() + " has left the Grand Prix."));
+ }
+
+ public void UpdateScoreBoard()
+ {
+ if (GetTrack() == null)
+ return;
+
+ if (GetTrack().GetState() == TrackState.Ended)
+ {
+ if (_scoreScoreboard == null)
+ {
+ ScoreboardManager manager = Bukkit.getScoreboardManager();
+ _scoreScoreboard = manager.getNewScoreboard();
+
+ _scoreObjective = _scoreScoreboard.registerNewObjective("showposition", "dummy");
+ _scoreObjective.setDisplaySlot(DisplaySlot.SIDEBAR);
+ _scoreObjective.setDisplayName(ChatColor.AQUA + "Total Score");
+
+ _switchScoreboards = true;
+ }
+
+ if (_switchScoreboards)
+ {
+ for (Kart kart : GetTrack().GetPositions())
+ {
+ if (kart.GetDriver() == null || !kart.GetDriver().isOnline())
+ continue;
+
+ kart.GetDriver().setScoreboard(_scoreScoreboard);
+ }
+
+ _switchScoreboards = false;
+ }
+
+ for (Kart kart : GetTrack().GetPositions())
+ {
+ if (kart.GetDriver() == null || !kart.GetDriver().isOnline())
+ continue;
+
+ Score score = _scoreObjective.getScore(Bukkit.getOfflinePlayer(UtilPlayer.safeNameLength(ChatColor.WHITE + kart.GetDriver().getName())));
+ score.setScore(GetScore(kart));
+ }
+ }
+ else
+ {
+ if (_posScoreboard == null)
+ {
+ ScoreboardManager manager = Bukkit.getScoreboardManager();
+ _posScoreboard = manager.getNewScoreboard();
+
+ _posObjective = _posScoreboard.registerNewObjective("showposition", "dummy");
+ _posObjective.setDisplaySlot(DisplaySlot.SIDEBAR);
+ _posObjective.setDisplayName(ChatColor.AQUA + "Kart Positions");
+
+ _switchScoreboards = true;
+ }
+
+ for (Kart kart : GetTrack().GetPositions())
+ {
+ if (kart.GetDriver() == null || !kart.GetDriver().isOnline())
+ continue;
+
+ ChatColor col = ChatColor.YELLOW;
+
+ if (kart.GetLap() > 3)
+ {
+ col = ChatColor.GREEN;
+ _posScoreboard.resetScores(Bukkit.getOfflinePlayer(UtilPlayer.safeNameLength(ChatColor.YELLOW + kart.GetDriver().getName())));
+ }
+ else
+ {
+ _posScoreboard.resetScores(Bukkit.getOfflinePlayer(UtilPlayer.safeNameLength(ChatColor.GREEN + kart.GetDriver().getName())));
+ }
+
+ Score score = _posObjective.getScore(Bukkit.getOfflinePlayer(UtilPlayer.safeNameLength(col + kart.GetDriver().getName())));
+ score.setScore(kart.GetLapPlace() + 1);
+ }
+
+ if (_switchScoreboards)
+ {
+ for (Kart kart : GetTrack().GetPositions())
+ {
+ if (kart.GetDriver() == null || !kart.GetDriver().isOnline())
+ continue;
+
+
+ kart.GetDriver().setScoreboard(_posScoreboard);
+ }
+
+ _switchScoreboards = false;
+ }
+ }
+ }
+
+ public int GetScore(Kart kart)
+ {
+ int score = 0;
+
+ for (Track track : _trackArray)
+ for (int i=0 ; i 16)
+ name = name.substring(0, 16);
+
+ Score score = objective.getScore(Bukkit.getOfflinePlayer(name));
+ score.setScore(GetScore(kart));
+ }
+
+ for (Kart kart : GetKarts())
+ {
+ if (kart.GetDriver() == null || !kart.GetDriver().isOnline())
+ continue;
+
+ kart.GetDriver().setScoreboard(board);
+ }
+ }
+ else
+ {
+ ScoreboardManager manager = Bukkit.getScoreboardManager();
+ Scoreboard board = manager.getNewScoreboard();
+
+ Objective objective = board.registerNewObjective("showposition", "dummy");
+ objective.setDisplaySlot(DisplaySlot.SIDEBAR);
+ objective.setDisplayName(ChatColor.AQUA + "Kart Balloons");
+
+ for (Kart kart : GetKarts())
+ {
+ if (kart.GetDriver() == null || !kart.GetDriver().isOnline())
+ continue;
+
+ ChatColor col = ChatColor.GRAY;
+ if (kart.GetLives() == 3) col = ChatColor.GREEN;
+ else if (kart.GetLives() == 2) col = ChatColor.YELLOW;
+ else if (kart.GetLives() == 1) col = ChatColor.RED;
+
+ String name = col + kart.GetDriver().getName();
+ if (name.length() > 16)
+ name = name.substring(0, 16);
+
+ Score score = objective.getScore(Bukkit.getOfflinePlayer(name));
+ score.setScore(kart.GetLives());
+ }
+
+ for (Kart kart : GetKarts())
+ {
+ if (kart.GetDriver() == null || !kart.GetDriver().isOnline())
+ continue;
+
+ kart.GetDriver().setScoreboard(board);
+ }
+ }
+ }
+
+ public void CheckBattleEnd()
+ {
+ if (GetTrack().GetState() == TrackState.Loading || GetTrack().GetState() == TrackState.Countdown)
+ return;
+
+ int alive = 0;
+ Kart winner = null;
+ for (Kart kart : GetKarts())
+ {
+ if (kart.GetLives() > 0)
+ {
+ alive++;
+ winner = kart;
+ }
+ }
+
+ if (alive > 1)
+ return;
+
+ if (GetTrack().GetState() != TrackState.Ended)
+ {
+ this.GetTrack().GetPositions().add(0, winner);
+ GetTrack().SetState(TrackState.Ended);
+ }
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GPManager.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GPManager.java
new file mode 100644
index 000000000..79c99c9af
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GPManager.java
@@ -0,0 +1,532 @@
+package nautilus.game.minekart.gp;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import nautilus.game.minekart.gp.GP.GPState;
+import nautilus.game.minekart.gp.command.GpCommand;
+import nautilus.game.minekart.gp.command.ItemCommand;
+import nautilus.game.minekart.gp.command.KartCommand;
+import nautilus.game.minekart.gp.command.VoteCommand;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartType;
+import nautilus.game.minekart.kart.KartManager;
+import nautilus.game.minekart.track.Track.TrackState;
+import nautilus.game.minekart.track.TrackManager;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.block.BlockSpreadEvent;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
+import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
+import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.event.player.AsyncPlayerChatEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerLoginEvent;
+import org.bukkit.event.player.PlayerLoginEvent.Result;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.event.server.ServerListPingEvent;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import mineplex.core.MiniPlugin;
+import mineplex.core.portal.Portal;
+import mineplex.core.recharge.Recharge;
+import mineplex.core.teleport.Teleport;
+import mineplex.core.updater.event.RestartServerEvent;
+import mineplex.core.updater.event.UpdateEvent;
+import mineplex.core.updater.UpdateType;
+import mineplex.core.common.util.C;
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.common.util.UtilServer;
+import mineplex.core.common.util.UtilTime;
+import mineplex.core.common.util.UtilWorld;
+import mineplex.core.donation.DonationManager;
+
+public class GPManager extends MiniPlugin
+{
+ private DonationManager _donationManager;
+ private Teleport _teleport;
+ private Recharge _recharge;
+
+ public KartManager KartManager;
+ public TrackManager TrackManager;
+ public Portal Portal;
+
+ //Queue Data
+ private GPSet _set;
+ private Location _spawn;
+
+ private ArrayList _players = new ArrayList();
+ private HashMap _playerVote = new HashMap();
+ private HashMap _kartSelect = new HashMap();
+
+ private long _voteTimer = 0;
+ private int _startTimer = 0;
+
+ //Live Sets
+ private HashSet _live = new HashSet();
+
+ //Result Maps
+ private HashSet _results = new HashSet();
+
+ public GPManager(JavaPlugin plugin, DonationManager donationManager, Teleport teleport, Recharge recharge, KartManager kartManager, TrackManager trackManager)
+ {
+ super("Race Manager", plugin);
+
+ _donationManager = donationManager;
+ _teleport = teleport;
+ _recharge = recharge;
+ KartManager = kartManager;
+ TrackManager = trackManager;
+ Portal = new Portal(plugin);
+
+ _spawn = new Location(UtilWorld.getWorld("world"), 8.5, 18, -22.5);
+ }
+
+ @Override
+ public void AddCommands()
+ {
+ AddCommand(new GpCommand(this));
+ AddCommand(new ItemCommand(this));
+ AddCommand(new KartCommand(this));
+ AddCommand(new VoteCommand(this));
+ }
+
+ public void SelectKart(Player player, KartType kart)
+ {
+ _kartSelect.put(player, kart);
+ UtilPlayer.message(player, F.main("MK", "You selected " + F.elem(kart.GetName() + " Kart") + "."));
+ }
+
+ public KartType GetSelectedKart(Player player)
+ {
+ if (!_kartSelect.containsKey(player))
+ _kartSelect.put(player, KartType.Sheep);
+
+ return _kartSelect.get(player);
+ }
+
+ @EventHandler
+ public void restartServerCheck(RestartServerEvent event)
+ {
+ if (_live.size() > 0 || _results.size() > 0)
+ event.setCancelled(true);
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR)
+ public void Motd(ServerListPingEvent event)
+ {
+ if (_live.size() > 0)
+ {
+ if (_live.iterator().next() instanceof GPBattle)
+ {
+ event.setMotd(ChatColor.AQUA + "In Battle...");
+ }
+ else
+ {
+ event.setMotd(ChatColor.AQUA + "In Race...");
+ }
+
+ event.setMaxPlayers(_plugin.getServer().getOnlinePlayers().length);
+ }
+ else
+ {
+ event.setMotd(ChatColor.GREEN + GetSet().GetName());
+ event.setMaxPlayers(10);
+ }
+ }
+
+ @EventHandler
+ public void CheckStart(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.SEC)
+ return;
+
+ //Full
+ if (_players.size() >= 10)
+ {
+ StartGP(false);
+ return;
+ }
+
+ //Votes
+ int votes = 0;
+ for (boolean vote : _playerVote.values())
+ {
+ if (vote)
+ votes++;
+ }
+
+ int needed = (_players.size() / 2) + (_players.size()%2);
+
+ if (votes >= needed && _players.size() >= 4)
+ {
+ StartGP(false);
+ }
+ else
+ {
+ if (UtilTime.elapsed(_voteTimer, 30000))
+ {
+ if (_players.size() >= 4)
+ {
+ Announce(F.main("MK", "Type " + F.elem(C.cGreen + "/vote") + " to start the game with less players."));
+ Announce(F.main("MK", F.elem((needed - votes)+"") + " more votes needed..."));
+ }
+ else
+ {
+ Announce(F.main("MK", "Waiting for players..."));
+ }
+
+
+ _voteTimer = System.currentTimeMillis();
+ }
+ }
+ }
+
+ public void StartGP(boolean force)
+ {
+ if (!force && _startTimer > 0)
+ {
+ Announce(F.main("MK", "Starting in " + F.time(UtilTime.MakeStr(_startTimer * 1000)) + "."));
+ _startTimer--;
+
+ return;
+ }
+
+ GP gp;
+ if (GetSet() != GPSet.Battle) gp = new GP(this, GetSet());
+ else gp = new GPBattle(this, GetSet());
+
+ //Add Players
+ int added = 0;
+ while (added < 10)
+ {
+ if (_players.isEmpty())
+ break;
+
+ Player player = _players.remove(0);
+ gp.AddPlayer(player, GetSelectedKart(player));
+
+ //Clean Player
+ _playerVote.remove(player);
+ _kartSelect.remove(player);
+
+ added++;
+ }
+
+ //Set Live
+ gp.SetState(GPState.Live);
+ gp.NextTrack();
+ _live.add(gp);
+ }
+
+ public void Vote(Player caller)
+ {
+ if (!_playerVote.containsKey(caller))
+ return;
+
+ boolean vote = _playerVote.get(caller);
+
+ _playerVote.put(caller, !vote);
+
+ if (!vote) Announce(F.main("MK", F.elem(caller.getName()) + " has " + F.elem(C.cGreen + "voted") + " to start the game."));
+ else Announce(F.main("MK", F.elem(caller.getName()) + " has " + F.elem(C.cRed + "unvoted") + " to start the game."));
+ }
+
+ public void Announce(String string)
+ {
+ for (Player player : _players)
+ UtilPlayer.message(player, string);
+ }
+
+ public GP GetGP(Player player)
+ {
+ for (GP race : _live)
+ if (race.GetPlayers().contains(player))
+ return race;
+
+ return null;
+ }
+
+ @EventHandler
+ public void PlayerLogin(PlayerLoginEvent event)
+ {
+ if (_live.size() > 0)
+ {
+ event.disallow(Result.KICK_FULL, ChatColor.AQUA + "A race is already in progress.");
+ }
+ }
+
+ @EventHandler
+ public void PlayerJoin(PlayerJoinEvent event)
+ {
+ Player player = event.getPlayer();
+ _players.add(player);
+ _playerVote.put(player, false);
+ _startTimer = 20;
+
+ player.teleport(_spawn);
+ }
+
+ @EventHandler
+ public void PlayerQuit(PlayerQuitEvent event)
+ {
+ Player player = event.getPlayer();
+
+ //Remove Kart Choice
+ _kartSelect.remove(player);
+
+ //Remove Kart
+ Kart kart = KartManager.GetKart(player);
+ if (kart != null)
+ KartManager.RemoveKart(kart.GetDriver());
+
+ //Leave Queue
+ _players.remove(player);
+ _playerVote.remove(player);
+ _kartSelect.remove(player);
+
+ //Leave GP
+ GP gp = GetGP(player);
+ if (gp != null)
+ gp.RemovePlayer(player, kart);
+
+ //Leave Result
+ for (GPResult result : _results)
+ result.RemovePlayer(player);
+
+ if (gp != null && gp.GetPlayers().size() == 0)
+ _plugin.getServer().shutdown();
+ }
+
+ @EventHandler
+ public void TeleportSpawn(EntityDamageEvent event)
+ {
+ if (event.getCause() != DamageCause.VOID)
+ return;
+
+ if (!_players.contains(event.getEntity()))
+ return;
+
+ event.getEntity().teleport(_spawn);
+ }
+
+ @EventHandler
+ public void UpdateGPScoreboard(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.FASTEST)
+ return;
+
+ for (GP gp : _live)
+ {
+ if (gp.GetState() != GPState.Ended && gp.GetTrack().GetState() != TrackState.Countdown)
+ {
+ gp.UpdateScoreBoard();
+ }
+ }
+ }
+
+ @EventHandler
+ public void UpdateGP(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.TICK)
+ return;
+
+ HashSet remove = new HashSet();
+
+ for (GP gp : _live)
+ {
+ if (gp.GetState() == GPState.Ended)
+ {
+ remove.add(gp);
+ continue;
+ }
+
+ if (gp.GetTrack().GetState() == TrackState.Countdown)
+ {
+ gp.GetTrack().SpawnTeleport();
+ }
+
+ if (gp instanceof GPBattle)
+ ((GPBattle)gp).CheckBattleEnd();
+
+ gp.GetTrack().Update();
+ }
+
+ for (GP gp : remove)
+ {
+ gp.Unload();
+ _live.remove(gp);
+ }
+ }
+
+ @EventHandler
+ public void UpdateGPResult(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.SEC)
+ return;
+
+ HashSet remove = new HashSet();
+
+ for (GPResult result : _results)
+ {
+ if (result.End())
+ remove.add(result);
+ }
+
+ for (GPResult result : remove)
+ {
+ _results.remove(result);
+ _plugin.getServer().getScheduler().scheduleSyncDelayedTask(_plugin, new Runnable()
+ {
+ public void run()
+ {
+ _plugin.getServer().shutdown();
+ }
+ }, 100L);
+ }
+ }
+
+ @EventHandler
+ public void CreatureSpawn(CreatureSpawnEvent event)
+ {
+ if (event.getSpawnReason() == SpawnReason.NATURAL || event.getSpawnReason() == SpawnReason.DEFAULT || event.getSpawnReason() == SpawnReason.EGG)
+ event.setCancelled(true);
+ }
+
+ @EventHandler
+ public void BlockSpread(BlockSpreadEvent event)
+ {
+ event.setCancelled(true);
+ }
+
+ public GPResult CreateResult(GP gp)
+ {
+ GPResult result = new GPResult(gp, _donationManager);
+ _results.add(result);
+ return result;
+ }
+
+ public void DeleteResult(GPResult result)
+ {
+ _results.remove(result);
+ }
+
+ @EventHandler
+ public void HandleChat(AsyncPlayerChatEvent event)
+ {
+ event.setCancelled(true);
+
+ final String message = event.getMessage();
+ final Player sender = event.getPlayer();
+ final GP senderGP = GetGP(event.getPlayer());
+
+ //Talk to GP
+ if (senderGP != null)
+ {
+ _plugin.getServer().getScheduler().scheduleSyncDelayedTask(_plugin, new Runnable()
+ {
+ public void run()
+ {
+ senderGP.Announce(C.cYellow + sender.getName() + " " + C.cWhite + message);
+ }
+ }, 0);
+ }
+ else
+ {
+ for (Player player : UtilServer.getPlayers())
+ {
+ if (GetGP(player) != null)
+ continue;
+
+ final Player recipient = player;
+
+ _plugin.getServer().getScheduler().scheduleSyncDelayedTask(_plugin, new Runnable()
+ {
+ public void run()
+ {
+ UtilPlayer.message(recipient, C.cYellow + sender.getName() + " " + C.cWhite + message);
+ }
+ }, 0);
+ }
+ }
+ }
+
+ public boolean InGame(Player player)
+ {
+ return GetGP(player) != null;
+ }
+
+ public GPSet GetSet()
+ {
+ if (_set == null)
+ {
+ File file = new File("GPSet.dat");
+
+ //Write If Blank
+ if (!file.exists())
+ {
+ try
+ {
+ FileWriter fstream = new FileWriter(file);
+ BufferedWriter out = new BufferedWriter(fstream);
+
+ out.write("MushroomCup");
+
+ out.close();
+ }
+ catch (Exception e)
+ {
+ System.out.println("Error: GP Set Write Exception");
+ }
+ }
+
+ //Read
+ try
+ {
+ FileInputStream fstream = new FileInputStream(file);
+ DataInputStream in = new DataInputStream(fstream);
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ String line = br.readLine();
+
+ _set = GPSet.valueOf(line);
+
+ in.close();
+ }
+ catch (Exception e)
+ {
+ System.out.println("Error: GP Set Read Exception");
+ }
+ }
+
+ if (_set == null)
+ {
+ return GPSet.MushroomCup;
+ }
+
+ return _set;
+ }
+
+ public Teleport GetTeleport()
+ {
+ return _teleport;
+ }
+
+ public Recharge GetRecharge()
+ {
+ return _recharge;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GPResult.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GPResult.java
new file mode 100644
index 000000000..a22a58db9
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GPResult.java
@@ -0,0 +1,258 @@
+package nautilus.game.minekart.gp;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import mineplex.core.common.util.FileUtil;
+import mineplex.core.common.util.FireworkUtil;
+import mineplex.core.common.util.MapUtil;
+import mineplex.core.common.util.UtilServer;
+import mineplex.core.common.util.UtilTime;
+import mineplex.core.common.util.WorldChunkLoader;
+import mineplex.core.common.util.WorldLoadInfo;
+import mineplex.core.common.util.WorldUtil;
+import mineplex.core.donation.DonationManager;
+import mineplex.core.fakeEntity.FakeEntity;
+import mineplex.core.fakeEntity.FakePlayer;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.minecraft.core.utils.ZipUtil;
+import net.minecraft.server.v1_7_R1.EntityPlayer;
+
+import org.apache.commons.lang.math.RandomUtils;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.WorldCreator;
+import org.bukkit.craftbukkit.v1_7_R1.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+
+public class GPResult
+{
+ private GPManager Manager;
+
+ private String _file = "Result";
+
+ private World _world;
+ private GP _gp;
+
+ private boolean _initialized = false;
+
+ private long _time;
+
+ private Kart _first;
+ private Kart _second;
+ private Kart _third;
+
+ private List _fireworkLocations;
+
+ public GPResult(GP gp, DonationManager manager)
+ {
+ Manager = gp.Manager;
+
+ _gp = gp;
+
+ _time = System.currentTimeMillis();
+
+ List sortedScores = new ArrayList(_gp.GetKarts());
+ Collections.sort(sortedScores, new ScoreComparator(_gp));
+
+ int buffer = (_gp instanceof GPBattle ? 9 : 14);
+
+ if (_gp.GetTrack().GetPositions().size() > 0 && sortedScores.size() > 0)
+ {
+ _first = sortedScores.get(0);
+ manager.RewardGems(null, "Earned Minekart", _first.GetDriver().getName(), 8 * _gp.GetPlayers().size() + buffer);
+ }
+
+ buffer += 2;
+
+ if (_gp.GetTrack().GetPositions().size() > 1 && sortedScores.size() > 1)
+ {
+ _second = sortedScores.get(1);
+ manager.RewardGems(null, "Earned Minekart", _second.GetDriver().getName(), 5 * _gp.GetPlayers().size() + buffer);
+ }
+
+ buffer += 2;
+
+ if (_gp.GetTrack().GetPositions().size() > 2 && sortedScores.size() > 2)
+ {
+ _third = sortedScores.get(2);
+ manager.RewardGems(null, "Earned Minekart", _third.GetDriver().getName(), 2 * _gp.GetPlayers().size() + buffer);
+ }
+
+ buffer += 2;
+
+ for (int i = 3; i < sortedScores.size(); i++)
+ {
+ manager.RewardGems(null, "Earned Minekart", sortedScores.get(i).GetDriver().getName(), buffer);
+ }
+
+ _fireworkLocations = new ArrayList(5);
+
+ Initialise();
+ }
+
+ public void TeleportPlayers()
+ {
+ Location loc = new Location(_world, 10, 23, -22);
+ loc.setYaw(180);
+
+ FakePlayer firstPlayer = null;
+ FakePlayer secondPlayer = null;
+ FakePlayer thirdPlayer = null;
+
+ FakeEntity firstKart = null;
+ FakeEntity secondKart = null;
+ FakeEntity thirdKart = null;
+
+ if (_first != null)
+ {
+ Location location = new Location(_world, 10, 25, -29);
+ firstPlayer = new FakePlayer(_first.GetDriver().getName(), location);
+ firstKart = new FakeEntity(_first.GetEntity().GetEntityType(), location);
+ }
+
+ if (_second != null)
+ {
+ Location location = new Location(_world, 6, 24, -29);
+ secondPlayer = new FakePlayer(_second.GetDriver().getName(), location);
+ secondKart = new FakeEntity(_second.GetEntity().GetEntityType(), location);
+ }
+
+ if (_third != null)
+ {
+ Location location = new Location(_world, 14, 23, -29);
+ thirdPlayer = new FakePlayer(_third.GetDriver().getName(), location);
+ thirdKart = new FakeEntity(_third.GetEntity().GetEntityType(), location);
+ }
+
+ for (Player player : _gp.GetPlayers())
+ {
+ if (!player.isOnline())
+ continue;
+
+ Manager.GetTeleport().TP(player, loc);
+
+ EntityPlayer entityPlayer = ((CraftPlayer)player).getHandle();
+
+ if (_first != null)
+ {
+ entityPlayer.playerConnection.sendPacket(firstPlayer.Spawn());
+ entityPlayer.playerConnection.sendPacket(firstKart.Spawn());
+ entityPlayer.playerConnection.sendPacket(firstKart.SetPassenger(firstPlayer.GetEntityId()));
+ }
+
+ if (_second != null)
+ {
+ entityPlayer.playerConnection.sendPacket(secondPlayer.Spawn());
+ entityPlayer.playerConnection.sendPacket(secondKart.Spawn());
+ entityPlayer.playerConnection.sendPacket(secondKart.SetPassenger(secondPlayer.GetEntityId()));
+ }
+
+ if (_third != null)
+ {
+ entityPlayer.playerConnection.sendPacket(thirdPlayer.Spawn());
+ entityPlayer.playerConnection.sendPacket(thirdKart.Spawn());
+ entityPlayer.playerConnection.sendPacket(thirdKart.SetPassenger(thirdPlayer.GetEntityId()));
+ }
+ }
+ }
+
+ public void Initialise()
+ {
+ UtilServer.getServer().getScheduler().runTaskAsynchronously(Manager.GetPlugin(), new Runnable()
+ {
+ public void run()
+ {
+ //Unzip
+ UnzipWorld();
+
+ SetLocations();
+
+ //Load Track Data Sync
+ UtilServer.getServer().getScheduler().runTask(Manager.GetPlugin(), new Runnable()
+ {
+ public void run()
+ {
+ WorldChunkLoader.AddWorld(new WorldLoadInfo(_world, -5, -6, 5, 2), new Runnable()
+ {
+ public void run()
+ {
+ _initialized = true;
+ TeleportPlayers();
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+
+ protected void SetLocations()
+ {
+ _fireworkLocations.add(new Location(_world, -9.5, 42, -54.5));
+ _fireworkLocations.add(new Location(_world, 29.5, 42, -54.5));
+ _fireworkLocations.add(new Location(_world, 32.5, 43, -77.5));
+ _fireworkLocations.add(new Location(_world, -12.5, 43, -77.5));
+ _fireworkLocations.add(new Location(_world, 10, 61, -61));
+ }
+
+ public void UnzipWorld()
+ {
+ //Unzip
+ String folder = _gp.GetId() + "-" + _gp.GetSet().GetName() + "-" + _file;
+ new File(folder).mkdir();
+ new File(folder + File.separatorChar + "region").mkdir();
+ new File(folder + File.separatorChar + "data").mkdir();
+ ZipUtil.UnzipToDirectory(_file + ".zip", folder);
+
+ //Start World
+ _world = WorldUtil.LoadWorld(new WorldCreator(folder));
+ }
+
+ public void Uninitialise()
+ {
+ MapUtil.UnloadWorld(Manager.GetPlugin(), _world);
+ MapUtil.ClearWorldReferences(_world.getName());
+ FileUtil.DeleteFolder(new File(_world.getName()));
+
+ _first = null;
+ _second = null;
+ _third = null;
+
+ _fireworkLocations.clear();
+
+ _world = null;
+ }
+
+ public boolean End()
+ {
+ if (!_initialized)
+ return false;
+
+ if (!UtilTime.elapsed(_time, 30000))
+ {
+ FireworkUtil.LaunchRandomFirework(_fireworkLocations.get(RandomUtils.nextInt(5)));
+
+ return false;
+ }
+
+ for (Player player : _gp.GetPlayers())
+ {
+ Manager.Portal.SendPlayerToServer(player, "Lobby");
+ }
+
+ //Clean
+ _gp.GetPlayers().clear();
+ _gp = null;
+ Uninitialise();
+
+ return true;
+ }
+
+ public void RemovePlayer(Player player)
+ {
+ _gp.RemovePlayer(player, null);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GPSet.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GPSet.java
new file mode 100644
index 000000000..f6f753505
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/GPSet.java
@@ -0,0 +1,47 @@
+package nautilus.game.minekart.gp;
+
+import org.bukkit.Material;
+
+public enum GPSet
+{
+ MushroomCup("Mushroom Cup", new String[] {"MushroomA", "MushroomB", "MushroomC", "MushroomD"}, Material.RAW_CHICKEN, false),
+ FlowerCup( "Flower Cup", new String[] {"MushroomA", "MushroomB", "MushroomC", "MushroomD"}, Material.COOKED_CHICKEN, false),
+ StarCup( "Star Cup", new String[] {"MushroomA", "MushroomB", "MushroomC", "MushroomD"}, Material.CARROT_ITEM, false),
+ SpecialCup( "Special Cup", new String[] {"MushroomA", "MushroomB", "MushroomC", "MushroomD"}, Material.GOLDEN_CARROT, false),
+
+ Battle("Battle", new String[] {"BattleA", "BattleB", "BattleC"}, Material.RAW_BEEF, true);
+
+
+ private String _name;
+ private String[] _mapNames;
+ private Material _displayMat;
+ private boolean _battle;
+
+ GPSet(String name, String[] mapNames, Material mat, boolean battle)
+ {
+ _name = name;
+ _mapNames = mapNames;
+ _displayMat = mat;
+ _battle = battle;
+ }
+
+ public String GetName()
+ {
+ return _name;
+ }
+
+ public String[] GetMapNames()
+ {
+ return _mapNames;
+ }
+
+ public Material GetDisplayMaterial()
+ {
+ return _displayMat;
+ }
+
+ public boolean IsBattle()
+ {
+ return _battle;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/ScoreComparator.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/ScoreComparator.java
new file mode 100644
index 000000000..768a3e70f
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/ScoreComparator.java
@@ -0,0 +1,27 @@
+package nautilus.game.minekart.gp;
+
+import java.util.Comparator;
+
+import nautilus.game.minekart.kart.Kart;
+
+public class ScoreComparator implements Comparator
+{
+ private GP _gp;
+
+ public ScoreComparator(GP gp)
+ {
+ _gp = gp;
+ }
+
+ @Override
+ public int compare(Kart kart1, Kart kart2)
+ {
+ if (_gp.GetScore(kart1) > _gp.GetScore(kart2))
+ return -1;
+
+ if (_gp.GetScore(kart1) == _gp.GetScore(kart2))
+ return 0;
+
+ return 1;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/GpCommand.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/GpCommand.java
new file mode 100644
index 000000000..691934dba
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/GpCommand.java
@@ -0,0 +1,26 @@
+package nautilus.game.minekart.gp.command;
+
+import org.bukkit.entity.Player;
+
+import nautilus.game.minekart.gp.GPManager;
+import nautilus.game.minekart.gp.command.gp.FinishCommand;
+import nautilus.game.minekart.gp.command.gp.StartCommand;
+import mineplex.core.command.MultiCommandBase;
+import mineplex.core.common.Rank;
+
+public class GpCommand extends MultiCommandBase
+{
+ public GpCommand(GPManager plugin)
+ {
+ super(plugin, Rank.MODERATOR, "gp");
+
+ AddCommand(new StartCommand(plugin));
+ AddCommand(new FinishCommand(plugin));
+ }
+
+ @Override
+ protected void Help(Player caller, String[] args)
+ {
+
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/ItemCommand.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/ItemCommand.java
new file mode 100644
index 000000000..c35b26ede
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/ItemCommand.java
@@ -0,0 +1,32 @@
+package nautilus.game.minekart.gp.command;
+
+import org.bukkit.entity.Player;
+
+import nautilus.game.minekart.gp.GPManager;
+import nautilus.game.minekart.item.KartItemType;
+import nautilus.game.minekart.kart.Kart;
+import mineplex.core.command.CommandBase;
+import mineplex.core.common.Rank;
+import mineplex.core.common.util.UtilEnum;
+
+public class ItemCommand extends CommandBase
+{
+ public ItemCommand(GPManager plugin)
+ {
+ super(plugin, Rank.MODERATOR, "item");
+ }
+
+ @Override
+ public void Execute(Player caller, String[] args)
+ {
+ if (args.length < 1)
+ return;
+
+ Kart kart = Plugin.KartManager.GetKart(caller);
+
+ KartItemType kartItem = UtilEnum.fromString(KartItemType.class, args[0]);
+
+ if (kart != null)
+ kart.SetItemStored(kartItem);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/KartCommand.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/KartCommand.java
new file mode 100644
index 000000000..6d98dc25f
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/KartCommand.java
@@ -0,0 +1,31 @@
+package nautilus.game.minekart.gp.command;
+
+import org.bukkit.entity.Player;
+
+import nautilus.game.minekart.gp.GPManager;
+import nautilus.game.minekart.kart.KartType;
+import mineplex.core.command.CommandBase;
+import mineplex.core.common.Rank;
+
+public class KartCommand extends CommandBase
+{
+ public KartCommand(GPManager plugin)
+ {
+ super(plugin, Rank.ADMIN, "kart");
+ }
+
+ @Override
+ public void Execute(Player caller, String[] args)
+ {
+ if (args.length < 1)
+ return;
+
+ for (KartType type : KartType.values())
+ {
+ if (args[0].equalsIgnoreCase(type.GetName()))
+ {
+ Plugin.SelectKart(caller, type);
+ }
+ }
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/VoteCommand.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/VoteCommand.java
new file mode 100644
index 000000000..2cb65b741
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/VoteCommand.java
@@ -0,0 +1,21 @@
+package nautilus.game.minekart.gp.command;
+
+import org.bukkit.entity.Player;
+
+import nautilus.game.minekart.gp.GPManager;
+import mineplex.core.command.CommandBase;
+import mineplex.core.common.Rank;
+
+public class VoteCommand extends CommandBase
+{
+ public VoteCommand(GPManager plugin)
+ {
+ super(plugin, Rank.ALL, "vote");
+ }
+
+ @Override
+ public void Execute(Player caller, String[] args)
+ {
+ Plugin.Vote(caller);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/gp/FinishCommand.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/gp/FinishCommand.java
new file mode 100644
index 000000000..288ec221b
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/gp/FinishCommand.java
@@ -0,0 +1,38 @@
+package nautilus.game.minekart.gp.command.gp;
+
+import org.bukkit.entity.Player;
+
+import nautilus.game.minekart.gp.GP;
+import nautilus.game.minekart.gp.GP.GPState;
+import nautilus.game.minekart.gp.GPManager;
+import nautilus.game.minekart.kart.Kart;
+import mineplex.core.command.CommandBase;
+import mineplex.core.common.Rank;
+
+public class FinishCommand extends CommandBase
+{
+ public FinishCommand(GPManager plugin)
+ {
+ super(plugin, Rank.MODERATOR, "finish");
+ }
+
+ @Override
+ public void Execute(Player caller, String[] args)
+ {
+ GP race = Plugin.GetGP(caller);
+ if (race == null)
+ {
+ caller.sendMessage("You are not in a race");
+ return;
+ }
+
+ if (race.GetState() != GPState.Live)
+ {
+ caller.sendMessage("Your race is not live...");
+ return;
+ }
+
+ for (Kart kart : race.GetKarts())
+ kart.SetLap(4);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/gp/StartCommand.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/gp/StartCommand.java
new file mode 100644
index 000000000..432cea324
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/gp/command/gp/StartCommand.java
@@ -0,0 +1,21 @@
+package nautilus.game.minekart.gp.command.gp;
+
+import org.bukkit.entity.Player;
+
+import nautilus.game.minekart.gp.GPManager;
+import mineplex.core.command.CommandBase;
+import mineplex.core.common.Rank;
+
+public class StartCommand extends CommandBase
+{
+ public StartCommand(GPManager plugin)
+ {
+ super(plugin, Rank.MODERATOR, "start");
+ }
+
+ @Override
+ public void Execute(Player caller, String[] args)
+ {
+ Plugin.StartGP(true);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemActive.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemActive.java
new file mode 100644
index 000000000..c53b5232f
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemActive.java
@@ -0,0 +1,49 @@
+package nautilus.game.minekart.item;
+
+import java.util.List;
+
+import nautilus.game.minekart.kart.Kart;
+
+public abstract class KartItemActive
+{
+ public enum ActiveType
+ {
+ Behind,
+ Orbit,
+ Trail
+ }
+
+ private Kart _kart;
+ private ActiveType _type;
+ private List _ents;
+
+ public KartItemActive(KartItemManager manager, Kart kart, ActiveType type, List ents)
+ {
+ _kart = kart;
+ _type = type;
+ _ents = ents;
+
+ for (KartItemEntity item : ents)
+ item.SetHost(this);
+
+ kart.SetItemActive(this);
+ manager.RegisterKartItem(this);
+ }
+
+ public Kart GetKart()
+ {
+ return _kart;
+ }
+
+ public ActiveType GetType()
+ {
+ return _type;
+ }
+
+ public List GetEntities()
+ {
+ return _ents;
+ }
+
+ public abstract boolean Use();
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemEntity.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemEntity.java
new file mode 100644
index 000000000..6bc423bb7
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemEntity.java
@@ -0,0 +1,164 @@
+package nautilus.game.minekart.item;
+
+import nautilus.game.minekart.item.control.Movement;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.track.Track;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.Entity;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.util.Vector;
+
+public abstract class KartItemEntity
+{
+ public KartItemManager Manager;
+
+ private Track _track;
+
+ private Material _mat;
+ private byte _data;
+
+ private KartItemActive _host;
+
+ private Entity _entity;
+ private Vector _velocity;
+ private long _fireTime;
+
+ private Kart _owner;
+ private Kart _target;
+
+ private double _radius = 2;
+
+ public KartItemEntity(KartItemManager manager, Kart owner, Location loc, Material mat, byte data)
+ {
+ Manager = manager;
+
+ _owner = owner;
+ _track = owner.GetGP().GetTrack();
+
+ _mat = mat;
+ _data = data;
+
+ _host = null;
+
+ Spawn(loc);
+
+ manager.RegisterWorldItem(this);
+ }
+
+ @SuppressWarnings("deprecation")
+ public void Spawn(Location loc)
+ {
+ SetEntity(loc.getWorld().dropItem(loc.add(0, 0.5, 0), new ItemStack(_mat, 1, (short)0, _data)));
+ SetFired();
+ }
+
+ public void SetEntity(Entity ent)
+ {
+ _entity = ent;
+ }
+
+ public Entity GetEntity()
+ {
+ return _entity;
+ }
+
+ public Material GetMaterial()
+ {
+ return _mat;
+ }
+
+ public void SetRadius(double rad)
+ {
+ _radius = rad;
+ }
+
+ public void SetVelocity(Vector vel)
+ {
+ _velocity = vel;
+ }
+
+ public Vector GetVelocity()
+ {
+ return _velocity;
+ }
+
+ public Vector GetVelocityClone()
+ {
+ return new Vector(_velocity.getX(), _velocity.getY(), _velocity.getZ());
+ }
+
+ public Kart GetOwner()
+ {
+ return _owner;
+ }
+
+ public void SetTarget(Kart kart)
+ {
+ _target = kart;
+ }
+
+ public Kart GetTarget()
+ {
+ return _target;
+ }
+
+ public long GetFireTime()
+ {
+ return _fireTime;
+ }
+
+ public void SetFired()
+ {
+ _fireTime = System.currentTimeMillis();
+ }
+
+ public void SetFiredAdd(long time)
+ {
+ _fireTime = System.currentTimeMillis() + time;
+ }
+
+ public KartItemActive GetHost()
+ {
+ return _host;
+ }
+
+ public void SetHost(KartItemActive host)
+ {
+ _host = host;
+ }
+
+ public double GetRadius()
+ {
+ return _radius;
+ }
+
+ public abstract void CollideHandle(Kart kart);
+
+ public boolean TickUpdate()
+ {
+ if (GetHost() != null)
+ return false;
+
+ Movement.Move(this);
+
+ return false;
+ }
+
+ public void Clean()
+ {
+ if (_entity == null)
+ return;
+
+ if (_entity.getPassenger() != null)
+ _entity.getPassenger().remove();
+
+ _entity.remove();
+ }
+
+ public Track GetTrack()
+ {
+ return _track;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemManager.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemManager.java
new file mode 100644
index 000000000..23e95ecf5
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemManager.java
@@ -0,0 +1,375 @@
+package nautilus.game.minekart.item;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import org.bukkit.Sound;
+import org.bukkit.entity.Egg;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.event.entity.EntityTargetEvent;
+import org.bukkit.event.player.PlayerDropItemEvent;
+import org.bukkit.event.player.PlayerPickupItemEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import mineplex.core.MiniPlugin;
+import mineplex.core.updater.event.UpdateEvent;
+import mineplex.core.updater.UpdateType;
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilMath;
+import mineplex.core.common.util.UtilPlayer;
+import nautilus.game.minekart.gp.GPBattle;
+import nautilus.game.minekart.item.KartItemActive.ActiveType;
+import nautilus.game.minekart.item.control.Collision;
+import nautilus.game.minekart.item.control.Movement;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartManager;
+import nautilus.game.minekart.kart.crash.Crash_Explode;
+
+public class KartItemManager extends MiniPlugin
+{
+ public KartManager KartManager;
+
+ private HashMap> _itemSelection = new HashMap>();
+
+ private HashSet _kartItems = new HashSet();
+ private HashSet _worldItems = new HashSet();
+
+ public KartItemManager(JavaPlugin plugin, KartManager kartManager)
+ {
+ super("Kart Item Manager", plugin);
+
+ KartManager = kartManager;
+ }
+
+ @EventHandler
+ public void UseItem(PlayerDropItemEvent event)
+ {
+ Kart kart = KartManager.GetKart(event.getPlayer());
+ if (kart == null) return;
+
+ event.setCancelled(true);
+
+ KartItemActive active = kart.GetItemActive();
+ if (active != null)
+ {
+ if (active.Use())
+ {
+ //Depleted
+ kart.SetItemActive(null);
+
+ //Due to Auto-Activate
+ ItemDecrement(kart);
+
+ GetKartItems().remove(active);
+
+ //Sound
+ kart.GetDriver().playSound(kart.GetDriver().getLocation(), kart.GetKartType().GetSoundMain(), 2f, 1f);
+ }
+
+ return;
+ }
+
+ KartItemType type = kart.GetItemStored();
+ if (type != null)
+ {
+ if (kart.GetItemCycles() > 10)
+ {
+ kart.SetItemCycles(kart.GetItemCycles() - 3);
+ return;
+ }
+ else if (kart.GetItemCycles() <= 0)
+ {
+ type.GetAction().Use(this, kart);
+
+ //Sound
+ kart.GetDriver().playSound(kart.GetDriver().getLocation(), kart.GetKartType().GetSoundMain(), 2f, 1f);
+ }
+ }
+ }
+
+ @EventHandler
+ public void CancelPickup(PlayerPickupItemEvent event)
+ {
+ for (KartItemEntity item : GetWorldItems())
+ if (item.GetEntity() != null && item.GetEntity().equals(event.getItem()))
+ {
+ event.setCancelled(true);
+ return;
+ }
+
+ //Not Map Item
+ event.setCancelled(true);
+ event.getItem().remove();
+ }
+
+ @EventHandler
+ public void CancelTarget(EntityTargetEvent event)
+ {
+ event.setCancelled(true);
+ }
+
+ @EventHandler
+ public void EggHit(EntityDamageEvent event)
+ {
+ if (!(event instanceof EntityDamageByEntityEvent))
+ return;
+
+ EntityDamageByEntityEvent eventEE = (EntityDamageByEntityEvent)event;
+
+ if (!(eventEE.getDamager() instanceof Egg))
+ return;
+
+ Egg egg = (Egg)eventEE.getDamager();
+
+ if (egg.getShooter() == null)
+ return;
+
+ if (!(egg.getShooter() instanceof Player))
+ return;
+
+ if (!(event.getEntity() instanceof Player))
+ return;
+
+ Player damager = (Player)egg.getShooter();
+ Player damagee = (Player)event.getEntity();
+
+ Kart kart = KartManager.GetKart(damagee);
+ if (kart == null) return;
+
+ new Crash_Explode(kart, 0.3f, false);
+
+ //Inform
+ if (damager.equals(damagee))
+ {
+ UtilPlayer.message(damagee, F.main("MK", "You hit yourself with " + F.item("Egg Blaster") + "."));
+ }
+ else
+ {
+ UtilPlayer.message(damagee, F.main("MK", F.elem(damager.getName()) + " hit you with " + F.item("Egg Blaster") + "."));
+ UtilPlayer.message(damager, F.main("MK", "You hit " + F.elem(damagee.getName()) + " with " + F.item("Egg Blaster") + "."));
+ }
+ }
+
+ @EventHandler
+ public void KartItemCycle(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.FASTEST)
+ return;
+
+ for (Kart kart : KartManager.GetKarts().values())
+ {
+ if (kart.GetItemCycles() > 0)
+ {
+ //Selected
+ if (kart.GetItemCycles() < 10)
+ {
+ //End Sound
+ if (kart.GetItemCycles()%3 == 0)
+ kart.GetDriver().playSound(kart.GetDriver().getLocation(), Sound.NOTE_PLING, 0.4f, 2f);
+ }
+ //Random
+ else
+ {
+ //Sound
+ kart.GetDriver().playSound(kart.GetDriver().getLocation(), Sound.NOTE_PLING, 0.2f, 1f + (10 - (kart.GetItemCycles()%10)) *0.05f);
+
+ KartItemType next = GetNewItem(kart);
+
+ //Ensure it doesnt cycle item twice in a row
+ while (next.equals(kart.GetItemStored()))
+ next = GetNewItem(kart);
+
+ kart.SetItemStored(next);
+ }
+
+ kart.SetItemCycles(kart.GetItemCycles() - 1);
+
+ //Auto Activate
+ if (kart.GetItemCycles() == 0)
+ {
+ if (kart.GetItemStored() == KartItemType.Banana ||
+ kart.GetItemStored() == KartItemType.BananaBunch ||
+ kart.GetItemStored() == KartItemType.SingleGreenShell ||
+ kart.GetItemStored() == KartItemType.DoubleGreenShell ||
+ kart.GetItemStored() == KartItemType.TripleGreenShell ||
+ kart.GetItemStored() == KartItemType.SingleRedShell ||
+ kart.GetItemStored() == KartItemType.DoubleRedShell ||
+ kart.GetItemStored() == KartItemType.TripleRedShell)
+ {
+ kart.GetItemStored().GetAction().Use(this, kart);
+ }
+ }
+ }
+ //Remove Stored, if active is gone
+ else if (kart.GetItemActive() == null && kart.GetItemStored() != null)
+ {
+ ItemDecrement(kart);
+ }
+ }
+ }
+
+ public void ItemDecrement(Kart kart)
+ {
+ if (kart.GetItemStored() == KartItemType.Banana ||
+ kart.GetItemStored() == KartItemType.SingleGreenShell ||
+ kart.GetItemStored() == KartItemType.SingleRedShell)
+ {
+ kart.SetItemStored(null);
+ }
+
+ if (kart.GetItemStored() == KartItemType.BananaBunch)
+ {
+ ItemStack item = kart.GetDriver().getInventory().getItem(3);
+
+ if (item == null || item.getAmount() == 1)
+ {
+ kart.SetItemStored(null);
+ }
+ else
+ {
+ item.setAmount(item.getAmount() - 1);
+ kart.GetItemStored().GetAction().Use(this, kart);
+ }
+ }
+
+ if (kart.GetItemStored() == KartItemType.DoubleGreenShell)
+ {
+ kart.SetItemStored(KartItemType.SingleGreenShell);
+ kart.GetItemStored().GetAction().Use(this, kart);
+ }
+
+ if (kart.GetItemStored() == KartItemType.TripleGreenShell)
+ {
+ kart.SetItemStored(KartItemType.DoubleGreenShell);
+ kart.GetItemStored().GetAction().Use(this, kart);
+ }
+
+ if (kart.GetItemStored() == KartItemType.DoubleRedShell)
+ {
+ kart.SetItemStored(KartItemType.SingleRedShell);
+ kart.GetItemStored().GetAction().Use(this, kart);
+ }
+
+ if (kart.GetItemStored() == KartItemType.TripleRedShell)
+ {
+ kart.SetItemStored(KartItemType.DoubleRedShell);
+ kart.GetItemStored().GetAction().Use(this, kart);
+ }
+ }
+
+ @EventHandler
+ public void KartItemUpdate(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.TICK)
+ return;
+
+ for (KartItemActive active : GetKartItems())
+ {
+ if (active.GetType() == ActiveType.Behind)
+ Movement.Behind(active.GetKart(), active.GetEntities());
+
+ if (active.GetType() == ActiveType.Orbit)
+ Movement.Orbit(active.GetKart(), active.GetEntities());
+
+ if (active.GetType() == ActiveType.Trail)
+ Movement.Trail(active.GetKart(), active.GetEntities());
+ }
+ }
+
+ @EventHandler
+ public void WorldItemUpdate(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.TICK)
+ return;
+
+ HashSet remove = new HashSet();
+
+ for (KartItemEntity item : GetWorldItems())
+ {
+ if (item.GetTrack() == null || item.GetTrack().GetWorld() == null)
+ {
+ remove.add(item);
+ continue;
+ }
+
+ if (remove.contains(item))
+ continue;
+
+ if (item.TickUpdate())
+ remove.add(item);
+
+ //Collide with Items
+ KartItemEntity other = Collision.CollideItem(item, GetWorldItems());
+ if (other != null)
+ {
+ remove.add(item);
+ remove.add(other);
+ }
+
+ //Collide with Players
+ if (Collision.CollidePlayer(item, KartManager.GetKarts().values()))
+ remove.add(item);
+ }
+
+ for (KartItemEntity item : remove)
+ {
+ if (item.GetHost() != null)
+ {
+ item.GetHost().GetEntities().remove(item);
+
+ if (item.GetHost().GetEntities().isEmpty())
+ {
+ item.GetHost().GetKart().SetItemActive(null);
+ GetKartItems().remove(item.GetHost());
+ }
+ }
+
+ item.Clean();
+
+ _worldItems.remove(item);
+ }
+ }
+
+ public void RegisterKartItem(KartItemActive item)
+ {
+ _kartItems.add(item);
+ }
+
+ public void RegisterWorldItem(KartItemEntity item)
+ {
+ _worldItems.add(item);
+ }
+
+ public HashSet GetKartItems()
+ {
+ return _kartItems;
+ }
+
+ public HashSet GetWorldItems()
+ {
+ return _worldItems;
+ }
+
+ public KartItemType GetNewItem(Kart kart)
+ {
+ if (Math.random() > 1 - kart.GetKartType().GetKartItem().GetChance())
+ return kart.GetKartType().GetKartItem();
+
+ int pos = kart.GetLapPlace();
+
+ if (kart.GetGP() instanceof GPBattle)
+ pos = -1;
+
+ if (!_itemSelection.containsKey(pos))
+ _itemSelection.put(pos, KartItemType.GetItem(pos));
+
+ ArrayList itemBag = _itemSelection.get(pos);
+
+ return itemBag.get(UtilMath.r(itemBag.size()));
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemType.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemType.java
new file mode 100644
index 000000000..c012498a8
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/KartItemType.java
@@ -0,0 +1,239 @@
+package nautilus.game.minekart.item;
+
+import java.util.ArrayList;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+
+import mineplex.core.common.util.C;
+import nautilus.game.minekart.item.use_custom.*;
+import nautilus.game.minekart.item.use_default.*;
+
+public enum KartItemType
+{
+ //Default
+ Banana( "Banana", Material.GOLD_INGOT, 1, new UseBanana()),
+ BananaBunch( "Banana Bunch", Material.GOLD_SPADE, 6, new UseBanana()),
+ FakeItem( "Fake Item", Material.FLINT, 1, new UseFakeItem()),
+
+ SingleGreenShell( "Green Shell", Material.SLIME_BALL, 1, new UseGreenShell()),
+ DoubleGreenShell( "2x Green Shell", Material.MELON_SEEDS, 1, new UseGreenShell()),
+ TripleGreenShell( "3x Green Shell", Material.PUMPKIN_SEEDS, 1, new UseGreenShell()),
+
+ SingleRedShell( "Red Shell", Material.MAGMA_CREAM, 1, new UseRedShell()),
+ DoubleRedShell( "2x Red Shell", Material.RAW_FISH, 1, new UseRedShell()),
+ TripleRedShell( "3x Red Shell", Material.COOKED_FISH, 1, new UseRedShell()),
+
+ Ghost( "Ghost", Material.GHAST_TEAR, 1, new UseGhost()),
+ Star( "Star", Material.NETHER_STAR, 1, new UseStar()),
+ Lightning( "Lightning", Material.GLOWSTONE_DUST, 1, new UseLightning()),
+
+ SingleMushroom( "1x Mushroom", Material.BREAD, 1, new UseMushroom()),
+ DoubleMushroom( "2x Mushroom", Material.BOWL, 1, new UseMushroom()),
+ TripleMushroom( "3x Mushroom", Material.MUSHROOM_SOUP, 1, new UseMushroom()),
+ SuperMushroom( "Super Mushroom", Material.GOLDEN_APPLE, 1, new UseMushroom()),
+
+ //Custom
+ Chicken("Egg Blaster", Material.EGG, 16, 0.16, new UseChicken(), new String[]
+ {
+ "",
+ ChatColor.RESET + C.cWhite + "16-Round Egg Blaster.",
+ }),
+
+ Pig("Pig Stink", Material.PORK, 1, 0.12, new UsePig(), new String[]
+ {
+ "",
+ ChatColor.RESET + C.cWhite + "Confuses all players.",
+ ChatColor.RESET + C.cWhite + "Lasts 20 seconds"
+ }),
+
+ Wolf("Heart Barrier", Material.APPLE, 1, 0.16, new UseWolf(), new String[]
+ {
+ "",
+ ChatColor.RESET + C.cWhite + "Blocks 1 Shell/Banana/Fake Item",
+ ChatColor.RESET + C.cWhite + "Lasts 60 Seconds"
+ }),
+
+ Spider("Spiderlings", Material.SEEDS, 1, 0.16, new UseSpider(), new String[]
+ {
+ "",
+ ChatColor.RESET + C.cWhite + "Release 1 Spiderling at each player.",
+ ChatColor.RESET + C.cWhite + "Spiderlings hunt players, causing a crash.",
+ ChatColor.RESET + C.cWhite + "Lasts 15 seconds."
+ }),
+
+ Blaze("Infernal Kart", Material.BLAZE_POWDER, 1, 0.16, new UseBlaze(), new String[]
+ {
+ "",
+ ChatColor.RESET + C.cWhite + "Boost forwards with amazing handling.",
+ ChatColor.RESET + C.cWhite + "Leaves a trail of flames, slowing players."
+ }),
+
+ Sheep("Super Sheep", Material.IRON_SPADE, 1, 0.08, new UseSheep(), new String[]
+ {
+ "",
+ ChatColor.RESET + C.cWhite + "Super Sheep flies around the track.",
+ ChatColor.RESET + C.cWhite + "Hunts down other nearby players.",
+ ChatColor.RESET + C.cWhite + "Lasts 15 seconds"
+ }),
+
+ Enderman("Blink", Material.ENDER_PEARL, 1, 0.16, new UseEnderman(), new String[]
+ {
+ "",
+ ChatColor.RESET + C.cWhite + "Instantly teleport forward 20 blocks.",
+ ChatColor.RESET + C.cWhite + "Converts velocity into new direction.",
+ ChatColor.RESET + C.cWhite + "3 Uses."
+ }),
+
+ Cow("Stampede", Material.DIAMOND_SPADE, 1, 0.16, new UseCow(), new String[]
+ {
+ "",
+ ChatColor.RESET + C.cWhite + "Angry cows charge foward at players."
+ }),
+
+ Golem("Earthquake", Material.COAL, 1, 0.08, new UseGolem(), new String[]
+ {
+ "",
+ ChatColor.RESET + C.cWhite + "Halves all players velocity.",
+ ChatColor.RESET + C.cWhite + "Enemies are propelled upwards.",
+ ChatColor.RESET + C.cWhite + "More powerful at close range."
+ });
+
+ private String _name;
+ private Material _mat;
+ private int _amount;
+
+ private ItemUse _action;
+
+ private double _chance = 0;
+ private String[] _customDesc = new String[] {"Default"};
+
+ KartItemType(String name, Material mat, int amount, ItemUse action)
+ {
+ _name = name;
+ _mat = mat;
+ _amount = amount;
+ _action = action;
+ }
+
+ KartItemType(String name, Material mat, int amount, double customChance, ItemUse action, String[] customString)
+ {
+ _name = name;
+ _mat = mat;
+ _amount = amount;
+
+ _action = action;
+
+ _chance = customChance;
+ _customDesc = customString;
+ }
+
+ public String GetName()
+ {
+ return _name;
+ }
+
+ public ItemUse GetAction()
+ {
+ return _action;
+ }
+
+ public Material GetMaterial()
+ {
+ return _mat;
+ }
+
+ public int GetAmount()
+ {
+ return _amount;
+ }
+
+ public double GetChance()
+ {
+ return _chance;
+ }
+
+ public String[] GetDesc()
+ {
+ return _customDesc;
+ }
+
+ public static ArrayList GetItem(int pos)
+ {
+ ArrayList itemBag = new ArrayList();
+
+ if (pos == -1)
+ {
+ for (int i=1 ; i>0 ; i--)
+ itemBag.add(KartItemType.Star);
+
+ for (int i=1 ; i>0 ; i--)
+ itemBag.add(KartItemType.Ghost);
+
+ for (int i=1 ; i>0 ; i--)
+ itemBag.add(KartItemType.TripleRedShell);
+
+ for (int i=2 ; i>0 ; i--)
+ itemBag.add(KartItemType.TripleGreenShell);
+
+ for (int i=2 ; i>0 ; i--)
+ itemBag.add(KartItemType.BananaBunch);
+
+ for (int i=2 ; i>0 ; i--)
+ itemBag.add(KartItemType.FakeItem);
+
+ for (int i=3 ; i>0 ; i--)
+ itemBag.add(KartItemType.SingleRedShell);
+
+ for (int i=3 ; i>0 ; i--)
+ itemBag.add(KartItemType.Banana);
+
+ for (int i=4 ; i>0 ; i--)
+ itemBag.add(KartItemType.SingleGreenShell);
+ }
+
+ else
+ {
+ for (int i=20 - (3 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.Lightning);
+
+ for (int i=20 - (2 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.Star);
+
+ for (int i=20 - (2 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.SuperMushroom);
+
+ for (int i=20 - (2 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.Ghost);
+
+ for (int i=20 - (2 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.TripleRedShell);
+
+ for (int i=20 - (1 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.TripleGreenShell);
+
+ for (int i=20 - (1 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.TripleMushroom);
+
+ for (int i=20 - (1 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.BananaBunch);
+
+ for (int i=5 + (2 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.SingleRedShell);
+
+ for (int i=10 + (2 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.SingleMushroom);
+
+ for (int i=10 + (2 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.SingleGreenShell);
+
+ for (int i=0 + (2 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.FakeItem);
+
+ for (int i=0 + (2 * 9-pos) ; i>0 ; i--)
+ itemBag.add(KartItemType.Banana);
+ }
+
+ return itemBag;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/control/Collision.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/control/Collision.java
new file mode 100644
index 000000000..6d33f1ae1
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/control/Collision.java
@@ -0,0 +1,144 @@
+package nautilus.game.minekart.item.control;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import mineplex.core.common.util.UtilBlock;
+import mineplex.core.common.util.UtilMath;
+import mineplex.core.common.util.UtilTime;
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.world_items_default.RedShell;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartState;
+import nautilus.game.minekart.kart.condition.ConditionType;
+
+import org.bukkit.block.Block;
+import org.bukkit.entity.Entity;
+import org.bukkit.util.Vector;
+
+public class Collision
+{
+ public static boolean CollideBlock(KartItemEntity item)
+ {
+ Entity ent = item.GetEntity();
+ if (ent == null) return true;
+
+ //Current Velocity
+ Vector vel = item.GetVelocity();
+ if (vel == null) return true;
+
+ if (vel.length() <= 0)
+ return true;
+
+ boolean collided = false;
+ double range = 0.31;
+
+ Block block;
+
+ block = ent.getLocation().add(range, 0, 0).getBlock();
+ if (vel.getX() > 0 && UtilBlock.solid(block)) {vel.setX(-vel.getX()); collided = true;}
+
+ block = ent.getLocation().add(-range, 0, 0).getBlock();
+ if (vel.getX() < 0 && UtilBlock.solid(block)) {vel.setX(-vel.getX()); collided = true;}
+
+ block = ent.getLocation().add(0, 0, range).getBlock();
+ if (vel.getZ() > 0 && UtilBlock.solid(block)) {vel.setZ(-vel.getZ()); collided = true;}
+
+ block = ent.getLocation().add(0, 0, -range).getBlock();
+ if (vel.getZ() < 0 && UtilBlock.solid(block)) {vel.setZ(-vel.getZ()); collided = true;}
+
+ return collided;
+ }
+
+ public static boolean CollidePlayer(KartItemEntity item, Collection allKarts)
+ {
+ if (item.GetEntity() == null)
+ return false;
+
+ for (Kart kart : allKarts)
+ {
+ if (kart.GetKartState() == KartState.Lakitu)
+ continue;
+
+ if (kart.HasCondition(ConditionType.Ghost))
+ {
+ if (item instanceof RedShell)
+ if (item.GetTarget() != null && item.GetTarget().equals(kart))
+ return true;
+
+ continue;
+ }
+
+ //Don't hit owner
+ if (item.GetOwner() != null && kart.equals(item.GetOwner()))
+ {
+ if (item.GetHost() != null)
+ continue;
+
+ if (!UtilTime.elapsed(item.GetFireTime(), 1000))
+ continue;
+ }
+
+ if (UtilMath.offset(kart.GetDriver(), item.GetEntity()) < item.GetRadius() && kart.GetDriver().getWorld() == item.GetEntity().getWorld())
+ {
+ item.CollideHandle(kart);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static KartItemEntity CollideItem(KartItemEntity item, HashSet allItems)
+ {
+ if (item.GetEntity() == null)
+ return null;
+
+ for (KartItemEntity other : allItems)
+ {
+ if (item.equals(other))
+ continue;
+
+ //Both Arent Moving
+ if (item.GetVelocity() == null && other.GetVelocity() == null)
+ continue;
+
+ //Both Arent Moving
+ if ((item.GetVelocity() != null && item.GetVelocity().length() <= 0) && (item.GetVelocity() != null && item.GetVelocity().length() <= 0))
+ continue;
+
+ //Dont collide with friends on orbit!
+ if (item.GetHost() != null && other.GetHost() != null)
+ if (item.GetHost().equals(other.GetHost()))
+ continue;
+
+ //Don't collide with friends after shot (same owner)
+ if (item.GetOwner() != null && other.GetOwner() != null && item.GetOwner().equals(other.GetOwner()))
+ {
+ //Item is trailing
+ if (item.GetHost() != null && other.GetHost() == null)
+ {
+ if (!UtilTime.elapsed(other.GetFireTime(), 1000))
+ {
+ continue;
+ }
+ }
+ //Other is trailing
+ else if (item.GetHost() == null && other.GetHost() != null)
+ {
+ if (!UtilTime.elapsed(item.GetFireTime(), 1000))
+ {
+ continue;
+ }
+ }
+ }
+
+ if (UtilMath.offset(other.GetEntity(), item.GetEntity()) < item.GetRadius())
+ {
+ return other;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/control/Movement.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/control/Movement.java
new file mode 100644
index 000000000..30305c9ec
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/control/Movement.java
@@ -0,0 +1,181 @@
+package nautilus.game.minekart.item.control;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_7_R1.CraftWorld;
+import org.bukkit.craftbukkit.v1_7_R1.entity.CraftLivingEntity;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.util.Vector;
+
+import mineplex.core.common.util.UtilAction;
+import mineplex.core.common.util.UtilAlg;
+import mineplex.core.common.util.UtilMath;
+import mineplex.core.common.util.UtilTime;
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+import nautilus.game.minekart.kart.condition.ConditionType;
+import net.minecraft.server.v1_7_R1.EntityInsentient;
+import net.minecraft.server.v1_7_R1.EntityLiving;
+import net.minecraft.server.v1_7_R1.PathfinderGoalSelector;
+
+public class Movement
+{
+ public static void Move(KartItemEntity item)
+ {
+ if (item.GetEntity() == null)
+ return;
+
+ if (item.GetVelocity() == null)
+ return;
+
+ if (item.GetVelocity().length() <= 0)
+ return;
+
+ //Attempt to fix glitch
+ item.GetEntity().teleport(item.GetEntity().getLocation());
+
+ //Apply Velocity
+ item.GetEntity().setVelocity(item.GetVelocity());
+ }
+
+ public static void Behind(Kart kart, List moons)
+ {
+ for (int i=0 ; i moons)
+ {
+ int i = 0;
+ for (KartItemEntity item : moons)
+ {
+ if (item.GetEntity() instanceof LivingEntity)
+ ClearGoals((LivingEntity)item.GetEntity());
+
+ double radialLead = i * ((2d * Math.PI)/moons.size());
+ i++;
+
+ Location desiredA = GetTarget(kart.GetDriver().getLocation(), kart.GetDriver().getTicksLived(), radialLead);
+ Location desiredB = GetTarget(kart.GetDriver().getLocation(), kart.GetDriver().getTicksLived() + 1, radialLead);
+
+ double distA = UtilMath.offset(item.GetEntity().getLocation(), desiredA);
+ double distB = UtilMath.offset(item.GetEntity().getLocation(), desiredB);
+ double distAB = UtilMath.offset(desiredA, desiredB);
+
+ if (distA > distB)
+ continue;
+
+ if (distA < distAB / 2)
+ continue;
+
+ Vector vel = UtilAlg.getTrajectory(item.GetEntity().getLocation(), desiredA);
+
+ //Kart velocity
+ Vector kartVel = kart.GetVelocity();
+ if (kart.GetCrash() != null && kart.GetCrash().GetVelocity() != null)
+ kartVel = kart.GetCrash().GetVelocity();
+ kartVel.setY(0);
+
+ vel.add(kartVel);
+
+ UtilAction.velocity(item.GetEntity(), vel, 0.2 + kartVel.length(), false, 0, 0, 10, false);
+ }
+ }
+
+ private static void ClearGoals(LivingEntity ent)
+ {
+ try
+ {
+ Field _goalSelector = EntityInsentient.class.getDeclaredField("goalSelector");
+ _goalSelector.setAccessible(true);
+ Field _targetSelector = EntityInsentient.class.getDeclaredField("targetSelector");
+ _targetSelector.setAccessible(true);
+
+ EntityLiving creature = ((CraftLivingEntity)ent).getHandle();
+
+ PathfinderGoalSelector goalSelector = new PathfinderGoalSelector(((CraftWorld)ent.getWorld()).getHandle().methodProfiler);
+
+ _goalSelector.set(creature, goalSelector);
+ _targetSelector.set(creature, new PathfinderGoalSelector(((CraftWorld)ent.getWorld()).getHandle().methodProfiler));
+ }
+ catch (IllegalArgumentException e)
+ {
+ e.printStackTrace();
+ }
+ catch (IllegalAccessException e)
+ {
+ e.printStackTrace();
+ }
+ catch (NoSuchFieldException e)
+ {
+ e.printStackTrace();
+ }
+ catch (SecurityException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public static Location GetTarget(Location origin, int ticks, double radialLead)
+ {
+ //Orbit
+ double speed = 10d;
+
+ double oX = Math.sin(ticks/speed + radialLead) * 1.5;
+ double oY = 0.5;
+ double oZ = Math.cos(ticks/speed + radialLead) * 1.5;
+
+ return new Location(origin.getWorld(), origin.getX() + oX, origin.getY() + oY, origin.getZ() + oZ);
+ }
+
+ public static void Trail(Kart kart, List moons)
+ {
+ for (int i=0 ; i 0)
+ target = moons.get(i-1).GetEntity();
+
+ double offset = UtilMath.offset(cur, target);
+
+ Vector vel = UtilAlg.getTrajectory(cur, target);
+
+ UtilAction.velocity(cur, vel, offset, false, 0, 0, 10, false);
+ }
+ }
+
+ public static void Home(KartItemEntity item)
+ {
+ if (!UtilTime.elapsed(item.GetFireTime(), 800))
+ return;
+
+ if (item.GetEntity() == null || item.GetTarget() == null)
+ return;
+
+ if (item.GetTarget().HasCondition(ConditionType.Ghost))
+ return;
+
+ Vector vec = UtilAlg.getTrajectory2d(item.GetEntity(), item.GetTarget().GetDriver());
+ UtilAlg.Normalize(vec);
+ vec.multiply(1.2);
+ vec.setY(-0.4);
+
+ item.SetVelocity(vec);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_active/ActiveBananas.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_active/ActiveBananas.java
new file mode 100644
index 000000000..aed9dc633
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_active/ActiveBananas.java
@@ -0,0 +1,36 @@
+package nautilus.game.minekart.item.use_active;
+
+import java.util.List;
+
+import nautilus.game.minekart.item.KartItemActive;
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart;
+
+public class ActiveBananas extends KartItemActive
+{
+ public ActiveBananas(KartItemManager manager, Kart kart, List ents)
+ {
+ super(manager, kart, ActiveType.Trail, ents);
+ }
+
+ @Override
+ public boolean Use()
+ {
+ if (GetEntities().isEmpty())
+ return true;
+
+ //Find Closest to firing trajectory
+ KartItemEntity back = GetEntities().get(GetEntities().size() - 1);
+
+ //Fire Shell
+ back.SetHost(null);
+ back.SetVelocity(null);
+ GetEntities().remove(back);
+
+ //Counter Collision with driver
+ back.SetFired();
+
+ return GetEntities().isEmpty();
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_active/ActiveShells.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_active/ActiveShells.java
new file mode 100644
index 000000000..f369e655b
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_active/ActiveShells.java
@@ -0,0 +1,77 @@
+package nautilus.game.minekart.item.use_active;
+
+import java.util.List;
+
+import org.bukkit.Location;
+
+import mineplex.core.common.util.UtilAlg;
+import mineplex.core.common.util.UtilMath;
+import nautilus.game.minekart.item.KartItemActive;
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.world_items_default.RedShell;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+
+public class ActiveShells extends KartItemActive
+{
+ public ActiveShells(KartItemManager manager, Kart kart, List ents)
+ {
+ super(manager, kart, ActiveType.Orbit, ents);
+ }
+
+ @Override
+ public boolean Use()
+ {
+ if (GetEntities().isEmpty())
+ return true;
+
+ //Find Closest to firing trajectory
+ Location loc = KartUtil.GetLook(GetKart());
+
+ KartItemEntity closest = null;
+ double closestDist = 10;
+
+ for (KartItemEntity item : GetEntities())
+ {
+ double dist = UtilMath.offset(item.GetEntity().getLocation(), loc);
+
+ if (closest == null)
+ {
+ closest = item;
+ closestDist = dist;
+ continue;
+ }
+
+ if (dist < closestDist)
+ {
+ closest = item;
+ closestDist = dist;
+ }
+ }
+
+ //Fire Shell
+ closest.SetHost(null);
+ closest.SetVelocity(UtilAlg.Normalize(GetKart().GetDriver().getLocation().getDirection().setY(0)));
+ GetEntities().remove(closest);
+
+ //Counter Collision with driver
+ closest.SetFired();
+
+ //Red Shell Chase
+ if (closest instanceof RedShell)
+ {
+ Kart target = null;
+
+ for (Kart other : GetKart().GetGP().GetKarts())
+ {
+ if (other.GetLapPlace() + 1 == GetKart().GetLapPlace())
+ target = other;
+ }
+
+ closest.SetTarget(target);
+ }
+
+ return GetEntities().isEmpty();
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_active/ActiveStandard.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_active/ActiveStandard.java
new file mode 100644
index 000000000..650d9d467
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_active/ActiveStandard.java
@@ -0,0 +1,99 @@
+package nautilus.game.minekart.item.use_active;
+
+import java.util.List;
+
+import org.bukkit.util.Vector;
+
+import mineplex.core.common.util.UtilAlg;
+import mineplex.core.common.util.UtilMath;
+import nautilus.game.minekart.gp.GPBattle;
+import nautilus.game.minekart.item.KartItemActive;
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.world_items_default.GreenShell;
+import nautilus.game.minekart.item.world_items_default.RedShell;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+
+public class ActiveStandard extends KartItemActive
+{
+ public ActiveStandard(KartItemManager manager, Kart kart, List ents)
+ {
+ super(manager, kart, ActiveType.Behind, ents);
+ }
+
+ @Override
+ public boolean Use()
+ {
+ if (GetEntities().isEmpty())
+ return true;
+
+ KartItemEntity item = GetEntities().get(0);
+
+ //Fire Item
+ item.SetVelocity(null);
+ item.SetFired();
+
+ //Green/Red Shell Velocity & Teleport
+ if (item instanceof RedShell || item instanceof GreenShell)
+ {
+ item.GetEntity().teleport(KartUtil.GetInfront(item.GetHost().GetKart()));
+
+ Vector vel = UtilAlg.Normalize(GetKart().GetDriver().getLocation().getDirection().setY(0));
+ vel.multiply(1.4);
+ vel.setY(-0.4);
+ item.SetVelocity(vel);
+ }
+
+ //Remove References
+ item.SetHost(null);
+ GetEntities().remove(item);
+
+ //Red Shell Home
+ if (item instanceof RedShell)
+ {
+ Kart target = null;
+
+ if (GetKart().GetGP() instanceof GPBattle)
+ {
+ double closest = 9999;
+
+ for (Kart other : GetKart().GetGP().GetKarts())
+ {
+ if (GetKart().equals(other))
+ continue;
+
+ if (GetKart().GetLives() <= 0)
+ continue;
+
+ double dist = UtilMath.offset(GetKart().GetDriver(), other.GetDriver());
+
+ if (target == null)
+ {
+ target = other;
+ closest = dist;
+
+ }
+
+ else if (dist < closest)
+ {
+ target = other;
+ closest = dist;
+ }
+ }
+ }
+ else
+ {
+ for (Kart other : GetKart().GetGP().GetKarts())
+ {
+ if (other.GetLapPlace() + 1 == GetKart().GetLapPlace())
+ target = other;
+ }
+ }
+
+ item.SetTarget(target);
+ }
+
+ return GetEntities().isEmpty();
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseBlaze.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseBlaze.java
new file mode 100644
index 000000000..ff756dbb4
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseBlaze.java
@@ -0,0 +1,18 @@
+package nautilus.game.minekart.item.use_custom;
+
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_default.ItemUse;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+
+public class UseBlaze extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ kart.AddCondition(new ConditionData(ConditionType.BlazeFire, 3000));
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseChicken.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseChicken.java
new file mode 100644
index 000000000..12adb2641
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseChicken.java
@@ -0,0 +1,38 @@
+package nautilus.game.minekart.item.use_custom;
+
+import org.bukkit.Sound;
+import org.bukkit.entity.Egg;
+import org.bukkit.util.Vector;
+
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_default.ItemUse;
+import nautilus.game.minekart.kart.Kart;
+
+public class UseChicken extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ if (kart.GetDriver().getInventory().getItem(3) == null)
+ {
+ kart.SetItemStored(null);
+ }
+ else if (kart.GetDriver().getInventory().getItem(3).getAmount() > 1)
+ {
+ kart.GetDriver().getInventory().getItem(3).setAmount(kart.GetDriver().getInventory().getItem(3).getAmount() - 1);
+ }
+ else
+ {
+ kart.SetItemStored(null);
+ }
+
+ Egg egg = kart.GetDriver().launchProjectile(Egg.class);
+
+ Vector vel = kart.GetDriver().getLocation().getDirection();
+ vel.setY(0.1);
+ vel.multiply(2);
+ egg.setVelocity(vel);
+
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.CHICKEN_EGG_POP, 2f, 1f);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseCow.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseCow.java
new file mode 100644
index 000000000..8658c9b75
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseCow.java
@@ -0,0 +1,39 @@
+package nautilus.game.minekart.item.use_custom;
+
+import org.bukkit.Location;
+
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_default.ItemUse;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+import nautilus.game.minekart.track.ents.Cow;
+
+public class UseCow extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ //Mid
+ kart.GetGP().GetTrack().GetCreatures().add(new Cow(kart.GetGP().GetTrack(), KartUtil.GetLook(kart), kart, kart.GetDriver().getLocation().getDirection()));
+
+ Location left1 = KartUtil.GetLook(kart).add(KartUtil.GetSide(kart).multiply(1.5));
+ kart.GetGP().GetTrack().GetCreatures().add(new Cow(kart.GetGP().GetTrack(), left1, kart, kart.GetDriver().getLocation().getDirection()));
+
+ Location left2 = KartUtil.GetLook(kart).add(KartUtil.GetSide(kart).multiply(3));
+ kart.GetGP().GetTrack().GetCreatures().add(new Cow(kart.GetGP().GetTrack(), left2, kart, kart.GetDriver().getLocation().getDirection()));
+
+ Location left3 = KartUtil.GetLook(kart).add(KartUtil.GetSide(kart).multiply(4.5));
+ kart.GetGP().GetTrack().GetCreatures().add(new Cow(kart.GetGP().GetTrack(), left3, kart, kart.GetDriver().getLocation().getDirection()));
+
+ Location right1 = KartUtil.GetLook(kart).subtract(KartUtil.GetSide(kart).multiply(1.5));
+ kart.GetGP().GetTrack().GetCreatures().add(new Cow(kart.GetGP().GetTrack(), right1, kart, kart.GetDriver().getLocation().getDirection()));
+
+ Location right2 = KartUtil.GetLook(kart).subtract(KartUtil.GetSide(kart).multiply(3));
+ kart.GetGP().GetTrack().GetCreatures().add(new Cow(kart.GetGP().GetTrack(), right2, kart, kart.GetDriver().getLocation().getDirection()));
+
+ Location right3 = KartUtil.GetLook(kart).subtract(KartUtil.GetSide(kart).multiply(4.5));
+ kart.GetGP().GetTrack().GetCreatures().add(new Cow(kart.GetGP().GetTrack(), right3, kart, kart.GetDriver().getLocation().getDirection()));
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseEnderman.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseEnderman.java
new file mode 100644
index 000000000..9b839eea2
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseEnderman.java
@@ -0,0 +1,105 @@
+package nautilus.game.minekart.item.use_custom;
+
+import org.bukkit.Effect;
+import org.bukkit.Location;
+import org.bukkit.Sound;
+import org.bukkit.block.Block;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
+
+import mineplex.core.common.util.UtilBlock;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_default.ItemUse;
+import nautilus.game.minekart.kart.Kart;
+
+public class UseEnderman extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ if (kart.GetDriver().getInventory().getItem(3) == null)
+ {
+ kart.SetItemStored(null);
+ }
+ else if (kart.GetDriver().getInventory().getItem(3).getAmount() > 1)
+ {
+ kart.GetDriver().getInventory().getItem(3).setAmount(kart.GetDriver().getInventory().getItem(3).getAmount() - 1);
+ }
+ else
+ {
+ kart.SetItemStored(null);
+ }
+
+ Player player = kart.GetDriver();
+
+ //Trail
+ Block lastEffect = player.getLocation().getBlock();
+
+ double maxRange = 20;
+ double curRange = 0;
+ while (curRange <= maxRange)
+ {
+ Vector look = player.getLocation().getDirection();
+ look.setY(0);
+ look.normalize();
+ look.multiply(curRange);
+
+ Location newTarget = player.getLocation().add(0, 0.1, 0).add(look);
+
+ if (UtilBlock.solid(newTarget.getBlock()))
+ break;
+
+ //Progress Forwards
+ curRange += 0.2;
+
+ //Trail
+ if (!lastEffect.equals(newTarget.getBlock()))
+ lastEffect.getWorld().playEffect(lastEffect.getLocation(), Effect.STEP_SOUND, 49);
+
+ lastEffect = newTarget.getBlock();
+ }
+
+ //Modify Range
+ curRange -= 0.4;
+ if (curRange < 0)
+ curRange = 0;
+
+ //Destination
+ Vector look = player.getLocation().getDirection();
+ look.setY(0);
+ look.normalize();
+ look.multiply(curRange);
+
+ Location loc = player.getLocation().add(look).add(new Vector(0, 0.4, 0));
+
+ //Sound
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.ZOMBIE_UNFECT, 2f, 2f);
+
+ Entity item = player.getPassenger();
+ if (item != null) item.leaveVehicle();
+ player.eject();
+
+ //Action
+ if (curRange > 0)
+ {
+ player.leaveVehicle();
+ player.teleport(loc);
+ }
+
+ //Re-Attach Item
+ if (item != null)
+ {
+ item.teleport(loc.add(0, 1.5, 0));
+ player.setPassenger(item);
+ }
+
+ //Adjust Velocity
+ double length = kart.GetVelocity().length();
+ Vector vel = player.getLocation().getDirection();
+ vel.setY(0);
+ vel.normalize();
+ vel.multiply(length);
+ kart.SetVelocity(vel);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseGolem.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseGolem.java
new file mode 100644
index 000000000..e5f6634cf
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseGolem.java
@@ -0,0 +1,61 @@
+package nautilus.game.minekart.item.use_custom;
+
+import org.bukkit.Effect;
+import org.bukkit.Sound;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilBlock;
+import mineplex.core.common.util.UtilEnt;
+import mineplex.core.common.util.UtilMath;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_default.ItemUse;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+import nautilus.game.minekart.kart.condition.ConditionType;
+import nautilus.game.minekart.kart.crash.Crash_Explode;
+
+public class UseGolem extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ kart.GetGP().Announce(F.main("MK", F.elem(UtilEnt.getName(kart.GetDriver())) + " used " + F.item("Earthquake") + "."));
+
+ for (Kart other : manager.KartManager.GetKarts().values())
+ {
+ if (other.equals(kart))
+ continue;
+
+ if (!KartUtil.IsGrounded(other))
+ continue;
+
+ if (other.HasCondition(ConditionType.Star) || other.HasCondition(ConditionType.Ghost))
+ continue;
+
+ double offset = UtilMath.offset(kart.GetDriver(), other.GetDriver());
+
+ //MiniBump Crash
+ if (offset < 100)
+ new Crash_Explode(other, 0.4 + ((100 - offset)/100), false);
+
+ //Half Velocity
+ other.GetVelocity().multiply(0.50);
+
+ //Sound
+ other.GetDriver().getWorld().playSound(other.GetDriver().getLocation(), Sound.IRONGOLEM_THROW, 2f, 0.5f);
+ }
+
+ //Sound
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.IRONGOLEM_THROW, 2f, 0.5f);
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.IRONGOLEM_THROW, 2f, 0.5f);
+
+ //Effect
+ for (Block cur : UtilBlock.getInRadius(kart.GetDriver().getLocation(), 4d).keySet())
+ if (UtilBlock.airFoliage(cur.getRelative(BlockFace.UP)) && !UtilBlock.airFoliage(cur))
+ cur.getWorld().playEffect(cur.getLocation(), Effect.STEP_SOUND, cur.getTypeId());
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UsePig.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UsePig.java
new file mode 100644
index 000000000..916db7693
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UsePig.java
@@ -0,0 +1,42 @@
+package nautilus.game.minekart.item.use_custom;
+
+import org.bukkit.Sound;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilEnt;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_default.ItemUse;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.condition.ConditionType;
+
+public class UsePig extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ kart.GetGP().Announce(F.main("MK", F.elem(UtilEnt.getName(kart.GetDriver())) + " used " + F.item("Pig Stink") + "."));
+
+ for (Kart other : manager.KartManager.GetKarts().values())
+ {
+ if (other.equals(kart))
+ continue;
+
+ if (other.HasCondition(ConditionType.Star) || other.HasCondition(ConditionType.Ghost))
+ continue;
+
+ PotionEffect effect = new PotionEffect(PotionEffectType.CONFUSION, 400, 0, false);
+ effect.apply(other.GetDriver());
+
+ //Sound
+ other.GetDriver().getWorld().playSound(other.GetDriver().getLocation(), Sound.PIG_IDLE, 2f, 0.5f);
+ }
+
+ //Sound
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.PIG_IDLE, 2f, 0.5f);
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.PIG_IDLE, 2f, 0.5f);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseSheep.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseSheep.java
new file mode 100644
index 000000000..10b1e9adc
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseSheep.java
@@ -0,0 +1,29 @@
+package nautilus.game.minekart.item.use_custom;
+
+import org.bukkit.Sound;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilEnt;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_default.ItemUse;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.track.ents.Sheepile;
+
+public class UseSheep extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ kart.GetGP().Announce(F.main("MK", F.elem(UtilEnt.getName(kart.GetDriver())) + " used " + F.item("Super Sheep") + "."));
+
+ //Spider
+ kart.GetGP().GetTrack().GetCreatures().add(
+ new Sheepile(kart.GetGP().GetTrack(), kart.GetDriver().getLocation(), kart));
+
+ //Sound
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.SHEEP_IDLE, 2f, 2f);
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.SHEEP_IDLE, 2f, 2f);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseSpider.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseSpider.java
new file mode 100644
index 000000000..ceb25d3ee
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseSpider.java
@@ -0,0 +1,47 @@
+package nautilus.game.minekart.item.use_custom;
+
+import org.bukkit.Sound;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilEnt;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_default.ItemUse;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.track.ents.Spiderling;
+
+public class UseSpider extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ kart.GetGP().Announce(F.main("MK", F.elem(UtilEnt.getName(kart.GetDriver())) + " used " + F.item("Spiderlings") + "."));
+
+ final Kart fKart = kart;
+
+ int i = 0;
+ for (Kart other : kart.GetGP().GetKarts())
+ {
+ if (other.equals(kart))
+ continue;
+
+ final Kart fOther = other;
+
+ manager.GetPlugin().getServer().getScheduler().scheduleSyncDelayedTask(manager.GetPlugin(), new Runnable()
+ {
+ public void run()
+ {
+ //Spider
+ fKart.GetGP().GetTrack().GetCreatures().add(
+ new Spiderling(fKart.GetGP().GetTrack(), fKart.GetDriver().getLocation(), fKart, fOther));
+
+ //Sound
+ fKart.GetDriver().getWorld().playSound(fKart.GetDriver().getLocation(), Sound.SPIDER_IDLE, 2f, 2f);
+ }
+ }, i * 3);
+
+ i++;
+ }
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseWolf.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseWolf.java
new file mode 100644
index 000000000..71e35624f
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_custom/UseWolf.java
@@ -0,0 +1,18 @@
+package nautilus.game.minekart.item.use_custom;
+
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_default.ItemUse;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+
+public class UseWolf extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ kart.AddCondition(new ConditionData(ConditionType.WolfHeart, 60000));
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/ItemUse.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/ItemUse.java
new file mode 100644
index 000000000..7b97c3c5e
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/ItemUse.java
@@ -0,0 +1,9 @@
+package nautilus.game.minekart.item.use_default;
+
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart;
+
+public abstract class ItemUse
+{
+ public abstract void Use(KartItemManager Manager, Kart kart);
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseBanana.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseBanana.java
new file mode 100644
index 000000000..6115a7d35
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseBanana.java
@@ -0,0 +1,26 @@
+package nautilus.game.minekart.item.use_default;
+
+import java.util.ArrayList;
+
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_active.ActiveStandard;
+import nautilus.game.minekart.item.world_items_default.Banana;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+
+public class UseBanana extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ //Auto-Trail = Dont do this
+ //kart.SetItemStored(null);
+
+ ArrayList ents = new ArrayList();
+
+ ents.add(new Banana(manager, kart, KartUtil.GetBehind(kart)));
+
+ new ActiveStandard(manager, kart, ents);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseBananas.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseBananas.java
new file mode 100644
index 000000000..6a8f813f2
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseBananas.java
@@ -0,0 +1,31 @@
+package nautilus.game.minekart.item.use_default;
+
+import java.util.ArrayList;
+
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_active.ActiveBananas;
+import nautilus.game.minekart.item.world_items_default.Banana;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+
+public class UseBananas extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ ArrayList ents = new ArrayList();
+
+ ents.add(new Banana(manager, kart, KartUtil.GetLook(kart)));
+ ents.add(new Banana(manager, kart, KartUtil.GetLook(kart)));
+ ents.add(new Banana(manager, kart, KartUtil.GetLook(kart)));
+ ents.add(new Banana(manager, kart, KartUtil.GetLook(kart)));
+ ents.add(new Banana(manager, kart, KartUtil.GetLook(kart)));
+ ents.add(new Banana(manager, kart, KartUtil.GetLook(kart)));
+ ents.add(new Banana(manager, kart, KartUtil.GetLook(kart)));
+
+ new ActiveBananas(manager, kart, ents);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseFakeItem.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseFakeItem.java
new file mode 100644
index 000000000..25c006ef8
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseFakeItem.java
@@ -0,0 +1,17 @@
+package nautilus.game.minekart.item.use_default;
+
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.world_items_default.FakeItem;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+
+public class UseFakeItem extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ new FakeItem(manager, kart, KartUtil.GetBehind(kart));
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseGhost.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseGhost.java
new file mode 100644
index 000000000..5a2a55a6b
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseGhost.java
@@ -0,0 +1,79 @@
+package nautilus.game.minekart.item.use_default;
+
+import java.util.ArrayList;
+
+import org.bukkit.Color;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.LeatherArmorMeta;
+
+import mineplex.core.common.util.UtilMath;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+
+public class UseGhost extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ if (kart.HasCondition(ConditionType.Star) || kart.HasCondition(ConditionType.Ghost) || kart.HasCondition(ConditionType.Lightning))
+ return;
+
+ kart.SetItemStored(null);
+
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.GHAST_MOAN, 2f, 1f);
+
+ kart.AddCondition(new ConditionData(ConditionType.Ghost, 8000));
+
+ ArrayList steal = new ArrayList();
+
+ for (Kart other : kart.GetGP().GetKarts())
+ {
+ if (kart.equals(other))
+ continue;
+
+ if (other.GetItemStored() != null)
+ steal.add(other);
+ }
+
+ if (!steal.isEmpty())
+ {
+ Kart target = steal.get(UtilMath.r(steal.size()));
+ kart.SetItemStored(target.GetItemStored());
+ target.SetItemStored(null);
+
+ target.GetDriver().getWorld().playSound(target.GetDriver().getLocation(), Sound.GHAST_MOAN, 2f, 1f);
+ }
+
+ Color color = Color.WHITE;
+ LeatherArmorMeta meta;
+
+ ItemStack head = new ItemStack(Material.LEATHER_HELMET);
+ meta = (LeatherArmorMeta)head.getItemMeta();
+ meta.setColor(color);
+ head.setItemMeta(meta);
+
+ ItemStack chest = new ItemStack(Material.LEATHER_CHESTPLATE);
+ meta = (LeatherArmorMeta)chest.getItemMeta();
+ meta.setColor(color);
+ chest.setItemMeta(meta);
+
+ ItemStack legs = new ItemStack(Material.LEATHER_LEGGINGS);
+ meta = (LeatherArmorMeta)legs.getItemMeta();
+ meta.setColor(color);
+ legs.setItemMeta(meta);
+
+ ItemStack boots = new ItemStack(Material.LEATHER_BOOTS);
+ meta = (LeatherArmorMeta)boots.getItemMeta();
+ meta.setColor(color);
+ boots.setItemMeta(meta);
+
+ kart.GetDriver().getInventory().setHelmet(head);
+ kart.GetDriver().getInventory().setChestplate(chest);
+ kart.GetDriver().getInventory().setLeggings(legs);
+ kart.GetDriver().getInventory().setBoots(boots);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseGhost.java.orig b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseGhost.java.orig
new file mode 100644
index 000000000..b3f877b2a
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseGhost.java.orig
@@ -0,0 +1,42 @@
+package nautilus.game.minekart.item.use_default;
+
+import java.util.ArrayList;
+
+import org.bukkit.Sound;
+
+import me.chiss.Core.Utility.UtilMath;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+
+public class UseGhost extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.GHAST_MOAN, 2f, 1f);
+
+ kart.AddCondition(new ConditionData(ConditionType.Ghost, 8000));
+
+ ArrayList steal = new ArrayList();
+
+ for (Kart other : kart.GetGP().GetKarts())
+ {
+ if (kart.equals(other))
+ continue;
+
+ if (kart.GetItemStored() != null)
+ steal.add(other);
+ }
+
+ if (!steal.isEmpty())
+ {
+ Kart target = steal.get(UtilMath.r(steal.size()));
+ kart.SetItemStored(target.GetItemStored());
+ target.SetItemStored(null);
+ }
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseGreenShell.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseGreenShell.java
new file mode 100644
index 000000000..c05ae7e70
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseGreenShell.java
@@ -0,0 +1,26 @@
+package nautilus.game.minekart.item.use_default;
+
+import java.util.ArrayList;
+
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_active.ActiveStandard;
+import nautilus.game.minekart.item.world_items_default.GreenShell;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+
+public class UseGreenShell extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ //Auto-Trail = Dont do this
+ //kart.SetItemStored(null);
+
+ ArrayList ents = new ArrayList();
+
+ ents.add(new GreenShell(manager, kart, KartUtil.GetLook(kart)));
+
+ new ActiveStandard(manager, kart, ents);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseLightning.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseLightning.java
new file mode 100644
index 000000000..56ef0368f
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseLightning.java
@@ -0,0 +1,37 @@
+package nautilus.game.minekart.item.use_default;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilEnt;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+import nautilus.game.minekart.kart.crash.Crash_Spin;
+
+public class UseLightning extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ if (kart.HasCondition(ConditionType.Star) || kart.HasCondition(ConditionType.Ghost) || kart.HasCondition(ConditionType.Lightning))
+ return;
+
+ kart.SetItemStored(null);
+
+ kart.GetGP().Announce(F.main("MK", F.elem(UtilEnt.getName(kart.GetDriver())) + " used " + F.item("Lightning") + "."));
+
+ for (Kart other : kart.GetGP().GetKarts())
+ {
+ if (kart.equals(other))
+ continue;
+
+ if (other.HasCondition(ConditionType.Star) || other.HasCondition(ConditionType.Ghost))
+ continue;
+
+ new Crash_Spin(other, 0.8f);
+
+ other.GetDriver().getWorld().strikeLightningEffect(other.GetDriver().getLocation());
+ other.AddCondition(new ConditionData(ConditionType.Lightning, 10000));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseLightning.java.orig b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseLightning.java.orig
new file mode 100644
index 000000000..25a0d73a8
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseLightning.java.orig
@@ -0,0 +1,33 @@
+package nautilus.game.minekart.item.use_default;
+
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+import nautilus.game.minekart.kart.crash.Crash_Spin;
+
+public class UseLightning extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ if (kart.GetGP() == null)
+ return;
+
+ for (Kart other : kart.GetGP().GetKarts())
+ {
+ if (kart.equals(other))
+ continue;
+
+ if (other.HasCondition(ConditionType.Star) || other.HasCondition(ConditionType.Ghost))
+ continue;
+
+ new Crash_Spin(kart, 0.8f);
+
+ other.GetDriver().getWorld().strikeLightningEffect(other.GetDriver().getLocation());
+ other.AddCondition(new ConditionData(ConditionType.Lightning, 10000));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseMushroom.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseMushroom.java
new file mode 100644
index 000000000..f09a90e7a
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseMushroom.java
@@ -0,0 +1,35 @@
+package nautilus.game.minekart.item.use_default;
+
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.KartItemType;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+
+public class UseMushroom extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, final Kart kart)
+ {
+ //Super
+ if (kart.GetItemStored() == KartItemType.SuperMushroom)
+ {
+ if (!kart.HasCondition(ConditionType.SuperMushroom))
+ kart.AddCondition(new ConditionData(ConditionType.SuperMushroom, 8000));
+ }
+
+ //Triple
+ else if (kart.GetItemStored() == KartItemType.TripleMushroom)
+ kart.SetItemStored(KartItemType.DoubleMushroom);
+
+ //Double
+ else if (kart.GetItemStored() == KartItemType.DoubleMushroom)
+ kart.SetItemStored(KartItemType.SingleMushroom);
+
+ //Single
+ else
+ kart.SetItemStored(null);
+
+ kart.AddCondition(new ConditionData(ConditionType.Boost, 2000));
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseRedShell.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseRedShell.java
new file mode 100644
index 000000000..fd7dee2b8
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseRedShell.java
@@ -0,0 +1,26 @@
+package nautilus.game.minekart.item.use_default;
+
+import java.util.ArrayList;
+
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_active.ActiveStandard;
+import nautilus.game.minekart.item.world_items_default.RedShell;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+
+public class UseRedShell extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ //Auto-Trail = Dont do this
+ //kart.SetItemStored(null);
+
+ ArrayList ents = new ArrayList();
+
+ ents.add(new RedShell(manager, kart, KartUtil.GetLook(kart)));
+
+ new ActiveStandard(manager, kart, ents);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseStar.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseStar.java
new file mode 100644
index 000000000..27d48e272
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseStar.java
@@ -0,0 +1,20 @@
+package nautilus.game.minekart.item.use_default;
+
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+
+public class UseStar extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ if (kart.HasCondition(ConditionType.Star) || kart.HasCondition(ConditionType.Ghost) || kart.HasCondition(ConditionType.Lightning))
+ return;
+
+ kart.SetItemStored(null);
+
+ kart.AddCondition(new ConditionData(ConditionType.Star, 10000));
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseTripleGreenShell.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseTripleGreenShell.java
new file mode 100644
index 000000000..ea57665eb
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseTripleGreenShell.java
@@ -0,0 +1,27 @@
+package nautilus.game.minekart.item.use_default;
+
+import java.util.ArrayList;
+
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_active.ActiveShells;
+import nautilus.game.minekart.item.world_items_default.GreenShell;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+
+public class UseTripleGreenShell extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ ArrayList ents = new ArrayList();
+
+ ents.add(new GreenShell(manager, kart, KartUtil.GetLook(kart)));
+ ents.add(new GreenShell(manager, kart, KartUtil.GetLook(kart)));
+ ents.add(new GreenShell(manager, kart, KartUtil.GetLook(kart)));
+
+ new ActiveShells(manager, kart, ents);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseTripleRedShell.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseTripleRedShell.java
new file mode 100644
index 000000000..d2f62edee
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/use_default/UseTripleRedShell.java
@@ -0,0 +1,27 @@
+package nautilus.game.minekart.item.use_default;
+
+import java.util.ArrayList;
+
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.use_active.ActiveShells;
+import nautilus.game.minekart.item.world_items_default.RedShell;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+
+public class UseTripleRedShell extends ItemUse
+{
+ @Override
+ public void Use(KartItemManager manager, Kart kart)
+ {
+ kart.SetItemStored(null);
+
+ ArrayList ents = new ArrayList();
+
+ ents.add(new RedShell(manager, kart, KartUtil.GetLook(kart)));
+ ents.add(new RedShell(manager, kart, KartUtil.GetLook(kart)));
+ ents.add(new RedShell(manager, kart, KartUtil.GetLook(kart)));
+
+ new ActiveShells(manager, kart, ents);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_custom/Flame.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_custom/Flame.java
new file mode 100644
index 000000000..be4f8219d
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_custom/Flame.java
@@ -0,0 +1,36 @@
+package nautilus.game.minekart.item.world_items_custom;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart;
+
+public class Flame extends KartItemEntity
+{
+ public Flame(KartItemManager manager, Kart kart, Location loc)
+ {
+ super(manager, kart, loc, Material.FIRE, (byte)0);
+
+ SetRadius(1);
+
+ this.SetFired();
+ }
+
+ @Override
+ public void CollideHandle(Kart kart)
+ {
+ if (!kart.IsInvulnerable(false))
+ {
+ int ticks = Math.min(100, kart.GetDriver().getFireTicks() + 20);
+ kart.GetDriver().setFireTicks(ticks);
+ }
+ }
+
+ @Override
+ public boolean TickUpdate()
+ {
+ return System.currentTimeMillis() - this.GetFireTime() > 6000;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/Banana.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/Banana.java
new file mode 100644
index 000000000..3fa354a9d
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/Banana.java
@@ -0,0 +1,53 @@
+package nautilus.game.minekart.item.world_items_default;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilAlg;
+import mineplex.core.common.util.UtilEnt;
+import mineplex.core.common.util.UtilPlayer;
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.crash.Crash_Spin;
+
+public class Banana extends KartItemEntity
+{
+ public Banana(KartItemManager manager, Kart kart, Location loc)
+ {
+ super(manager, kart, loc, Material.INK_SACK, (byte)11);
+
+ SetRadius(1.5);
+ }
+
+ @Override
+ public void CollideHandle(Kart kart)
+ {
+ if (!kart.IsInvulnerable(true))
+ {
+ //Inform
+ if (kart.equals(GetOwner()))
+ {
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", "You hit yourself with " + F.item("Banana") + "."));
+ }
+ else
+ {
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", F.elem(UtilEnt.getName(GetOwner().GetDriver())) + " hit you with " + F.item("Banana") + "."));
+ UtilPlayer.message(GetOwner().GetDriver(), F.main("MK", "You hit " + F.elem(UtilEnt.getName(kart.GetDriver())) + " with " + F.item("Banana") + "."));
+ }
+
+ //Crash
+ if (kart.GetVelocity().length() == 0)
+ kart.SetVelocity(kart.GetDriver().getLocation().getDirection().setY(0));
+
+ kart.SetVelocity(UtilAlg.Normalize(kart.GetVelocityClone().setY(0)).multiply(0.6));
+ new Crash_Spin(kart, 0.6f);
+ kart.SetStability(0);
+ }
+
+ //Effect
+ GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.BAT_HURT, 1f, 1f);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/FakeItem.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/FakeItem.java
new file mode 100644
index 000000000..5c3f7a716
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/FakeItem.java
@@ -0,0 +1,58 @@
+package nautilus.game.minekart.item.world_items_default;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.entity.EnderCrystal;
+import org.bukkit.entity.Entity;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilEnt;
+import mineplex.core.common.util.UtilPlayer;
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.crash.Crash_Explode;
+
+public class FakeItem extends KartItemEntity
+{
+ public FakeItem(KartItemManager manager, Kart kart, Location loc)
+ {
+ super(manager, kart, loc, Material.TRAPPED_CHEST, (byte)0);
+
+ SetRadius(1.5);
+ }
+
+ @Override
+ public void CollideHandle(Kart kart)
+ {
+ if (!kart.IsInvulnerable(true))
+ {
+ //Inform
+ if (kart.equals(GetOwner()))
+ {
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", "You hit yourself with " + F.item("Fake Item") + "."));
+ }
+ else
+ {
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", F.elem(UtilEnt.getName(GetOwner().GetDriver())) + " hit you with " + F.item("Fake Item") + "."));
+ UtilPlayer.message(GetOwner().GetDriver(), F.main("MK", "You hit " + F.elem(UtilEnt.getName(kart.GetDriver())) + " with " + F.item("Fake Item") + "."));
+ }
+
+ //Crash
+ kart.CrashStop();
+ new Crash_Explode(kart, 1.2f, false);
+ }
+
+ //Effect
+ GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.EXPLODE, 2f, 0.2f);
+ }
+
+ @Override
+ public void Spawn(Location loc)
+ {
+ Entity ent = loc.getWorld().spawn(loc, EnderCrystal.class);
+ SetEntity(ent);
+ SetFired();
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/GreenShell.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/GreenShell.java
new file mode 100644
index 000000000..cc9f2555f
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/GreenShell.java
@@ -0,0 +1,81 @@
+package nautilus.game.minekart.item.world_items_default;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Slime;
+import org.bukkit.util.Vector;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilAlg;
+import mineplex.core.common.util.UtilEnt;
+import mineplex.core.common.util.UtilPlayer;
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.control.Collision;
+import nautilus.game.minekart.item.control.Movement;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.crash.Crash_Explode;
+
+public class GreenShell extends KartItemEntity
+{
+ public GreenShell(KartItemManager manager, Kart kart, Location loc)
+ {
+ super(manager, kart, loc, Material.EMERALD_BLOCK, (byte)0);
+
+ Vector vel = UtilAlg.Normalize(kart.GetDriver().getLocation().getDirection().setY(0));
+ vel.multiply(1.4);
+ vel.setY(-0.5);
+
+ SetVelocity(vel);
+
+ SetRadius(1.5);
+ }
+
+ @Override
+ public void CollideHandle(Kart kart)
+ {
+ if (!kart.IsInvulnerable(true))
+ {
+ //Inform
+ if (kart.equals(GetOwner()))
+ {
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", "You hit yourself with " + F.item("Green Shell") + "."));
+ }
+ else
+ {
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", F.elem(UtilEnt.getName(GetOwner().GetDriver())) + " hit you with " + F.item("Green Shell") + "."));
+ UtilPlayer.message(GetOwner().GetDriver(), F.main("MK", "You hit " + F.elem(UtilEnt.getName(kart.GetDriver())) + " with " + F.item("Green Shell") + "."));
+ }
+
+ //Crash
+ new Crash_Explode(kart, 1f, true);
+ }
+
+ //Effect
+ GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.EXPLODE, 2f, 1.5f);
+ }
+
+ @Override
+ public void Spawn(Location loc)
+ {
+ Slime slime = (Slime) loc.getWorld().spawnEntity(loc.add(0, 0.5, 0), EntityType.SLIME);
+ slime.setSize(1);
+ SetEntity(slime);
+ SetFired();
+ }
+
+ public boolean TickUpdate()
+ {
+ if (GetHost() != null)
+ return false;
+
+ Movement.Move(this);
+
+ if (Collision.CollideBlock(this))
+ GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.CHICKEN_EGG_POP, 2f, 1f);
+
+ return false;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/RedShell.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/RedShell.java
new file mode 100644
index 000000000..988936085
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/item/world_items_default/RedShell.java
@@ -0,0 +1,84 @@
+package nautilus.game.minekart.item.world_items_default;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Slime;
+import org.bukkit.util.Vector;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilAlg;
+import mineplex.core.common.util.UtilEnt;
+import mineplex.core.common.util.UtilPlayer;
+import nautilus.game.minekart.item.KartItemEntity;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.item.control.Collision;
+import nautilus.game.minekart.item.control.Movement;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.crash.Crash_Explode;
+
+public class RedShell extends KartItemEntity
+{
+ public RedShell(KartItemManager manager, Kart kart, Location loc)
+ {
+ super(manager, kart, loc, Material.REDSTONE_BLOCK, (byte)0);
+
+ Vector vel = UtilAlg.Normalize(kart.GetDriver().getLocation().getDirection().setY(0));
+ vel.multiply(1.2);
+ vel.setY(-0.5);
+
+ SetVelocity(vel);
+
+ SetTarget(null);
+
+ SetRadius(1.5);
+ }
+
+ @Override
+ public void CollideHandle(Kart kart)
+ {
+ if (!kart.IsInvulnerable(true))
+ {
+ //Inform
+ if (kart.equals(GetOwner()))
+ {
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", "You hit yourself with " + F.item("Red Shell") + "."));
+ }
+ else
+ {
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", F.elem(UtilEnt.getName(GetOwner().GetDriver())) + " hit you with " + F.item("Red Shell") + "."));
+ UtilPlayer.message(GetOwner().GetDriver(), F.main("MK", "You hit " + F.elem(UtilEnt.getName(kart.GetDriver())) + " with " + F.item("Red Shell") + "."));
+ }
+
+ //Crash
+ new Crash_Explode(kart, 1f, true);
+ }
+
+ //Effect
+ GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.EXPLODE, 2f, 1.5f);
+ }
+
+ @Override
+ public void Spawn(Location loc)
+ {
+ Slime slime = (Slime) loc.getWorld().spawnEntity(loc.add(0, 0.5, 0), EntityType.MAGMA_CUBE);
+ slime.setSize(1);
+ SetEntity(slime);
+ SetFired();
+ }
+
+ public boolean TickUpdate()
+ {
+ if (GetHost() != null)
+ return false;
+
+ if (GetTarget() != null)
+ GetTarget().GetDriver().playSound(this.GetEntity().getLocation(), Sound.NOTE_BASS, 0.2f, 1f);
+
+ Movement.Home(this);
+ Movement.Move(this);
+
+ return Collision.CollideBlock(this);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/Kart.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/Kart.java
new file mode 100644
index 000000000..0bfab798b
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/Kart.java
@@ -0,0 +1,660 @@
+package nautilus.game.minekart.kart;
+
+import java.util.ArrayList;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilMath;
+import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.fakeEntity.FakeEntity;
+import mineplex.core.fakeEntity.FakeEntityManager;
+import mineplex.core.fakeEntity.FakeItemDrop;
+import mineplex.core.fakeEntity.FakePlayer;
+import mineplex.core.itemstack.ItemStackFactory;
+import nautilus.game.minekart.gp.GP;
+import nautilus.game.minekart.gp.GP.GPState;
+import nautilus.game.minekart.gp.GPBattle;
+import nautilus.game.minekart.item.KartItemActive;
+import nautilus.game.minekart.item.KartItemType;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+import nautilus.game.minekart.kart.crash.Crash;
+import nautilus.game.minekart.track.Track.TrackState;
+
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.util.Vector;
+
+public class Kart
+{
+ public enum DriftDirection
+ {
+ Left,
+ Right,
+ None
+ }
+
+ private Player _driver = null;
+ private FakeEntity _entity = null;
+ private FakeItemDrop _fakeItem = null;
+ private FakePlayer _fakePlayer = null;
+
+ private GP _gp;
+
+ //Kart
+ private KartType _kartType;
+ private KartState _kartState = KartState.Drive;
+ private long _kartStateTime = System.currentTimeMillis();
+ private Vector _yaw;
+
+ //Drift Data
+ private DriftDirection _drift = DriftDirection.None;
+ private long _driftStart = 0;
+
+ //Crash Data
+ private Crash _crash;
+
+ //Items
+ private int _itemCycles = 0;
+ private KartItemActive _itemActive = null;
+ private KartItemType _itemStored = null;
+
+ //Conditions
+ private ArrayList _conditions = new ArrayList();
+
+ //Battle
+ private int _lives = 3;
+
+ //Lap
+ private int _lap = 0;
+ private int _lapNode = 0;
+ private double _lapScore = 0;
+ private int _lapMomentum = 10000;
+
+ private int _lapPlace = 0;
+
+ private int _lakituTick = 0;
+
+ //Music
+ private int _songStarTick = 0;
+
+ //Physics
+ private Vector _velocity = new Vector(0,0,0);
+
+ public Kart(Player player, KartType kartType, GP gp)
+ {
+ _gp = gp;
+
+ _driver = player;
+ _kartType = kartType;
+ _entity = new FakeEntity(kartType.GetType(), player.getLocation());
+
+ Equip();
+ }
+
+ public GP GetGP()
+ {
+ return _gp;
+ }
+
+ public FakeEntity GetEntity()
+ {
+ return _entity;
+ }
+
+ public Player GetDriver()
+ {
+ return _driver;
+ }
+
+ public KartType GetKartType()
+ {
+ return _kartType;
+ }
+
+ public void SetKartType(KartType type)
+ {
+ _kartType = type;
+ Equip();
+ }
+
+ public KartState GetKartState()
+ {
+ return _kartState;
+ }
+
+ public long GetKartStateTime()
+ {
+ return _kartStateTime;
+ }
+
+ public void SetKartState(KartState state)
+ {
+ _kartState = state;
+ _kartStateTime = System.currentTimeMillis();
+ }
+
+ public Vector GetKartDirection()
+ {
+ return _velocity;
+ }
+
+ public int GetLakituTick()
+ {
+ return _lakituTick;
+ }
+
+ public void SetLakituTick(int tick)
+ {
+ _lakituTick += tick;
+
+ if (_lakituTick <= 0)
+ _lakituTick = 0;
+ }
+
+ public ArrayList GetConditions()
+ {
+ return _conditions;
+ }
+
+ public void AddCondition(ConditionData data)
+ {
+ _conditions.add(data);
+
+ if (data.IsCondition(ConditionType.Star))
+ SetStarSongTick(0);
+ }
+
+ public boolean HasCondition(ConditionType type)
+ {
+ for (ConditionData data : _conditions)
+ {
+ if (data.IsCondition(type))
+ return true;
+ }
+
+ return false;
+ }
+
+ public void ExpireCondition(ConditionType type)
+ {
+ for (ConditionData data : GetConditions())
+ if (data.IsCondition(type))
+ data.Expire();
+ }
+
+ public void ExpireConditions()
+ {
+ for (ConditionData data : GetConditions())
+ data.Expire();
+ }
+
+ public void Equip()
+ {
+ _driver.getInventory().clear();
+
+ //Driving
+ GetDriver().getInventory().setItem(0, ItemStackFactory.Instance.CreateStack(Material.STONE_SWORD, (byte)0, 1, "§a§lAccelerate"));
+ GetDriver().getInventory().setItem(1, ItemStackFactory.Instance.CreateStack(Material.WOOD_SWORD, (byte)0, 1, "§a§lHand Brake"));
+
+ //Item Slot
+ GetDriver().getInventory().setItem(2, null);
+ GetDriver().getInventory().setItem(3, null);
+ GetDriver().getInventory().setItem(4, null);
+
+ //State
+ ItemStack a = ItemStackFactory.Instance.CreateStack(Material.WOOD_HOE, (byte)0, (int)(GetKartType().GetTopSpeed() * 100), "§e§lTop Speed");
+ ItemStack b = ItemStackFactory.Instance.CreateStack(Material.STONE_HOE, (byte)0, (int)GetKartType().GetAcceleration() - 10, "§e§lAcceleration");
+ ItemStack c = ItemStackFactory.Instance.CreateStack(Material.IRON_HOE, (byte)0, (int)GetKartType().GetHandling() - 10, "§e§lHandling");
+ ItemStack d = ItemStackFactory.Instance.CreateStack(GetKartType().GetAvatar(), (byte)0, 1, "§e§l" + GetKartType().GetName() + " Kart");
+
+ GetDriver().getInventory().setItem(5, d);
+ GetDriver().getInventory().setItem(6, a);
+ GetDriver().getInventory().setItem(7, b);
+ GetDriver().getInventory().setItem(8, c);
+
+ }
+
+ public Vector GetVelocity()
+ {
+ return _velocity;
+ }
+
+ public Vector GetVelocityClone()
+ {
+ return new Vector(_velocity.getX(), _velocity.getY(), _velocity.getZ());
+ }
+
+ public void SetVelocity(Vector vec)
+ {
+ _velocity = vec;
+ }
+
+ public Vector GetYaw()
+ {
+ return _yaw;
+ }
+
+ public void CrashStop()
+ {
+ _velocity = new Vector(0,0,0);
+ ExpireCondition(ConditionType.Boost);
+
+ if (GetKartState() == KartState.Drive)
+ LoseLife();
+ }
+
+ public double GetSpeed()
+ {
+ Vector vec = new Vector(_velocity.getX(), 0, _velocity.getZ());
+ return vec.length();
+ }
+
+ public void SetDrift()
+ {
+ ClearDrift();
+
+ //Check Speed Requirement
+ if (GetSpeed() < 0.4)
+ {
+ return;
+ }
+
+ //Check Turn Requirement
+ Vector look = GetDriver().getLocation().getDirection();
+ look.setY(0);
+ look.normalize();
+
+ Vector vel = new Vector(GetVelocity().getX(), 0, GetVelocity().getZ());
+ vel.normalize();
+
+ look.subtract(vel);
+
+ if (look.length() < 0.2)
+ {
+ return;
+ }
+
+
+ //Get Drift Direction
+ Vector kartVec = new Vector(_velocity.getX(), 0, _velocity.getZ());
+ kartVec.normalize();
+
+ Vector lookVec = GetDriver().getLocation().getDirection();
+ lookVec.setY(0);
+ lookVec.normalize();
+
+ Vector left = new Vector(kartVec.getZ(), 0, kartVec.getX() * -1);
+ Vector right = new Vector(kartVec.getZ() * -1, 0, kartVec.getX());
+
+ double distLeft = UtilMath.offset(left, lookVec);
+ double distRight = UtilMath.offset(right, lookVec);
+
+ if (distLeft < distRight) _drift = DriftDirection.Left;
+ else _drift = DriftDirection.Right;
+
+ _driftStart = System.currentTimeMillis();
+ }
+
+ public DriftDirection GetDrift()
+ {
+ return _drift;
+ }
+
+ public Vector GetDriftVector()
+ {
+ if (_drift == DriftDirection.None)
+ return new Vector(0,0,0);
+
+ //Get Drift Direction
+ Vector kartVec = new Vector(_velocity.getX(), 0, _velocity.getZ());
+ kartVec.normalize();
+
+ Vector lookVec = GetDriver().getLocation().getDirection();
+ lookVec.setY(0);
+ lookVec.normalize();
+
+ if (_drift == DriftDirection.Left)
+ {
+ Vector drift = new Vector(kartVec.getZ(), 0, kartVec.getX() * -1);
+ return drift.subtract(kartVec);
+ }
+ else
+ {
+ Vector drift = new Vector(kartVec.getZ() * -1, 0, kartVec.getX());
+ return drift.subtract(kartVec);
+ }
+ }
+
+ public long GetDriftTime()
+ {
+ return System.currentTimeMillis() - _driftStart;
+ }
+
+ public void ClearDrift()
+ {
+ _driftStart = System.currentTimeMillis();
+ _drift = DriftDirection.None;
+ }
+
+ public Crash GetCrash()
+ {
+ if (GetKartState() != KartState.Crash)
+ return null;
+
+ return _crash;
+ }
+
+ public void SetCrash(Crash crash)
+ {
+ _crash = crash;
+ }
+
+ public void PickupItem()
+ {
+ if (GetItemStored() == null && GetItemCycles() == 0)
+ SetItemCycles(40);
+ }
+
+ public void SetItemCycles(int cycles)
+ {
+ _itemCycles = cycles;
+ }
+
+ public int GetItemCycles()
+ {
+ return _itemCycles;
+ }
+
+ public KartItemType GetItemStored()
+ {
+ return _itemStored;
+ }
+
+ public KartItemActive GetItemActive()
+ {
+ return _itemActive;
+ }
+
+ public void SetItemStored(KartItemType item)
+ {
+ _itemStored = item;
+
+ if (item == null)
+ {
+ if (_fakeItem != null)
+ RemoveFakeKartItemInfo();
+ }
+ else
+ {
+ SetFakeKartItemInfo(item);
+ }
+ }
+
+ private void SetFakeKartItemInfo(KartItemType item)
+ {
+ boolean showPlayer = false;
+ boolean spawnItem = false;
+
+ if (_fakeItem == null)
+ {
+ _fakeItem = new FakeItemDrop(new ItemStack(item.GetMaterial()), GetDriver().getLocation());
+ spawnItem = true;
+ }
+ else
+ _fakeItem.SetItemStack(new ItemStack(item.GetMaterial()));
+
+ if (_fakePlayer == null)
+ {
+ showPlayer = true;
+ _fakePlayer = new FakePlayer("Buffer", GetDriver().getLocation().subtract(0, 10, 0));
+ }
+
+ //Set Item
+ GetDriver().getInventory().setItem(3, ItemStackFactory.Instance.CreateStack(item.GetMaterial(), (byte)0, item.GetAmount(), "§a§l"+item.GetName()));
+
+ for (Kart kart : GetGP().GetKarts())
+ {
+ if (kart == this)
+ {
+ if (spawnItem)
+ {
+ FakeEntityManager.Instance.SendPacketTo(_fakeItem.Spawn(), kart.GetDriver());
+ FakeEntityManager.Instance.SendPacketTo(_fakeItem.SetVehicle(kart.GetDriver().getEntityId()), kart.GetDriver());
+ }
+
+ FakeEntityManager.Instance.SendPacketTo(_fakeItem.Show(), kart.GetDriver());
+
+ continue;
+ }
+
+ if (showPlayer)
+ {
+ FakeEntityManager.Instance.SendPacketTo(_fakePlayer.Spawn(), kart.GetDriver());
+ FakeEntityManager.Instance.SendPacketTo(_fakePlayer.Hide(), kart.GetDriver());
+ FakeEntityManager.Instance.SendPacketTo(_fakePlayer.SetVehicle(GetDriver().getEntityId()), kart.GetDriver());
+
+ FakeEntityManager.Instance.FakePassenger(kart.GetDriver(), GetDriver().getEntityId(), _fakePlayer.SetVehicle(GetDriver().getEntityId()));
+ }
+
+ if (spawnItem)
+ {
+ FakeEntityManager.Instance.SendPacketTo(_fakeItem.Spawn(), kart.GetDriver());
+ FakeEntityManager.Instance.SendPacketTo(_fakeItem.SetVehicle(_fakePlayer.GetEntityId()), kart.GetDriver());
+
+ FakeEntityManager.Instance.FakePassenger(kart.GetDriver(), _fakePlayer.GetEntityId(), _fakeItem.SetVehicle(_fakePlayer.GetEntityId()));
+ }
+
+ FakeEntityManager.Instance.SendPacketTo(_fakeItem.Show(), kart.GetDriver());
+ }
+ }
+
+ private void RemoveFakeKartItemInfo()
+ {
+ GetDriver().getInventory().setItem(3, null);
+
+ for (Kart kart : GetGP().GetKarts())
+ {
+ if (_fakeItem != null)
+ {
+ FakeEntityManager.Instance.SendPacketTo(_fakeItem.Destroy(), kart.GetDriver());
+ }
+
+ if (kart != this)
+ {
+ if (_fakeItem != null && _fakePlayer != null)
+ {
+ FakeEntityManager.Instance.RemoveFakePassenger(kart.GetDriver(), _fakePlayer.GetEntityId());
+ }
+ }
+ }
+
+ _fakeItem = null;
+ }
+
+ public void SetItemActive(KartItemActive item)
+ {
+ _itemActive = item;
+ }
+
+ public void SetStability(int i)
+ {
+ GetDriver().setFoodLevel(i);
+ }
+
+ public boolean CanControl()
+ {
+ if (GetGP() == null)
+ return true;
+
+ if (GetGP().GetState() != GPState.Live)
+ return false;
+
+ if (GetGP().GetTrack().GetState() != TrackState.Live && GetGP().GetTrack().GetState() != TrackState.Ending)
+ return false;
+
+ if (HasFinishedTrack())
+ return false;
+
+ return true;
+ }
+
+ public int GetLives()
+ {
+ return _lives;
+ }
+
+ public void LoseLife()
+ {
+ if (_lives < 1)
+ return;
+
+ if (GetGP() == null)
+ return;
+
+ if (!(GetGP() instanceof GPBattle))
+ return;
+
+ GPBattle battle = (GPBattle)GetGP();
+ _lives = _lives - 1;
+
+ if (_lives == 0)
+ {
+ battle.GetTrack().GetPositions().add(0, this);
+ battle.CheckBattleEnd();
+ }
+ }
+
+ public int GetLap()
+ {
+ return _lap;
+ }
+
+ public void SetLap(int lap)
+ {
+ _lap = lap;
+ }
+
+ public int GetLapNode()
+ {
+ return _lapNode;
+ }
+
+ public void SetLapNode(int lapNode)
+ {
+ if ((lapNode > _lapNode && !(_lapNode <= GetGP().GetTrack().GetProgress().size() / 5 && lapNode >= GetGP().GetTrack().GetProgress().size() * 4 / 5)) || (lapNode <= GetGP().GetTrack().GetProgress().size() / 5 && _lapNode >= GetGP().GetTrack().GetProgress().size() * 4 / 5))
+ SetLapMomentum(GetLapMomentum() + 1);
+ else if (lapNode < _lapNode || (_lapNode <= GetGP().GetTrack().GetProgress().size() / 5 && lapNode >= GetGP().GetTrack().GetProgress().size() * 4 / 5))
+ SetLapMomentum(GetLapMomentum() - 1);
+
+ _lapNode = lapNode;
+
+ //Next Lap
+ if (lapNode <= GetGP().GetTrack().GetProgress().size() / 5)
+ {
+ if (_lapMomentum > GetGP().GetTrack().GetProgress().size() / 4)
+ {
+ SetLap(GetLap() + 1);
+ SetLapMomentum(0);
+
+ GetDriver().getWorld().playSound(GetDriver().getLocation(), GetKartType().GetSoundMain(), 0.5f, 1f);
+
+ if (GetLap() > 3)
+ {
+ int place = GetLapPlace() + 1;
+
+ String placeString = "st";
+ if (place == 2) placeString = "nd";
+ else if (place == 3) placeString = "rd";
+ else if (place >= 4) placeString = "th";
+
+ GetGP().Announce(F.main("MK", F.name(GetDriver().getName()) + " finished in " + F.elem(place + placeString) + " place."));
+ }
+ else
+ UtilPlayer.message(GetDriver(), F.main("MK", "Lap " + GetLap()));
+ }
+ }
+ }
+
+ public double GetLapScore()
+ {
+ return _lapScore;
+ }
+
+ public void SetLapScore(double lapScore)
+ {
+ _lapScore = lapScore + (1000000 * (_lap - (GetLapMomentum() < 0 ? 1 : 0)));
+ }
+
+ public int GetLapMomentum()
+ {
+ return _lapMomentum;
+ }
+
+ public void SetLapMomentum(int lapMomentum)
+ {
+ _lapMomentum = lapMomentum;
+ }
+
+ public int GetLapPlace()
+ {
+ return _lapPlace;
+ }
+
+ public void SetLapPlace(int place)
+ {
+ //Roar with joy!
+ if (place < _lapPlace)
+ GetDriver().getWorld().playSound(GetDriver().getLocation(), GetKartType().GetSoundMain(), 0.5f, 1f);
+
+ _lapPlace = place;
+ }
+
+ public boolean HasFinishedTrack()
+ {
+ return GetLap() > 3 || GetLives() <= 0;
+ }
+
+ public void ClearTrackData()
+ {
+ //Battle
+ _lives = 3;
+
+ //Lap
+ _lap = 0;
+ _lapNode = 0;
+ _lapScore = 0;
+ _lapMomentum = 10000;
+
+ _lapPlace = 0;
+ }
+
+ public int GetStarSongTick()
+ {
+ return _songStarTick;
+ }
+
+ public void SetStarSongTick(int tick)
+ {
+ _songStarTick = tick;
+ }
+
+ public void SetPlayerArmor()
+ {
+ GetDriver().getInventory().setHelmet(null);
+ GetDriver().getInventory().setChestplate(null);
+ GetDriver().getInventory().setLeggings(null);
+ GetDriver().getInventory().setBoots(null);
+ }
+
+ public boolean IsInvulnerable(boolean useHeart)
+ {
+ if (useHeart && HasCondition(ConditionType.WolfHeart))
+ {
+ ExpireCondition(ConditionType.WolfHeart);
+ return true;
+ }
+
+ return HasCondition(ConditionType.Star) || HasCondition(ConditionType.Ghost);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartManager.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartManager.java
new file mode 100644
index 000000000..5fcb7cb1f
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartManager.java
@@ -0,0 +1,273 @@
+package nautilus.game.minekart.kart;
+
+import java.util.HashMap;
+import java.util.HashSet;
+
+import nautilus.game.minekart.gp.GP;
+import nautilus.game.minekart.item.KartItemManager;
+import nautilus.game.minekart.kart.Kart.DriftDirection;
+import nautilus.game.minekart.kart.condition.Condition;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+import nautilus.game.minekart.kart.control.*;
+import nautilus.game.minekart.kart.crash.Crash;
+import nautilus.game.minekart.track.Track.TrackState;
+
+import net.minecraft.server.v1_7_R1.EntityPlayer;
+import net.minecraft.server.v1_7_R1.MathHelper;
+import net.minecraft.server.v1_7_R1.Packet;
+import net.minecraft.server.v1_7_R1.Packet34EntityTeleport;
+
+import org.bukkit.Location;
+import org.bukkit.Sound;
+
+import org.bukkit.craftbukkit.v1_7_R1.entity.CraftPlayer;
+
+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.EntityRegainHealthEvent;
+import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
+import org.bukkit.event.player.PlayerToggleSneakEvent;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import mineplex.core.MiniPlugin;
+import mineplex.core.recharge.Recharge;
+import mineplex.core.updater.event.UpdateEvent;
+import mineplex.core.updater.UpdateType;
+import mineplex.core.common.util.UtilInv;
+import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.common.util.UtilTime;
+
+public class KartManager extends MiniPlugin
+{
+ private Recharge _recharge;
+
+ public KartItemManager ItemManager;
+
+ private HashMap _karts = new HashMap();
+
+ public KartManager(JavaPlugin plugin, Recharge recharge)
+ {
+ super("Kart Manager", plugin);
+
+ _recharge = recharge;
+ ItemManager = new KartItemManager(plugin, this);
+ }
+
+ @EventHandler
+ public void KartUpdate(UpdateEvent event)
+ {
+ if (event.getType() == UpdateType.FASTER)
+ {
+ for (Kart kart : GetKarts().values())
+ {
+ Condition.WolfHeart(kart);
+ Condition.SuperMushroom(kart);
+ }
+ }
+
+ if (event.getType() == UpdateType.FAST)
+ {
+ for (Kart kart : GetKarts().values())
+ {
+ Location location = kart.GetDriver().getLocation();
+ Packet teleportPacket = new Packet34EntityTeleport(
+ kart.GetDriver().getEntityId(),
+ MathHelper.floor(location.getX() * 32.0D),
+ MathHelper.floor(location.getY() * 32.0D),
+ MathHelper.floor(location.getZ() * 32.0D),
+ (byte) ((int) (MathHelper.d(location.getYaw() * 256.0F / 360.0F))),
+ (byte) ((int) (MathHelper.d(location.getPitch() * 256.0F / 360.0F))));
+
+ for (Kart otherPlayer : kart.GetGP().GetKarts())
+ {
+ if (kart.GetGP().GetTrack().GetState() != TrackState.Live)
+ break;
+
+ if (otherPlayer.GetDriver() == kart.GetDriver())
+ continue;
+
+ EntityPlayer entityPlayer = ((CraftPlayer) otherPlayer
+ .GetDriver()).getHandle();
+
+ entityPlayer.playerConnection.sendPacket(teleportPacket);
+ }
+ }
+ }
+
+ if (event.getType() == UpdateType.TICK)
+ {
+ for (Kart kart : GetKarts().values())
+ {
+ // Physics
+ World.Gravity(kart);
+
+ // Drag
+ World.AirDrag(kart);
+ World.FireDrag(kart);
+ World.RoadDrag(kart);
+ World.BlockDrag(kart);
+
+ // Conditions
+ Condition.Boost(kart);
+ Condition.LightningSlow(kart);
+ Condition.StarEffect(kart);
+ Condition.StarCollide(kart);
+ Condition.BlazeFire(kart);
+
+ // Collision
+ Collision.CollideBlock(kart);
+ Collision.CollidePlayer(kart);
+
+ // Movement
+ if (kart.GetKartState() == KartState.Drive)
+ {
+ // Start/Stop
+ Drive.Accelerate(kart);
+ Drive.Brake(kart);
+
+ // Turn
+ if (kart.GetDrift() == DriftDirection.None)
+ Drive.Turn(kart);
+ else
+ DriveDrift.Drift(kart);
+
+ // Speed Limit
+ Drive.TopSpeed(kart);
+
+ // Move Player
+ Drive.Move(kart);
+
+ kart.GetDriver()
+ .getWorld()
+ .playSound(kart.GetDriver().getLocation(),
+ Sound.PIG_IDLE, .15f - (float)kart.GetSpeed() / 10,
+ .5f + (float)kart.GetSpeed());
+ }
+ if (kart.GetKartState() == KartState.Crash)
+ {
+ Crash crash = kart.GetCrash();
+
+ if (crash == null
+ || (crash.CrashEnd() && KartUtil.IsGrounded(kart)))
+ {
+ // State Return
+ kart.SetKartState(KartState.Drive);
+
+ // Restore Stability
+ if (crash == null || crash.StabilityRestore())
+ kart.GetDriver().setFoodLevel(20);
+
+ continue;
+ }
+
+ crash.Move(kart);
+ }
+ if (kart.GetKartState() == KartState.Lakitu)
+ {
+ if (UtilTime.elapsed(kart.GetKartStateTime(), 8000))
+ {
+ kart.SetKartState(KartState.Drive);
+ } else
+ {
+ kart.GetDriver().playSound(
+ kart.GetDriver().getLocation(),
+ Sound.NOTE_BASS, 0.3f, 0.1f);
+ }
+
+ // Move Player
+ Drive.Move(kart);
+ }
+ }
+ }
+ }
+
+ @EventHandler
+ public void ConditionExpire(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.TICK)
+ return;
+
+ for (Kart kart : GetKarts().values())
+ {
+ HashSet remove = new HashSet();
+
+ for (ConditionData data : kart.GetConditions())
+ {
+ if (data.IsExpired())
+ remove.add(data);
+ }
+
+ for (ConditionData data : remove)
+ {
+ kart.GetConditions().remove(data);
+
+ if (data.IsCondition(ConditionType.Star)
+ || data.IsCondition(ConditionType.Ghost))
+ {
+ kart.SetPlayerArmor();
+ }
+
+ if (data.IsCondition(ConditionType.SuperMushroom))
+ {
+ kart.SetItemStored(null);
+ }
+ }
+ }
+ }
+
+ @EventHandler
+ public void StabilityRecover(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.SEC)
+ return;
+
+ for (Kart kart : GetKarts().values())
+ UtilPlayer.hunger(kart.GetDriver(), 1);
+ }
+
+ @EventHandler
+ public void DriftHop(PlayerToggleSneakEvent event)
+ {
+ if (_recharge.use(event.getPlayer(), "Drift Hop", 250, false))
+ DriveDrift.Hop(GetKart(event.getPlayer()), event);
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void Damage(EntityDamageEvent event)
+ {
+ event.setCancelled(true);
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void Damage(EntityRegainHealthEvent event)
+ {
+ if (event.getRegainReason() != RegainReason.CUSTOM)
+ event.setCancelled(true);
+ }
+
+ public HashMap GetKarts()
+ {
+ return _karts;
+ }
+
+ public Kart GetKart(Player player)
+ {
+ return _karts.get(player);
+ }
+
+ public void AddKart(Player player, KartType type, GP gp)
+ {
+ RemoveKart(player);
+
+ _karts.put(player, new Kart(player, type, gp));
+ }
+
+ public void RemoveKart(Player player)
+ {
+ _karts.remove(player);
+ UtilInv.Clear(player);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartState.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartState.java
new file mode 100644
index 000000000..43624f664
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartState.java
@@ -0,0 +1,14 @@
+package nautilus.game.minekart.kart;
+
+
+public enum KartState
+{
+ Drive(),
+ Lakitu(),
+ Crash(),
+
+ KartState()
+ {
+
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartType.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartType.java
new file mode 100644
index 000000000..4bfc2c026
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartType.java
@@ -0,0 +1,176 @@
+package nautilus.game.minekart.kart;
+
+import mineplex.core.common.util.NautHashMap;
+import nautilus.game.minekart.item.KartItemType;
+
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.entity.EntityType;
+
+public enum KartType
+{
+ //Light
+ Pig("Pig", EntityType.PIG, Material.GRILLED_PORK, Material.GRILLED_PORK,
+ 0.9, 6, 5, 3,
+ Sound.PIG_IDLE, Sound.PIG_DEATH, Sound.PIG_WALK,
+ KartItemType.Pig),
+
+ Chicken("Chicken", EntityType.CHICKEN, Material.FEATHER, Material.POTATO_ITEM,
+ 0.85, 8, 6, 1,
+ Sound.CHICKEN_IDLE, Sound.CHICKEN_HURT, Sound.CHICKEN_WALK,
+ KartItemType.Chicken),
+
+ Wolf("Wolf", EntityType.WOLF, Material.SUGAR, Material.BAKED_POTATO,
+ 1.00, 5, 3, 2,
+ Sound.WOLF_BARK, Sound.WOLF_HURT, Sound.WOLF_WALK,
+ KartItemType.Wolf),
+
+ //Med
+ Sheep("Sheep", EntityType.SHEEP, Material.WHEAT, Material.WHEAT,
+ 0.95, 4, 6, 5,
+ Sound.SHEEP_IDLE, Sound.SHEEP_SHEAR, Sound.SHEEP_WALK,
+ KartItemType.Sheep),
+
+ Enderman("Enderman", EntityType.ENDERMAN, Material.FIREBALL, Material.ROTTEN_FLESH,
+ 0.90, 6, 5, 4,
+ Sound.ENDERMAN_IDLE, Sound.ENDERMAN_SCREAM, Sound.ENDERMAN_TELEPORT,
+ KartItemType.Enderman),
+
+ Spider("Spider", EntityType.SPIDER, Material.STRING, Material.SPIDER_EYE,
+ 0.80, 7, 8, 4,
+ Sound.SPIDER_IDLE, Sound.SPIDER_DEATH, Sound.SPIDER_WALK,
+ KartItemType.Spider),
+
+ //Heavy
+ Cow("Cow", EntityType.COW, Material.MILK_BUCKET, Material.MILK_BUCKET,
+ 1.0, 3, 5, 7,
+ Sound.COW_IDLE, Sound.COW_HURT, Sound.COW_WALK,
+ KartItemType.Cow),
+
+ Blaze("Blaze", EntityType.BLAZE, Material.BLAZE_ROD, Material.COOKED_BEEF,
+ 1.0, 7, 1, 6,
+ Sound.BLAZE_BREATH, Sound.BLAZE_BREATH, Sound.BLAZE_BREATH,
+ KartItemType.Blaze),
+
+ Golem("Golem", EntityType.IRON_GOLEM, Material.IRON_INGOT, Material.NETHER_BRICK_ITEM,
+ 1.05, 1, 7, 8,
+ Sound.IRONGOLEM_THROW, Sound.IRONGOLEM_HIT, Sound.IRONGOLEM_WALK,
+ KartItemType.Golem);
+
+ private static NautHashMap _kartTypes;
+
+ private String _name;
+ private EntityType _type;
+ private Material _kartAvatar;
+ private Material _grayAvatar;
+
+ private double _topSpeed;
+ private double _acceleration;
+ private double _handling;
+ private double _stability;
+
+ private Sound _soundUse;
+ private Sound _soundCrash;
+ private Sound _soundEngine;
+
+ private KartItemType _kartItem;
+
+ KartType(String name, EntityType type, Material kartAvatar, Material grayAvatar, double topSpeed, double acceleration, double handling, double stability, Sound use, Sound crash, Sound engine, KartItemType item)
+ {
+ _name = name;
+ _type = type;
+ _kartAvatar = kartAvatar;
+ _grayAvatar = grayAvatar;
+
+ _topSpeed = topSpeed;
+ _acceleration = acceleration;
+ _handling = handling;
+ _stability = stability;
+
+ _soundUse = use;
+ _soundCrash = crash;
+ _soundEngine = engine;
+
+ _kartItem = item;
+
+ GetMap().put(type, this);
+ }
+
+ private static NautHashMap GetMap()
+ {
+ if (_kartTypes == null)
+ _kartTypes = new NautHashMap();
+
+ return _kartTypes;
+ }
+
+ public static KartType GetByEntityType(EntityType entityType)
+ {
+ return _kartTypes.get(entityType);
+ }
+
+ public String GetName()
+ {
+ return _name;
+ }
+
+ public EntityType GetType()
+ {
+ return _type;
+ }
+
+ public double GetTopSpeed()
+ {
+ return _topSpeed;
+ }
+
+ public double GetAcceleration()
+ {
+ return 10 + _acceleration;
+ }
+
+ public double GetHandling()
+ {
+ return 10 + _handling;
+ }
+
+ public double GetStability()
+ {
+ return 10 + _stability;
+ }
+
+ public Sound GetSoundMain()
+ {
+ return _soundUse;
+ }
+
+ public Sound GetSoundCrash()
+ {
+ return _soundCrash;
+ }
+
+ public Sound GetSoundEngine()
+ {
+ return _soundEngine;
+ }
+
+ public KartItemType GetKartItem()
+ {
+ return _kartItem;
+ }
+
+ public String[] GetDescription()
+ {
+ return new String[] {};
+ }
+
+ public Material GetAvatar()
+ {
+ return _kartAvatar;
+ }
+
+ public Material GetAvatarGray()
+ {
+ return _grayAvatar;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartUtil.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartUtil.java
new file mode 100644
index 000000000..1407ba002
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/KartUtil.java
@@ -0,0 +1,67 @@
+package nautilus.game.minekart.kart;
+
+import mineplex.core.common.util.UtilAlg;
+import mineplex.core.common.util.UtilEnt;
+import mineplex.core.common.util.UtilPlayer;
+
+import org.bukkit.Location;
+import org.bukkit.util.Vector;
+
+public class KartUtil
+{
+ public static boolean IsGrounded(Kart kart)
+ {
+ if (UtilEnt.isGrounded(kart.GetDriver()))
+ return true;
+
+ //Standing on Air
+ int ground = kart.GetDriver().getLocation().subtract(0, 0.1, 0).getBlock().getTypeId() ;
+ if (ground == 0 ||
+ ground == 8 ||
+ ground == 9 ||
+ ground == 10 ||
+ ground == 11)
+ {
+ return false;
+ }
+
+ return kart.GetDriver().getLocation().getY() % 0.5 == 0;
+ }
+
+ public static boolean Stability(Kart kart, int amount)
+ {
+ UtilPlayer.hunger(kart.GetDriver(), -amount);
+
+ return (kart.GetDriver().getFoodLevel() <= 0);
+ }
+
+ public static Location GetBehind(Kart kart)
+ {
+ Location loc = kart.GetDriver().getLocation();
+ loc.subtract(UtilAlg.Normalize(kart.GetVelocityClone().setY(0)));
+
+ return loc;
+ }
+
+ public static Location GetInfront(Kart kart)
+ {
+ Location loc = kart.GetDriver().getLocation();
+ loc.add(UtilAlg.Normalize(kart.GetVelocityClone().setY(0)));
+
+ return loc;
+ }
+
+ public static Location GetLook(Kart kart)
+ {
+ Location loc = kart.GetDriver().getLocation();
+ loc.add(UtilAlg.Normalize(kart.GetDriver().getLocation().getDirection().setY(0)));
+
+ return loc;
+ }
+
+ public static Vector GetSide(Kart kart)
+ {
+ Vector look = kart.GetDriver().getLocation().getDirection();
+ return new Vector(look.getZ() * -1, 0, look.getX());
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/condition/Condition.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/condition/Condition.java
new file mode 100644
index 000000000..5edac5f1d
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/condition/Condition.java
@@ -0,0 +1,293 @@
+package nautilus.game.minekart.kart.condition;
+
+import org.bukkit.Color;
+import org.bukkit.Effect;
+import org.bukkit.EntityEffect;
+import org.bukkit.Material;
+import org.bukkit.Note;
+import org.bukkit.Sound;
+import org.bukkit.Note.Tone;
+import org.bukkit.entity.Entity;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.LeatherArmorMeta;
+import org.bukkit.util.Vector;
+
+import mineplex.core.common.util.F;
+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.UtilSound;
+import nautilus.game.minekart.item.KartItemType;
+import nautilus.game.minekart.item.world_items_custom.Flame;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartState;
+import nautilus.game.minekart.kart.KartUtil;
+import nautilus.game.minekart.kart.crash.Crash_Knockback;
+
+public class Condition
+{
+ public static Tone[] starSong = new Tone[]
+ {
+ Tone.C,
+ null,
+ Tone.C,
+ null,
+ null,
+ null,
+ Tone.C,
+ null,
+ null,
+ null,
+ null,
+ null,
+ Tone.C,
+ null,
+ null,
+ null,
+ Tone.C,
+ null,
+ null,
+ null,
+ Tone.C,
+ null,
+ Tone.C,
+ null,
+ null,
+ null,
+ Tone.C,
+ null,
+ null,
+ null,
+ null,
+ null,
+ Tone.B,
+ null,
+ Tone.B,
+ null,
+ null,
+ null,
+ Tone.B,
+ null,
+ null,
+ null,
+ null,
+ null,
+ Tone.B,
+ null,
+ null,
+ null,
+ Tone.B,
+ null,
+ null,
+ null,
+ Tone.B,
+ null,
+ Tone.B,
+ null,
+ null,
+ null,
+ Tone.B,
+ null,
+ null,
+ null,
+ null,
+ null,
+ };
+
+ public static void Boost(Kart kart)
+ {
+ if (!kart.HasCondition(ConditionType.Boost))
+ return;
+
+ if (!kart.CanControl())
+ return;
+
+ //Initial Velocity (if not moving)
+ if (kart.GetVelocity().length() <= 0)
+ kart.SetVelocity(kart.GetDriver().getLocation().getDirection().setY(0));
+
+ UtilAlg.Normalize(kart.GetVelocity());
+ kart.GetVelocity().multiply(1.2);
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.FIZZ, 0.2f, 0.5f);
+ }
+
+ public static void LightningSlow(Kart kart)
+ {
+ if (!kart.HasCondition(ConditionType.Lightning))
+ return;
+
+ //Effect
+ Entity ent = kart.GetDriver();
+
+ 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);
+
+
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+ if (kart.GetCrash() != null)
+ vel = kart.GetCrash().GetVelocity();
+
+ if (vel.length() <= 0)
+ return;
+
+ //Drag Horizontal
+ if (KartUtil.IsGrounded(kart))
+ {
+ double drag = 0.008;
+
+ //Variable Drag
+ vel.multiply(1 - drag);
+
+ //Constant Drag
+ Vector dragVec = new Vector(vel.getX(), 0, vel.getZ());
+ UtilAlg.Normalize(dragVec);
+ dragVec.multiply(0.0016);
+ vel.subtract(dragVec);
+ }
+ }
+
+ public static void StarEffect(Kart kart)
+ {
+ if (!kart.HasCondition(ConditionType.Star))
+ return;
+
+ if (!kart.GetDriver().isOnline())
+ return;
+
+ //Song
+ if (starSong[kart.GetStarSongTick() % starSong.length] != null)
+ {
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.NOTE_PIANO, 1f,
+ UtilSound.GetPitch(new Note(1, starSong[kart.GetStarSongTick() % starSong.length], false)));
+ }
+
+ //Effect
+ if (kart.GetStarSongTick() % 3 == 0)
+ {
+ Color color = Color.RED;
+
+ if (kart.GetStarSongTick() % 12 == 0) color = Color.BLUE;
+ else if (kart.GetStarSongTick() % 9 == 0) color = Color.GREEN;
+ else if (kart.GetStarSongTick() % 6 == 0) color = Color.YELLOW;
+
+ LeatherArmorMeta meta;
+
+ ItemStack head = new ItemStack(Material.LEATHER_HELMET);
+ meta = (LeatherArmorMeta)head.getItemMeta();
+ meta.setColor(color);
+ head.setItemMeta(meta);
+
+ ItemStack chest = new ItemStack(Material.LEATHER_CHESTPLATE);
+ meta = (LeatherArmorMeta)chest.getItemMeta();
+ meta.setColor(color);
+ chest.setItemMeta(meta);
+
+ ItemStack legs = new ItemStack(Material.LEATHER_LEGGINGS);
+ meta = (LeatherArmorMeta)legs.getItemMeta();
+ meta.setColor(color);
+ legs.setItemMeta(meta);
+
+ ItemStack boots = new ItemStack(Material.LEATHER_BOOTS);
+ meta = (LeatherArmorMeta)boots.getItemMeta();
+ meta.setColor(color);
+ boots.setItemMeta(meta);
+
+ kart.GetDriver().getInventory().setHelmet(head);
+ kart.GetDriver().getInventory().setChestplate(chest);
+ kart.GetDriver().getInventory().setLeggings(legs);
+ kart.GetDriver().getInventory().setBoots(boots);
+ }
+
+ //Tick
+ kart.SetStarSongTick(kart.GetStarSongTick() + 1);
+ }
+
+ public static void StarCollide(Kart kart)
+ {
+ if (!kart.HasCondition(ConditionType.Star))
+ return;
+
+ for (Kart other : kart.GetGP().GetKarts())
+ {
+ if (other.equals(kart))
+ continue;
+
+ if (other.HasCondition(ConditionType.Ghost) || other.HasCondition(ConditionType.Star))
+ continue;
+
+ if (other.GetKartState() != KartState.Drive)
+ continue;
+
+ if (!kart.GetDriver().getWorld().equals(other.GetDriver().getWorld()))
+ continue;
+
+ if (UtilMath.offset(kart.GetDriver(), other.GetDriver()) > 1)
+ continue;
+
+ //Effects
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.EXPLODE, (float)0.5f, 0.5f);
+
+ //Inform
+ UtilPlayer.message(other.GetDriver(), F.main("MK", F.elem(UtilEnt.getName(kart.GetDriver())) + " rammed you with " + F.item("Star") + "."));
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", "You rammed " + F.elem(UtilEnt.getName(other.GetDriver())) + " with " + F.item("Star") + "."));
+
+ //Hit Kart
+ new Crash_Knockback(other, kart.GetDriver().getLocation(), 1.5);
+ }
+ }
+
+ public static void SuperMushroom(Kart kart)
+ {
+ if (!kart.HasCondition(ConditionType.SuperMushroom))
+ return;
+
+ if (kart.GetItemStored() != KartItemType.SuperMushroom)
+ return;
+
+ ItemStack item = kart.GetDriver().getInventory().getItem(3);
+
+ if (item == null)
+ {
+ kart.SetItemStored(KartItemType.SuperMushroom);
+ }
+ else
+ {
+ kart.SetItemStored(null);
+ }
+ }
+
+ public static void WolfHeart(Kart kart)
+ {
+ if (!kart.HasCondition(ConditionType.WolfHeart))
+ return;
+
+ kart.GetDriver().playEffect(EntityEffect.WOLF_HEARTS);
+ }
+
+ public static void BlazeFire(Kart kart)
+ {
+ if (!kart.HasCondition(ConditionType.BlazeFire))
+ return;
+
+ //Speed Boost
+ Vector vel = kart.GetDriver().getLocation().getDirection();
+ vel.setY(0);
+ vel.normalize();
+ kart.GetVelocity().setX(vel.getX());
+ kart.GetVelocity().setZ(vel.getZ());
+
+ if (kart.GetVelocity().length() <= 0)
+ kart.SetVelocity(kart.GetDriver().getLocation().getDirection().setY(0));
+
+ UtilAlg.Normalize(kart.GetVelocity());
+ kart.GetVelocity().multiply(1.1);
+
+ //Drop Fire
+ new Flame(kart.GetGP().Manager.KartManager.ItemManager, kart, KartUtil.GetBehind(kart));
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.FIRE, 2f, 2f);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/condition/ConditionData.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/condition/ConditionData.java
new file mode 100644
index 000000000..7edf6cc6f
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/condition/ConditionData.java
@@ -0,0 +1,30 @@
+package nautilus.game.minekart.kart.condition;
+
+public class ConditionData
+{
+ private ConditionType _type;
+ private long _start;
+ private long _duration;
+
+ public ConditionData(ConditionType type, long duration)
+ {
+ _type = type;
+ _start = System.currentTimeMillis();
+ _duration = duration;
+ }
+
+ public boolean IsExpired()
+ {
+ return System.currentTimeMillis() > _start + _duration;
+ }
+
+ public boolean IsCondition(ConditionType type)
+ {
+ return _type == type;
+ }
+
+ public void Expire()
+ {
+ _start = 0;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/condition/ConditionType.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/condition/ConditionType.java
new file mode 100644
index 000000000..ed5627049
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/condition/ConditionType.java
@@ -0,0 +1,14 @@
+package nautilus.game.minekart.kart.condition;
+
+public enum ConditionType
+{
+ Ghost,
+ Boost,
+ Star,
+ Lightning,
+ SuperMushroom,
+
+ WolfHeart,
+ BlazeFire,
+ CowSuper
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/Collision.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/Collision.java
new file mode 100644
index 000000000..3b6241f7e
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/Collision.java
@@ -0,0 +1,201 @@
+package nautilus.game.minekart.kart.control;
+
+import mineplex.core.common.util.F;
+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 nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartState;
+import nautilus.game.minekart.kart.KartUtil;
+import nautilus.game.minekart.kart.condition.ConditionType;
+import nautilus.game.minekart.kart.crash.Crash_Bump;
+import nautilus.game.minekart.kart.crash.Crash_Knockback;
+import nautilus.game.minekart.kart.crash.Crash_Spin;
+
+import org.bukkit.Effect;
+import org.bukkit.Sound;
+import org.bukkit.block.Block;
+import org.bukkit.util.Vector;
+
+public class Collision
+{
+ public static void CollideBlock(Kart kart)
+ {
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+ if (kart.GetCrash() != null)
+ if (kart.GetCrash().GetVelocity() != null)
+ vel = kart.GetCrash().GetVelocity();
+
+ Block block;
+
+ double dist = 0.5;
+
+ boolean done = false;
+
+ block = kart.GetDriver().getLocation().add(dist, 0, 0).getBlock();
+ if (vel.getX() > 0 && UtilBlock.solid(block)) {CollideBlock(kart, block, vel, true); done = true;}
+
+ block = kart.GetDriver().getLocation().add(-dist, 0, 0).getBlock();
+ if (vel.getX() < 0 && UtilBlock.solid(block)) {CollideBlock(kart, block, vel, true); done = true;}
+
+ block = kart.GetDriver().getLocation().add(0, 0, dist).getBlock();
+ if (vel.getZ() > 0 && UtilBlock.solid(block)) {CollideBlock(kart, block, vel, false); done = true;}
+
+ block = kart.GetDriver().getLocation().add(0, 0, -dist).getBlock();
+ if (vel.getZ() < 0 && UtilBlock.solid(block)) {CollideBlock(kart, block, vel, false); done = true;}
+
+ if (done)
+ return;
+
+ block = kart.GetDriver().getLocation().add(dist, 1, 0).getBlock();
+ if (vel.getX() > 0 && UtilBlock.solid(block)) CollideBlock(kart, block, vel, true);
+
+ block = kart.GetDriver().getLocation().add(-dist, 1, 0).getBlock();
+ if (vel.getX() < 0 && UtilBlock.solid(block)) CollideBlock(kart, block, vel, true);
+
+ block = kart.GetDriver().getLocation().add(0, 1, dist).getBlock();
+ if (vel.getZ() > 0 && UtilBlock.solid(block)) CollideBlock(kart, block, vel, false);
+
+ block = kart.GetDriver().getLocation().add(0, 1, -dist).getBlock();
+ if (vel.getZ() < 0 && UtilBlock.solid(block)) CollideBlock(kart, block, vel, false);
+ }
+
+ public static void CollideBlock(Kart kart, Block block, Vector vel, boolean X)
+ {
+ //Get Collision Power
+ double power = vel.getX();
+ if (!X) power = vel.getZ();
+
+ power = Math.abs(power);
+
+ //Set Velocity
+ if (X) vel.setX(0);
+ else vel.setZ(0);
+
+ if (power < 0.4)
+ return;
+
+ //Effects
+ block.getWorld().playSound(kart.GetDriver().getLocation(), Sound.IRONGOLEM_WALK, (float)power * 3, 1f);
+ block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
+
+ //Effect Stability
+ if (KartUtil.Stability(kart, (int) (power * 20)))
+ {
+ new Crash_Knockback(kart, block.getLocation().add(0.5, 0.5, 0.5), power);
+ }
+ else
+ {
+ new Crash_Bump(kart, block.getLocation().add(0.5, 0.5, 0.5), power);
+ }
+ }
+
+ public static void CollidePlayer(Kart kart)
+ {
+ if (kart.HasCondition(ConditionType.Ghost) || kart.HasCondition(ConditionType.Star))
+ return;
+
+ for (Kart other : kart.GetGP().GetKarts())
+ {
+ if (other.equals(kart))
+ continue;
+
+ if (other.HasCondition(ConditionType.Ghost) || other.HasCondition(ConditionType.Star))
+ continue;
+
+ if (kart.GetKartState() != KartState.Drive && other.GetKartState() != KartState.Drive)
+ continue;
+
+ if (!kart.GetDriver().getWorld().equals(other.GetDriver().getWorld()))
+ continue;
+
+ if (UtilMath.offset(kart.GetDriver(), other.GetDriver()) > 1)
+ continue;
+
+ double collisionVel = 0;
+
+ //Collisions
+ {
+ //X-Pos
+ if (kart.GetVelocity().getX() > 0 && other.GetDriver().getLocation().getX() > kart.GetDriver().getLocation().getX())
+ {
+ double vel = kart.GetVelocity().getX() - other.GetVelocity().getX();
+
+ if (vel > 0)
+ collisionVel += vel;
+ }
+ //X-Neg
+ else if (kart.GetVelocity().getX() < 0 && other.GetDriver().getLocation().getX() < kart.GetDriver().getLocation().getX())
+ {
+ double vel = kart.GetVelocity().getX() - other.GetVelocity().getX();
+
+ if (vel < 0)
+ collisionVel -= vel;
+ }
+
+ //Z-Pos
+ if (kart.GetVelocity().getZ() > 0 && other.GetDriver().getLocation().getZ() > kart.GetDriver().getLocation().getZ())
+ {
+ double vel = kart.GetVelocity().getZ() - other.GetVelocity().getZ();
+
+ if (vel > 0)
+ collisionVel += vel;
+ }
+ //Z-Neg
+ else if (kart.GetVelocity().getZ() < 0 && other.GetDriver().getLocation().getZ() < kart.GetDriver().getLocation().getZ())
+ {
+ double vel = kart.GetVelocity().getZ() - other.GetVelocity().getZ();
+
+ if (vel < 0)
+ collisionVel -= vel;
+ }
+ }
+
+ if (collisionVel <= 0)
+ return;
+
+ collisionVel *= 2;
+
+ //Effects
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.IRONGOLEM_HIT, (float)collisionVel, 1f);
+
+ double powScale = 0.05;
+
+ //Hit Kart
+ double relPower = ((collisionVel * other.GetKartType().GetStability()) / (kart.GetKartType().GetStability() / 10));
+ if (KartUtil.Stability(kart, (int)relPower))
+ {
+ //Inform
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", F.elem(UtilEnt.getName(other.GetDriver())) + " knocked you out."));
+ UtilPlayer.message(other.GetDriver(), F.main("MK", "You knocked out " + F.elem(UtilEnt.getName(kart.GetDriver())) + "."));
+
+ //Crash
+ if (collisionVel > 2) new Crash_Knockback(kart, other.GetDriver().getLocation(), relPower * powScale);
+ else new Crash_Spin(kart, other.GetDriver().getLocation(), relPower * powScale);
+ }
+ else
+ {
+ new Crash_Bump(kart, other.GetDriver().getLocation(), relPower * powScale);
+ }
+
+ //Hit Other
+ relPower = ((collisionVel * kart.GetKartType().GetStability()) / (other.GetKartType().GetStability() / 10));
+ if (KartUtil.Stability(other, (int)relPower))
+ {
+ //Inform
+ UtilPlayer.message(other.GetDriver(), F.main("MK", F.elem(UtilEnt.getName(kart.GetDriver())) + " knocked you out."));
+ UtilPlayer.message(kart.GetDriver(), F.main("MK", "You knocked out " + F.elem(UtilEnt.getName(other.GetDriver())) + "."));
+
+ //Crash
+ if (collisionVel > 2) new Crash_Knockback(other, kart.GetDriver().getLocation(), relPower * powScale);
+ else new Crash_Spin(other, kart.GetDriver().getLocation(), relPower * powScale);
+ }
+ else
+ {
+ new Crash_Bump(other, kart.GetDriver().getLocation(), relPower * powScale);
+ }
+ }
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/Drive.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/Drive.java
new file mode 100644
index 000000000..bc8eb69ae
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/Drive.java
@@ -0,0 +1,159 @@
+package nautilus.game.minekart.kart.control;
+
+import mineplex.core.common.util.UtilAlg;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+import nautilus.game.minekart.kart.condition.ConditionType;
+
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.util.Vector;
+
+public class Drive
+{
+ public static void TopSpeed(Kart kart)
+ {
+ if (!kart.CanControl())
+ return;
+
+ if (!KartUtil.IsGrounded(kart))
+ return;
+
+ if (kart.HasCondition(ConditionType.Boost))
+ return;
+
+ double topSpeed = kart.GetKartType().GetTopSpeed();
+
+ if (kart.HasCondition(ConditionType.Star))
+ topSpeed *= 1.2;
+
+ if (kart.GetSpeed() > topSpeed)
+ {
+ Vector vel = kart.GetVelocityClone();
+ vel.setY(0);
+ vel.normalize();
+ vel.multiply(topSpeed);
+
+ kart.SetVelocity(vel);
+ }
+ }
+
+ public static void Accelerate(Kart kart)
+ {
+ if (!kart.CanControl())
+ return;
+
+ if (!KartUtil.IsGrounded(kart))
+ return;
+
+ if (!kart.GetDriver().isBlocking())
+ return;
+
+ ItemStack item = kart.GetDriver().getItemInHand();
+ if (item == null || item.getType() != Material.STONE_SWORD)
+ return;
+
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+
+ //Initial Velocity
+ if (vel.length() == 0)
+ {
+ vel = kart.GetDriver().getLocation().getDirection().setY(0);
+
+ //Looking directly Up/Down
+ if (vel.length() == 0)
+ return;
+
+ vel.normalize();
+ vel.multiply(0.001);
+
+ kart.SetVelocity(vel);
+ }
+
+ //Kart Acceleration
+ Vector acc = new Vector(vel.getX(), 0, vel.getZ());
+ UtilAlg.Normalize(acc);
+
+ double acceleration = kart.GetKartType().GetAcceleration();
+ if (kart.HasCondition(ConditionType.Star))
+ acceleration *= 1.2;
+
+ acc.multiply(0.001 * acceleration);
+ vel.add(acc);
+}
+
+ public static void Brake(Kart kart)
+ {
+ if (!kart.CanControl())
+ return;
+
+ if (!KartUtil.IsGrounded(kart))
+ return;
+
+ if (!kart.GetDriver().isBlocking())
+ return;
+
+ ItemStack item = kart.GetDriver().getItemInHand();
+ if (item == null || item.getType() != Material.WOOD_SWORD)
+ return;
+
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+
+ //Drag %
+ vel.multiply(0.95);
+
+ if (vel.length() < 0.05)
+ vel.multiply(0);
+ }
+
+ public static void Turn(Kart kart)
+ {
+ if (!kart.CanControl())
+ return;
+
+ if (!KartUtil.IsGrounded(kart))
+ return;
+
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+
+ if (vel.length() <= 0)
+ return;
+
+ double speed = vel.length();
+
+ double handling = kart.GetKartType().GetHandling();
+ if (kart.HasCondition(ConditionType.Star))
+ handling *= 1.2;
+
+ //Turn
+ Vector turn = kart.GetDriver().getLocation().getDirection();
+ turn.setY(0);
+ UtilAlg.Normalize(turn);
+
+ turn.subtract(UtilAlg.Normalize(new Vector(vel.getX(), 0, vel.getZ())));
+
+ turn.multiply(0.003 * handling);
+
+ vel.add(turn);
+
+ //Reapply Speed
+ speed = (speed + (vel.length()*3)) / 4;
+ UtilAlg.Normalize(vel);
+ vel.multiply(speed);
+ }
+
+ public static void Move(Kart kart)
+ {
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+
+ kart.GetDriver().setVelocity(vel);
+
+ //Display Velocity as Exp
+ kart.GetDriver().setExp(Math.min(0.999f, ((float)kart.GetSpeed()/(float)kart.GetKartType().GetTopSpeed())));
+ kart.GetDriver().setLevel((int) (kart.GetSpeed() * 100));
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/DriveDrift.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/DriveDrift.java
new file mode 100644
index 000000000..b7b723431
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/DriveDrift.java
@@ -0,0 +1,140 @@
+package nautilus.game.minekart.kart.control;
+
+import mineplex.core.common.util.UtilAlg;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.Kart.DriftDirection;
+import nautilus.game.minekart.kart.condition.ConditionData;
+import nautilus.game.minekart.kart.condition.ConditionType;
+import nautilus.game.minekart.kart.KartUtil;
+
+import org.bukkit.Effect;
+import org.bukkit.event.player.PlayerToggleSneakEvent;
+import org.bukkit.util.Vector;
+
+public class DriveDrift
+{
+ public static void Hop(Kart kart, PlayerToggleSneakEvent event)
+ {
+ if (kart == null)
+ return;
+
+ if (!kart.CanControl())
+ return;
+
+ if (event.getPlayer().isSneaking())
+ {
+ Boost(kart);
+ kart.ClearDrift();
+ return;
+ }
+
+ if (!KartUtil.IsGrounded(kart))
+ return;
+
+ //Save Drift Values
+ kart.SetDrift();
+
+ /*
+
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+ double speed = vel.length();
+
+ //Turn
+ if (vel.length() > 0)
+ {
+ Vector turn = kart.GetDriver().getLocation().getDirection();
+ turn.setY(0);
+ UtilAlg.Normalize(turn);
+
+ turn.subtract(UtilAlg.Normalize(new Vector(vel.getX(), 0, vel.getZ())));
+
+ turn.multiply(0.1);
+
+ vel.add(turn);
+
+ UtilAlg.Normalize(vel);
+ vel.multiply(speed);
+ }
+
+ //Hop
+ Vector hop = kart.GetDriver().getLocation().getDirection();
+ hop.setY(0);
+ UtilAlg.Normalize(hop);
+ hop.multiply(0.03);
+ hop.setY(0.12);
+
+ if (hop.length() > 0)
+ vel.add(hop);
+ */
+ }
+
+ public static void Drift(Kart kart)
+ {
+ if (!kart.CanControl())
+ return;
+
+ if (!kart.GetDriver().isSneaking())
+ {
+ kart.ClearDrift();
+ return;
+ }
+
+ if (!KartUtil.IsGrounded(kart))
+ return;
+
+ if (kart.GetDrift() == DriftDirection.None)
+ return;
+
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+ double speed = kart.GetVelocity().length();
+
+ if (speed < 0.5)
+ {
+ kart.ClearDrift();
+ return;
+ }
+
+ //Drift
+ vel.add(kart.GetDriftVector().multiply(0.030));
+
+ //Turn
+ Vector turn = kart.GetDriver().getLocation().getDirection();
+ turn.setY(0);
+ UtilAlg.Normalize(turn);
+
+ turn.subtract(UtilAlg.Normalize(new Vector(vel.getX(), 0, vel.getZ())));
+
+ turn.multiply(0.0015 * kart.GetKartType().GetHandling());
+
+ vel.add(turn);
+
+ //Reapply Speed
+ UtilAlg.Normalize(vel);
+ vel.multiply(speed);
+
+ //Effect
+ long driftTime = kart.GetDriftTime();
+ int effectId = 42;
+ if (driftTime > 4000) effectId = 57;
+ else if (driftTime > 2500) effectId = 41;
+
+ kart.GetDriver().getWorld().playEffect(kart.GetDriver().getLocation().add(0, -1, 0), Effect.STEP_SOUND, effectId);
+ }
+
+ public static void Boost(Kart kart)
+ {
+ if (kart.GetDrift() == DriftDirection.None)
+ return;
+
+ if (kart.GetDriftTime() < 4000)
+ return;
+
+ kart.AddCondition(new ConditionData(ConditionType.Boost, 2000));
+
+ //Effect
+ kart.GetDriver().getWorld().playEffect(kart.GetDriver().getLocation(), Effect.STEP_SOUND, 57);
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), kart.GetKartType().GetSoundMain(), 2f, 1f);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/World.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/World.java
new file mode 100644
index 000000000..9398d7b5f
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/control/World.java
@@ -0,0 +1,163 @@
+package nautilus.game.minekart.kart.control;
+
+import mineplex.core.common.util.UtilAlg;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartUtil;
+
+import org.bukkit.Effect;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.util.Vector;
+
+public class World
+{
+ public static void Gravity(Kart kart)
+ {
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+ if (kart.GetCrash() != null)
+ vel = kart.GetCrash().GetVelocity();
+
+ //Landed
+ if (KartUtil.IsGrounded(kart))
+ {
+ if (vel.getY() < 0)
+ vel.setY(0);
+
+ return;
+ }
+
+ //Downward Gravity
+ double down = Math.max(-1.0, vel.getY() - 0.1);
+ vel.setY(down);
+ }
+
+ public static void AirDrag(Kart kart)
+ {
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+ if (kart.GetCrash() != null)
+ vel = kart.GetCrash().GetVelocity();
+
+ if (vel.length() <= 0)
+ return;
+
+ //Drag Horizontal
+ if (KartUtil.IsGrounded(kart))
+ {
+ double drag = Math.log(vel.length() + 1) / 50d;
+ drag *= 1 / kart.GetKartType().GetTopSpeed(); //Increase for lower top speed karts
+ drag *= (kart.GetKartType().GetAcceleration() / 21d); //Reduce for lower accel karts
+
+ //Variable Drag
+ vel.multiply(1 - drag);
+ }
+ //Drag Vertical
+ else
+ {
+ vel.setY(vel.getY() * 0.98);
+ }
+ }
+
+ public static void FireDrag(Kart kart)
+ {
+ if (kart.GetDriver().getFireTicks() <= 0)
+ return;
+
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+ if (kart.GetCrash() != null)
+ return;
+
+ if (vel.length() <= 0)
+ return;
+
+ //Drag Horizontal
+ double drag = 0.008;
+
+ //Variable Drag
+ vel.multiply(1 - drag);
+ }
+
+ public static void RoadDrag(Kart kart)
+ {
+ if (!KartUtil.IsGrounded(kart))
+ return;
+
+ if (kart.GetGP() == null)
+ return;
+
+ if (kart.GetGP().GetTrack() == null)
+ return;
+
+ Block block = kart.GetDriver().getLocation().getBlock().getRelative(BlockFace.DOWN);
+
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+ if (kart.GetCrash() != null)
+ vel = kart.GetCrash().GetVelocity();
+
+ if (vel.length() <= 0)
+ return;
+
+ //Constant Drag
+ Vector dragVec = new Vector(vel.getX(), 0, vel.getZ());
+ UtilAlg.Normalize(dragVec);
+ dragVec.multiply(0.003);
+ vel.subtract(dragVec);
+
+ //Off Road
+ if (!kart.GetGP().GetTrack().GetTrackBlocks().contains(block.getTypeId()))
+ if (block.getType() == Material.GRASS ||
+ block.getType() == Material.SAND)
+ {
+ //Drag Horizontal
+ double drag = 0.025;
+
+ //Variable Drag
+ vel.multiply(1 - drag);
+
+ //Effect
+ if (kart.GetSpeed() > 0.2)
+ block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
+ }
+
+ //Stop Completely
+ if (!kart.GetDriver().isBlocking())
+ if (vel.length() < 0.02)
+ vel.multiply(0);
+ }
+
+ public static void BlockDrag(Kart kart)
+ {
+ if (!KartUtil.IsGrounded(kart))
+ return;
+
+ Block block = kart.GetDriver().getLocation().getBlock();
+
+ //Current Velocity
+ Vector vel = kart.GetVelocity();
+ if (kart.GetCrash() != null)
+ vel = kart.GetCrash().GetVelocity();
+
+ if (vel.length() <= 0)
+ return;
+
+ double drag = 0;
+
+ if (block.getType() == Material.LONG_GRASS) drag = 0.02;
+ else if (block.getType() == Material.WATER) drag = 0.03;
+ else if (block.getType() == Material.STATIONARY_WATER) drag = 0.03;
+
+ if (drag <= 0)
+ return;
+
+ //Slow
+ vel.multiply(1 - drag);
+
+ //Effect
+ if (vel.length() > 0.2)
+ block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash.java
new file mode 100644
index 000000000..095da60bf
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash.java
@@ -0,0 +1,83 @@
+package nautilus.game.minekart.kart.crash;
+
+import mineplex.core.common.util.UtilTime;
+import nautilus.game.minekart.kart.Kart;
+
+import org.bukkit.EntityEffect;
+import org.bukkit.util.Vector;
+
+public class Crash
+{
+ private Vector _velocity;
+ private long _crashTime;
+ private long _crashReq;
+ private boolean _canEnd;
+ private boolean _restoreStability;
+
+ public Crash(Kart kart, Vector vel, long timeReq, boolean canEnd, boolean restoreStability)
+ {
+ kart.SetCrash(this);
+ kart.ClearDrift();
+
+ _velocity = vel;
+ _crashTime = System.currentTimeMillis();
+ _crashReq = timeReq;
+ _canEnd = canEnd;
+ _restoreStability = restoreStability;
+
+ kart.GetDriver().playEffect(EntityEffect.HURT);
+ }
+
+ public void Update(Kart kart)
+ {
+ Move(kart);
+ }
+
+ public void Move(Kart kart)
+ {
+ kart.GetDriver().setVelocity(_velocity);
+
+ //Display Velocity as Exp
+ kart.GetDriver().setExp(Math.min(0.999f, ((float)_velocity.length()/(float)1.8)));
+ }
+
+ public boolean CrashEnd()
+ {
+ return _canEnd && UtilTime.elapsed(_crashTime , _crashReq);
+ }
+
+ public Vector GetVelocity()
+ {
+ return _velocity;
+ }
+
+ public void SetVelocity(Vector vel)
+ {
+ _velocity = vel;
+ }
+
+ public long GetCrashTime()
+ {
+ return _crashTime;
+ }
+
+ public long GetCrashReq()
+ {
+ return _crashReq;
+ }
+
+ public void SetCanEnd(boolean end)
+ {
+ _canEnd = end;
+ }
+
+ public void SetCrashReq(long time)
+ {
+ _crashReq = time;
+ }
+
+ public boolean StabilityRestore()
+ {
+ return _restoreStability;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Bump.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Bump.java
new file mode 100644
index 000000000..15fad997a
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Bump.java
@@ -0,0 +1,33 @@
+package nautilus.game.minekart.kart.crash;
+
+import mineplex.core.common.util.UtilAlg;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartState;
+
+import org.bukkit.Location;
+import org.bukkit.Sound;
+import org.bukkit.util.Vector;
+
+public class Crash_Bump extends Crash
+{
+ public Crash_Bump(Kart kart, Location other, double power)
+ {
+ super(kart, new Vector(0,0,0), (long) (800 * power), true, false);
+
+ //Effect
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), Sound.IRONGOLEM_HIT, (float)power, 1f);
+
+ //Apply Knockback
+ Vector knock = UtilAlg.getTrajectory(other, kart.GetDriver().getLocation());
+ knock.multiply(0.4 * power);
+ knock.add(new Vector(0, 0.4 * power, 0));
+ SetVelocity(knock);
+
+ double powerTrim = Math.min(power, 1) / 2;
+
+ //Lose some velocity
+ kart.GetVelocity().multiply(1 - powerTrim);
+
+ kart.SetKartState(KartState.Crash);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Explode.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Explode.java
new file mode 100644
index 000000000..5617cb00d
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Explode.java
@@ -0,0 +1,26 @@
+package nautilus.game.minekart.kart.crash;
+
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartState;
+
+import org.bukkit.util.Vector;
+
+public class Crash_Explode extends Crash
+{
+ public Crash_Explode(Kart kart, double power, boolean resetVelocity)
+ {
+ super(kart, new Vector(0,0,0), (long) (1400 * power), true, true);
+
+ //Effect
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), kart.GetKartType().GetSoundCrash(), 2f, 1f);
+
+ //Apply Upwards
+ SetVelocity(kart.GetVelocityClone().add(new Vector(0, power * 1, 0)));
+
+ //Remove Karts Velocity
+ if (resetVelocity)
+ kart.CrashStop();
+
+ kart.SetKartState(KartState.Crash);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Knockback.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Knockback.java
new file mode 100644
index 000000000..7b409d9e8
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Knockback.java
@@ -0,0 +1,33 @@
+package nautilus.game.minekart.kart.crash;
+
+import mineplex.core.common.util.UtilAlg;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartState;
+
+import org.bukkit.Location;
+import org.bukkit.util.Vector;
+
+public class Crash_Knockback extends Crash
+{
+
+ public Crash_Knockback(Kart kart, Location other, double power)
+ {
+ super(kart, new Vector(0,0,0), 1000, true, true);
+
+ power = Math.min(power, 1.5);
+
+ //Effect
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), kart.GetKartType().GetSoundCrash(), 2f, 1f);
+
+ //Apply Knockback
+ Vector knock = UtilAlg.getTrajectory(other, kart.GetDriver().getLocation());
+ knock.multiply(0.6 * power);
+ knock.add(new Vector(0, power * 0.8, 0));
+ SetVelocity(knock);
+
+ //Remove Karts Velocity
+ kart.CrashStop();
+
+ kart.SetKartState(KartState.Crash);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Spin.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Spin.java
new file mode 100644
index 000000000..302486780
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/kart/crash/Crash_Spin.java
@@ -0,0 +1,51 @@
+package nautilus.game.minekart.kart.crash;
+
+import mineplex.core.common.util.UtilAlg;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartState;
+
+import org.bukkit.Location;
+import org.bukkit.util.Vector;
+
+public class Crash_Spin extends Crash
+{
+ public Crash_Spin(Kart kart, Location other, double power)
+ {
+ super(kart, new Vector(0,0,0), (long) (1500 * power), true, true);
+
+ power = Math.min(power, 1.5);
+
+ //Effect
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), kart.GetKartType().GetSoundCrash(), 2f, 1f);
+
+ //Apply Knockback
+ Vector knock = UtilAlg.getTrajectory(other, kart.GetDriver().getLocation());
+ knock.setY(0);
+ UtilAlg.Normalize(knock);
+ knock.multiply(0.6 * power);
+ SetVelocity(knock);
+
+ //Remove Karts Velocity
+ kart.CrashStop();
+
+ kart.SetKartState(KartState.Crash);
+ }
+
+ public Crash_Spin(Kart kart, double power)
+ {
+ super(kart, new Vector(0,0,0), (long) (2000 * power), true, true);
+
+ power = Math.min(power, 1.5);
+
+ //Effect
+ kart.GetDriver().getWorld().playSound(kart.GetDriver().getLocation(), kart.GetKartType().GetSoundCrash(), 2f, 1f);
+
+ //Apply Knockback
+ SetVelocity(kart.GetVelocity());
+
+ //Remove Karts Velocity
+ kart.CrashStop();
+
+ kart.SetKartState(KartState.Crash);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/menu/KartMenu.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/menu/KartMenu.java
new file mode 100644
index 000000000..8feab8342
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/menu/KartMenu.java
@@ -0,0 +1,34 @@
+package nautilus.game.minekart.menu;
+
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.shop.ShopBase;
+import mineplex.core.shop.page.ShopPageBase;
+
+import nautilus.game.minekart.KartFactory;
+import nautilus.game.minekart.gp.GPManager;
+import nautilus.game.minekart.shop.KartItem;
+
+import org.bukkit.entity.Player;
+
+public class KartMenu extends ShopBase
+{
+ private GPManager _gpManager;
+
+ public KartMenu(KartFactory plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager, GPManager gpManager)
+ {
+ super(plugin, clientManager, donationManager, "Kart Select");
+
+ _gpManager = gpManager;
+ }
+
+ @Override
+ protected ShopPageBase> BuildPagesFor(Player player)
+ {
+ return new KartPage(Plugin, ClientManager, DonationManager, this, _gpManager, player);
+ }
+
+ public void SelectKart(Player player, KartItem kartItem)
+ {
+ _gpManager.SelectKart(player, kartItem.GetKartType());
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/menu/KartPage.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/menu/KartPage.java
new file mode 100644
index 000000000..dfda3b253
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/menu/KartPage.java
@@ -0,0 +1,213 @@
+package nautilus.game.minekart.menu;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.common.Rank;
+import mineplex.core.common.util.C;
+import mineplex.core.itemstack.ItemStackFactory;
+import mineplex.core.shop.item.ShopItem;
+import mineplex.core.shop.page.ShopPageBase;
+
+import nautilus.game.minekart.KartFactory;
+import nautilus.game.minekart.gp.GPManager;
+import nautilus.game.minekart.gp.GPSet;
+import nautilus.game.minekart.item.KartItemType;
+import nautilus.game.minekart.kart.KartType;
+import nautilus.game.minekart.shop.KartItem;
+import net.minecraft.server.v1_7_R1.NBTTagList;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.PlayerInventory;
+
+public class KartPage extends ShopPageBase
+{
+ private GPManager _gpManager;
+ private ItemStack[] _playerInventoryContents;
+
+ public KartPage(KartFactory plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager, KartMenu shop, GPManager gpManager, Player player)
+ {
+ super(plugin, shop, clientManager, donationManager, " ", player);
+
+ _gpManager = gpManager;
+ _playerInventoryContents = player.getInventory().getContents().clone();
+
+ BuildPage();
+ }
+
+ public void PlayerOpened()
+ {
+ UpdateKarts();
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void PlayerClosed()
+ {
+ super.PlayerClosed();
+
+ Player.getInventory().setContents(_playerInventoryContents);
+
+ Player.updateInventory();
+ }
+
+ @Override
+ protected void BuildPage()
+ {
+ getInventory().setItem(0, new ShopItem(Material.INK_SACK, (byte)1, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(1, new ShopItem(Material.INK_SACK, (byte)4, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(2, new ShopItem(Material.INK_SACK, (byte)3, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(3, new ShopItem(Material.INK_SACK, (byte)6, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(4, new ShopItem(Material.INK_SACK, (byte)8, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(5, new ShopItem(Material.INK_SACK, (byte)2, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(6, new ShopItem(Material.INK_SACK, (byte)12, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(7, new ShopItem(Material.INK_SACK, (byte)10, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(8, new ShopItem(Material.INK_SACK, (byte)13, "", new String[] {}, 1, false, true).getHandle());
+
+ UpdateKarts();
+
+ ShowKartStats(_gpManager.GetSelectedKart(Player));
+ }
+
+ public void SelectKart(Player player, KartItem kartItem)
+ {
+ if (DonationManager.Get(player.getName()).Owns(kartItem.GetSalesPackageId()) || kartItem.IsFree() || DonationManager.Get(Client.GetPlayerName()).OwnsUnknownPackage("Minekart ULTRA") || Client.GetRank().Has(player, Rank.ULTRA, false))
+ {
+ Shop.SelectKart(player, kartItem);
+ PlayAcceptSound(player);
+ ShowKartStats(_gpManager.GetSelectedKart(Player));
+ UpdateKarts();
+ }
+ else
+ {
+ PlayDenySound(player);
+ ShowKartStats(kartItem.GetKartType());
+ }
+ }
+
+ protected void ShowKartStats(KartType kartType)
+ {
+ for (KartItem item : Plugin.GetKarts())
+ {
+ if (kartType == item.GetKartType())
+ {
+ PlayerInventory inventory = Player.getInventory();
+ inventory.clear();
+
+ double statValue = Math.ceil((kartType.GetTopSpeed() * 100 - 79) / 2.625);
+ Material statMaterial = GetStatMaterial(statValue);
+ int slot = 9;
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(Material.WOOD_HOE, (byte)0, (int)(kartType.GetTopSpeed() * 100), "§e§lTop Speed"));
+
+ slot++;
+ while (statValue >= 1)
+ {
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(statMaterial, (byte)0, 1, "§e§lSpeed Bar"));
+ slot++;
+ statValue -= 1;
+ }
+
+ statValue = kartType.GetAcceleration() - 10;
+ statMaterial = GetStatMaterial(statValue);
+ slot = 18;
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(Material.STONE_HOE, (byte)0, (int)statValue, "§e§lAcceleration"));
+
+ slot++;
+ while (statValue >= 1)
+ {
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(statMaterial, (byte)0, 1, "§e§lAcceleration Bar"));
+ slot++;
+ statValue -= 1;
+ }
+
+ statValue = kartType.GetHandling() - 10;
+ statMaterial = GetStatMaterial(statValue);
+ slot = 27;
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(Material.IRON_HOE, (byte)0, (int)statValue, "§e§lHandling"));
+
+ slot++;
+ while (statValue >= 1)
+ {
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(statMaterial, (byte)0, 1, "§e§lHandling Bar"));
+ slot++;
+ statValue -= 1;
+ }
+ }
+ }
+ }
+
+ protected boolean IsValidGPSet(GPSet gpSet)
+ {
+ return gpSet == GPSet.MushroomCup || gpSet == GPSet.Battle;
+ }
+
+ public void UpdateKarts()
+ {
+ int slot = 45;
+ boolean locked = true;
+
+ for (KartItem item : Plugin.GetKarts())
+ {
+ if (DonationManager.Get(Client.GetPlayerName()).Owns(item.GetSalesPackageId()) || DonationManager.Get(Client.GetPlayerName()).OwnsUnknownPackage("Minekart ULTRA") || Client.GetRank().Has(Client.GetPlayer(), Rank.ULTRA, false) || item.IsFree())
+ locked = false;
+ else
+ locked = true;
+
+ List itemLore = new ArrayList();
+
+ if (locked)
+ {
+ itemLore.add(C.cGreen + "Purchase at Kart Shop");
+ }
+
+ itemLore.add(C.cBlack);
+
+ itemLore.add(C.cWhite + "Max Speed: " + GetStatColor(Math.ceil((item.GetKartType().GetTopSpeed() * 100 - 79) / 2.625)) + item.GetKartType().GetTopSpeed() * 100);
+ itemLore.add(C.cWhite + "Acceleration: " + GetStatColor(item.GetKartType().GetAcceleration() - 10) + (item.GetKartType().GetAcceleration() - 10));
+ itemLore.add(C.cWhite + "Handling: " + GetStatColor(item.GetKartType().GetHandling() - 10) + (item.GetKartType().GetHandling() - 10));
+ itemLore.add(C.cWhite + "Weight: " + GetStatColor(item.GetKartType().GetStability() - 10) + (item.GetKartType().GetStability() - 10));
+
+ itemLore.add(C.cBlack);
+
+ itemLore.add(C.cWhite + "Special Item: " + C.cYellow + item.GetKartType().GetKartItem().GetName());
+
+ ShopItem shopItem = new ShopItem(item.GetDisplayMaterial(),
+ item.GetDisplayData(), item.GetName(),
+ itemLore.toArray(new String[itemLore.size()]), 1, locked,
+ false);
+
+ if (_gpManager.GetSelectedKart(Player) == item.GetKartType())
+ {
+ shopItem.getHandle().tag.set("ench", new NBTTagList());
+
+ KartItemType kartItemType = item.GetKartType().GetKartItem();
+
+ ShopItem kartItem = new ShopItem(kartItemType.GetMaterial(), kartItemType.GetName(), kartItemType.GetDesc(), kartItemType.GetAmount(), false);
+ kartItem.getHandle().c((locked ? ChatColor.RED : ChatColor.GREEN) + kartItem.GetName() + (locked ? ChatColor.RED + " (Locked)" : ""));
+
+ getInventory().setItem(slot - 9, kartItem.getHandle());
+ }
+ else
+ {
+ getInventory().setItem(slot - 9, null);
+ }
+
+ AddButton(slot, shopItem, new KartSelectButton(this, item));
+ slot++;
+ }
+ }
+
+ private ChatColor GetStatColor(double statValue)
+ {
+ return statValue >= 3 ? (statValue >= 6 ? ChatColor.GREEN : ChatColor.YELLOW) : ChatColor.RED;
+ }
+
+ private Material GetStatMaterial(double statValue)
+ {
+ return statValue >= 3 ? (statValue >= 6 ? Material.EMERALD : Material.GOLD_NUGGET) : Material.REDSTONE;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/menu/KartSelectButton.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/menu/KartSelectButton.java
new file mode 100644
index 000000000..792551f3b
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/menu/KartSelectButton.java
@@ -0,0 +1,24 @@
+package nautilus.game.minekart.menu;
+
+import mineplex.core.shop.item.IButton;
+import nautilus.game.minekart.shop.KartItem;
+
+import org.bukkit.entity.Player;
+
+public class KartSelectButton implements IButton
+{
+ private KartPage _page;
+ private KartItem _kartItem;
+
+ public KartSelectButton(KartPage shop, KartItem kartItem)
+ {
+ _page = shop;
+ _kartItem = kartItem;
+ }
+
+ @Override
+ public void Clicked(Player player)
+ {
+ _page.SelectKart(player, _kartItem);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/repository/KartItemToken.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/repository/KartItemToken.java
new file mode 100644
index 000000000..f8af0ba37
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/repository/KartItemToken.java
@@ -0,0 +1,11 @@
+package nautilus.game.minekart.repository;
+
+import mineplex.core.donation.repository.GameSalesPackageToken;
+
+public class KartItemToken
+{
+ public String Name;
+ public String Material;
+ public String Data;
+ public GameSalesPackageToken SalesPackage;
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/repository/KartRepository.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/repository/KartRepository.java
new file mode 100644
index 000000000..7be4fe262
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/repository/KartRepository.java
@@ -0,0 +1,22 @@
+package nautilus.game.minekart.repository;
+
+import java.util.List;
+
+import org.bukkit.craftbukkit.libs.com.google.gson.reflect.TypeToken;
+
+import mineplex.core.server.remotecall.JsonWebCall;
+
+public class KartRepository
+{
+ private String _webAddress;
+
+ public KartRepository(String webserverAddress)
+ {
+ _webAddress = webserverAddress;
+ }
+
+ public List GetKartItems(List itemTokens)
+ {
+ return new JsonWebCall(_webAddress + "MineKart/GetKartItems").Execute(new TypeToken>(){}.getType(), itemTokens);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/KartItem.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/KartItem.java
new file mode 100644
index 000000000..7f49ed358
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/KartItem.java
@@ -0,0 +1,31 @@
+package nautilus.game.minekart.shop;
+
+import mineplex.core.common.CurrencyType;
+import mineplex.core.shop.item.SalesPackageBase;
+import nautilus.game.minekart.kart.KartType;
+
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+
+public class KartItem extends SalesPackageBase
+{
+ private KartType _kartType;
+
+ public KartItem(Material monsterEgg, KartType kartType)
+ {
+ super(kartType.GetName(), monsterEgg, (byte)0, kartType.GetDescription());
+
+ _kartType = kartType;
+ }
+
+ @Override
+ public void Sold(Player player, CurrencyType currencyType)
+ {
+
+ }
+
+ public KartType GetKartType()
+ {
+ return _kartType;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/KartItemButton.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/KartItemButton.java
new file mode 100644
index 000000000..1bfcdfb00
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/KartItemButton.java
@@ -0,0 +1,24 @@
+package nautilus.game.minekart.shop;
+
+import mineplex.core.shop.item.IButton;
+import nautilus.game.minekart.shop.page.KartPage;
+
+import org.bukkit.entity.Player;
+
+public class KartItemButton implements IButton
+{
+ private KartPage _shop;
+ private KartItem _kartItem;
+
+ public KartItemButton(KartPage shop, KartItem kartItem)
+ {
+ _shop = shop;
+ _kartItem = kartItem;
+ }
+
+ @Override
+ public void Clicked(Player player)
+ {
+ _shop.PurchaseKart(player, _kartItem);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/KartShop.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/KartShop.java
new file mode 100644
index 000000000..57f31050d
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/KartShop.java
@@ -0,0 +1,25 @@
+package nautilus.game.minekart.shop;
+
+import org.bukkit.entity.Player;
+
+import nautilus.game.minekart.KartFactory;
+import nautilus.game.minekart.shop.page.KartPage;
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.common.CurrencyType;
+import mineplex.core.donation.DonationManager;
+import mineplex.core.shop.ShopBase;
+import mineplex.core.shop.page.ShopPageBase;
+
+public class KartShop extends ShopBase
+{
+ public KartShop(KartFactory plugin, CoreClientManager clientManager, DonationManager donationManger, CurrencyType...currencyTypes)
+ {
+ super(plugin, clientManager, donationManger, "Kart Shop", currencyTypes);
+ }
+
+ @Override
+ protected ShopPageBase> BuildPagesFor(Player player)
+ {
+ return new KartPage(Plugin, ClientManager, DonationManager, this, player);
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/page/KartPage.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/page/KartPage.java
new file mode 100644
index 000000000..126ee5cce
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/shop/page/KartPage.java
@@ -0,0 +1,189 @@
+package nautilus.game.minekart.shop.page;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import mineplex.core.account.CoreClientManager;
+import mineplex.core.common.CurrencyType;
+import mineplex.core.common.Rank;
+import mineplex.core.common.util.C;
+import mineplex.core.donation.DonationManager;
+import mineplex.core.itemstack.ItemStackFactory;
+import mineplex.core.shop.item.ShopItem;
+import mineplex.core.shop.page.ConfirmationPage;
+import mineplex.core.shop.page.ShopPageBase;
+
+import nautilus.game.minekart.KartFactory;
+import nautilus.game.minekart.kart.KartType;
+import nautilus.game.minekart.shop.KartItem;
+import nautilus.game.minekart.shop.KartItemButton;
+import nautilus.game.minekart.shop.KartShop;
+import net.minecraft.server.v1_7_R1.NBTTagList;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.PlayerInventory;
+
+public class KartPage extends ShopPageBase
+{
+ public KartPage(KartFactory plugin, CoreClientManager clientManager, DonationManager donationManager, KartShop shop, Player player)
+ {
+ super(plugin, shop, clientManager, donationManager, " Kart Shop", player);
+
+ CurrencySlot = 22;
+
+ BuildPage();
+ }
+
+ @Override
+ protected void BuildPage()
+ {
+ getInventory().setItem(0, new ShopItem(Material.INK_SACK, (byte)1, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(1, new ShopItem(Material.INK_SACK, (byte)4, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(2, new ShopItem(Material.INK_SACK, (byte)3, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(3, new ShopItem(Material.INK_SACK, (byte)6, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(4, new ShopItem(Material.INK_SACK, (byte)8, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(5, new ShopItem(Material.INK_SACK, (byte)2, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(6, new ShopItem(Material.INK_SACK, (byte)12, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(7, new ShopItem(Material.INK_SACK, (byte)10, "", new String[] {}, 1, false, true).getHandle());
+ getInventory().setItem(8, new ShopItem(Material.INK_SACK, (byte)13, "", new String[] {}, 1, false, true).getHandle());
+
+ UpdateKarts();
+ }
+
+ public void PlayerOpened()
+ {
+ UpdateKarts();
+ }
+
+ protected void ShowKartStats(KartType kartType)
+ {
+ for (KartItem item : Plugin.GetKarts())
+ {
+ if (kartType == item.GetKartType())
+ {
+ PlayerInventory inventory = Player.getInventory();
+ inventory.clear();
+
+ double statValue = Math.ceil((kartType.GetTopSpeed() * 100 - 79) / 2.625);
+ Material statMaterial = GetStatMaterial(statValue);
+ int slot = 9;
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(Material.WOOD_HOE, (byte)0, (int)(kartType.GetTopSpeed() * 100), "§e§lTop Speed"));
+
+ slot++;
+ while (statValue >= 1)
+ {
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(statMaterial, (byte)0, 1, "§e§lSpeed Bar"));
+ slot++;
+ statValue -= 1;
+ }
+
+ statValue = kartType.GetAcceleration() - 10;
+ statMaterial = GetStatMaterial(statValue);
+ slot = 18;
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(Material.STONE_HOE, (byte)0, (int)statValue, "§e§lAcceleration"));
+
+ slot++;
+ while (statValue >= 1)
+ {
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(statMaterial, (byte)0, 1, "§e§lAcceleration Bar"));
+ slot++;
+ statValue -= 1;
+ }
+
+ statValue = kartType.GetHandling() - 10;
+ statMaterial = GetStatMaterial(statValue);
+ slot = 27;
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(Material.IRON_HOE, (byte)0, (int)statValue, "§e§lHandling"));
+
+ slot++;
+ while (statValue >= 1)
+ {
+ inventory.setItem(slot, ItemStackFactory.Instance.CreateStack(statMaterial, (byte)0, 1, "§e§lHandling Bar"));
+ slot++;
+ statValue -= 1;
+ }
+ }
+ }
+ }
+
+ public void UpdateKarts()
+ {
+ int slot = 45;
+ boolean locked = true;
+
+ for (KartItem item : Plugin.GetKarts())
+ {
+ if (DonationManager.Get(Client.GetPlayerName()).Owns(item.GetSalesPackageId()) || DonationManager.Get(Client.GetPlayerName()).OwnsUnknownPackage("Minekart ULTRA") || Client.GetRank().Has(Client.GetPlayer(), Rank.ULTRA, false) || item.IsFree())
+ locked = false;
+ else
+ locked = true;
+
+ List itemLore = new ArrayList();
+
+ if (locked)
+ {
+ StringBuilder currencyBuilder = new StringBuilder();
+
+ int cost = item.GetCost(CurrencyType.Gems);
+
+ if (cost > 0)
+ {
+ currencyBuilder.append(C.cYellow + cost + " Gems");
+ }
+
+ itemLore.add(currencyBuilder.toString());
+ }
+
+ itemLore.add(C.cBlack);
+
+ itemLore.add(C.cWhite + "Max Speed: " + GetStatColor(Math.ceil((item.GetKartType().GetTopSpeed() * 100 - 79) / 2.625)) + item.GetKartType().GetTopSpeed() * 100);
+ itemLore.add(C.cWhite + "Acceleration: " + GetStatColor(item.GetKartType().GetAcceleration() - 10) + (item.GetKartType().GetAcceleration() - 10));
+ itemLore.add(C.cWhite + "Handling: " + GetStatColor(item.GetKartType().GetHandling() - 10) + (item.GetKartType().GetHandling() - 10));
+ itemLore.add(C.cWhite + "Weight: " + GetStatColor(item.GetKartType().GetStability() - 10) + (item.GetKartType().GetStability() - 10));
+
+ itemLore.add(C.cBlack);
+
+ itemLore.add(C.cWhite + "Special Item: " + C.cYellow + item.GetKartType().GetKartItem().GetName());
+
+ ShopItem shopItem = new ShopItem(item.GetDisplayMaterial(),
+ item.GetDisplayData(), item.GetName(),
+ itemLore.toArray(new String[itemLore.size()]), 1, locked,
+ false);
+
+ if (!locked)
+ {
+ shopItem.getHandle().tag.set("ench", new NBTTagList());
+ }
+
+ AddButton(slot, shopItem, new KartItemButton(this, item));
+ slot++;
+ }
+ }
+
+ private ChatColor GetStatColor(double statValue)
+ {
+ return statValue >= 3 ? (statValue >= 6 ? ChatColor.GREEN : ChatColor.YELLOW) : ChatColor.RED;
+ }
+
+ private Material GetStatMaterial(double statValue)
+ {
+ return statValue >= 3 ? (statValue >= 6 ? Material.EMERALD : Material.GOLD_NUGGET) : Material.REDSTONE;
+ }
+
+ public void PurchaseKart(Player player, KartItem kartItem)
+ {
+ if ((DonationManager.Get(Client.GetPlayerName()).GetGems() > kartItem.GetCost(CurrencyType.Gems)) && !DonationManager.Get(Client.GetPlayerName()).Owns(kartItem.GetSalesPackageId()) && !DonationManager.Get(Client.GetPlayerName()).OwnsUnknownPackage("Minekart ULTRA") && !Client.GetRank().Has(Client.GetPlayer(), Rank.ULTRA, false) && !kartItem.IsFree())
+ {
+ PlayAcceptSound(player);
+ Shop.OpenPageForPlayer(player, new ConfirmationPage(Plugin, Shop, ClientManager, DonationManager, null,
+ this, kartItem, SelectedCurrency, player));
+ }
+ else
+ {
+ PlayDenySound(player);
+ ShowKartStats(kartItem.GetKartType());
+ }
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/Track.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/Track.java
new file mode 100644
index 000000000..bb606e852
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/Track.java
@@ -0,0 +1,708 @@
+package nautilus.game.minekart.track;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.FileUtil;
+import mineplex.core.common.util.MapUtil;
+import mineplex.core.common.util.UtilAlg;
+import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.common.util.UtilServer;
+import mineplex.core.common.util.UtilTime;
+import mineplex.core.common.util.WorldUtil;
+import mineplex.core.recharge.Recharge;
+import mineplex.core.teleport.Teleport;
+import nautilus.game.minekart.gp.GP;
+import nautilus.game.minekart.gp.GPBattle;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.track.ents.*;
+import nautilus.minecraft.core.utils.ZipUtil;
+import net.minecraft.server.v1_7_R1.ChunkPreLoadEvent;
+
+import org.bukkit.Location;
+import org.bukkit.Sound;
+import org.bukkit.World;
+import org.bukkit.WorldCreator;
+import org.bukkit.entity.Player;
+import org.bukkit.event.world.ChunkUnloadEvent;
+import org.bukkit.util.Vector;
+
+public class Track
+{
+ public enum TrackState
+ {
+ Loading,
+ Countdown,
+ Live,
+ Ending,
+ Ended
+ }
+
+ private World World = null;
+
+ private int MinX = 0;
+ private int MinZ = 0;
+ private int MaxX = 0;
+ private int MaxZ = 0;
+ private int CurX = 0;
+ private int CurZ = 0;
+
+ private GP GP;
+ private Teleport _teleport;
+ private Recharge _recharge;
+ private int _trackId;
+
+ private String _name;
+ private String _file;
+
+ //Race Data
+ private TrackState _state = TrackState.Loading;
+ private long _stateTime = System.currentTimeMillis();
+ private int _countdown = 6;
+ private boolean _nextTrack = false;
+
+ private HashMap _scores = new HashMap();
+ private ArrayList _positions = new ArrayList();
+
+ //Map Data
+ private float _yaw = 0f;
+ private ArrayList _kartStart;
+ private ArrayList _returnPoints;
+ private ArrayList _trackProgress;
+ private ArrayList _itemBlocks;
+
+ private HashMap _jumps;
+
+ private ArrayList _creatures;
+
+ private ArrayList _trackBlocks;
+ private ArrayList _returnBlocks;
+
+ public Track(GP gp, Teleport teleport, Recharge recharge, String file, int id)
+ {
+ GP = gp;
+ _teleport = teleport;
+ _recharge = recharge;
+
+ _trackId = id;
+
+ _file = file;
+
+ _kartStart = new ArrayList();
+ _returnPoints = new ArrayList();
+ _trackProgress = new ArrayList();
+ _itemBlocks = new ArrayList();
+
+ _jumps = new HashMap();
+ _creatures = new ArrayList();
+
+ _trackBlocks = new ArrayList();
+ _returnBlocks = new ArrayList();
+
+ //Register Self
+ GP.Manager.TrackManager.RegisterTrack(this);
+ }
+
+ public GP GetGP()
+ {
+ return GP;
+ }
+
+ public String GetName()
+ {
+ return _name;
+ }
+
+ public String GetFile()
+ {
+ return _file;
+ }
+
+ public World GetWorld()
+ {
+ return World;
+ }
+
+ public float GetYaw()
+ {
+ return _yaw;
+ }
+
+ public ArrayList GetSpawns()
+ {
+ return _kartStart;
+ }
+
+ public HashMap GetScores()
+ {
+ return _scores;
+ }
+
+ public ArrayList GetPositions()
+ {
+ return _positions;
+ }
+
+ public ArrayList GetProgress()
+ {
+ return _trackProgress;
+ }
+
+ public ArrayList GetReturn()
+ {
+ return _returnPoints;
+ }
+
+ public ArrayList GetItems()
+ {
+ return _itemBlocks;
+ }
+
+ public HashMap GetJumps()
+ {
+ return _jumps;
+ }
+
+ public ArrayList GetCreatures()
+ {
+ return _creatures;
+ }
+
+ public ArrayList GetTrackBlocks()
+ {
+ return _trackBlocks;
+ }
+
+ public ArrayList GetReturnBlocks()
+ {
+ return _returnBlocks;
+ }
+
+ public void SetState(TrackState state)
+ {
+ if (_state != state)
+ {
+ if (state == TrackState.Ended || _state == TrackState.Ended)
+ GP.SwitchScoreboards();
+ else if (state == TrackState.Countdown || _state == TrackState.Countdown)
+ GP.SwitchScoreboards();
+ }
+
+ _state = state;
+ _stateTime = System.currentTimeMillis();
+ _countdown = 31;
+
+ if (state == TrackState.Countdown)
+ _countdown = 8;
+ }
+
+ public TrackState GetState()
+ {
+ return _state;
+ }
+
+ public long GetStateTime()
+ {
+ return _stateTime;
+ }
+
+ public void Update()
+ {
+ String type = "Race";
+ if (GP instanceof GPBattle)
+ type = "Battle";
+
+ if (_state == TrackState.Loading)
+ {
+
+ }
+ else if (_state == TrackState.Countdown)
+ {
+ if (UtilTime.elapsed(_stateTime, 1000))
+ {
+ _stateTime = System.currentTimeMillis();
+ _countdown--;
+
+ //Inform + Sound
+ for (Player cur : GP.GetPlayers())
+ {
+ if (_countdown > 5)
+ {
+
+ }
+ else if (_countdown > 0)
+ {
+ UtilPlayer.message(cur, F.main("MK", type + " begins in " + F.time(_countdown + " Seconds") + "..."));
+ cur.playSound(cur.getLocation(), Sound.NOTE_PIANO, 1f, 1f);
+ }
+ else
+ {
+ UtilPlayer.message(cur, F.main("MK", type + " has started!"));
+ cur.playSound(cur.getLocation(), Sound.NOTE_PIANO, 2f, 2f);
+ }
+ }
+
+ if (_countdown <= 0)
+ SetState(TrackState.Live);
+ }
+ }
+ else if (_state == TrackState.Live)
+ {
+
+ }
+ else if (_state == TrackState.Ending)
+ {
+ boolean allFinished = true;
+
+ for (Kart kart : GetGP().GetKarts())
+ if (!kart.HasFinishedTrack())
+ allFinished = false;
+
+ if (allFinished)
+ {
+ GP.Announce(F.main("MK", type + " has ended."));
+ SetState(TrackState.Ended);
+ }
+
+ else if (UtilTime.elapsed(_stateTime, 1000))
+ {
+ _stateTime = System.currentTimeMillis();
+ _countdown--;
+
+ //Inform + Sound
+ if (_countdown%5 == 0)
+ {
+ GP.Announce(F.main("MK", type + " ends in " + F.time(_countdown + " Seconds") + "..."));
+
+ for (Player cur : GP.GetPlayers())
+ {
+ if (_countdown > 0) cur.playSound(cur.getLocation(), Sound.NOTE_PIANO, 1f, 0.5f);
+ else cur.playSound(cur.getLocation(), Sound.NOTE_PIANO, 2f, 0f);
+ }
+ }
+
+ if (_countdown <= 0)
+ {
+ GP.Announce(F.main("MK", type + " has ended."));
+ SetState(TrackState.Ended);
+ }
+ }
+ }
+ else
+ {
+ if (_nextTrack)
+ return;
+
+ if (UtilTime.elapsed(_stateTime, 10000))
+ {
+ GetGP().NextTrack();
+ _nextTrack = true;
+ }
+ }
+ }
+
+ protected String GetFolder()
+ {
+ return GetGP().GetId() + "-" + GetGP().GetSet().GetName() + "-" + GetFile();
+ }
+
+ public void Initialize()
+ {
+ final Track track = this;
+
+ System.out.println("Initializing....");
+
+ UtilServer.getServer().getScheduler().runTaskAsynchronously(GP.Manager.GetPlugin(), new Runnable()
+ {
+ public void run()
+ {
+ //Unzip
+ track.UnzipWorld();
+
+ //Load Track Data Sync
+ UtilServer.getServer().getScheduler().runTask(GP.Manager.GetPlugin(), new Runnable()
+ {
+ public void run()
+ {
+ //Start World
+ World = WorldUtil.LoadWorld(new WorldCreator(GetFolder()));
+
+ //Load Track Data
+ track.LoadTrackData();
+ }
+ });
+ }
+ });
+ }
+
+ protected void UnzipWorld()
+ {
+ String folder = GetFolder();
+ new File(folder).mkdir();
+ new File(folder + File.separatorChar + "region").mkdir();
+ new File(folder + File.separatorChar + "data").mkdir();
+ ZipUtil.UnzipToDirectory(GetFile() + ".zip", folder);
+ }
+
+ public void LoadTrackData()
+ {
+ //Load Track Data
+ try
+ {
+ FileInputStream fstream = new FileInputStream(GetFolder() + File.separatorChar + "TrackInfo.dat");
+ DataInputStream in = new DataInputStream(fstream);
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ String line;
+
+ while ((line = br.readLine()) != null)
+ {
+ String[] tokens = line.split(":");
+
+ if (tokens.length < 2)
+ continue;
+
+ if (tokens[0].length() == 0)
+ continue;
+
+ //TRACK NAME
+ if (tokens[0].equalsIgnoreCase("TRACK_NAME"))
+ {
+ _name = tokens[1];
+ }
+
+ else if (tokens[0].equalsIgnoreCase("ROAD_TYPES"))
+ {
+ try
+ {
+ _trackBlocks.add(Integer.parseInt(tokens[1]));
+ }
+ catch (Exception e)
+ {
+ System.out.println("Track Data Read Error: Invalid Road Type [" + tokens[1] + "]");
+ }
+ }
+
+ else if (tokens[0].equalsIgnoreCase("RETURN_TYPES"))
+ {
+ try
+ {
+ _returnBlocks.add(Integer.parseInt(tokens[1]));
+ }
+ catch (Exception e)
+ {
+ System.out.println("Track Data Read Error: Invalid Return Type [" + tokens[1] + "]");
+ }
+ }
+
+ else if (tokens[0].equalsIgnoreCase("SPAWN_DIRECTION"))
+ {
+ try
+ {
+ _yaw = Float.valueOf(tokens[1]);
+ }
+ catch (Exception e)
+ {
+ System.out.println("Track Data Read Error: Invalid Yaw [" + tokens[1] + "]");
+ }
+ }
+
+ else if (tokens[0].equalsIgnoreCase("SPAWNS"))
+ {
+ for (int i=1 ; i= maxMilliseconds)
+ return false;
+
+ World.getChunkAt(new Location(World, CurX, 0, CurZ));
+ }
+
+ CurZ = MinZ;
+ }
+
+ return true;
+ }
+
+ public void Uninitialize()
+ {
+ //Wipe Storage
+ _kartStart.clear();
+ _returnPoints.clear();
+ _trackProgress.clear();
+ _itemBlocks.clear();
+ _jumps.clear();
+ _creatures.clear();
+ _trackBlocks.clear();
+ _returnBlocks.clear();
+
+ //Wipe World
+ MapUtil.UnloadWorld(GetGP().Manager.GetPlugin(), World);
+ MapUtil.ClearWorldReferences(World.getName());
+ FileUtil.DeleteFolder(new File(World.getName()));
+
+ World = null;
+ }
+
+ private Location StrToLoc(String loc)
+ {
+ String[] coords = loc.split(",");
+
+ try
+ {
+ return new Location(World, Integer.valueOf(coords[0])+0.5, Integer.valueOf(coords[1]), Integer.valueOf(coords[2])+0.5);
+ }
+ catch (Exception e)
+ {
+ System.out.println("Track Data Read Error: Invalid Location String [" + loc + "]");
+ }
+
+ return null;
+ }
+
+ public void SpawnTeleport()
+ {
+ Track prevTrack = GP.GetTrack(_trackId - 1);
+
+ //Use Previous Positions
+ if (prevTrack != null)
+ {
+ int i = 0;
+ for (Kart kart : prevTrack.GetPositions())
+ {
+ Location loc = GetSpawns().get(i);
+ loc.setYaw(GetYaw());
+ loc.setPitch(30f);
+
+ //Battle
+ if (GetGP() instanceof GPBattle)
+ {
+ Vector dir = UtilAlg.getTrajectory(kart.GetDriver().getLocation(), GetProgress().get(0));
+ loc.setYaw(UtilAlg.GetYaw(dir));
+ loc.setPitch(UtilAlg.GetPitch(dir));
+ }
+
+ _teleport.TP(kart.GetDriver(), loc, false);
+ i++;
+ }
+ }
+ //Use Join Positions
+ else
+ {
+ int i = 0;
+ for (Player player : GetGP().GetPlayers())
+ {
+ Location loc = GetSpawns().get(i);
+ loc.setYaw(GetYaw());
+ loc.setPitch(30f);
+
+ //Battle
+ if (GetGP() instanceof GPBattle)
+ {
+ Vector dir = UtilAlg.getTrajectory(player.getLocation(), GetProgress().get(0));
+ loc.setYaw(UtilAlg.GetYaw(dir));
+ loc.setPitch(UtilAlg.GetPitch(dir));
+ }
+
+ _teleport.TP(player, loc, false);
+ i++;
+ }
+ }
+ }
+
+ public void RemoveKart(Kart kart)
+ {
+ _scores.remove(kart);
+ _positions.remove(kart);
+ }
+
+ public void ChunkUnload(ChunkUnloadEvent event)
+ {
+ if (World == null)
+ return;
+
+ if (!event.getWorld().equals(World))
+ return;
+
+ event.setCancelled(true);
+ }
+
+ public void ChunkLoad(ChunkPreLoadEvent event)
+ {
+ if (World == null)
+ return;
+
+ if (!event.GetWorld().equals(World))
+ return;
+
+ int x = event.GetX();
+ int z = event.GetZ();
+
+ if (x >= MinX >> 4 && x <= MaxX >> 4 && z >= MinZ >> 4 && z <= MaxZ >> 4)
+ {
+ return;
+ }
+
+ event.setCancelled(true);
+ }
+
+ public Recharge GetRecharge()
+ {
+ return _recharge;
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackEntity.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackEntity.java
new file mode 100644
index 000000000..5a7d67516
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackEntity.java
@@ -0,0 +1,153 @@
+package nautilus.game.minekart.track;
+
+import mineplex.core.common.util.UtilMath;
+import mineplex.core.common.util.UtilTime;
+import nautilus.game.minekart.kart.Kart;
+import net.minecraft.server.v1_7_R1.EntityCreature;
+import net.minecraft.server.v1_7_R1.Navigation;
+
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_7_R1.entity.CraftCreature;
+import org.bukkit.entity.Creature;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+
+public abstract class TrackEntity
+{
+ public Track Track;
+
+ private String _name;
+
+ private Entity _ent;
+ private EntityType _type;
+
+ private Location _loc;
+ private double _offset = 3;
+ private double _collideRange = 1;
+
+ private long _spawnRate = 30000;
+ private long _spawnTimer = 0;
+
+ public TrackEntity(Track track, EntityType type, String name, double offset, double collideRange, long spawnRate, Location loc)
+ {
+ Track = track;
+
+ _name = name;
+
+ _type = type;
+
+ _spawnRate = spawnRate;
+
+ _offset = offset;
+ _collideRange = collideRange;
+
+ _loc = loc;
+ }
+
+ public String GetName()
+ {
+ return _name;
+ }
+
+ public Entity GetEntity()
+ {
+ return _ent;
+ }
+
+ public void SetEntity(Entity ent)
+ {
+ _ent = ent;
+ }
+
+ public EntityType GetType()
+ {
+ return _type;
+ }
+
+ public Location GetLocation()
+ {
+ return _loc;
+ }
+
+ public long GetSpawnRate()
+ {
+ return _spawnRate;
+ }
+
+ public long GetSpawnTimer()
+ {
+ return _spawnTimer;
+ }
+
+ public void SetSpawnTimer(long time)
+ {
+ _spawnTimer = time;
+ }
+
+ public double GetOffset()
+ {
+ return _offset;
+ }
+
+ public double GetCollideRange()
+ {
+ return _collideRange;
+ }
+
+ public boolean Update()
+ {
+ //Respawn
+ if (GetEntity() == null || !GetEntity().isValid())
+ {
+ Respawn();
+ }
+ //Return
+ else
+ {
+ Movement();
+ }
+
+ return false;
+ }
+
+ public void Respawn()
+ {
+ if (GetType() == null)
+ return;
+
+ if (GetEntity() != null)
+ GetEntity().remove();
+
+ if (UtilTime.elapsed(GetSpawnTimer(), GetSpawnRate()))
+ {
+ _ent = GetLocation().getWorld().spawnEntity(GetLocation(), GetType());
+ SetSpawnTimer(System.currentTimeMillis());
+ }
+ }
+
+ public void Movement()
+ {
+ if (UtilMath.offset(GetLocation(), GetEntity().getLocation()) > GetOffset())
+ {
+ if (GetEntity() instanceof Creature)
+ {
+ EntityCreature ec = ((CraftCreature)GetEntity()).getHandle();
+ Navigation nav = ec.getNavigation();
+ nav.a(GetLocation().getX(), GetLocation().getY(), GetLocation().getZ(), 0.4f);
+ }
+ }
+ }
+
+ public void CheckCollision(Kart kart)
+ {
+ if (GetEntity() == null || !GetEntity().isValid())
+ return;
+
+ if (UtilMath.offset(kart.GetDriver().getLocation(), GetEntity().getLocation()) > GetCollideRange())
+ return;
+
+ Collide(kart);
+ }
+
+ public abstract void Collide(Kart kart);
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackItem.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackItem.java
new file mode 100644
index 000000000..e721aa1b8
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackItem.java
@@ -0,0 +1,71 @@
+package nautilus.game.minekart.track;
+
+import nautilus.game.minekart.kart.Kart;
+
+import org.bukkit.Effect;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+
+public class TrackItem
+{
+ private Location _loc;
+ private Entity _ent = null;
+ private long _delay = 0;
+
+ public TrackItem(Location loc)
+ {
+ _loc = loc;
+ }
+
+ public Location GetLocation()
+ {
+ return _loc;
+ }
+
+ public Entity GetEntity()
+ {
+ return _ent;
+ }
+
+ public long GetDelay()
+ {
+ return _delay;
+ }
+
+ public void SetEntity(Entity ent)
+ {
+ _ent = ent;
+ }
+
+ public void SetDelay(long delay)
+ {
+ _delay = delay;
+ }
+
+ public void SpawnEntity(World world)
+ {
+ if (GetEntity() != null)
+ GetEntity().remove();
+
+ SetEntity(world.spawnEntity(_loc.clone().add(0, 0, 0), EntityType.ENDER_CRYSTAL));
+
+ //SetEntity(world.dropItem(new Location(_loc.getWorld(), _loc.getX(), _loc.getY() + 1, _loc.getZ()), new ItemStack(Material.CHEST)));
+ //SetEntity(world.spawnFallingBlock(GetLocation(), Material.LOCKED_CHEST, (byte)0));
+ //GetEntity().setVelocity(new Vector(0,0,0));
+ }
+
+ public void Pickup(Kart kart)
+ {
+ if (GetEntity() != null)
+ GetEntity().remove();
+
+ SetEntity(null);
+ SetDelay(System.currentTimeMillis());
+
+ GetLocation().getWorld().playEffect(GetLocation().clone().add(0, 1, 0), Effect.STEP_SOUND, 35);
+
+ kart.PickupItem();
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackLogic.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackLogic.java
new file mode 100644
index 000000000..7dfe79e34
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackLogic.java
@@ -0,0 +1,243 @@
+package nautilus.game.minekart.track;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import mineplex.core.common.util.UtilMath;
+import mineplex.core.common.util.UtilTime;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.track.Track.TrackState;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.util.Vector;
+
+public class TrackLogic
+{
+ public static void Positions(Track track)
+ {
+ if (track.GetWorld() == null)
+ return;
+
+ if (track.GetState() == TrackState.Loading || track.GetState() == TrackState.Ended)
+ return;
+
+ for (Kart kart : track.GetGP().GetKarts())
+ SetKartProgress(track, kart);
+
+ //Store Scores
+ track.GetScores().clear();
+ for (Kart kart : track.GetGP().GetKarts())
+ track.GetScores().put(kart, kart.GetLapScore());
+
+
+ ArrayList pos = track.GetPositions();
+
+ //Order Scores
+ pos.clear();
+ for (Kart kart : track.GetScores().keySet())
+ {
+ boolean added = false;
+
+ for (int i=0 ; i track.GetScores().get(pos.get(i)))
+ {
+ pos.add(i, kart);
+ added = true;
+ break;
+ }
+ }
+
+ if (!added)
+ pos.add(kart);
+ }
+
+ //Set Lap Place
+ for (int i=0 ; i iterator = track.GetCreatures().iterator();
+
+ while (iterator.hasNext())
+ {
+ TrackEntity ent = iterator.next();
+
+ if (ent.Update())
+ {
+ if (ent.GetEntity() != null)
+ ent.GetEntity().remove();
+
+ iterator.remove();
+ }
+
+ }
+ }
+}
diff --git a/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackManager.java b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackManager.java
new file mode 100644
index 000000000..5144dcf51
--- /dev/null
+++ b/Plugins/Nautilus.Game.MineKart/src/nautilus/game/minekart/track/TrackManager.java
@@ -0,0 +1,348 @@
+package nautilus.game.minekart.track;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import mineplex.core.MiniPlugin;
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilAlg;
+import mineplex.core.common.util.UtilMath;
+import mineplex.core.common.util.UtilPlayer;
+import mineplex.core.fakeEntity.FakeEntityManager;
+import mineplex.core.teleport.Teleport;
+import mineplex.core.updater.event.UpdateEvent;
+import mineplex.core.updater.UpdateType;
+import nautilus.game.minekart.gp.GPBattle;
+import nautilus.game.minekart.kart.Kart;
+import nautilus.game.minekart.kart.KartState;
+import nautilus.game.minekart.track.Track.TrackState;
+import net.minecraft.server.v1_7_R1.ChunkPreLoadEvent;
+import net.minecraft.server.v1_7_R1.EntityPlayer;
+import net.minecraft.server.v1_7_R1.Packet;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Sound;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.craftbukkit.v1_7_R1.entity.CraftPlayer;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.block.BlockIgniteEvent;
+import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
+import org.bukkit.event.entity.EntityCombustEvent;
+import org.bukkit.event.world.ChunkUnloadEvent;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.util.Vector;
+
+public class TrackManager extends MiniPlugin
+{
+ private Teleport _teleport;
+ private HashSet