Add Dropper and fix some other bugs

This commit is contained in:
Sam 2018-09-08 16:01:30 +01:00 committed by Alexander Meech
parent 718b2c5391
commit ee619c0a22
17 changed files with 278 additions and 87 deletions

View File

@ -3,10 +3,10 @@ package mineplex.core.common.weight;
public class Weight<T>
{
private int _weight;
private final int _weight;
public int getWeight() { return _weight; }
private T _value;
private final T _value;
public T getValue() { return _value; }
public Weight(int weight, T value)

View File

@ -10,27 +10,28 @@ public enum NanoDisplay implements Display
{
BAWK_BAWK(20, "Bawk Bawk's Wrath", Material.EGG),
COPY_CAT(17, "Copy Cat", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.OCELOT)),
CHICKEN_SHOOT(14, "Chicken Shoot", Material.BOW),
COLOUR_CHANGE(6, "Color Swap", Material.WOOL, (byte) 4),
DEATH_TAG(4, "Zombie Survival", Material.SKULL_ITEM, (byte) 2),
FIND_ORES(11, "Ores Ores Ores", Material.DIAMOND_PICKAXE),
HOT_POTATO(1, "Hot Potato", Material.POTATO_ITEM),
JUMP_ROPE(10, "Jump Rope", Material.LEASH),
KING_SLIME(8, "King Slime", Material.SLIME_BALL),
MICRO_BATTLE(3, "Nano Battle", Material.IRON_SWORD),
MOB_FARM(13, "Mob Farm", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.PIG)),
MUSIC_MINECARTS(12, "Musical Minecarts", Material.MINECART),
QUICK(21, "Quick", Material.DIAMOND),
PARKOUR(19, "Hardcore Parkour", Material.FEATHER),
RED_GREEN_LIGHT(5, "Red Light Green Light", Material.WOOL, (byte) 5),
REVERSE_TAG(2, "Reverse Tag", Material.EMERALD),
SLIME_CYCLES(15, "Slime Cycles", Material.SLIME_BLOCK),
SNOWBALL_TROUBLE(18, "Snowball Trouble", Material.SNOW_BALL),
SPLEEF(9, "AAAAAAAA! Spleef", Material.DIAMOND_SPADE),
SPLOOR(7, "Sploor", Material.DIAMOND_BARDING),
TERRITORY(16, "Slime Territory", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.SLIME)),
BAWK_BAWK(1, "Bawk Bawk's Wrath", Material.EGG),
COPY_CAT(2, "Copy Cat", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.OCELOT)),
CHICKEN_SHOOT(3, "Chicken Shoot", Material.BOW),
COLOUR_CHANGE(4, "Color Swap", Material.WOOL, (byte) 4),
DEATH_TAG(5, "Zombie Survival", Material.SKULL_ITEM, (byte) 2),
DROPPER(6, "Dropper", Material.ANVIL),
FIND_ORES(7, "Ores Ores Ores", Material.DIAMOND_PICKAXE),
HOT_POTATO(8, "Hot Potato", Material.POTATO_ITEM),
JUMP_ROPE(9, "Jump Rope", Material.LEASH),
KING_SLIME(10, "King Slime", Material.SLIME_BALL),
MICRO_BATTLE(11, "Nano Battle", Material.IRON_SWORD),
MOB_FARM(12, "Mob Farm", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.PIG)),
MUSIC_MINECARTS(13, "Musical Minecarts", Material.MINECART),
QUICK(14, "Quick", Material.DIAMOND),
PARKOUR(15, "Hardcore Parkour", Material.FEATHER),
RED_GREEN_LIGHT(16, "Red Light Green Light", Material.WOOL, (byte) 5),
REVERSE_TAG(17, "Reverse Tag", Material.EMERALD),
SLIME_CYCLES(18, "Slime Cycles", Material.SLIME_BLOCK),
SNOWBALL_TROUBLE(19, "Snowball Trouble", Material.SNOW_BALL),
SPLEEF(20, "AAAAAAAA! Spleef", Material.DIAMOND_SPADE),
SPLOOR(21, "Sploor", Material.DIAMOND_BARDING),
TERRITORY(22, "Slime Territory", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.SLIME)),
;
public static NanoDisplay getFromId(int gameId)

