package com.useful.uCarsAPI; import com.useful.ucars.ucars; import com.useful.ucarsCommon.StatValue; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * Some basic API tools that allow plugins to manipulate uCars for their use * * @author storm345 * */ public class uCarsAPI { private ucars plugin = null; private Map carChecks = new HashMap(); private Map itemCarChecks = new HashMap(); private Map carSpeedMods = new HashMap(); private Map carRotMods = new HashMap(); private Map carAccelMods = new HashMap(); private Map carDecelMods = new HashMap(); private Map> ucarsMeta = new HashMap>(); private boolean uCarsHandlesPlacingCars = true; public uCarsAPI() { this.plugin = ucars.plugin; } public boolean hasItemCarCheckCriteria(){ return this.itemCarChecks.size() > 0; } /** * Get the running instance of the API implementation * * @return Returns the API */ public static uCarsAPI getAPI() { return ucars.plugin.getAPI(); } /** * Will hook your plugin into uCars. This first step must be done before any * API calls can be made. * * @param plugin * Your plugin */ public void hookPlugin(Plugin plugin) { ucars.plugin.getLogger().info( "Successfully hooked into by: " + plugin.getName()); ucars.plugin.hookedPlugins.add(plugin); return; } /** * Call onDisable() to show the user your plugin being unhooked. Else it * will be unhooked automatically anyway. * * @param plugin * Your plugin */ public void unHookPlugin(Plugin plugin) { ucars.plugin.getLogger().info("Successfully unhooked: " + plugin.getName()); ucars.plugin.hookedPlugins.remove(plugin); return; } /** * Will reset all hooked plugins -Don't call unless absolutely needed * */ public void unHookPlugins() { plugin.hookedPlugins.removeAll(plugin.hookedPlugins); plugin.getLogger().info("Successfully unhooked all plugins!"); return; } /** * Checks if your plugin is hooked, your plugin needs to be hooked to use * the API * * @param plugin * Your plugin * @return True if the plugin is hooked, False if not */ public Boolean isPluginHooked(Plugin plugin) { if (plugin == ucars.plugin) { return true; } return ucars.plugin.hookedPlugins.contains(plugin); } /** * Registers an isACar() check for your plugin, only one check is allowed * per hooked plugin. Trying to add more than one check will result in * overriding the original * * @param plugin * Your plugin * @param carCheck * The CarCheck to perform * @return True if registered, False if not because plugin isn't hooked */ public Boolean registerCarCheck(Plugin plugin, CarCheck carCheck) { if (!isPluginHooked(plugin)) { return false; } carChecks.put(plugin, carCheck); return true; } /** * Registers an item isACar() check for your plugin, only one check is allowed * per hooked plugin. Trying to add more than one check will result in * overriding the original * * @param plugin * Your plugin * @param carCheck * The CarCheck to perform * @return True if registered, False if not because plugin isn't hooked * @since v17 */ public Boolean registerItemCarCheck(Plugin plugin, ItemCarCheck carCheck) { if (!isPluginHooked(plugin)) { return false; } itemCarChecks.put(plugin, carCheck); return true; } /** * Removes a carCheck registered by a plugin * * @param plugin * Your plugin * @return True if unregistered, False if not because plugin isn't hooked */ public Boolean unRegisterCarCheck(Plugin plugin) { if (!isPluginHooked(plugin)) { return false; } carChecks.remove(plugin); return true; } /** * Removes an item carCheck registered by a plugin * * @param plugin * Your plugin * @return True if unregistered, False if not because plugin isn't hooked * @since v17 */ public Boolean unRegisterItemCarCheck(Plugin plugin) { if (!isPluginHooked(plugin)) { return false; } itemCarChecks.remove(plugin); return true; } public synchronized Boolean runCarChecks(Entity car) { for (CarCheck c : carChecks.values()) { if (!c.isACar(car)) { return false; } } return true; } public synchronized Boolean runCarChecks(ItemStack carStack) { for (ItemCarCheck c : itemCarChecks.values()) { if (!c.isACar(carStack)) { return false; } } return true; } /** * Registers an car turning mod for your plugin so you can manipulate the amount the car turns per tick * * @param plugin * Your plugin * @param mod * The turningMod to add * @return True if registered, False if not because plugin isn't hooked */ public Boolean registerTurningMod(Plugin plugin, CarTurningModifier mod) { if (!isPluginHooked(plugin)) { return false; } carRotMods.put(plugin, mod); return true; } /** * Registers an car speed mod check for your plugin, only one speed mod is * allowed per hooked plugin. Trying to add more than one check will result * in overriding the original * * @param plugin * Your plugin * @param speedMod * The speedMod to add * @return True if registered, False if not because plugin isn't hooked */ public Boolean registerSpeedMod(Plugin plugin, CarSpeedModifier speedMod) { if (!isPluginHooked(plugin)) { return false; } carSpeedMods.put(plugin, speedMod); return true; } /** * Removes a turning mod registered by a plugin * * @param plugin * Your plugin * @return True if unregistered, False if not because plugin isn't hooked */ public Boolean unRegisterTurningMod(Plugin plugin) { if (!isPluginHooked(plugin)) { return false; } carRotMods.remove(plugin); return true; } /** * Removes a speed mod registered by a plugin * * @param plugin * Your plugin * @return True if unregistered, False if not because plugin isn't hooked */ public Boolean unRegisterSpeedMod(Plugin plugin) { if (!isPluginHooked(plugin)) { return false; } carSpeedMods.remove(plugin); return true; } /** * Registers a car deceleration modifier to your plugin, only one is * allowed per hooked plugin. Trying to add more than one check will result * in overriding the original * * @param plugin * Your plugin * @param decMod * The Acceleration Mod to add * @return True if registered, False if not because plugin isn't hooked */ public Boolean registerDecelerationMod(Plugin plugin, CarDecelerationModifier accMod) { if (!isPluginHooked(plugin)) { return false; } carDecelMods.put(plugin, accMod); return true; } /** * Removes an deceleration mod registered by a plugin * * @param plugin * Your plugin * @return True if unregistered, False if not because plugin isn't hooked */ public Boolean unRegisterDecelerationMod(Plugin plugin) { if (!isPluginHooked(plugin)) { return false; } carDecelMods.remove(plugin); return true; } public float getDeceleration(Player driver, float currentMult) { if(carDecelMods.size() < 1){ return currentMult; } for (CarDecelerationModifier m : new ArrayList(carDecelMods.values())) { currentMult = m.getAccelerationDecimal(driver, currentMult); } return currentMult; } /** * Registers a car acceleration modifier to your plugin, only one is * allowed per hooked plugin. Trying to add more than one check will result * in overriding the original * * @param plugin * Your plugin * @param accMod * The Acceleration Mod to add * @return True if registered, False if not because plugin isn't hooked */ public Boolean registerAccelerationMod(Plugin plugin, CarAccelerationModifier accMod) { if (!isPluginHooked(plugin)) { return false; } carAccelMods.put(plugin, accMod); return true; } /** * Removes an acceleration mod registered by a plugin * * @param plugin * Your plugin * @return True if unregistered, False if not because plugin isn't hooked */ public Boolean unRegisterAccelerationMod(Plugin plugin) { if (!isPluginHooked(plugin)) { return false; } carAccelMods.remove(plugin); return true; } public float getAcceleration(Player driver, float currentMult) { if(carAccelMods.size() < 1){ return currentMult; } for (CarAccelerationModifier m : new ArrayList(carAccelMods.values())) { currentMult = m.getAccelerationDecimal(driver, currentMult); } return currentMult; } public synchronized double getMaxCarTurnAmountDegrees(Entity car, double normalAmount){ double m = normalAmount; for (CarTurningModifier mod : carRotMods.values()) { m = mod.getModifiedTurningSpeed(car, m); } return m; } public synchronized Vector getTravelVector(Entity car, Vector travelVector, double currentMult) { for (CarSpeedModifier m : carSpeedMods.values()) { travelVector = m.getModifiedSpeed(car, travelVector, currentMult); } return travelVector; } /** * Gets all non-permanent uCarMeta for a car * * -uCarMeta is removed each time the server restarts so use for temporary * buffs such as speed-buffs or upgrades (If you track and save them) * * @param entityId * Id of the uCar entity (ID can be changed without your notice * So don't use this for tracking cars) * @return All the meta set for that car */ public Map getuCarMeta(UUID entityId) { if (!ucarsMeta.containsKey(entityId)) { return new HashMap(); } return ucarsMeta.get(entityId); } /** * Sets a uCar to use a control scheme where the car motion is not based of user input, but is * played out through the server to ensure absolute fair speeds between players. * * -uCarMeta is removed each time the server restarts so use for temporary * buffs such as speed-buffs or upgrades (If you track and save them) * * @param plugin * Your plugin * @param id * Id of the uCar entity (ID can be changed without your notice * So don't use this for tracking cars) * @return True is successful and False if plugin is not hooked or * unsuccessful * * @since v17 */ public boolean setUseRaceControls(UUID id, Plugin plugin){ return adduCarsMeta(plugin, id, "car.controls", new StatValue("race", ucars.plugin)); } /** * Sets uCarMeta for a car * * -uCarMeta is removed each time the server restarts so use for temporary * buffs such as speed-buffs or upgrades (If you track and save them) * * @param plugin * Your plugin * @param entityId * Id of the uCar entity (ID can be changed without your notice * So don't use this for tracking cars) * @param toAdd * The ucarMeta to add to the car * @param statName * The key/Name of the stat eg. 'myPlugin.myStat' * @return True is successful and False if plugin is not hooked or * unsuccessful */ public Boolean adduCarsMeta(Plugin plugin, UUID entityId, String statName, StatValue toAdd) { if (!isPluginHooked(plugin)) { return false; } Map stats = new HashMap(); if (ucarsMeta.containsKey(entityId)) { stats = ucarsMeta.get(entityId); } stats.put(statName, toAdd); ucarsMeta.put(entityId, stats); return true; } /** * Gets uCarMeta for a car * * -uCarMeta is removed each time the server restarts so use for temporary * buffs such as speed-buffs or upgrades (If you track and save them) * * @param plugin * Your plugin * @param entityId * Id of the uCar entity (ID can be changed without your notice * So don't use this for tracking cars) * @param statName * The key/Name of the stat eg. 'myPlugin.myStat' * @return ucarMeta is successful and null if not existing on car or plugin * is not hooked or unsuccessful */ public StatValue getUcarMeta(Plugin plugin, String statName, UUID entityId) { if (!isPluginHooked(plugin) || !ucarsMeta.containsKey(entityId)) { return null; } Map metas = ucarsMeta.get(entityId); if (!metas.containsKey(statName)) { return null; } return metas.get(statName); } /** * Remove a meta value of a car * * -uCarMeta is removed each time the server restarts so use for temporary * buffs such as speed-buffs or upgrades (If you track and save them) * * @param plugin * Your plugin * @param statName * The name of the stat to remove * @param entityId * The entityId of the car * @return True if removed, False if plugin not hooked or removal * unsuccessful (Not set) */ public Boolean removeUcarMeta(Plugin plugin, String statName, UUID entityId) { if (!isPluginHooked(plugin) || !ucarsMeta.containsKey(entityId)) { return false; } Map metas = ucarsMeta.get(entityId); if (!metas.containsKey(statName)) { return false; } metas.remove(statName); ucarsMeta.put(entityId, metas); return true; } /** * Clears uCarMeta for a car * * -uCarMeta is removed each time the server restarts so use for temporary * buffs such as speed-buffs or upgrades (If you track and save them) * * @param plugin * Your plugin * @param entityId * Id of the uCar entity (ID can be changed without your notice * So don't use this for tracking cars) * @return True is successful and False is plugin is not hooked or * unsuccessfull */ public Boolean clearCarMeta(Plugin plugin, UUID entityId) { if (!isPluginHooked(plugin)) { return false; } ucarsMeta.remove(entityId); return true; } /** * Updates the ID of a car entity * * @param previousId * The old ID of the entity * @param newId * The new ID of the entity */ public void updateUcarMeta(UUID previousId, UUID newId) { if (!ucarsMeta.containsKey(previousId)) { return; } ucarsMeta.put(newId, new HashMap(ucarsMeta.get(previousId))); ucarsMeta.remove(previousId); return; } /** * Checks if the given vehicle is a car * * @param car * The Minecart to check if it's a car * @return True if it's a car */ public Boolean checkIfCar(Entity car) { return ucars.listener.isACar(car); } /** * Checks if the given player is in a car * * @param player * The player to check * @return True if they're in a car */ public Boolean checkInCar(Player player) { return ucars.listener.inACar(player); } /** * Checks if the given player is in a car * * @param player * The player to check * @return True if they're in a car */ public Boolean checkInCar(String player) { return ucars.listener.inACar(player); } /** * Get's the version of uCars * * @return Return's the version of uCars used */ public String getUCarsVersion(){ return plugin.getDescription().getVersion(); } /** * Returns if the car should be waiting at traffic lights * * @param car The car to check * @return True if it should stop, false else * * @since v17 */ public Boolean atTrafficLight(Entity car){ Location loc = car.getLocation(); Block under = loc.getBlock().getRelative(BlockFace.DOWN); Block underunder = under.getRelative(BlockFace.DOWN); return ucars.listener.atTrafficLight(car, under, underunder, loc); } public boolean isuCarsHandlingPlacingCars() { return uCarsHandlesPlacingCars; } public void setuCarsHandlesPlacingCars(boolean uCarsHandlesPlacingCars) { this.uCarsHandlesPlacingCars = uCarsHandlesPlacingCars; } }