Merge branch 'update/skyfall-nolag' into develop

This commit is contained in:
cnr 2017-04-12 23:39:01 -06:00
commit 490fe56b34
10 changed files with 945 additions and 317 deletions

View File

@ -1,6 +1,7 @@
package mineplex.core.loot;
import java.util.ArrayList;
import java.util.Iterator;
import mineplex.core.common.util.UtilMath;
@ -32,9 +33,32 @@ public class ChestLoot
public ItemStack getLoot()
{
int no = UtilMath.r(_totalLoot);
return getLoot(new ArrayList<>());
}
public ItemStack getLoot(ArrayList<Material> exclude)
{
int totalLoot = _totalLoot;
ArrayList<RandomItem> items = (ArrayList<RandomItem>) _randomItems.clone();
Iterator<RandomItem> rItems = items.iterator();
while (rItems.hasNext())
{
RandomItem item = rItems.next();
for (Material mat : exclude)
{
if (item.getItemStack().getType() == mat)
{
totalLoot -= item.getAmount();
rItems.remove();
}
}
}
int no = UtilMath.r(totalLoot);
for (RandomItem item : _randomItems)
for (RandomItem item : items)
{
no -= item.getAmount();

View File

@ -48,4 +48,15 @@ public class RandomItem
return _item;
}
@Override
public boolean equals(Object obj)
{
if (!(obj instanceof RandomItem))
return false;
RandomItem item = (RandomItem) obj;
return _item.getType() == item.getItemStack().getType();
}
}

View File

@ -16,6 +16,7 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import org.omg.DynamicAny._DynUnionStub;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilBlock;
@ -40,8 +41,8 @@ import nautilus.game.arcade.game.Game.GameState;
*/
public class BoosterRing extends Crumbleable implements Listener
{
private static int MAX_RING_BOUNDS = 15;
private static int SEARCH_OUTER_RING_RANGE = 10;
private static int MAX_RING_BOUNDS = 18;
private static int SEARCH_OUTER_RING_RANGE = 12;
private Game _host;
@ -63,6 +64,11 @@ public class BoosterRing extends Crumbleable implements Listener
private long _disabledSince;
private long _disabledFor;
private long _disableDelay;
private long _disableDelayStarted;
private CooldownData _delayedData;
private Hologram _hologram;
private boolean _timer;
@ -89,6 +95,8 @@ public class BoosterRing extends Crumbleable implements Listener
_boostStrength = boostStrength;
_disabledSince = System.currentTimeMillis();
_disableDelayStarted = 0;
System.out.println("Registering Ring");
setupRing();
@ -100,6 +108,8 @@ public class BoosterRing extends Crumbleable implements Listener
_hologram = new Hologram(host.getArcadeManager().getHologramManager(), _ringMiddle, "");
_hologram.setViewDistance(300);
init();
}
@EventHandler
@ -305,7 +315,7 @@ public class BoosterRing extends Crumbleable implements Listener
if (event.getType() != UpdateType.TICK)
return;
for (Player player : _host.GetPlayers(true))
for (Player player : UtilServer.getPlayers())
{
if (!UtilPlayer.isGliding(player))
continue;
@ -331,7 +341,8 @@ public class BoosterRing extends Crumbleable implements Listener
Vector vec = player.getEyeLocation().getDirection();
UtilAction.velocity(player, vec.multiply(event.getStrength()));
UtilFirework.playFirework(player.getEyeLocation(), Type.BALL_LARGE, Color.BLUE, true, false);
if (_host.IsAlive(player))
UtilFirework.playFirework(player.getEyeLocation(), Type.BALL_LARGE, Color.BLUE, true, false);
}
@EventHandler
@ -346,6 +357,9 @@ public class BoosterRing extends Crumbleable implements Listener
if (!_disabled)
return;
if (isCrumbling())
return;
double blocks = (double) _ring.size() / (double)(_disabledFor/1000);
_blocksToFill += blocks;
@ -391,6 +405,42 @@ public class BoosterRing extends Crumbleable implements Listener
enable();
}
@EventHandler
public void disableUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER)
return;
if (_delayedData == null)
return;
if (UtilTime.elapsed(_disableDelayStarted, _disableDelay))
{
disable(_delayedData.getTime(), _delayedData.getMaterial(), _delayedData.getData(), _delayedData.showTimer());
_delayedData = null;
}
}
public void disableLater(long delay, long time, Material mat, byte data, boolean showTimer)
{
if (_delayedData != null)
return;
_delayedData = new CooldownData(time, mat, data, showTimer);
_disableDelayStarted = System.currentTimeMillis();
_disableDelay = delay;
}
public void disableLater(long delay, long time, boolean showTimer)
{
disableLater(delay, time, Material.STAINED_CLAY, (byte) 14, showTimer);
}
public void disableLater(long delay)
{
disableLater(delay, Long.MAX_VALUE, Material.STAINED_CLAY, (byte) 14, false);
}
public void disable()
{
disable(Long.MAX_VALUE, false);
@ -493,4 +543,40 @@ public class BoosterRing extends Crumbleable implements Listener
return _ring;
}
private class CooldownData
{
private long _time;
private Material _mat;
private byte _data;
private boolean _showTimer;
public CooldownData(long time, Material mat, byte data, boolean showTimer)
{
_time = time;
_mat = mat;
_data = data;
_showTimer = showTimer;
}
public long getTime()
{
return _time;
}
public Material getMaterial()
{
return _mat;
}
public byte getData()
{
return _data;
}
public boolean showTimer()
{
return _showTimer;
}
}
}