View File

@ -35,6 +35,7 @@ import mineplex.core.game.GameDisplay;
import mineplex.core.game.nano.NanoFavourite;
import mineplex.core.incognito.IncognitoManager;
import mineplex.core.incognito.events.IncognitoStatusChangeEvent;
import mineplex.core.newnpc.NewNPCManager;
import mineplex.core.serverConfig.ServerConfiguration;
import mineplex.core.stats.StatsManager;
import mineplex.core.status.ServerStatusManager;
@ -112,6 +113,9 @@ public class NanoManager extends MiniPlugin implements IRelation
// AntiCheat
private final AntiHack _antiHack;
// NPC
private final NewNPCManager _npcManager;
// Damage
private final DamageManager _damageManager;
private final GameDamageManager _gameDamageManager;
@ -185,6 +189,8 @@ public class NanoManager extends MiniPlugin implements IRelation
_antiHack = require(AntiHack.class);
_npcManager = require(NewNPCManager.class);
_damageManager = require(DamageManager.class);
_gameDamageManager = require(GameDamageManager.class);
@ -406,6 +412,11 @@ public class NanoManager extends MiniPlugin implements IRelation
return _antiHack;
}
public NewNPCManager getNpcManager()
{
return _npcManager;
}
public DamageManager getDamageManager()
{
return _damageManager;

View File

@ -15,8 +15,8 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.scheduler.BukkitRunnable;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.weight.WeightSet;
import mineplex.core.game.nano.NanoDisplay;
import mineplex.game.nano.GameManager;
import mineplex.game.nano.NanoManager;
@ -214,35 +214,22 @@ public class GameCycle extends GameManager
// The games mapped to the number of people that have them favourited
Map<NanoDisplay, Integer> favourites = _manager.getFavourite().getFavourites();
WeightSet<GameType> weightedGames = new WeightSet<>();
// Out of all games
List<GameType> gameTypes = Arrays.stream(GameType.values())
Arrays.stream(GameType.values())
// Remove recent games and ones which no one has sent as their favourite
.filter(game -> !_recentGames.contains(game) && favourites.containsKey(game.getDisplay()))
// Then sort them inversely of how many people have them set as their favourites
.sorted((o1, o2) -> favourites.get(o2.getDisplay()).compareTo(favourites.get(o1.getDisplay())))
.collect(Collectors.toList());
.filter(game -> !_recentGames.contains(game))
// Add the games to a weighted set
// Add 1 to all weights to prevent it throwing an error when favourites are empty
.forEach(gameType -> weightedGames.add(1 + favourites.getOrDefault(gameType.getDisplay(), 0), gameType));
log("Recent Games : " + _recentGames);
log("Favourites Sorted : " + gameTypes);
GameType gameType;
// Get a random game, a more popular game has a higher chance of coming up
GameType gameType = weightedGames.generateRandom();
// No game? Happens if no one has anything set or there isn't a huge variety in the games selected as favourites
if (gameTypes.isEmpty())
{
// Get a random game that hasn't been played recently
gameType = UtilAlg.Random(Arrays.stream(GameType.values())
.filter(game -> !_recentGames.contains(game))
.collect(Collectors.toList()));
log("Setting by Random : " + gameType);
}
else
{
// Get the most favourited game
gameType = gameTypes.get(0);
log("Setting by Favourite : " + gameType);
}
log("Setting by Favourite : " + gameType);
return gameType;
}

View File

