Merge branch 'feature/battle-royale' into develop
This commit is contained in:
commit
0ac3e227fd
@ -107,6 +107,8 @@ public enum GameDisplay
|
||||
MOBA("Heroes of GWEN", Material.PRISMARINE, (byte)0, GameCategory.CLASSICS, 70, true),
|
||||
MOBATraining("Heroes of GWEN Training", Material.PRISMARINE, (byte)0, GameCategory.CLASSICS, 70, false),
|
||||
|
||||
BattleRoyale("Battle Royale", Material.DIAMOND_SWORD, (byte)0, GameCategory.EVENT, 72, false),
|
||||
|
||||
GemHunters("Gem Hunters", Material.EMERALD, (byte) 0, GameCategory.SURVIVAL, 71, false),
|
||||
|
||||
Event("Mineplex Event", Material.CAKE, (byte)0, GameCategory.EVENT, 999, false),
|
||||
|
@ -9,6 +9,7 @@ import nautilus.game.arcade.game.games.alieninvasion.AlienInvasion;
|
||||
import nautilus.game.arcade.game.games.baconbrawl.BaconBrawl;
|
||||
import nautilus.game.arcade.game.games.barbarians.Barbarians;
|
||||
import nautilus.game.arcade.game.games.basketball.Basketball;
|
||||
import nautilus.game.arcade.game.games.battleroyale.BattleRoyaleSolo;
|
||||
import nautilus.game.arcade.game.games.bossbattles.BossBattles;
|
||||
import nautilus.game.arcade.game.games.bouncyballs.BouncyBalls;
|
||||
import nautilus.game.arcade.game.games.bridge.Bridge;
|
||||
@ -237,6 +238,12 @@ public enum GameType
|
||||
MOBA(MobaClassic.class, GameDisplay.MOBA),
|
||||
MOBATraining(MobaTraining.class, GameDisplay.MOBATraining),
|
||||
|
||||
BattleRoyale(BattleRoyaleSolo.class, GameDisplay.BattleRoyale, new Pair[]
|
||||
{
|
||||
Pair.create(MinecraftVersion.Version1_8, "http://file.mineplex.com/ResStrikeGames18.zip"),
|
||||
Pair.create(MinecraftVersion.Version1_9, "http://file.mineplex.com/ResStrikeGames19.zip")
|
||||
}, true),
|
||||
|
||||
Event(EventGame.class, GameDisplay.Event, new GameType[]{
|
||||
GameType.BaconBrawl, GameType.Barbarians, GameType.Bridge, GameType.Build, GameType.Build,
|
||||
GameType.Cards, GameType.CastleSiege, GameType.ChampionsDominate, GameType.ChampionsTDM, GameType.Christmas,
|
||||
|
@ -0,0 +1,875 @@
|
||||
package nautilus.game.arcade.game.games.battleroyale;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.WorldBorder;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Chicken;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockFadeEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.AnvilInventory;
|
||||
import org.bukkit.inventory.EnchantingInventory;
|
||||
import org.bukkit.inventory.FurnaceInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilBlock;
|
||||
import mineplex.core.common.util.UtilEvent;
|
||||
import mineplex.core.common.util.UtilEvent.ActionType;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilTextBottom;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.common.util.UtilWorld;
|
||||
import mineplex.core.itemstack.ItemBuilder;
|
||||
import mineplex.core.recharge.Recharge;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.minecraft.game.core.combat.CombatComponent;
|
||||
import mineplex.minecraft.game.core.combat.event.CombatDeathEvent;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
import nautilus.game.arcade.ArcadeManager;
|
||||
import nautilus.game.arcade.GameType;
|
||||
import nautilus.game.arcade.events.GameStateChangeEvent;
|
||||
import nautilus.game.arcade.game.Game;
|
||||
import nautilus.game.arcade.game.games.minestrike.GunModule;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.guns.GunStats;
|
||||
import nautilus.game.arcade.game.modules.StrikeGamesModule;
|
||||
import nautilus.game.arcade.game.modules.chest.ChestLootModule;
|
||||
import nautilus.game.arcade.game.modules.chest.ChestLootPool;
|
||||
import nautilus.game.arcade.game.modules.compass.CompassModule;
|
||||
import nautilus.game.arcade.kit.Kit;
|
||||
|
||||
public abstract class BattleRoyale extends Game
|
||||
{
|
||||
|
||||
private static final long PREPARE_TIME = TimeUnit.SECONDS.toMillis(30);
|
||||
private static final int MIN_CORD = 100;
|
||||
private static final int MAX_CORD = 1000;
|
||||
private static final int SPAWN_Y = 130;
|
||||
private static final int WORLD_SIZE_BUFFER = 300;
|
||||
private static final int MIN_DISTANCE_APART_FOR_SPAWNS_SQUARED = 100;
|
||||
private static final long MIN_DRAGON_TIME = TimeUnit.SECONDS.toMillis(5);
|
||||
private static final long MAX_DRAGON_TIME = TimeUnit.SECONDS.toMillis(60);
|
||||
private static final long BORDER_TIME = TimeUnit.MINUTES.toSeconds(20);
|
||||
protected static final long SUPPLY_DROP_TIME = TimeUnit.MINUTES.toMillis(5);
|
||||
private static final int MAX_DROPS_PER_GAME = 3;
|
||||
|
||||
private static final ItemStack SMALL_BACKPACK = new ItemBuilder(Material.CHEST)
|
||||
.setTitle(C.cGreen + "Small Backpack")
|
||||
.addLore("Clicking this will unlock a new row in your inventory!")
|
||||
.build();
|
||||
private static final ItemStack LARGE_BACKPACK = new ItemBuilder(Material.ENDER_CHEST)
|
||||
.setTitle(C.cGreen + "Large Backpack")
|
||||
.addLore("Clicking this will unlock two new rows in your inventory!")
|
||||
.build();
|
||||
|
||||
private static final ItemStack SMALL_HEALTH_POT = new ItemBuilder(Material.POTION)
|
||||
.setTitle(C.cGreen + "Small Health Pot")
|
||||
.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 0))
|
||||
.build();
|
||||
|
||||
private static final ItemStack LARGE_HEALTH_POT = new ItemBuilder(Material.POTION)
|
||||
.setTitle(C.cGreen + "Large Health Pot")
|
||||
.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 1))
|
||||
.build();
|
||||
|
||||
protected final Map<Player, BattleRoyalePlayer> _playerData = new HashMap<>(70);
|
||||
|
||||
protected GunModule _gunModule;
|
||||
|
||||
protected WorldBorder _border;
|
||||
private boolean _colouredMessage;
|
||||
|
||||
protected BattleRoyaleSupplyDrop _supplyDrop;
|
||||
protected long _lastSupplyDrop;
|
||||
private int _totalDrops;
|
||||
|
||||
public BattleRoyale(ArcadeManager manager, GameType gameType, Kit[] kits, String[] gameDesc)
|
||||
{
|
||||
super(manager, gameType, kits, gameDesc);
|
||||
|
||||
PrepareTime = PREPARE_TIME;
|
||||
PrepareFreeze = false;
|
||||
SpawnTeleport = false;
|
||||
Damage = false;
|
||||
DamageTeamSelf = true;
|
||||
DeathDropItems = true;
|
||||
QuitDropItems = true;
|
||||
HungerSet = 20;
|
||||
DeathTeleport = false;
|
||||
WorldChunkUnload = true;
|
||||
GameTimeout = TimeUnit.MINUTES.toMillis(40);
|
||||
|
||||
ItemDrop = true;
|
||||
ItemPickup = true;
|
||||
|
||||
StrictAntiHack = true;
|
||||
InventoryClick = true;
|
||||
InventoryOpenBlock = true;
|
||||
InventoryOpenChest = true;
|
||||
|
||||
BlockBreakAllow.add(Material.GLASS.getId());
|
||||
BlockBreakAllow.add(Material.STAINED_GLASS.getId());
|
||||
BlockBreakAllow.add(Material.THIN_GLASS.getId());
|
||||
BlockBreakAllow.add(Material.STAINED_GLASS_PANE.getId());
|
||||
BlockBreakAllow.add(Material.LEAVES.getId());
|
||||
|
||||
_gunModule = new GunModule(this);
|
||||
_gunModule.EnableCleaning = false;
|
||||
_gunModule.EnableDrop = false;
|
||||
_gunModule.EnablePickup = false;
|
||||
_gunModule.BlockRegeneration = false;
|
||||
_gunModule.EnableNormalArmor = true;
|
||||
|
||||
new StrikeGamesModule(_gunModule)
|
||||
.register(this);
|
||||
|
||||
new CompassModule()
|
||||
.register(this);
|
||||
|
||||
manager.GetCreature().SetDisableCustomDrops(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ParseData()
|
||||
{
|
||||
List<Location> chestSpawns = new ArrayList<>(500);
|
||||
chestSpawns.addAll(WorldData.GetDataLocs("ORANGE"));
|
||||
chestSpawns.addAll(WorldData.GetDataLocs("GREEN"));
|
||||
chestSpawns.addAll(WorldData.GetDataLocs("YELLOW"));
|
||||
chestSpawns.addAll(WorldData.GetDataLocs("BLUE"));
|
||||
|
||||
new ChestLootModule()
|
||||
.destroyAfterOpened(20)
|
||||
.spawnNearbyDataPoints()
|
||||
.registerChestType("Standard", chestSpawns,
|
||||
|
||||
// Guns
|
||||
new ChestLootPool()
|
||||
.addItem(buildFromGun(GunStats.GLOCK_18))
|
||||
.addItem(buildFromGun(GunStats.CZ75))
|
||||
.addItem(buildFromGun(GunStats.DEAGLE))
|
||||
.addItem(buildFromGun(GunStats.P250))
|
||||
.addItem(buildFromGun(GunStats.P2000))
|
||||
.addItem(buildFromGun(GunStats.P90), 0.5)
|
||||
.addItem(buildFromGun(GunStats.PPBIZON), 0.5)
|
||||
.addItem(buildFromGun(GunStats.GALIL), 0.2)
|
||||
.addItem(buildFromGun(GunStats.FAMAS), 0.2)
|
||||
.addItem(buildFromGun(GunStats.AK47), 0.2)
|
||||
.addItem(buildFromGun(GunStats.M4A4), 0.2)
|
||||
.addItem(buildFromGun(GunStats.SG553), 0.2)
|
||||
.addItem(buildFromGun(GunStats.AUG), 0.2)
|
||||
.addItem(buildFromGun(GunStats.SSG08), 0.2)
|
||||
.addItem(buildFromGun(GunStats.NOVA), 0.2)
|
||||
.addItem(buildFromGun(GunStats.XM1014), 0.2)
|
||||
.setProbability(0.5)
|
||||
,
|
||||
|
||||
// Grenades
|
||||
new ChestLootPool()
|
||||
.addItem(buildGrenade(Material.CARROT_ITEM, "Flash Bang"))
|
||||
.addItem(buildGrenade(Material.APPLE, "High Explosive"))
|
||||
.addItem(buildGrenade(Material.POTATO_ITEM, "Smoke"))
|
||||
.addItem(buildGrenade(Material.PORK, "Incendiary"), 0.5)
|
||||
.addItem(buildGrenade(Material.GRILLED_PORK, "Molotov"), 0.5)
|
||||
.setProbability(0.2)
|
||||
,
|
||||
|
||||
// Weapons
|
||||
new ChestLootPool()
|
||||
.addItem(new ItemStack(Material.IRON_SWORD))
|
||||
.addItem(new ItemStack(Material.IRON_AXE))
|
||||
.addItem(new ItemStack(Material.BOW))
|
||||
.setProbability(0.1)
|
||||
,
|
||||
|
||||
// Ammo
|
||||
new ChestLootPool()
|
||||
.addItem(new ItemStack(Material.ARROW), 1, 8)
|
||||
.setProbability(0.2)
|
||||
.setAmountsPerChest(1, 3)
|
||||
,
|
||||
|
||||
// Medical
|
||||
new ChestLootPool()
|
||||
.addItem(SMALL_HEALTH_POT)
|
||||
.addItem(LARGE_HEALTH_POT)
|
||||
.setProbability(0.1)
|
||||
.setAmountsPerChest(1, 2)
|
||||
,
|
||||
|
||||
// Armour
|
||||
new ChestLootPool()
|
||||
.addItem(new ItemBuilder(Material.LEATHER_HELMET)
|
||||
.setTitle(C.cRed + "Red Baseball Cap")
|
||||
.setColor(Color.RED)
|
||||
.build())
|
||||
.addItem(new ItemBuilder(Material.LEATHER_HELMET)
|
||||
.setTitle(C.cAqua + "Blue Baseball Cap")
|
||||
.setColor(Color.BLUE)
|
||||
.build())
|
||||
.addItem(new ItemBuilder(Material.CHAINMAIL_HELMET)
|
||||
.setTitle(C.cDGreen + "Tactical Helmet")
|
||||
.build())
|
||||
.addItem(new ItemBuilder(Material.IRON_HELMET)
|
||||
.setTitle(C.cDGreen + "Motorcycle Helmet")
|
||||
.build())
|
||||
.addItem(new ItemBuilder(Material.LEATHER_CHESTPLATE)
|
||||
.setTitle(C.cDGreen + "Wooden Body Armour")
|
||||
.build())
|
||||
.addItem(new ItemBuilder(Material.CHAINMAIL_CHESTPLATE)
|
||||
.setTitle(C.cDGreen + "Plated Body Armour")
|
||||
.build())
|
||||
.addItem(new ItemBuilder(Material.IRON_CHESTPLATE)
|
||||
.setTitle(C.cDGreen + "Laminated Tactical Body Armour")
|
||||
.build())
|
||||
.addItem(new ItemStack(Material.LEATHER_LEGGINGS))
|
||||
.addItem(new ItemStack(Material.LEATHER_BOOTS))
|
||||
,
|
||||
|
||||
// Food
|
||||
new ChestLootPool()
|
||||
.addItem(new ItemStack(Material.MELON), 1, 3)
|
||||
.addItem(new ItemStack(Material.BREAD), 1, 2, 0.6)
|
||||
.addItem(new ItemStack(Material.COOKED_FISH), 0.5)
|
||||
.addItem(new ItemStack(Material.COOKED_BEEF), 0.5)
|
||||
.addItem(new ItemStack(Material.COOKED_CHICKEN), 0.5)
|
||||
.addItem(new ItemStack(Material.COOKED_MUTTON), 0.5)
|
||||
.addItem(new ItemStack(Material.COOKIE), 0.5)
|
||||
,
|
||||
|
||||
// Misc
|
||||
new ChestLootPool()
|
||||
.addItem(SMALL_BACKPACK, 0.5)
|
||||
.addItem(LARGE_BACKPACK, 0.2)
|
||||
.setProbability(0.2)
|
||||
)
|
||||
.registerChestType("Supply Drop", new ArrayList<>(0),
|
||||
|
||||
// Guns
|
||||
new ChestLootPool()
|
||||
.addItem(buildFromGun(GunStats.AUG))
|
||||
.addItem(buildFromGun(GunStats.AK47))
|
||||
.addItem(buildFromGun(GunStats.M4A4))
|
||||
.addItem(buildFromGun(GunStats.XM1014))
|
||||
.addItem(buildFromGun(GunStats.AWP))
|
||||
.setAmountsPerChest(1, 2)
|
||||
,
|
||||
// Backpack
|
||||
new ChestLootPool()
|
||||
.addItem(SMALL_BACKPACK)
|
||||
.addItem(LARGE_BACKPACK)
|
||||
,
|
||||
|
||||
// Armour
|
||||
new ChestLootPool()
|
||||
.addItem(new ItemBuilder(Material.IRON_HELMET)
|
||||
.setTitle(C.cDGreen + "Motorcycle Helmet")
|
||||
.build())
|
||||
.addItem(new ItemBuilder(Material.IRON_CHESTPLATE)
|
||||
.setTitle(C.cDGreen + "Laminated Tactical Body Armour")
|
||||
.build())
|
||||
,
|
||||
|
||||
// Grenades
|
||||
new ChestLootPool()
|
||||
.addItem(buildGrenade(Material.CARROT_ITEM, "Flash Bang"))
|
||||
.addItem(buildGrenade(Material.APPLE, "High Explosive"))
|
||||
.addItem(buildGrenade(Material.POTATO_ITEM, "Smoke"))
|
||||
.addItem(buildGrenade(Material.PORK, "Incendiary"), 0.5)
|
||||
.addItem(buildGrenade(Material.GRILLED_PORK, "Molotov"), 0.5)
|
||||
.setAmountsPerChest(1, 2)
|
||||
,
|
||||
|
||||
// Medical
|
||||
new ChestLootPool()
|
||||
.addItem(SMALL_HEALTH_POT)
|
||||
.addItem(LARGE_HEALTH_POT)
|
||||
.setAmountsPerChest(1, 2)
|
||||
|
||||
)
|
||||
.register(this);
|
||||
|
||||
WorldData.MinX = -MAX_CORD;
|
||||
WorldData.MinZ = -MAX_CORD;
|
||||
WorldData.MaxX = MAX_CORD;
|
||||
WorldData.MaxZ = MAX_CORD;
|
||||
|
||||
_border = WorldData.World.getWorldBorder();
|
||||
}
|
||||
|
||||
private ItemStack buildFromGun(GunStats gunStats)
|
||||
{
|
||||
return new ItemBuilder(gunStats.getSkin())
|
||||
.setTitle(C.cWhiteB + gunStats.getName())
|
||||
.build();
|
||||
}
|
||||
|
||||
private ItemStack buildGrenade(Material material, String name)
|
||||
{
|
||||
return new ItemBuilder(material)
|
||||
.setTitle(C.cDGreenB + name)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@EventHandler
|
||||
public void ScoreboardUpdate(UpdateEvent event)
|
||||
{
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void prepare(GameStateChangeEvent event)
|
||||
{
|
||||
if (event.GetState() != GameState.Prepare)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_border.setCenter(getRandomCenter());
|
||||
_border.setSize(MAX_CORD * 2);
|
||||
|
||||
List<Player> toTeleport = GetPlayers(true);
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
|
||||
Manager.runSyncTimer(new BukkitRunnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (index.get() >= toTeleport.size())
|
||||
{
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = toTeleport.get(index.get());
|
||||
|
||||
if (player == null || !player.isOnline() || UtilPlayer.isSpectator(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Location spawn = null;
|
||||
int attempts = 0;
|
||||
int initialXZ = 0;
|
||||
|
||||
while (spawn == null && attempts++ < 20)
|
||||
{
|
||||
if (attempts > 10)
|
||||
{
|
||||
initialXZ += 20;
|
||||
}
|
||||
|
||||
spawn = getPlayerSpawn(initialXZ);
|
||||
}
|
||||
|
||||
// Couldn't create a spawn, this should never happen and is pretty much impossible
|
||||
if (spawn == null)
|
||||
{
|
||||
cancel();
|
||||
SetState(GameState.Dead);
|
||||
return;
|
||||
}
|
||||
|
||||
Location goal = spawn.clone();
|
||||
|
||||
goal.setX(-spawn.getX());
|
||||
goal.setZ(-spawn.getZ());
|
||||
|
||||
BattleRoyalePlayer royalePlayer = new BattleRoyalePlayer(Manager, player, spawn, goal);
|
||||
_playerData.put(player, royalePlayer);
|
||||
|
||||
index.getAndIncrement();
|
||||
}
|
||||
}, 40, 2);
|
||||
}
|
||||
|
||||
private Location getPlayerSpawn(int initialXZ)
|
||||
{
|
||||
// Calculate where a player should spawn
|
||||
int max = MAX_CORD - WORLD_SIZE_BUFFER;
|
||||
int x = initialXZ;
|
||||
int z = initialXZ;
|
||||
boolean varyX = UtilMath.random.nextBoolean();
|
||||
boolean sign = UtilMath.random.nextBoolean();
|
||||
|
||||
if (varyX)
|
||||
{
|
||||
x += UtilMath.rRange(-max, max);
|
||||
z += sign ? max : -max;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += sign ? max : -max;
|
||||
z += UtilMath.rRange(-max, max);
|
||||
}
|
||||
|
||||
Location location = new Location(WorldData.World, x, SPAWN_Y, z);
|
||||
|
||||
// Check to make sure no players are nearby
|
||||
for (BattleRoyalePlayer other : _playerData.values())
|
||||
{
|
||||
if (UtilMath.offsetSquared(location, other.getLocation()) < MIN_DISTANCE_APART_FOR_SPAWNS_SQUARED)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, GetSpectatorLocation())));
|
||||
return location;
|
||||
}
|
||||
|
||||
private Location getRandomCenter()
|
||||
{
|
||||
int attempts = 0;
|
||||
|
||||
while (attempts++ < 20)
|
||||
{
|
||||
Location location = UtilAlg.getRandomLocation(GetSpectatorLocation(), WORLD_SIZE_BUFFER, 0, WORLD_SIZE_BUFFER);
|
||||
Block block = location.getBlock();
|
||||
|
||||
while (!UtilBlock.solid(block))
|
||||
{
|
||||
block = block.getRelative(BlockFace.DOWN);
|
||||
}
|
||||
|
||||
if (block.isLiquid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
return SpectatorSpawn;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void live(GameStateChangeEvent event)
|
||||
{
|
||||
if (event.GetState() != GameState.Live)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_lastSupplyDrop = System.currentTimeMillis();
|
||||
|
||||
CreatureAllowOverride = true;
|
||||
|
||||
ItemStack locked = new ItemBuilder(Material.STAINED_GLASS_PANE, (byte) 15)
|
||||
.setTitle(C.cGray + "Locked")
|
||||
.build();
|
||||
|
||||
_playerData.forEach((player, battleRoyalePlayer) ->
|
||||
{
|
||||
battleRoyalePlayer.removeCage();
|
||||
battleRoyalePlayer.spawnDragon();
|
||||
|
||||
for (int i = 18; i < player.getInventory().getSize(); i++)
|
||||
{
|
||||
player.getInventory().setItem(i, locked);
|
||||
}
|
||||
});
|
||||
|
||||
CreatureAllowOverride = false;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void updateDragons(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.FAST || !IsLive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_colouredMessage = !_colouredMessage;
|
||||
|
||||
Iterator<Player> iterator = _playerData.keySet().iterator();
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Player player = iterator.next();
|
||||
BattleRoyalePlayer royalePlayer = _playerData.get(player);
|
||||
|
||||
if (royalePlayer == null || !player.isOnline())
|
||||
{
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
EnderDragon dragon = royalePlayer.getDragon();
|
||||
Chicken chicken = royalePlayer.getChicken();
|
||||
|
||||
if (dragon == null || !dragon.isValid() || chicken == null || !chicken.isValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UtilTextBottom.display((_colouredMessage ? C.cGreenB : C.cWhiteB) + "PRESS YOUR SNEAK KEY TO DISMOUNT YOUR DRAGON", player);
|
||||
if (dragon.getPassenger() == null || chicken.getPassenger() == null)
|
||||
{
|
||||
if (!UtilTime.elapsed(GetStateTime(), MIN_DRAGON_TIME))
|
||||
{
|
||||
player.sendMessage(F.main("Game", "Did you accidentally press sneak? It's too soon to jump! Don't worry I'll put you back on your dragon."));
|
||||
dragon.setPassenger(chicken);
|
||||
chicken.setPassenger(player);
|
||||
continue;
|
||||
}
|
||||
|
||||
dismountDragon(player, royalePlayer);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Damage && UtilTime.elapsed(GetStateTime(), MAX_DRAGON_TIME))
|
||||
{
|
||||
_playerData.forEach(this::dismountDragon);
|
||||
|
||||
Announce(C.cRedB + "Grace Period Over!", false);
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
player.playSound(player.getLocation(), Sound.ENDERDRAGON_GROWL, 1, 1);
|
||||
}
|
||||
|
||||
Damage = true;
|
||||
HungerSet = -1;
|
||||
_border.setSize(MIN_CORD, BORDER_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
private void dismountDragon(Player player, BattleRoyalePlayer royalePlayer)
|
||||
{
|
||||
if (!royalePlayer.getDragon().isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Recharge this so that players won't take fall damage for the next 10 seconds
|
||||
Recharge.Instance.useForce(player, "Fall Damage", TimeUnit.SECONDS.toMillis(10));
|
||||
player.playSound(player.getLocation(), Sound.BLAZE_DEATH, 1, 0.6F);
|
||||
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, player.getLocation(), 5, 5, 5, 0.01F, 100, ViewDist.NORMAL);
|
||||
royalePlayer.getDragon().remove();
|
||||
royalePlayer.getChicken().remove();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void fallDamage(CustomDamageEvent event)
|
||||
{
|
||||
Player player = event.GetDamageePlayer();
|
||||
|
||||
if (player == null || event.GetCause() != DamageCause.FALL || Recharge.Instance.usable(player, "Fall Damage"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event.SetCancelled("Dragon Fall");
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void preventDragonExplosion(EntityExplodeEvent event)
|
||||
{
|
||||
if (event.getEntity() instanceof EnderDragon)
|
||||
{
|
||||
event.blockList().clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable()
|
||||
{
|
||||
super.disable();
|
||||
|
||||
_playerData.clear();
|
||||
if (_supplyDrop != null)
|
||||
{
|
||||
_supplyDrop.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void updateSupplyDrop(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.FAST || !IsLive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_totalDrops < MAX_DROPS_PER_GAME && UtilTime.elapsed(_lastSupplyDrop, SUPPLY_DROP_TIME))
|
||||
{
|
||||
_lastSupplyDrop = System.currentTimeMillis();
|
||||
|
||||
List<Location> locations = WorldData.GetDataLocs("RED");
|
||||
Location location = null;
|
||||
int attempts = 0;
|
||||
|
||||
while (location == null || attempts++ < 20)
|
||||
{
|
||||
location = UtilAlg.Random(locations);
|
||||
|
||||
if (UtilWorld.inWorldBorder(location))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_supplyDrop = new BattleRoyaleSupplyDrop(this, location);
|
||||
_totalDrops++;
|
||||
Announce(C.cGoldB + "A New Supply Drop Will Spawn At " + C.cYellow + UtilWorld.locToStrClean(_supplyDrop.getDropLocation()) + C.cGold + "!");
|
||||
}
|
||||
else if (_supplyDrop != null && _supplyDrop.isOpened())
|
||||
{
|
||||
_supplyDrop = null;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerDeath(CombatDeathEvent event)
|
||||
{
|
||||
Player player = (Player) event.GetEvent().getEntity();
|
||||
CombatComponent killer = event.GetLog().GetKiller();
|
||||
|
||||
if (killer.IsPlayer())
|
||||
{
|
||||
Player killerPlayer = UtilPlayer.searchExact(killer.getUniqueIdOfEntity());
|
||||
|
||||
if (killerPlayer != null)
|
||||
{
|
||||
BattleRoyalePlayer royalePlayer = _playerData.get(killerPlayer);
|
||||
|
||||
if (royalePlayer != null)
|
||||
{
|
||||
royalePlayer.incrementKills();
|
||||
UtilTextBottom.display(C.cRedB + royalePlayer.getKills() + " Kill" + (royalePlayer.getKills() == 1 ? "" : "s"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<CombatComponent> attackers = event.GetLog().GetAttackers();
|
||||
|
||||
for (CombatComponent attacker : attackers)
|
||||
{
|
||||
if (!attacker.IsPlayer() || killer.equals(attacker))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Player attackerPlayer = UtilPlayer.searchExact(attacker.getUniqueIdOfEntity());
|
||||
|
||||
if (attackerPlayer == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
BattleRoyalePlayer royalePlayer = _playerData.get(attackerPlayer);
|
||||
|
||||
if (royalePlayer != null)
|
||||
{
|
||||
attackerPlayer.sendMessage(F.main("Game", "You assisted in killing " + F.name(player.getName()) + "."));
|
||||
royalePlayer.incrementAssists();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void preventLockedInventoryClick(InventoryClickEvent event)
|
||||
{
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
ItemStack itemStack = event.getCurrentItem();
|
||||
|
||||
if (event.getClickedInventory() == null || itemStack == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (itemStack.getType() == Material.STAINED_GLASS_PANE)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0.6F);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void clickBackpack(PlayerInteractEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
ItemStack itemStack = event.getItem();
|
||||
|
||||
if (itemStack == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!UtilEvent.isAction(event, ActionType.R))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int slots = 0;
|
||||
|
||||
if (itemStack.isSimilar(SMALL_BACKPACK))
|
||||
{
|
||||
slots = 9;
|
||||
}
|
||||
else if (itemStack.isSimilar(LARGE_BACKPACK))
|
||||
{
|
||||
slots = 18;
|
||||
}
|
||||
|
||||
if (slots == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack[] items = player.getInventory().getContents();
|
||||
int removed = 0;
|
||||
|
||||
for (int i = 0; i < items.length && removed < slots; i++)
|
||||
{
|
||||
ItemStack inventoryItem = items[i];
|
||||
|
||||
if (inventoryItem != null && inventoryItem.getType() == Material.STAINED_GLASS_PANE)
|
||||
{
|
||||
player.getInventory().setItem(i, null);
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemStack.getAmount() > 1)
|
||||
{
|
||||
itemStack.setAmount(itemStack.getAmount() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.getInventory().setItemInHand(null);
|
||||
}
|
||||
player.updateInventory();
|
||||
player.playSound(player.getLocation(), Sound.LEVEL_UP, 1, 1);
|
||||
player.sendMessage(F.main("Game", "You unlocked an additional " + F.elem(removed) + " slots in your inventory."));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void noHungerRegeneration(EntityRegainHealthEvent event)
|
||||
{
|
||||
if (event.getRegainReason() == RegainReason.SATIATED)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void inventoryOpen(InventoryOpenEvent event)
|
||||
{
|
||||
Inventory inventory = event.getInventory();
|
||||
|
||||
if (inventory instanceof EnchantingInventory || inventory instanceof AnvilInventory || inventory instanceof FurnaceInventory)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void damageToLevel(CustomDamageEvent event)
|
||||
{
|
||||
event.SetDamageToLevel(false);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerQuit(PlayerQuitEvent event)
|
||||
{
|
||||
_playerData.remove(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void removeEmptyPotions(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.FAST)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Player player : GetPlayers(true))
|
||||
{
|
||||
player.getInventory().remove(Material.GLASS_BOTTLE);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerDeath(PlayerDeathEvent event)
|
||||
{
|
||||
if (!IsLive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event.getDrops().removeIf(itemStack -> itemStack.getType() == Material.STAINED_GLASS_PANE);
|
||||
|
||||
Player player = event.getEntity();
|
||||
awardTimeGems(player);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onIceMelt(BlockFadeEvent event)
|
||||
{
|
||||
if (!event.getBlock().getWorld().equals(WorldData.World))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (event.getBlock().getType() == Material.ICE)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected void awardTimeGems(Player player)
|
||||
{
|
||||
long timeAlive = Math.min(System.currentTimeMillis() - GetStateTime(), TimeUnit.MINUTES.toMillis(30));
|
||||
|
||||
// i.e 1 gem per 10 seconds alive
|
||||
AddGems(player, timeAlive / TimeUnit.SECONDS.toMillis(10), "Surviving " + UtilTime.MakeStr(timeAlive), false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double GetKillsGems(Player killer, Player killed, boolean assist)
|
||||
{
|
||||
if (assist)
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
|
||||
return _border.getSize() == MIN_CORD ? 200 : 100;
|
||||
}
|
||||
}
|
@ -0,0 +1,153 @@
|
||||
package nautilus.game.arcade.game.games.battleroyale;
|
||||
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.MapUtil;
|
||||
import mineplex.core.common.util.UtilColor;
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import nautilus.game.arcade.ArcadeManager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEnderDragon;
|
||||
import org.bukkit.entity.Chicken;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
class BattleRoyalePlayer
|
||||
{
|
||||
|
||||
private final Player _player;
|
||||
private final Location _location;
|
||||
private final Location _goal;
|
||||
private final Set<Location> _cageBlocks;
|
||||
private EnderDragon _dragon;
|
||||
private Chicken _chicken;
|
||||
private int _kills;
|
||||
private int _assists;
|
||||
|
||||
BattleRoyalePlayer(ArcadeManager manager, Player player, Location location, Location goal)
|
||||
{
|
||||
_player = player;
|
||||
_location = location;
|
||||
_goal = goal;
|
||||
_cageBlocks = new HashSet<>();
|
||||
|
||||
// Colour the cage based on the player's rank
|
||||
Rank rank = manager.GetClients().Get(player).GetRank();
|
||||
byte data = UtilColor.chatColorToWoolData(rank.getColor());
|
||||
|
||||
// Build the cage
|
||||
buildCage(data);
|
||||
// Teleport the player to the cage
|
||||
player.teleport(_location.add(0, 1, 0));
|
||||
}
|
||||
|
||||
private void buildCage(byte colourData)
|
||||
{
|
||||
// Floor
|
||||
for (int x = -2; x <= 2; x++)
|
||||
{
|
||||
for (int z = -2; z <= 2; z++)
|
||||
{
|
||||
_location.add(x, -1, z);
|
||||
MapUtil.QuickChangeBlockAt(_location, Material.STAINED_GLASS, colourData);
|
||||
_cageBlocks.add(_location.clone());
|
||||
_location.subtract(x, -1, z);
|
||||
}
|
||||
}
|
||||
|
||||
// Roof
|
||||
for (int x = -2; x <= 2; x++)
|
||||
{
|
||||
for (int z = -2; z <= 2; z++)
|
||||
{
|
||||
_location.add(x, 4, z);
|
||||
MapUtil.QuickChangeBlockAt(_location, Material.STAINED_GLASS, colourData);
|
||||
_cageBlocks.add(_location.clone());
|
||||
_location.subtract(x, 4, z);
|
||||
}
|
||||
}
|
||||
|
||||
// Walls
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
for (int x = -2; x <= 2; x++)
|
||||
{
|
||||
for (int z = -2; z <= 2; z++)
|
||||
{
|
||||
if (x != -2 && x != 2 && z != -2 && z != 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_location.add(x, y, z);
|
||||
MapUtil.QuickChangeBlockAt(_location, Material.STAINED_GLASS, colourData);
|
||||
_cageBlocks.add(_location.clone());
|
||||
_location.subtract(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeCage()
|
||||
{
|
||||
for (Location location : _cageBlocks)
|
||||
{
|
||||
MapUtil.QuickChangeBlockAt(location, Material.AIR);
|
||||
}
|
||||
}
|
||||
|
||||
public void spawnDragon()
|
||||
{
|
||||
_dragon = _location.getWorld().spawn(_location, EnderDragon.class);
|
||||
UtilEnt.vegetate(_dragon);
|
||||
UtilEnt.ghost(_dragon, true, false);
|
||||
|
||||
_chicken = _location.getWorld().spawn(_location, Chicken.class);
|
||||
_chicken.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 0, false, false));
|
||||
|
||||
_dragon.setPassenger(_chicken);
|
||||
_chicken.setPassenger(_player);
|
||||
|
||||
((CraftEnderDragon) _dragon).getHandle().setTargetBlock(_goal.getBlockX(), _goal.getBlockY(), _goal.getBlockZ());
|
||||
}
|
||||
|
||||
public Location getLocation()
|
||||
{
|
||||
return _location;
|
||||
}
|
||||
|
||||
public EnderDragon getDragon()
|
||||
{
|
||||
return _dragon;
|
||||
}
|
||||
|
||||
public Chicken getChicken()
|
||||
{
|
||||
return _chicken;
|
||||
}
|
||||
|
||||
public void incrementKills()
|
||||
{
|
||||
_kills++;
|
||||
}
|
||||
|
||||
public int getKills()
|
||||
{
|
||||
return _kills;
|
||||
}
|
||||
|
||||
public void incrementAssists()
|
||||
{
|
||||
_assists++;
|
||||
}
|
||||
|
||||
public int getAssists()
|
||||
{
|
||||
return _assists;
|
||||
}
|
||||
}
|
@ -0,0 +1,299 @@
|
||||
package nautilus.game.arcade.game.games.battleroyale;
|
||||
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.common.util.UtilWorld;
|
||||
import mineplex.core.treasure.TreasureType;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import nautilus.game.arcade.ArcadeManager;
|
||||
import nautilus.game.arcade.GameType;
|
||||
import nautilus.game.arcade.events.GameStateChangeEvent;
|
||||
import nautilus.game.arcade.game.GameTeam;
|
||||
import nautilus.game.arcade.game.games.moba.kit.KitPlayer;
|
||||
import nautilus.game.arcade.game.modules.CustomScoreboardModule;
|
||||
import nautilus.game.arcade.kit.Kit;
|
||||
import nautilus.game.arcade.scoreboard.GameScoreboard;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class BattleRoyaleSolo extends BattleRoyale
|
||||
{
|
||||
|
||||
private static final String[] DESCRIPTION = {
|
||||
"Battle Royale!"
|
||||
};
|
||||
|
||||
private GameTeam _players;
|
||||
|
||||
// Scoreboard data
|
||||
private final String _playersAliveTitle = C.cYellowB + "Players";
|
||||
private String _playersAlive;
|
||||
private final String _statsTitle = C.cYellowB + "Stats";
|
||||
private String _supplyDropTitle = C.cGoldB + "Supply Drop";
|
||||
private String _supplyDropLocation;
|
||||
private String _supplyDropState;
|
||||
private final String _borderTitle = C.cRedB + "World Border";
|
||||
private String _borderCenter;
|
||||
private String _borderSize;
|
||||
private boolean _showBorderCenter;
|
||||
|
||||
public BattleRoyaleSolo(ArcadeManager manager)
|
||||
{
|
||||
super(manager, GameType.BattleRoyale, new Kit[]{new KitPlayer(manager)}, DESCRIPTION);
|
||||
|
||||
new CustomScoreboardModule()
|
||||
.setSidebar((player, scoreboard) ->
|
||||
{
|
||||
switch (GetState())
|
||||
{
|
||||
case Prepare:
|
||||
writePrepare(player, scoreboard);
|
||||
break;
|
||||
case Live:
|
||||
writeLive(player, scoreboard);
|
||||
break;
|
||||
}
|
||||
})
|
||||
.setPrefix((perspective, subject) ->
|
||||
{
|
||||
if (!IsAlive(subject))
|
||||
{
|
||||
return C.cGray;
|
||||
}
|
||||
|
||||
return perspective.equals(subject) ? C.cGreen : C.cRed;
|
||||
})
|
||||
.register(this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void customTeamGeneration(GameStateChangeEvent event)
|
||||
{
|
||||
if (event.GetState() != GameState.Recruit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_players = GetTeamList().get(0);
|
||||
_players.SetColor(ChatColor.YELLOW);
|
||||
_players.SetName("Players");
|
||||
}
|
||||
|
||||
// LOW so that this is run before the scoreboards are updated
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void scoreboardDataUpdate(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.FAST || _border == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Due to many players being in this game and the fact that the scoreboard module scales O(n^2)
|
||||
// we can optimise this by storing global variables that all players would see on their scoreboard
|
||||
// regardless of their state.
|
||||
_playersAlive = GetPlayers(true).size() + " Alive";
|
||||
|
||||
if (_supplyDrop != null)
|
||||
{
|
||||
Location location = _supplyDrop.getDropLocation();
|
||||
_supplyDropLocation = "(" + location.getBlockX() + ", " + location.getBlockZ() + ")";
|
||||
_supplyDropState = _supplyDrop.getScoreboardString();
|
||||
}
|
||||
else
|
||||
{
|
||||
_supplyDropLocation = "";
|
||||
_supplyDropState = UtilTime.MakeStr(_lastSupplyDrop + BattleRoyale.SUPPLY_DROP_TIME - System.currentTimeMillis());
|
||||
}
|
||||
|
||||
int size = (int) _border.getSize();
|
||||
Location center = _border.getCenter();
|
||||
|
||||
if (size < 1000 && !_showBorderCenter)
|
||||
{
|
||||
_showBorderCenter = true;
|
||||
Announce(C.cRedB + "The Center Of The Border Is Now Visible!");
|
||||
}
|
||||
|
||||
if (_showBorderCenter)
|
||||
{
|
||||
_borderCenter = "(" + center.getBlockX() + ", " + center.getBlockZ() + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
_borderCenter = "Center Unknown";
|
||||
}
|
||||
|
||||
_borderSize = size + " Blocks Wide";
|
||||
}
|
||||
|
||||
public void writePrepare(Player player, GameScoreboard scoreboard)
|
||||
{
|
||||
scoreboard.writeNewLine();
|
||||
|
||||
scoreboard.write(_playersAliveTitle);
|
||||
scoreboard.write(_playersAlive);
|
||||
|
||||
scoreboard.writeNewLine();
|
||||
}
|
||||
|
||||
public void writeLive(Player player, GameScoreboard scoreboard)
|
||||
{
|
||||
BattleRoyalePlayer royalePlayer = _playerData.get(player);
|
||||
|
||||
scoreboard.writeNewLine();
|
||||
|
||||
scoreboard.write(_playersAliveTitle);
|
||||
scoreboard.write(_playersAlive);
|
||||
|
||||
scoreboard.writeNewLine();
|
||||
|
||||
if (royalePlayer != null)
|
||||
{
|
||||
scoreboard.write(_statsTitle);
|
||||
scoreboard.write("Kills: " + C.cGreen + royalePlayer.getKills());
|
||||
scoreboard.write("Assists: " + C.cGreen + royalePlayer.getAssists());
|
||||
|
||||
scoreboard.writeNewLine();
|
||||
}
|
||||
|
||||
scoreboard.write(_supplyDropTitle);
|
||||
if (_supplyDrop != null)
|
||||
{
|
||||
scoreboard.write(_supplyDropLocation);
|
||||
}
|
||||
if (_supplyDropState != null)
|
||||
{
|
||||
scoreboard.write(_supplyDropState);
|
||||
}
|
||||
else if (_supplyDrop != null && IsAlive(player))
|
||||
{
|
||||
int dist = (int) UtilMath.offset2d(_supplyDrop.getDropLocation(), player.getLocation());
|
||||
|
||||
scoreboard.write(dist + " Blocks Away");
|
||||
}
|
||||
|
||||
scoreboard.writeNewLine();
|
||||
|
||||
scoreboard.write(_borderTitle);
|
||||
scoreboard.write(_borderCenter);
|
||||
scoreboard.write(_borderSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void EndCheck()
|
||||
{
|
||||
if (!IsLive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Player> alive = GetPlayers(true);
|
||||
|
||||
if (alive.size() <= 1)
|
||||
{
|
||||
alive.forEach(this::awardTimeGems);
|
||||
|
||||
List<Player> places = _players.GetPlacements(true);
|
||||
|
||||
AnnounceEnd(places);
|
||||
|
||||
if (places.size() >= 1)
|
||||
{
|
||||
Player player = places.get(0);
|
||||
long wins = Manager.GetStatsManager().Get(player).getStat("Battle Royale.Wins");
|
||||
|
||||
if (wins > 1)
|
||||
{
|
||||
Manager.getInventoryManager().addItemToInventory(success ->
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
player.sendMessage(F.main("Game", "Unlocked 1 " + C.cAqua + "Mythical Chest" + C.mBody + "."));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(F.main("Game", "Failed to give you your Mythical Chest, you should inform a staff member!"));
|
||||
}
|
||||
|
||||
}, player, TreasureType.MYTHICAL.getItemName(), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Manager.getInventoryManager().addItemToInventory(success ->
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
player.sendMessage(F.main("Game", "Unlocked 1 " + C.cRed + "Freedom Chest" + C.mBody + "."));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(F.main("Game", "Failed to give you your Freedom Chest, you should inform a staff member!"));
|
||||
}
|
||||
|
||||
}, player, TreasureType.FREEDOM.getItemName(), 1);
|
||||
}
|
||||
|
||||
AddGems(places.get(0), 20, "1st Place", false, false);
|
||||
}
|
||||
if (places.size() >= 2)
|
||||
{
|
||||
AddGems(places.get(1), 15, "2nd Place", false, false);
|
||||
}
|
||||
if (places.size() >= 3)
|
||||
{
|
||||
AddGems(places.get(2), 10, "3rd Place", false, false);
|
||||
}
|
||||
|
||||
_border.setSize(10000);
|
||||
SetState(GameState.End);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Player> getWinners()
|
||||
{
|
||||
if (GetState().ordinal() >= GameState.End.ordinal())
|
||||
{
|
||||
List<Player> places = _players.GetPlacements(true);
|
||||
|
||||
if (places.isEmpty() || !places.get(0).isOnline())
|
||||
{
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Collections.singletonList(places.get(0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Player> getLosers()
|
||||
{
|
||||
List<Player> winners = getWinners();
|
||||
|
||||
if (winners == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Player> losers = _players.GetPlayers(false);
|
||||
losers.removeAll(winners);
|
||||
|
||||
return losers;
|
||||
}
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
package nautilus.game.arcade.game.games.battleroyale;
|
||||
|
||||
import mineplex.core.common.Pair;
|
||||
import mineplex.core.common.util.MapUtil;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilBlock;
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import mineplex.core.common.util.UtilFirework;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import nautilus.game.arcade.game.modules.chest.ChestLootModule;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.FireworkEffect;
|
||||
import org.bukkit.FireworkEffect.Type;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Chicken;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
class BattleRoyaleSupplyDrop implements Listener
|
||||
{
|
||||
|
||||
private static final int DRAGON_Y = 120;
|
||||
private static long DROP_WAIT = TimeUnit.MINUTES.toMillis(2);
|
||||
private static final ItemStack CHEST = new ItemStack(Material.CHEST);
|
||||
private static final FireworkEffect FIREWORK_EFFECT = FireworkEffect.builder()
|
||||
.with(Type.BALL_LARGE)
|
||||
.withColor(Color.YELLOW)
|
||||
.withFlicker()
|
||||
.build();
|
||||
|
||||
private final BattleRoyale _host;
|
||||
private final long _start;
|
||||
private final Set<Block> _beaconBlocks;
|
||||
|
||||
private Location _dropLocation;
|
||||
|
||||
private ArmorStand _chest;
|
||||
private Chicken _seat;
|
||||
private final List<Chicken> _chute;
|
||||
|
||||
private boolean _dropped;
|
||||
private boolean _opened;
|
||||
private boolean _landed;
|
||||
|
||||
BattleRoyaleSupplyDrop(BattleRoyale host, Location dropLocation)
|
||||
{
|
||||
_host = host;
|
||||
_dropLocation = dropLocation.clone();
|
||||
_start = System.currentTimeMillis();
|
||||
_beaconBlocks = new HashSet<>();
|
||||
_chute = new ArrayList<>();
|
||||
|
||||
// Construct a beacon
|
||||
for (Pair<Location, Pair<Material, Byte>> pair : UtilBlock.getBeaconBlocks(_dropLocation, (byte) 0))
|
||||
{
|
||||
// Look it's like a maze
|
||||
_beaconBlocks.add(pair.getLeft().getBlock());
|
||||
host.getArcadeManager().GetBlockRestore().add(pair.getLeft().getBlock(), pair.getRight().getLeft().getId(), pair.getRight().getRight(), Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
_dropLocation.setY(DRAGON_Y);
|
||||
|
||||
UtilServer.RegisterEvents(this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void updateDrop(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.FAST)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (UtilTime.elapsed(_start, DROP_WAIT) && !_dropped)
|
||||
{
|
||||
_dropped = true;
|
||||
_host.CreatureAllowOverride = true;
|
||||
|
||||
UtilFirework.playFirework(_dropLocation, FIREWORK_EFFECT);
|
||||
_chest = _dropLocation.getWorld().spawn(_dropLocation, ArmorStand.class);
|
||||
_chest.setGravity(false);
|
||||
_chest.setVisible(false);
|
||||
_chest.setHelmet(CHEST);
|
||||
|
||||
_seat = _dropLocation.getWorld().spawn(_dropLocation, Chicken.class);
|
||||
UtilEnt.vegetate(_seat);
|
||||
UtilEnt.ghost(_seat, true, true);
|
||||
UtilEnt.silence(_seat, true);
|
||||
_seat.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 0, false, false));
|
||||
_seat.setPassenger(_chest);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Chicken chicken = _dropLocation.getWorld().spawn(UtilAlg.getRandomLocation(_dropLocation, 2, 0.5, 2).add(0, 5, 0), Chicken.class);
|
||||
UtilEnt.vegetate(chicken);
|
||||
UtilEnt.ghost(chicken, true, false);
|
||||
chicken.setLeashHolder(_seat);
|
||||
_chute.add(chicken);
|
||||
}
|
||||
|
||||
_host.CreatureAllowOverride = false;
|
||||
}
|
||||
else if (_dropped && !_landed && UtilEnt.isGrounded(_seat))
|
||||
{
|
||||
_landed = true;
|
||||
|
||||
Location chest = _seat.getLocation();
|
||||
UtilFirework.playFirework(chest, FIREWORK_EFFECT);
|
||||
MapUtil.QuickChangeBlockAt(chest, Material.CHEST);
|
||||
_dropLocation = chest;
|
||||
|
||||
ChestLootModule lootModule = _host.getModule(ChestLootModule.class);
|
||||
lootModule.addChestLocation("Supply Drop", chest);
|
||||
|
||||
_beaconBlocks.forEach(block -> _host.getArcadeManager().GetBlockRestore().restore(block));
|
||||
|
||||
_chest.remove();
|
||||
_seat.remove();
|
||||
_chute.forEach(Chicken::remove);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void playerInteract(PlayerInteractEvent event)
|
||||
{
|
||||
if (event.isCancelled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Block block = event.getClickedBlock();
|
||||
|
||||
if (block == null || block.getType() != Material.CHEST)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (UtilMath.offsetSquared(block.getLocation(), _dropLocation) < 4)
|
||||
{
|
||||
_opened = true;
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanup()
|
||||
{
|
||||
_chute.clear();
|
||||
UtilServer.Unregister(this);
|
||||
}
|
||||
|
||||
public Location getDropLocation()
|
||||
{
|
||||
return _dropLocation;
|
||||
}
|
||||
|
||||
public boolean isOpened()
|
||||
{
|
||||
return _opened;
|
||||
}
|
||||
|
||||
public String getScoreboardString()
|
||||
{
|
||||
return _dropped ? null : UtilTime.MakeStr(_start + DROP_WAIT - System.currentTimeMillis());
|
||||
}
|
||||
}
|
@ -832,14 +832,6 @@ public class Bridge extends TeamGame implements OreObsfucation
|
||||
if (!_bridgesDown)
|
||||
{
|
||||
_bridgesDown = true;
|
||||
|
||||
// WorldBorderModule borderModule = getModule(WorldBorderModule.class);
|
||||
//
|
||||
// for (Player player : GetPlayers(true))
|
||||
// {
|
||||
// borderModule.setSize(player, 10000);
|
||||
// }
|
||||
|
||||
Manager.GetExplosion().SetLiquidDamage(true);
|
||||
Announce(C.cRedB + "ALERT: " + C.Reset + C.Bold + "THE BRIDGES ARE SPAWNING!");
|
||||
UtilTextMiddle.display(C.cRedB + "ALERT", "The BRIDGES ARE SPAWNING!");
|
||||
|
@ -1,31 +1,5 @@
|
||||
package nautilus.game.arcade.game.games.survivalgames.modes;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.enchantment.EnchantItemEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemConsumeEvent;
|
||||
import org.bukkit.event.player.PlayerItemDamageEvent;
|
||||
import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSneakEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilEvent;
|
||||
import mineplex.core.common.util.UtilEvent.ActionType;
|
||||
@ -36,29 +10,28 @@ import mineplex.core.itemstack.ItemStackFactory;
|
||||
import mineplex.core.loot.RandomItem;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
import nautilus.game.arcade.ArcadeManager;
|
||||
import nautilus.game.arcade.GameType;
|
||||
import nautilus.game.arcade.events.GameStateChangeEvent;
|
||||
import nautilus.game.arcade.events.PlayerKitGiveEvent;
|
||||
import nautilus.game.arcade.game.GameTeam;
|
||||
import nautilus.game.arcade.game.games.minestrike.GunModule;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.StrikeItemType;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.FlashBang;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.Grenade;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.HighExplosive;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.Incendiary;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.Molotov;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.Smoke;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.guns.Gun;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.guns.GunStats;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.guns.GunType;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.guns.Shotgun;
|
||||
import nautilus.game.arcade.game.games.survivalgames.SoloSurvivalGames;
|
||||
import nautilus.game.arcade.game.games.survivalgames.SupplyChestOpenEvent;
|
||||
import nautilus.game.arcade.game.games.survivalgames.kit.KitLooter;
|
||||
import nautilus.game.arcade.game.games.survivalgames.modes.kit.KitPlayer;
|
||||
import nautilus.game.arcade.game.modules.StrikeGamesModule;
|
||||
import nautilus.game.arcade.kit.Kit;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
/**
|
||||
* StrikeGames
|
||||
@ -68,12 +41,8 @@ import nautilus.game.arcade.kit.Kit;
|
||||
public class StrikeGames extends SoloSurvivalGames
|
||||
{
|
||||
|
||||
private GunModule _gunModule;
|
||||
|
||||
private long _peacePhase;
|
||||
private boolean _peace = false;
|
||||
|
||||
private HashMap<Player, ItemStack> _helmets;
|
||||
|
||||
public StrikeGames(ArcadeManager manager)
|
||||
{
|
||||
@ -83,19 +52,20 @@ public class StrikeGames extends SoloSurvivalGames
|
||||
}, GameType.StrikeGames);
|
||||
|
||||
Damage = false;
|
||||
|
||||
_helmets = new HashMap<>();
|
||||
|
||||
|
||||
_peacePhase = 20000;
|
||||
|
||||
HungerSet = 20;
|
||||
|
||||
_gunModule = new GunModule(this);
|
||||
_gunModule.EnableCleaning = false;
|
||||
_gunModule.EnableDrop = false;
|
||||
_gunModule.EnablePickup = false;
|
||||
_gunModule.BlockRegeneration = false;
|
||||
_gunModule.EnableNormalArmor = true;
|
||||
GunModule gunModule = new GunModule(this);
|
||||
gunModule.EnableCleaning = false;
|
||||
gunModule.EnableDrop = false;
|
||||
gunModule.EnablePickup = false;
|
||||
gunModule.BlockRegeneration = false;
|
||||
gunModule.EnableNormalArmor = true;
|
||||
|
||||
new StrikeGamesModule(gunModule)
|
||||
.register(this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -119,20 +89,6 @@ public class StrikeGames extends SoloSurvivalGames
|
||||
Damage = true;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void eatingGrenades(PlayerItemConsumeEvent event)
|
||||
{
|
||||
if (event.getItem().getType() == Material.POTATO_ITEM
|
||||
|| event.getItem().getType() == Material.CARROT_ITEM
|
||||
|| event.getItem().getType() == Material.APPLE
|
||||
|| event.getItem().getType() == Material.PORK
|
||||
|| event.getItem().getType() == Material.GRILLED_PORK)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void DeathmatchDamage(UpdateEvent event)
|
||||
{
|
||||
@ -163,39 +119,6 @@ public class StrikeGames extends SoloSurvivalGames
|
||||
Announce(F.main("Game", "A Peace Phase of " + F.time((_peacePhase/1000) + "") + " seconds has started!"));
|
||||
}
|
||||
|
||||
@EventHandler(priority=EventPriority.HIGHEST)
|
||||
public void addHelmet(PlayerToggleSneakEvent event)
|
||||
{
|
||||
if (!IsLive())
|
||||
return;
|
||||
|
||||
if (!IsAlive(event.getPlayer()))
|
||||
return;
|
||||
|
||||
if (_gunModule.getScoped().containsKey(event.getPlayer()))
|
||||
return;
|
||||
|
||||
if (event.getPlayer().getInventory().getHelmet() != null)
|
||||
_helmets.put(event.getPlayer(), event.getPlayer().getInventory().getHelmet());
|
||||
}
|
||||
|
||||
@EventHandler(priority=EventPriority.HIGHEST)
|
||||
public void pumpkinDrop(PlayerDeathEvent event)
|
||||
{
|
||||
Iterator<ItemStack> itemIterator = event.getDrops().iterator();
|
||||
while (itemIterator.hasNext())
|
||||
{
|
||||
ItemStack item = itemIterator.next();
|
||||
if (item.getType() == Material.PUMPKIN
|
||||
|| item.getType() == Material.PUMPKIN_STEM)
|
||||
{
|
||||
itemIterator.remove();
|
||||
}
|
||||
}
|
||||
if (_helmets.containsKey(event.getEntity()))
|
||||
event.getDrops().add(_helmets.get(event.getEntity()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void disableCrafting(PlayerInteractEvent event)
|
||||
{
|
||||
@ -205,13 +128,6 @@ public class StrikeGames extends SoloSurvivalGames
|
||||
if (event.getClickedBlock().getType() == Material.WORKBENCH)
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void weaponEnchantment(EnchantItemEvent event)
|
||||
{
|
||||
if (!UtilItem.isArmor(event.getItem()))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
public void setupLoot()
|
||||
{
|
||||
@ -414,131 +330,6 @@ public class StrikeGames extends SoloSurvivalGames
|
||||
getSupplyBlocks().remove(block);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void addEquipment(InventoryClickEvent event)
|
||||
{
|
||||
if (event.getCurrentItem() == null)
|
||||
return;
|
||||
|
||||
if (!(event.getWhoClicked() instanceof Player))
|
||||
return;
|
||||
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
|
||||
if (!(event.getClickedInventory() instanceof PlayerInventory))
|
||||
{
|
||||
ItemStack stack = event.getCurrentItem();
|
||||
for (GunStats stat : GunStats.values())
|
||||
{
|
||||
if (stat.getSkin() == stack.getType())
|
||||
{
|
||||
Gun gun = null;
|
||||
if (stat.getGunType() == GunType.SHOTGUN)
|
||||
{
|
||||
gun = new Shotgun(stat, _gunModule);
|
||||
}
|
||||
else
|
||||
{
|
||||
gun = new Gun(stat, _gunModule);
|
||||
}
|
||||
gun.setStack(stack);
|
||||
gun.updateWeaponName(player, null, false);
|
||||
gun.addID();
|
||||
_gunModule.registerGun(gun, player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Grenade grenade = null;
|
||||
|
||||
if (stack.getType() == Material.APPLE)
|
||||
{
|
||||
grenade = new HighExplosive();
|
||||
}
|
||||
else if (stack.getType() == Material.CARROT_ITEM)
|
||||
{
|
||||
grenade = new FlashBang();
|
||||
}
|
||||
else if (stack.getType() == Material.POTATO_ITEM)
|
||||
{
|
||||
grenade = new Smoke();
|
||||
}
|
||||
else if (stack.getType() == Material.PORK)
|
||||
{
|
||||
grenade = new Incendiary();
|
||||
}
|
||||
else if (stack.getType() == Material.GRILLED_PORK)
|
||||
{
|
||||
grenade = new Molotov();
|
||||
}
|
||||
|
||||
if (grenade != null)
|
||||
{
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
meta.setDisplayName(grenade.getName());
|
||||
stack.setItemMeta(meta);
|
||||
grenade.setStack(stack);
|
||||
_gunModule.registerGrenade(grenade, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void triggerPickup(PlayerPickupItemEvent event)
|
||||
{
|
||||
|
||||
if (!InProgress())
|
||||
return;
|
||||
|
||||
if (!IsAlive(event.getPlayer()))
|
||||
return;
|
||||
|
||||
//Guns
|
||||
Gun gun = _gunModule.getDroppedGuns().get(event.getItem());
|
||||
if (gun != null)
|
||||
{
|
||||
_gunModule.deregisterDroppedGun(gun);
|
||||
_gunModule.registerGun(gun, event.getPlayer());
|
||||
gun.setStack(event.getItem().getItemStack());
|
||||
}
|
||||
|
||||
//Grenades
|
||||
Grenade grenade = _gunModule.getDroppedGrenades().get(event.getItem());
|
||||
if (grenade != null)
|
||||
{
|
||||
_gunModule.deregisterDroppedGrenade(grenade);
|
||||
_gunModule.registerGrenade(grenade, event.getPlayer());
|
||||
grenade.setStack(event.getItem().getItemStack());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void triggerDrop(PlayerDropItemEvent event)
|
||||
{
|
||||
if (!InProgress())
|
||||
return;
|
||||
|
||||
//Guns
|
||||
Gun gun = _gunModule.getGunInHand(event.getPlayer(), event.getItemDrop().getItemStack());
|
||||
if (gun != null)
|
||||
{
|
||||
gun.drop(_gunModule, event.getPlayer(), false, false);
|
||||
event.getItemDrop().remove();
|
||||
event.getPlayer().setItemInHand(null);
|
||||
return;
|
||||
}
|
||||
|
||||
//Grenades
|
||||
Grenade grenade = _gunModule.getGrenadeInHand(event.getPlayer(), event.getItemDrop().getItemStack());
|
||||
if (grenade != null)
|
||||
{
|
||||
grenade.drop(_gunModule, event.getPlayer(), false, false);
|
||||
event.getItemDrop().remove();
|
||||
event.getPlayer().setItemInHand(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@Override
|
||||
public void ItemSpawn(ItemSpawnEvent event)
|
||||
|
@ -82,6 +82,7 @@ public class CustomScoreboardModule extends Module
|
||||
}
|
||||
|
||||
setupScoreboard(player);
|
||||
refreshAsSubject(player);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,220 @@
|
||||
package nautilus.game.arcade.game.modules;
|
||||
|
||||
import mineplex.core.common.util.UtilItem;
|
||||
import nautilus.game.arcade.game.games.minestrike.GunModule;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.FlashBang;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.Grenade;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.HighExplosive;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.Incendiary;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.Molotov;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.grenades.Smoke;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.guns.Gun;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.guns.GunStats;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.guns.GunType;
|
||||
import nautilus.game.arcade.game.games.minestrike.items.guns.Shotgun;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.enchantment.EnchantItemEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerItemConsumeEvent;
|
||||
import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSneakEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class StrikeGamesModule extends Module
|
||||
{
|
||||
|
||||
private final Map<Player, ItemStack> _helmets;
|
||||
private final GunModule _gunModule;
|
||||
|
||||
public StrikeGamesModule(GunModule gunModule)
|
||||
{
|
||||
_gunModule = gunModule;
|
||||
_helmets = new HashMap<>();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void eatingGrenades(PlayerItemConsumeEvent event)
|
||||
{
|
||||
Material material = event.getItem().getType();
|
||||
|
||||
switch (material)
|
||||
{
|
||||
case POTATO_ITEM:
|
||||
case CARROT_ITEM:
|
||||
case APPLE:
|
||||
case PORK:
|
||||
case GRILLED_PORK:
|
||||
event.setCancelled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void addHelmet(PlayerToggleSneakEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
ItemStack helmet = player.getInventory().getHelmet();
|
||||
|
||||
if (!getGame().IsLive() || !getGame().IsAlive(player) || _gunModule.getScoped().containsKey(player) || helmet == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_helmets.put(event.getPlayer(), helmet);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void pumpkinDrop(PlayerDeathEvent event)
|
||||
{
|
||||
Player player = event.getEntity();
|
||||
|
||||
event.getDrops().removeIf(item -> item.getType() == Material.PUMPKIN || item.getType() == Material.PUMPKIN_STEM);
|
||||
|
||||
if (_helmets.containsKey(player))
|
||||
{
|
||||
event.getDrops().add(_helmets.get(player));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void weaponEnchantment(EnchantItemEvent event)
|
||||
{
|
||||
if (!UtilItem.isArmor(event.getItem()))
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void addEquipment(InventoryClickEvent event)
|
||||
{
|
||||
if (event.getCurrentItem() == null || !(event.getWhoClicked() instanceof Player) || event.getClickedInventory() instanceof PlayerInventory)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
ItemStack stack = event.getCurrentItem();
|
||||
for (GunStats stat : GunStats.values())
|
||||
{
|
||||
if (stat.getSkin() == stack.getType())
|
||||
{
|
||||
Gun gun;
|
||||
if (stat.getGunType() == GunType.SHOTGUN)
|
||||
{
|
||||
gun = new Shotgun(stat, _gunModule);
|
||||
}
|
||||
else
|
||||
{
|
||||
gun = new Gun(stat, _gunModule);
|
||||
}
|
||||
gun.setStack(stack);
|
||||
gun.updateWeaponName(player, null, false);
|
||||
gun.addID();
|
||||
_gunModule.registerGun(gun, player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Grenade grenade = null;
|
||||
|
||||
switch (stack.getType())
|
||||
{
|
||||
case APPLE:
|
||||
grenade = new HighExplosive();
|
||||
break;
|
||||
case CARROT_ITEM:
|
||||
grenade = new FlashBang();
|
||||
break;
|
||||
case POTATO_ITEM:
|
||||
grenade = new Smoke();
|
||||
break;
|
||||
case PORK:
|
||||
grenade = new Incendiary();
|
||||
break;
|
||||
case GRILLED_PORK:
|
||||
grenade = new Molotov();
|
||||
break;
|
||||
}
|
||||
|
||||
if (grenade == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
meta.setDisplayName(grenade.getName());
|
||||
stack.setItemMeta(meta);
|
||||
grenade.setStack(stack);
|
||||
_gunModule.registerGrenade(grenade, player);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void triggerPickup(PlayerPickupItemEvent event)
|
||||
{
|
||||
if (!getGame().InProgress() || !getGame().IsAlive(event.getPlayer()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Guns
|
||||
Gun gun = _gunModule.getDroppedGuns().get(event.getItem());
|
||||
if (gun != null)
|
||||
{
|
||||
_gunModule.deregisterDroppedGun(gun);
|
||||
_gunModule.registerGun(gun, event.getPlayer());
|
||||
gun.setStack(event.getItem().getItemStack());
|
||||
}
|
||||
|
||||
//Grenades
|
||||
Grenade grenade = _gunModule.getDroppedGrenades().get(event.getItem());
|
||||
if (grenade != null)
|
||||
{
|
||||
_gunModule.deregisterDroppedGrenade(grenade);
|
||||
_gunModule.registerGrenade(grenade, event.getPlayer());
|
||||
grenade.setStack(event.getItem().getItemStack());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void triggerDrop(PlayerDropItemEvent event)
|
||||
{
|
||||
if (!getGame().InProgress())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
ItemStack itemStack = event.getItemDrop().getItemStack();
|
||||
|
||||
//Guns
|
||||
Gun gun = _gunModule.getGunInHand(player, itemStack);
|
||||
|
||||
if (gun != null)
|
||||
{
|
||||
gun.drop(_gunModule, player, false, false);
|
||||
event.getItemDrop().remove();
|
||||
player.setItemInHand(null);
|
||||
return;
|
||||
}
|
||||
|
||||
//Grenades
|
||||
Grenade grenade = _gunModule.getGrenadeInHand(player, itemStack);
|
||||
if (grenade != null)
|
||||
{
|
||||
grenade.drop(_gunModule, player, false, false);
|
||||
event.getItemDrop().remove();
|
||||
player.setItemInHand(null);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
package nautilus.game.arcade.game.modules;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
import mineplex.core.common.Pair;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.packethandler.IPacketHandler;
|
||||
import mineplex.core.packethandler.PacketHandler;
|
||||
import mineplex.core.packethandler.PacketInfo;
|
||||
import nautilus.game.arcade.events.GameStateChangeEvent;
|
||||
import nautilus.game.arcade.game.Game.GameState;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutWorldBorder;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutWorldBorder.EnumWorldBorderAction;
|
||||
import net.minecraft.server.v1_8_R3.WorldBorder;
|
||||
|
||||
public class WorldBorderModule extends Module implements IPacketHandler
|
||||
{
|
||||
|
||||
private PacketHandler _packetHandler;
|
||||
private Map<UUID, Double> _sizeToSet;
|
||||
private Map<UUID, Pair<Double, Double>> _centerToSet;
|
||||
|
||||
@Override
|
||||
protected void setup()
|
||||
{
|
||||
_packetHandler = getGame().getArcadeManager().getPacketHandler();
|
||||
_sizeToSet = new HashMap<>();
|
||||
_centerToSet = new HashMap<>();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void live(GameStateChangeEvent event)
|
||||
{
|
||||
if (event.GetState() != GameState.Prepare)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_packetHandler.addPacketHandler(this, PacketPlayOutWorldBorder.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketInfo packetInfo)
|
||||
{
|
||||
UUID player = packetInfo.getPlayer().getUniqueId();
|
||||
PacketPlayOutWorldBorder packet = (PacketPlayOutWorldBorder) packetInfo.getPacket();
|
||||
|
||||
try
|
||||
{
|
||||
Field actionField = packet.getClass().getDeclaredField("a");
|
||||
actionField.setAccessible(true);
|
||||
EnumWorldBorderAction action = (EnumWorldBorderAction) actionField.get(packet);
|
||||
|
||||
if (action == EnumWorldBorderAction.SET_SIZE)
|
||||
{
|
||||
Field sizeField = packet.getClass().getDeclaredField("e");
|
||||
sizeField.setAccessible(true);
|
||||
double newSize = _sizeToSet.get(player);
|
||||
|
||||
sizeField.set(packet, newSize);
|
||||
}
|
||||
else if (action == EnumWorldBorderAction.SET_CENTER)
|
||||
{
|
||||
Field xField = packet.getClass().getDeclaredField("c");
|
||||
Field zField = packet.getClass().getDeclaredField("d");
|
||||
|
||||
xField.setAccessible(true);
|
||||
zField.setAccessible(true);
|
||||
|
||||
Pair<Double, Double> pair = _centerToSet.get(player);
|
||||
|
||||
xField.set(packet, pair.getLeft());
|
||||
zField.set(packet, pair.getRight());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
_packetHandler.removePacketHandler(this);
|
||||
}
|
||||
|
||||
public void setSize(Player player, double size)
|
||||
{
|
||||
_sizeToSet.put(player.getUniqueId(), size);
|
||||
|
||||
sendPacket(player, EnumWorldBorderAction.SET_SIZE);
|
||||
}
|
||||
|
||||
public void setCenter(Player player, Location location)
|
||||
{
|
||||
_centerToSet.put(player.getUniqueId(), Pair.create(location.getX(), location.getZ()));
|
||||
|
||||
sendPacket(player, EnumWorldBorderAction.SET_CENTER);
|
||||
}
|
||||
|
||||
private void sendPacket(Player player, EnumWorldBorderAction action)
|
||||
{
|
||||
WorldBorder border = ((CraftWorld) player.getWorld()).getHandle().getWorldBorder();
|
||||
UtilPlayer.sendPacket(player, new PacketPlayOutWorldBorder(border, action));
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package nautilus.game.arcade.game.modules.chest;
|
||||
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ChestLootItem
|
||||
{
|
||||
|
||||
private ItemStack _item;
|
||||
private int _lowestAmount, _highestAmount;
|
||||
private double _rarity;
|
||||
|
||||
public ChestLootItem(ItemStack item, int lowestAmount, int highestAmount, double rarity)
|
||||
{
|
||||
_item = item;
|
||||
_lowestAmount = lowestAmount;
|
||||
_highestAmount = highestAmount;
|
||||
_rarity = rarity;
|
||||
}
|
||||
|
||||
public ItemStack getItem()
|
||||
{
|
||||
ItemStack itemStack = _item.clone();
|
||||
|
||||
if (_lowestAmount != _highestAmount)
|
||||
{
|
||||
itemStack.setAmount(UtilMath.rRange(_lowestAmount, _highestAmount));
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public double getProbability()
|
||||
{
|
||||
return _rarity;
|
||||
}
|
||||
}
|
@ -0,0 +1,337 @@
|
||||
package nautilus.game.arcade.game.modules.chest;
|
||||
|
||||
import mineplex.core.common.util.MapUtil;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilBlock;
|
||||
import mineplex.core.common.util.UtilEvent;
|
||||
import mineplex.core.common.util.UtilEvent.ActionType;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import nautilus.game.arcade.events.GameStateChangeEvent;
|
||||
import nautilus.game.arcade.game.Game.GameState;
|
||||
import nautilus.game.arcade.game.modules.Module;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ChestLootModule extends Module
|
||||
{
|
||||
|
||||
private static final BlockFace[] FACES = {
|
||||
BlockFace.NORTH,
|
||||
BlockFace.SOUTH,
|
||||
BlockFace.WEST,
|
||||
BlockFace.EAST
|
||||
};
|
||||
|
||||
private final Map<ChestType, Set<ChestMetadata>> _chests;
|
||||
|
||||
private long _destroyAfterOpened;
|
||||
private boolean _autoRotateChests = true;
|
||||
private boolean _spawnNearby;
|
||||
private int _spawnNearbyRadius = 8;
|
||||
|
||||
public ChestLootModule()
|
||||
{
|
||||
_chests = new HashMap<>();
|
||||
}
|
||||
|
||||
public ChestLootModule registerChestType(String name, List<Location> chestLocations, ChestLootPool... pools)
|
||||
{
|
||||
return registerChestType(name, chestLocations, 1, pools);
|
||||
}
|
||||
|
||||
public ChestLootModule registerChestType(String name, List<Location> chestLocations, double spawnChance, ChestLootPool... pools)
|
||||
{
|
||||
_chests.put(new ChestType(name, chestLocations, spawnChance, pools), new HashSet<>());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChestLootModule destroyAfterOpened(int seconds)
|
||||
{
|
||||
_destroyAfterOpened = TimeUnit.SECONDS.toMillis(seconds);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChestLootModule autoRotateChests(boolean autoRotate)
|
||||
{
|
||||
_autoRotateChests = autoRotate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChestLootModule spawnNearbyDataPoints()
|
||||
{
|
||||
_spawnNearby = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChestLootModule spawnNearbyDataPoints(int radius)
|
||||
{
|
||||
_spawnNearby = true;
|
||||
_spawnNearbyRadius = radius;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void addChestLocation(String typeName, Location location)
|
||||
{
|
||||
for (Entry<ChestType, Set<ChestMetadata>> entry : _chests.entrySet())
|
||||
{
|
||||
if (!entry.getKey().Name.equals(typeName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
entry.getValue().add(new ChestMetadata(location.getBlock(), entry.getKey()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void refill()
|
||||
{
|
||||
_chests.forEach((type, metadataSet) -> metadataSet.forEach(metadata -> metadata.Opened = false));
|
||||
}
|
||||
|
||||
public void refill(String typeName)
|
||||
{
|
||||
_chests.forEach((type, metadataSet) ->
|
||||
{
|
||||
if (!type.Name.equals(typeName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
metadataSet.forEach(metadata -> metadata.Opened = false);
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void populateChests(GameStateChangeEvent event)
|
||||
{
|
||||
if (event.GetState() != GameState.Prepare)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Entry<ChestType, Set<ChestMetadata>> entry : _chests.entrySet())
|
||||
{
|
||||
ChestType chestType = entry.getKey();
|
||||
|
||||
if (chestType.ChestSpawns == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<ChestMetadata> metadataSet = entry.getValue();
|
||||
|
||||
for (Location location : chestType.ChestSpawns)
|
||||
{
|
||||
if (chestType.SpawnChance == 1 || Math.random() < chestType.SpawnChance)
|
||||
{
|
||||
Block block = location.getBlock();
|
||||
|
||||
if (_spawnNearby)
|
||||
{
|
||||
Location nearby = getNearbyLocation(location);
|
||||
|
||||
if (nearby == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
block = nearby.getBlock();
|
||||
}
|
||||
|
||||
block.setType(Material.CHEST);
|
||||
|
||||
if (_autoRotateChests)
|
||||
{
|
||||
for (BlockFace face : FACES)
|
||||
{
|
||||
if (UtilBlock.airFoliage(block.getRelative(face)))
|
||||
{
|
||||
block.setData(getData(face));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ChestMetadata metadata = new ChestMetadata(block, chestType);
|
||||
metadataSet.add(metadata);
|
||||
}
|
||||
}
|
||||
|
||||
_chests.put(chestType, metadataSet);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void openChest(PlayerInteractEvent event)
|
||||
{
|
||||
Block block = event.getClickedBlock();
|
||||
|
||||
if (event.isCancelled() || !UtilEvent.isAction(event, ActionType.R_BLOCK) || block == null || !(block.getState() instanceof Chest))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChestMetadata metadata = getFromBlock(block);
|
||||
|
||||
if (metadata == null || metadata.Opened)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
metadata.Opened = true;
|
||||
metadata.OpenedAt = System.currentTimeMillis();
|
||||
metadata.populateChest((Chest) block.getState());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void destroyOpenedChests(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.SEC || _destroyAfterOpened == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Set<ChestMetadata> metadataSet : _chests.values())
|
||||
{
|
||||
metadataSet.removeIf(metadata ->
|
||||
{
|
||||
if (metadata.Opened && UtilTime.elapsed(metadata.OpenedAt, _destroyAfterOpened))
|
||||
{
|
||||
Block block = metadata.Chest;
|
||||
Location location = block.getLocation();
|
||||
location.getWorld().playEffect(location.add(0.5, 0.5, 0.5), Effect.STEP_SOUND, block.getType());
|
||||
((Chest) block.getState()).getBlockInventory().clear();
|
||||
MapUtil.QuickChangeBlockAt(location, Material.AIR);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private ChestMetadata getFromBlock(Block block)
|
||||
{
|
||||
Location blockLocation = block.getLocation();
|
||||
|
||||
for (Set<ChestMetadata> metadataSet : _chests.values())
|
||||
{
|
||||
for (ChestMetadata metadata : metadataSet)
|
||||
{
|
||||
if (UtilMath.offsetSquared(blockLocation, metadata.Chest.getLocation()) < 4)
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private byte getData(BlockFace face)
|
||||
{
|
||||
switch (face)
|
||||
{
|
||||
case NORTH:
|
||||
return 0;
|
||||
case SOUTH:
|
||||
return 3;
|
||||
case WEST:
|
||||
return 4;
|
||||
case EAST:
|
||||
return 5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private Location getNearbyLocation(Location center)
|
||||
{
|
||||
int attempts = 0;
|
||||
while (attempts++ < 20)
|
||||
{
|
||||
Location newLocation = UtilAlg.getRandomLocation(center, _spawnNearbyRadius, 1, _spawnNearbyRadius);
|
||||
|
||||
if (isSuitable(newLocation.getBlock()))
|
||||
{
|
||||
return newLocation;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isSuitable(Block block)
|
||||
{
|
||||
Block up = block.getRelative(BlockFace.UP);
|
||||
Block down = block.getRelative(BlockFace.DOWN);
|
||||
|
||||
return block.getType() == Material.AIR && up.getType() == Material.AIR && down.getType() != Material.AIR && !UtilBlock.liquid(down) && !UtilBlock.liquid(up) && !UtilBlock.liquid(block);
|
||||
}
|
||||
|
||||
private class ChestMetadata
|
||||
{
|
||||
|
||||
Block Chest;
|
||||
ChestType Type;
|
||||
long OpenedAt;
|
||||
boolean Opened;
|
||||
|
||||
ChestMetadata(Block chest, ChestType type)
|
||||
{
|
||||
Chest = chest;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
void populateChest(Chest chest)
|
||||
{
|
||||
chest.getBlockInventory().clear();
|
||||
|
||||
for (ChestLootPool pool : Type.Pools)
|
||||
{
|
||||
if (pool.getProbability() == 1 || Math.random() < pool.getProbability())
|
||||
{
|
||||
pool.populateChest(chest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ChestType
|
||||
{
|
||||
String Name;
|
||||
double SpawnChance;
|
||||
List<ChestLootPool> Pools;
|
||||
List<Location> ChestSpawns;
|
||||
|
||||
ChestType(String name, List<Location> chestLocations, double spawnChance, ChestLootPool... pools)
|
||||
{
|
||||
Name = name;
|
||||
SpawnChance = spawnChance;
|
||||
Pools = Arrays.asList(pools);
|
||||
ChestSpawns = chestLocations;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package nautilus.game.arcade.game.modules.chest;
|
||||
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ChestLootPool
|
||||
{
|
||||
|
||||
private List<ChestLootItem> _items;
|
||||
private int _minimumPerChest;
|
||||
private int _maximumPerChest;
|
||||
private double _rarity;
|
||||
|
||||
public ChestLootPool()
|
||||
{
|
||||
_items = new ArrayList<>();
|
||||
_minimumPerChest = 1;
|
||||
_maximumPerChest = 1;
|
||||
_rarity = 1;
|
||||
}
|
||||
|
||||
public ChestLootPool addItem(ItemStack itemStack)
|
||||
{
|
||||
return addItem(itemStack, itemStack.getAmount(), itemStack.getAmount(), 1);
|
||||
}
|
||||
|
||||
public ChestLootPool addItem(ItemStack itemStack, double rarity)
|
||||
{
|
||||
return addItem(itemStack, itemStack.getAmount(), itemStack.getAmount(), rarity);
|
||||
}
|
||||
|
||||
public ChestLootPool addItem(ItemStack itemStack, int lowestAmount, int highestAmount)
|
||||
{
|
||||
return addItem(itemStack, lowestAmount, highestAmount, 1);
|
||||
}
|
||||
|
||||
public ChestLootPool addItem(ItemStack itemStack, int lowestAmount, int highestAmount, double rarity)
|
||||
{
|
||||
_items.add(new ChestLootItem(itemStack, lowestAmount, highestAmount, rarity));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChestLootPool setAmountsPerChest(int minimumPerChest, int maximumPerChest)
|
||||
{
|
||||
_minimumPerChest = minimumPerChest;
|
||||
_maximumPerChest = maximumPerChest;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChestLootPool setProbability(double probability)
|
||||
{
|
||||
_rarity = probability;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void populateChest(Chest chest)
|
||||
{
|
||||
Inventory inventory = chest.getBlockInventory();
|
||||
|
||||
for (int i = 0; i < UtilMath.rRange(_minimumPerChest, _maximumPerChest); i++)
|
||||
{
|
||||
int slot = UtilMath.r(inventory.getSize());
|
||||
ChestLootItem item = getRandomItem();
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
inventory.setItem(slot, item.getItem());
|
||||
}
|
||||
|
||||
chest.update();
|
||||
}
|
||||
|
||||
private ChestLootItem getRandomItem()
|
||||
{
|
||||
double totalWeight = 0;
|
||||
|
||||
for (ChestLootItem item : _items)
|
||||
{
|
||||
totalWeight += item.getProbability();
|
||||
}
|
||||
|
||||
double select = Math.random() * totalWeight;
|
||||
|
||||
for (ChestLootItem item : _items)
|
||||
{
|
||||
if ((select -= item.getProbability()) <= 0)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public double getProbability()
|
||||
{
|
||||
return _rarity;
|
||||
}
|
||||
}
|
@ -1096,9 +1096,14 @@ public class GameFlagManager implements Listener
|
||||
return;
|
||||
}
|
||||
|
||||
if (game.WorldWaterDamage <= 0 && !game.WorldData.GetCustomLocs("WATER_DAMAGE").isEmpty())
|
||||
if (game.WorldWaterDamage <= 0)
|
||||
{
|
||||
game.WorldWaterDamage = 4;
|
||||
if (!game.WorldData.GetCustomLocs("WATER_DAMAGE").isEmpty())
|
||||
{
|
||||
game.WorldWaterDamage = 4;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (Player player : game.GetPlayers(true))
|
||||
|
@ -1,12 +1,15 @@
|
||||
package nautilus.game.arcade.stats;
|
||||
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.minecraft.game.core.combat.event.CombatDeathEvent;
|
||||
import nautilus.game.arcade.game.Game;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -51,11 +54,6 @@ public class DeathBomberStatTracker extends StatTracker<Game>
|
||||
if(killer.equals(killed))
|
||||
return;
|
||||
|
||||
if (killer.getItemInHand().getType() != Material.TNT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.GetLog().GetKiller() != null && event.GetLog().GetKiller().GetReason().contains("Throwing TNT"))
|
||||
{
|
||||
Integer count = _killCount.get(killer.getUniqueId());
|
||||
@ -70,4 +68,32 @@ public class DeathBomberStatTracker extends StatTracker<Game>
|
||||
addStat(killer, "DeathBomber", 1, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void removeFakeThrowingTNT(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.FAST)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Player player : getGame().GetPlayers(true))
|
||||
{
|
||||
ItemStack[] contents = player.getInventory().getContents();
|
||||
int i = 0;
|
||||
|
||||
for (ItemStack itemStack : contents)
|
||||
{
|
||||
if (itemStack == null || itemStack.getItemMeta() == null || itemStack.getItemMeta().getDisplayName() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (itemStack.getItemMeta().getDisplayName().contains("Throwing TNT") && itemStack.getType() != Material.TNT)
|
||||
{
|
||||
player.getInventory().setItem(i, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user