Merge branch 'feature/battle-royale' into develop

This commit is contained in:
cnr 2017-06-30 22:15:53 -07:00
commit 0ac3e227fd
16 changed files with 2281 additions and 362 deletions

View File

@ -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),

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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!");

View File

@ -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)

View File

@ -82,6 +82,7 @@ public class CustomScoreboardModule extends Module
}
setupScoreboard(player);
refreshAsSubject(player);
}
/**

View File

@ -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);
}
}
}

View File

@ -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));
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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))

View File

@ -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);
}
}
}
}
}