@ -10,6 +10,7 @@ import mineplex.game.nano.game.games.chickenshoot.ChickenShoot;
import mineplex.game.nano.game.games.colourchange.ColourChange;
import mineplex.game.nano.game.games.copycat.CopyCat;
import mineplex.game.nano.game.games.deathtag.DeathTag;
import mineplex.game.nano.game.games.dropper.Dropper;
import mineplex.game.nano.game.games.findores.FindOres;
import mineplex.game.nano.game.games.hotpotato.HotPotato;
import mineplex.game.nano.game.games.jumprope.JumpRope;
@ -50,7 +51,8 @@ public enum GameType
SNOWBALL_TROUBLE(SnowballTrouble.class, NanoDisplay.SNOWBALL_TROUBLE, mapsFromArcade(GameDisplay.Quiver)),
PARKOUR(Parkour.class, NanoDisplay.PARKOUR),
BAWK_BAWK(BawkBawk.class, NanoDisplay.BAWK_BAWK),
QUICK(Quick.class, NanoDisplay.QUICK);
QUICK(Quick.class, NanoDisplay.QUICK),
DROPPER(Dropper.class, NanoDisplay.DROPPER);
private static String maps()
{

View File

@ -5,6 +5,7 @@ import java.text.DecimalFormat;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
@ -19,6 +20,7 @@ import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextBottom;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.nano.game.Game;
@ -79,16 +81,7 @@ public class GameCompassComponent extends GameComponent<Game>
if (COMPASS.equals(player.getItemInHand()))
{
Player closest;
if (alive)
{
closest = UtilPlayer.getClosest(player.getLocation(), getGame().getTeam(player).getAlivePlayers());
}
else
{
closest = UtilPlayer.getClosest(player.getLocation(), player);
}
Player closest = getClosest(player);
if (closest == null)
{
@ -112,7 +105,7 @@ public class GameCompassComponent extends GameComponent<Game>
@EventHandler
public void playerInteract(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R))
if (event.getAction() == Action.PHYSICAL)
{
return;
}
@ -125,7 +118,31 @@ public class GameCompassComponent extends GameComponent<Game>
return;
}
_shop.attemptShopOpen(player);
if (UtilEvent.isAction(event, ActionType.R))
{
_shop.attemptShopOpen(player);
}
else if (Recharge.Instance.use(player, "Spectate", 1000, true, false))
{
Player closest = getClosest(player);
if (closest != null)
{
player.teleport(closest);
}
}
}
private Player getClosest(Player player)
{
if (getGame().isAlive(player))
{
return UtilPlayer.getClosest(player.getLocation(), getGame().getTeam(player).getAlivePlayers());
}
else
{
return UtilPlayer.getClosest(player.getLocation(), player);
}
}
@EventHandler(ignoreCancelled = true)

View File

@ -77,7 +77,6 @@ public class GamePlayerManager extends GameManager implements ComponentHook<Game
case Dead:
setHook(null);
break;
}
}

View File

@ -148,10 +148,8 @@ public class DeathTag extends SoloGame
setChaser(player, false);
event.setRespawnLocation(player.getLocation());
}
else
{
event.setClearPlayer(false);
}
event.setClearPlayer(false);
}
else
{
@ -208,6 +206,8 @@ public class DeathTag extends SoloGame
disguise.setName(_chasers.getChatColour() + player.getName());
disguise.setCustomNameVisible(true);
UtilPlayer.clearInventory(player);
if (forced)
{
announce(F.main(getManager().getName(), F.elem(_runners.getChatColour() + player.getName()) + " has become an " + F.elem(_chasers.getChatColour() + "Alpha Zombie") + "."));
@ -221,10 +221,6 @@ public class DeathTag extends SoloGame
.build()
});
}
else
{
UtilPlayer.clearInventory(player);
}
UtilTextMiddle.display(C.cRedB + "Zombie", "You are now a zombie!", 0, 60, 10, player);
_manager.getDisguiseManager().disguise(disguise);

View File