View File

@ -1,12 +1,27 @@
package nautilus.game.arcade.game.games.skyfall;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import net.minecraft.server.v1_8_R3.Chunk;
import net.minecraft.server.v1_8_R3.PacketPlayOutMapChunk;
import org.bukkit.DyeColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
import org.bukkit.entity.Player;
import mineplex.core.common.util.MapUtil;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
/**
* Crumbleable is a Superclass to create decayable/crumleable Objects like Sky Islands
@ -15,9 +30,81 @@ import mineplex.core.common.util.UtilMath;
*/
public abstract class Crumbleable
{
private static final long CHUNK_CRUMBLE_DELAY = 1000;
private boolean _crumble;
private ArrayList<Location> _initBlocks;
private ArrayList<Location> _realBlocks;
private Map<Chunk, BitSet> _chunksToUpdate;
private boolean _onlyTop;
private int _height;
private long _lastChunk;
public Crumbleable()
{
this(false, 0);
}
public Crumbleable(boolean onlyTop, int height)
{
_onlyTop = onlyTop;
_height = height;
_realBlocks = new ArrayList<>();
_chunksToUpdate = new HashMap<>();
_lastChunk = System.currentTimeMillis();
}
/**
* Must be called when getBlocks is set
*/
public void init()
{
if (_onlyTop)
{
ArrayList<Location> flatMap = new ArrayList<>();
ArrayList<Location> locs = getBlocks();
int y = Integer.MIN_VALUE;
for (Location loc : locs)
{
if (loc.getBlockY() > y)
y = loc.getBlockY();
}
for (Location loc : locs)
{
if (loc.getBlockY() == y)
flatMap.add(loc.clone());
}
for (Location loc : flatMap)
{
Block block = loc.getBlock();
int i = 0;
while (i <= _height)
{
if (block.getType() != Material.AIR && block.getRelative(BlockFace.UP).getType() == Material.AIR)
_realBlocks.add(block.getLocation());
block = block.getRelative(BlockFace.DOWN);
i++;
}
}
_initBlocks = (ArrayList<Location>) _realBlocks.clone();
}
else
{
_realBlocks = (ArrayList<Location>) getBlocks().clone();
_initBlocks = (ArrayList<Location>) getBlocks().clone();
}
}
/**
* @see #crumble(int, Material...)
@ -44,26 +131,50 @@ public abstract class Crumbleable
crumblePercentage();
Material material = replacements[UtilMath.r(replacements.length)];
if (getBlocks().isEmpty())
if (_realBlocks.isEmpty())
{
crumbledAway();
if (!_chunksToUpdate.isEmpty())
{
if (UtilTime.elapsed(_lastChunk, CHUNK_CRUMBLE_DELAY))
{
Chunk chunk = _chunksToUpdate.keySet().iterator().next();
BitSet bitSet = _chunksToUpdate.remove(chunk);
int mask = 0;
for (int i = 0; i < bitSet.length(); i++)
{
if (bitSet.get(i))
{
mask |= 1 << i;
}
}
for (Player player : UtilServer.getPlayers())
{
UtilPlayer.sendPacket(player, new PacketPlayOutMapChunk(chunk, false, mask));
}
_lastChunk = System.currentTimeMillis();
}
}
return true;
}
for (int i = 0; i < blocks; i++)
{
if (getBlocks().isEmpty())
Material material = replacements[UtilMath.r(replacements.length)];
if (_realBlocks.isEmpty())
{
crumbledAway();
return true;
}
Location toRemove = getBlocks().remove(UtilMath.r(getBlocks().size()));
if (toRemove.getBlock().getType() == Material.CHEST && getBlocks().size() > 25)
Location toRemove = _realBlocks.remove(UtilMath.r(_realBlocks.size()));
if (toRemove.getBlock().getType() == Material.CHEST && _realBlocks.size() > 25)
{
getBlocks().add(toRemove);
_realBlocks.add(toRemove);
continue;
}
@ -74,8 +185,19 @@ public abstract class Crumbleable
|| toRemove.getBlock().getType() == Material.STATIONARY_LAVA)
continue;
MapUtil.QuickChangeBlockAt(toRemove, material);
byte id = 0;
if (toRemove.getBlock().getType() == Material.STAINED_GLASS ||
toRemove.getBlock().getType() == Material.GLASS)
{
material = Material.STAINED_GLASS;
id = DyeColor.BLACK.getData();
}
MapUtil.ChunkBlockChange(toRemove, material.getId(), id, false);
_chunksToUpdate.computeIfAbsent(((CraftChunk) toRemove.getChunk()).getHandle(), key -> new BitSet()).set(((int) toRemove.getY()) >> 4);
}
return false;
}
@ -86,7 +208,7 @@ public abstract class Crumbleable
public boolean isCrumbledAway()
{
return getBlocks().isEmpty();
return _realBlocks.isEmpty();
}
/**
@ -94,19 +216,21 @@ public abstract class Crumbleable
*/
public double crumblePercentage()
{
if (_initBlocks == null)
_initBlocks = (ArrayList<Location>) getBlocks().clone();
try
{
return (getBlocks().size()/(_initBlocks.size()/100))/100;
return (_realBlocks.size()/(_initBlocks.size()));
}
catch (Exception e)
{
return 100;
return 1;
}
}
public ArrayList<Location> getRealBlocks()
{
return _realBlocks;
}
/**
* Overrideable method which is called by
* {@link #crumble(int, Material...)} or {@link #crumble(int)}

View File

@ -8,15 +8,15 @@ import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilItem;
import mineplex.core.common.util.UtilMath;
import mineplex.core.loot.ChestLoot;
import mineplex.core.titles.tracks.standard.LuckyTrack;
import mineplex.core.titles.tracks.standard.UnluckyTrack;
import nautilus.game.arcade.ArcadeManager;
/**
* The Island Object represents a flying Island <br/>
* which has it's own chests and is able to crumble away.
@ -69,6 +69,8 @@ public class Island extends Crumbleable
*/
public Island(Location location, ChestLoot loot, int bounds, int height)
{
super(true, height);
_location = location;
_bounds = bounds;
_height = height;
@ -78,24 +80,25 @@ public class Island extends Crumbleable
_loot = loot;
registerBlocks();
init();
}
public void fillLoot(Block block, Player player, ArcadeManager arcadeManager)
public void fillLoot(Block block)
{
if (block.getType() != Material.CHEST
&& block.getType() != Material.TRAPPED_CHEST)
return;
if (_lootedBlocks.contains(block.getLocation()))
return;
_lootedBlocks.add(block.getLocation());
Chest chest = (Chest) block.getState();
Inventory inventory = chest.getBlockInventory();
inventory.clear();
int items = 3;
int items = 5;
if (Math.random() > 0.50)
items++;
if (Math.random() > 0.65)
@ -104,24 +107,78 @@ public class Island extends Crumbleable
items++;
if (Math.random() > 0.95)
items++;
ArrayList<Material> exclude = new ArrayList<>();
for (int i = 0; i < items; i++)
{
int trys = 0;
int slot = UtilMath.r(27);
int slot = UtilMath.r(26);
while (inventory.getItem(slot) != null && trys <= 5)
{
trys++;
slot = UtilMath.r(27);
slot = UtilMath.r(26);
}
inventory.setItem(slot, _loot.getLoot());
}
if (player != null && arcadeManager != null && arcadeManager.GetServerConfig().RewardStats)
{
arcadeManager.getTrackManager().getTrack(LuckyTrack.class).handleLoot(player, chest.getBlockInventory());
arcadeManager.getTrackManager().getTrack(UnluckyTrack.class).handleLoot(player, chest.getBlockInventory());
ItemStack item = _loot.getLoot(exclude);
inventory.setItem(slot, item);
if (item.getType() == Material.DIAMOND)
{
inventory.setItem(slot + 1, new ItemStack(Material.STICK, 2));
}
if (item.getType() == Material.BOW)
{
inventory.setItem(slot + 1, new ItemStack(Material.ARROW, UtilMath.r(6) + 1));
}
if (UtilItem.isHelmet(item))
{
exclude.add(Material.CHAINMAIL_HELMET);
exclude.add(Material.GOLD_HELMET);
exclude.add(Material.IRON_HELMET);
exclude.add(Material.LEATHER_HELMET);
exclude.add(Material.DIAMOND_HELMET);
}
if (UtilItem.isChestplate(item))
{
exclude.add(Material.CHAINMAIL_CHESTPLATE);
exclude.add(Material.GOLD_CHESTPLATE);
exclude.add(Material.IRON_CHESTPLATE);
exclude.add(Material.LEATHER_CHESTPLATE);
exclude.add(Material.DIAMOND_CHESTPLATE);
}
if (UtilItem.isLeggings(item))
{
exclude.add(Material.CHAINMAIL_LEGGINGS);
exclude.add(Material.GOLD_LEGGINGS);
exclude.add(Material.IRON_LEGGINGS);
exclude.add(Material.LEATHER_LEGGINGS);
exclude.add(Material.DIAMOND_LEGGINGS);
}
if (UtilItem.isBoots(item))
{
exclude.add(Material.CHAINMAIL_BOOTS);
exclude.add(Material.GOLD_BOOTS);
exclude.add(Material.IRON_BOOTS);
exclude.add(Material.LEATHER_BOOTS);
exclude.add(Material.DIAMOND_BOOTS);
}
if (UtilItem.isSword(item))
{
exclude.add(Material.WOOD_SWORD);
exclude.add(Material.STONE_SWORD);
exclude.add(Material.IRON_SWORD);
exclude.add(Material.DIAMOND_SWORD);
}
if (UtilItem.isAxe(item))
{
exclude.add(Material.WOOD_AXE);
exclude.add(Material.STONE_AXE);
exclude.add(Material.IRON_AXE);
exclude.add(Material.DIAMOND_AXE);
}
if (item.getType() == Material.BOW)
exclude.add(Material.BOW);
}
}
@ -151,11 +208,11 @@ public class Island extends Crumbleable
}
public boolean isOnIsland(Location location)
{
if (UtilMath.offset(location, _location) > _bounds)
{
if (UtilMath.offset2d(location, _location) > _bounds + 1)
return false;
for (int y = ((int) (Math.round(_location.getY()) - _height)); y <= _location.getBlockY(); y++)
for (int y = (_location.getBlockY() - _height); y <= _location.getBlockY(); y++)
{
if (location.getBlockY() == y)
return true;
@ -175,7 +232,7 @@ public class Island extends Crumbleable
public void registerBlocks()
{
for (Block block : UtilBlock.getInBoundingBox(_location.clone().add(_bounds, 0, _bounds), _location.clone().subtract(_bounds, _height, _bounds)))
for (Block block : UtilBlock.getInBoundingBox(_location.clone().add(_bounds, 0, _bounds), _location.clone().subtract(_bounds, _height, _bounds), false))
{
if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST)
getChests().add(block.getLocation());
@ -189,7 +246,7 @@ public class Island extends Crumbleable
_lootedBlocks.clear();
for (Location loc : _chests)
{
fillLoot(loc.getBlock(), null, null);
fillLoot(loc.getBlock());
}
}

View File

@ -1,6 +1,9 @@
package nautilus.game.arcade.game.games.skyfall;
import java.util.ArrayList;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.F;
import mineplex.core.itemstack.ItemStackFactory;
@ -14,15 +17,15 @@ import mineplex.core.loot.RandomItem;
*/
public class LootTable
{
public final static LootTable BASIC = new LootTable(
// Survival Loot
public final static LootTable BASIC = new LootTable(true,
new RandomItem(Material.BAKED_POTATO, 30, 1, 3),
new RandomItem(Material.COOKED_BEEF, 30, 1, 2),
new RandomItem(Material.COOKED_CHICKEN, 30, 1, 2),
new RandomItem(Material.CARROT_ITEM, 30, 1, 3),
new RandomItem(Material.MUSHROOM_SOUP, 15, 1, 1),
new RandomItem(Material.WHEAT, 30, 1, 6),
new RandomItem(Material.APPLE, 30, 1, 4),
new RandomItem(Material.PORK, 30, 1, 4),
new RandomItem(Material.ROTTEN_FLESH, 40, 1, 6),
new RandomItem(Material.WOOD_AXE, 100),
@ -57,26 +60,28 @@ public class LootTable
Material.TNT, (byte) 0, 1, F.item("Throwing TNT")), 15),
new RandomItem(Material.MUSHROOM_SOUP, 15),
new RandomItem(Material.BAKED_POTATO, 20, 1, 5),
new RandomItem(Material.MUSHROOM_SOUP, 20, 1, 1),
new RandomItem(Material.COOKED_BEEF, 30, 1, 3),
new RandomItem(Material.COOKED_CHICKEN, 30, 1, 3),
new RandomItem(Material.COOKED_FISH, 30, 1, 6),
new RandomItem(Material.GRILLED_PORK, 20, 1, 3),
new RandomItem(Material.BAKED_POTATO, 25, 1, 5),
new RandomItem(Material.MUSHROOM_SOUP, 25, 1, 1),
new RandomItem(Material.COOKED_BEEF, 35, 1, 3),
new RandomItem(Material.COOKED_CHICKEN, 35, 1, 3),
new RandomItem(Material.COOKED_FISH, 35, 1, 6),
new RandomItem(Material.GRILLED_PORK, 25, 1, 3),
new RandomItem(Material.COOKIE, 30),
new RandomItem(Material.PUMPKIN_PIE, 20, 1, 3),
new RandomItem(Material.APPLE, 20, 2, 6),
new RandomItem(Material.IRON_INGOT, 30, 1, 2),
new RandomItem(Material.DIAMOND, 30)
);
public final static LootTable SUPPLY_DROP = new LootTable(
public final static LootTable SUPPLY_DROP = new LootTable(true,
new RandomItem(Material.DIAMOND_HELMET, 30),
new RandomItem(Material.DIAMOND_LEGGINGS, 27),
new RandomItem(Material.DIAMOND_BOOTS, 30),
new RandomItem(Material.DIAMOND_SWORD, 16),
new RandomItem(Material.DIAMOND_AXE, 24)
new RandomItem(Material.DIAMOND_AXE, 24),
new RandomItem(Material.GOLDEN_APPLE, 4),
new RandomItem(Material.BOW, 4),
new RandomItem(Material.ARROW, 2)
// new RandomItem(ItemStackFactory.Instance.CreateStack(Material.IRON_SWORD, 1, Enchantment.DAMAGE_ALL), 8),
// new RandomItem(ItemStackFactory.Instance.CreateStack(Material.DIAMOND_SWORD, 1, Enchantment.DAMAGE_ALL), 4),
//
@ -86,10 +91,26 @@ public class LootTable
// new RandomItem(new Potion(PotionType.STRENGTH, 2, false).toItemStack(1), 3)
);
public final static LootTable ALL = new LootTable(BASIC.includes(SUPPLY_DROP));
private RandomItem[] _items;
private boolean _unbreakable;
private LootTable(LootTable table)
{
_unbreakable = table.isUnbreakable();
_items = table.getItems();
}
private LootTable(RandomItem... items)
{
_unbreakable = false;
_items = items;
}
private LootTable(boolean unbreakable, RandomItem... items)
{
_unbreakable = unbreakable;
_items = items;
}
@ -98,9 +119,14 @@ public class LootTable
return _items;
}
public boolean isUnbreakable()
{
return _unbreakable;
}
public ChestLoot getloot()
{
ChestLoot loot = new ChestLoot();
ChestLoot loot = new ChestLoot(_unbreakable);
for (RandomItem item : _items)
{
loot.addLoot(item);
@ -127,6 +153,35 @@ public class LootTable
i++;
}
return new LootTable(items);
return new LootTable(_unbreakable, items);
}
public LootTable excludes(ArrayList<Material> randomItems)
{
int size = _items.length - randomItems.size();
RandomItem[] items = new RandomItem[size];
int i = 0;
for (RandomItem item : _items)
{
boolean cont = false;
for (Material other : randomItems)
{
if (item.getItemStack().getType() == other)
{
cont = true;
}
}
if (cont)
continue;
items[i] = item;
i++;
}
return new LootTable(_unbreakable, items);
}
}

View File

@ -3,6 +3,7 @@ package nautilus.game.arcade.game.games.skyfall;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -25,6 +26,7 @@ import nautilus.game.arcade.game.modules.TeamModule;
*/
public class TeamSkyfall extends Skyfall
{
private static final long BOOSTER_COOLDOWN_TIME = 1000*20; // 20 Seconds
public TeamSkyfall(ArcadeManager manager)
{
@ -34,7 +36,6 @@ public class TeamSkyfall extends Skyfall
FillTeamsInOrderToCount = 2;
SpawnNearAllies = true;
SpawnNearEnemies = true;
DamageTeamSelf = false;
@ -155,6 +156,14 @@ public class TeamSkyfall extends Skyfall
SetState(GameState.End);
}
}
@EventHandler
@Override
public void ringBoost(PlayerBoostRingEvent event)
{
if (IsAlive(event.getPlayer()))
event.getRing().disableLater(3000, BOOSTER_COOLDOWN_TIME, Material.STAINED_CLAY, (byte) 14, true);
}
@Override
public List<Player> getWinners()

View File

@ -92,13 +92,12 @@ public class PerkElytraBoost extends Perk
while (i < 10 && !UtilPlayer.isGliding(player))
{
UtilPlayer.setGliding(player, true);
Vector vec = player.getEyeLocation().getDirection();
UtilAction.velocity(player, vec.multiply(2.5));
i++;
}
Vector vec = player.getEyeLocation().getDirection();
UtilAction.velocity(player, vec.multiply(2.5));
UtilFirework.playFirework(player.getEyeLocation(), Type.BALL_LARGE, Color.BLUE, true, false);
}
}, 4);

View File

@ -29,6 +29,9 @@ public class RingStatTracker extends StatTracker<Game>
if (event.isCancelled())
return;
if (!getGame().IsAlive(event.getPlayer()))
return;
addStat(event.getPlayer(), "Rings", 1, false, false);
}