@ -0,0 +1,168 @@
package mineplex.game.nano.game.games.dropper;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.MapUtil;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import mineplex.core.newnpc.NPC;
import mineplex.core.newnpc.SimpleNPC;
import mineplex.core.newnpc.event.NPCInteractEvent;
import mineplex.game.nano.NanoManager;
import mineplex.game.nano.game.GamePlacements;
import mineplex.game.nano.game.GameType;
import mineplex.game.nano.game.SoloGame;
import mineplex.game.nano.game.components.player.NightVisionComponent;
import mineplex.game.nano.game.event.GameStateChangeEvent;
import mineplex.game.nano.game.event.PlayerGameRespawnEvent;
import mineplex.minecraft.game.core.combat.DeathMessageType;
import mineplex.minecraft.game.core.combat.event.CombatDeathEvent;
public class Dropper extends SoloGame
{
private List<Location> _floor;
private final List<Player> _completed;
public Dropper(NanoManager manager)
{
super(manager, GameType.DROPPER, new String[]
{
"Get to the " + C.cYellow + "Bottom" + C.Reset + "!",
C.cYellow + "First player" + C.Reset + " down wins!"
});
_completed = new ArrayList<>();
_prepareComponent.setPrepareFreeze(false);
_teamComponent.setRespawnRechargeTime(0);
_damageComponent.setPvp(false);
_spectatorComponent.setDeathOut(false);
_endComponent.setTimeout(TimeUnit.MINUTES.toMillis(1));
new NightVisionComponent(this);
_scoreboardComponent
.setSidebar((player, scoreboard) ->
{
scoreboard.writeNewLine();
List<Player> players = getAllPlayers();
scoreboard.write(C.cYellowB + "Players");
if (players.size() > 11)
{
scoreboard.write(players.size() + " Playing");
}
else
{
players.forEach(other -> scoreboard.write((other.equals(player) ? C.cGreen : (_completed.contains(other) ? C.cYellow : "")) + other.getName()));
}
scoreboard.writeNewLine();
scoreboard.draw();
})
.setSetupSettingsConsumer((player, team, scoreboardTeam) -> scoreboardTeam.setCanSeeFriendlyInvisibles(false));
}
@Override
protected void parseData()
{
Location goal = _mineplexWorld.getIronLocation("YELLOW");
goal.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(goal, getSpectatorLocation())));
_worldComponent.setCreatureAllowOverride(true);
NPC npc = SimpleNPC.of(goal, Villager.class, getGameType().getName());
npc.getEntity().setCustomName(C.cYellowB + "CLICK ME");
npc.getEntity().setCustomNameVisible(true);
_manager.getNpcManager().addNPC(npc);
_worldComponent.setCreatureAllowOverride(false);
_floor = _mineplexWorld.getSpongeLocations(String.valueOf(Material.GLASS.getId()));
_floor.forEach(location -> MapUtil.QuickChangeBlockAt(location, Material.STAINED_GLASS, (byte) 5));
}
@Override
public boolean endGame()
{
return false;
}
@Override
public void disable()
{
}
@EventHandler
public void combatDeath(CombatDeathEvent event)
{
event.SetBroadcastType(DeathMessageType.None);
}
@EventHandler
public void respawn(PlayerGameRespawnEvent event)
{
event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 0, false, false));
}
@EventHandler
public void live(GameStateChangeEvent event)
{
if (event.getState() != GameState.Live)
{
return;
}
_floor.forEach(location -> MapUtil.QuickChangeBlockAt(location, Material.AIR));
}
@EventHandler
public void npcInteract(NPCInteractEvent event)
{
Player player = event.getPlayer();
if (!event.getNpc().getMetadata().equals(getGameType().getName()) || !isAlive(player))
{
return;
}
event.setCancelled(true);
announce(F.main(getManager().getName(), F.name(player.getName()) + " completed the fall in " + F.time(UtilTime.MakeStr(System.currentTimeMillis() - getStateTime())) + "!"), null);
UtilTextMiddle.display(C.cGreen + "End!", "You survived the drop!", 0, 50, 20, player);
_completed.add(player);
addSpectator(event.getPlayer(), false, true);
}
@Override
public GamePlacements getGamePlacements()
{
return GamePlacements.fromTeamPlacements(_completed);
}
}

View File

@ -119,20 +119,20 @@ public abstract class Challenge extends ListenerComponent implements Lifetimed,
}
player.playSound(player.getLocation(), Sound.VILLAGER_YES, 1, 1);
}
if (!_playerWon && _winConditions.isTimeoutAfterFirst())
{
_playerWon = true;
_game.announce(F.main(_game.getManager().getName(), "A player has completed the challenge. " + F.time("3 Seconds") + " left."), Sound.NOTE_STICKS);
_game.getManager().runSyncLater(() ->
if (!_playerWon && _winConditions.isTimeoutAfterFirst())
{
if (isRunning())
_playerWon = true;
_game.announce(F.main(_game.getManager().getName(), "A player has completed the challenge. " + F.time("3 Seconds") + " left."), Sound.NOTE_STICKS);
_game.getManager().runSyncLater(() ->
{
end();
}
}, 3 * 20);
if (isRunning())
{
end();
}
}, 3 * 20);
}
}
}

View File

@ -14,7 +14,7 @@ public class ChallengeCrouch extends Challenge
{
super(game, ChallengeType.CROUCH);
_timeout = 1200;
_timeout = 1500;
}
@Override

View File

@ -62,7 +62,7 @@ public class ChallengeSlimeJump extends Challenge
@Override
protected void completeRemaining()
{
for (Player player : _game.getAlivePlayers())
playerLoop: for (Player player : _game.getAlivePlayers())
{
Pair<Location, Location> box = UtilEnt.getSideStandingBox(player);
Location min = box.getLeft(), max = box.getRight();
@ -74,7 +74,7 @@ public class ChallengeSlimeJump extends Challenge
if (player.getLocation().subtract(x, 0.5, z).getBlock().getType() == Material.EMERALD_BLOCK)
{
completePlayer(player, true);
return;
continue playerLoop;
}
}
}

View File

@ -32,6 +32,7 @@ import mineplex.game.nano.game.GamePlacements;
import mineplex.game.nano.game.GameType;
import mineplex.game.nano.game.SoloGame;
import mineplex.game.nano.game.event.GameStateChangeEvent;
import mineplex.game.nano.game.event.PlayerStateChangeEvent;
public class RedGreenLight extends SoloGame
{
@ -291,6 +292,15 @@ public class RedGreenLight extends SoloGame
UtilTextMiddle.display(null, state.Title, 5, 10, 5, players);
}
@EventHandler
public void playerOut(PlayerStateChangeEvent event)
{
if (!event.isAlive())
{
_order.remove(event.getPlayer());
}
}
@EventHandler
public void playerInteractEntity(PlayerInteractEntityEvent event)
{

View File

@ -62,7 +62,7 @@ public class LobbyManager extends GameManager
private void generatePermissions()
{
PermissionGroup.ETERNAL.setPermission(Perm.BETA_WHITELIST, true, true);
PermissionGroup.TITAN.setPermission(Perm.BETA_WHITELIST, true, true);
}
@EventHandler(priority = EventPriority.HIGHEST)

View File

@ -156,7 +156,7 @@ public class ReturnToHubManager extends GameManager
private void sendToHub(Player player)
{
if (!Recharge.Instance.use(player, "Return To Hub", 2000, false, false))
if (!Recharge.Instance.use(player, "Return To Hub", 1000, false, false))
{
return;
}
@ -166,7 +166,7 @@ public class ReturnToHubManager extends GameManager
private void openShop(Player player)
{
if (!Recharge.Instance.use(player, "Open Favourite", 2000, false, false))
if (!Recharge.Instance.use(player, "Open Favourite", 1000, false, false))
{
return;
}

View File

@ -339,7 +339,7 @@ public class ServerGameMenu extends ShopPageBase<ServerManager, QuickShop>
"you're down hit the Cash Out Clock and",
"claim your rewards.",
"",
C.cWhite + "Limited Beta for " + C.cDAquaB + "ETERNAL" + C.cWhite + " and " + C.cAquaB + "PPC" + C.cWhite + "!",
C.cWhite + "Limited Beta for " + C.cRedB + "TITAN" + C.cWhite + " and " + C.cAquaB + "PPC" + C.cWhite + "!",
"",
C.cWhite + "Perfect for Solo or Parties up to 16."
}, "Nano_Games", true);

View File

@ -112,7 +112,7 @@ public class MinecraftServer
}
// This is super dodgy, this is the only way around monitor not killing game servers with the new MOTD system
if (_motd.isEmpty() || _motd.contains("VOTING") || _motd.contains("STARTING") || _motd.contains("WAITING"))
if (_motd.isEmpty() || _motd.contains("VOTING") || _motd.contains("STARTING") || _motd.contains("WAITING") || _motd.contains("ALWAYS_OPEN"))
{
if (_playerCount < _maxPlayerCount)
{