Make changes from the QA testing

This commit is contained in:
Sam 2018-09-15 14:38:14 +01:00 committed by Alexander Meech
parent 4372854775
commit d066252288
32 changed files with 229 additions and 379 deletions

View File

@ -1523,7 +1523,7 @@ public enum Achievement
NANO_SLIME_TAIL("Not dead yet", 3000, NANO_SLIME_TAIL("Not dead yet", 3000,
new String[]{"Nano Games.SlimeCyclesTail"}, new String[]{"Nano Games.SlimeCyclesTail"},
new String[]{"Get a trail length of 60 blocks", "in Slime Cycles"}, new String[]{"Get a trail length of 100 blocks", "in Slime Cycles"},
new int[]{1}, new int[]{1},
AchievementCategory.NANO_GAMES), AchievementCategory.NANO_GAMES),

View File

@ -14,14 +14,14 @@ public enum NanoDisplay implements Display
COPY_CAT(2, "Copy Cat", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.OCELOT)), COPY_CAT(2, "Copy Cat", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.OCELOT)),
CHICKEN_SHOOT(3, "Chicken Shoot", Material.BOW), CHICKEN_SHOOT(3, "Chicken Shoot", Material.BOW),
COLOUR_CHANGE(4, "Color Swap", Material.WOOL, (byte) 4), COLOUR_CHANGE(4, "Color Swap", Material.WOOL, (byte) 4),
DEATH_TAG(5, "Zombie Survival", Material.SKULL_ITEM, (byte) 2), DEATH_TAG(5, "Zombie Survival", Material.ROTTEN_FLESH),
DROPPER(6, "Dropper", Material.ANVIL), DROPPER(6, "Dropper", Material.ANVIL),
FIND_ORES(7, "Ores Ores Ores", Material.DIAMOND_PICKAXE), FIND_ORES(7, "Ores Ores Ores", Material.DIAMOND_PICKAXE),
HOT_POTATO(8, "Hot Potato", Material.POTATO_ITEM), HOT_POTATO(8, "Hot Potato", Material.POTATO_ITEM),
JUMP_ROPE(9, "Jump Rope", Material.LEASH), JUMP_ROPE(9, "Jump Rope", Material.LEASH),
KING_SLIME(10, "King Slime", Material.SLIME_BALL), KING_SLIME(10, "King Slime", Material.SLIME_BALL),
MICRO_BATTLE(11, "Nano Battle", Material.IRON_SWORD), MICRO_BATTLE(11, "Nano Battle", Material.IRON_SWORD),
MOB_FARM(12, "Mob Farm", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.PIG)), // MOB_FARM(12, "Mob Farm", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.PIG)),
MUSIC_MINECARTS(13, "Musical Minecarts", Material.MINECART), MUSIC_MINECARTS(13, "Musical Minecarts", Material.MINECART),
QUICK(14, "Quick", Material.DIAMOND), QUICK(14, "Quick", Material.DIAMOND),
PARKOUR(15, "Hardcore Parkour", Material.FEATHER), PARKOUR(15, "Hardcore Parkour", Material.FEATHER),

View File

@ -93,7 +93,7 @@ public class LoopedNotePlayer implements Runnable, Component, Lifetimed
if (!_playing) if (!_playing)
{ {
sleep(); sleep();
return; continue;
} }
setTick(_tick + 1); setTick(_tick + 1);

View File

@ -149,7 +149,8 @@ public class NanoGames extends JavaPlugin
ThankManager thankManager = new ThankManager(this, clientManager, donationManager); ThankManager thankManager = new ThankManager(this, clientManager, donationManager);
BoosterManager boosterManager = new BoosterManager(this, boosterGroup, clientManager, donationManager, inventoryManager, thankManager); BoosterManager boosterManager = new BoosterManager(this, boosterGroup, clientManager, donationManager, inventoryManager, thankManager);
new CosmeticManager(this, clientManager, donationManager, inventoryManager, require(GadgetManager.class), petManager, require(TreasureManager.class), boosterManager, punish).setActive(false); CosmeticManager cosmeticManager = new CosmeticManager(this, clientManager, donationManager, inventoryManager, require(GadgetManager.class), petManager, require(TreasureManager.class), boosterManager, punish);
cosmeticManager.setInterfaceSlot(7);
new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, friendManager, require(Chat.class)); new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, friendManager, require(Chat.class));
new MemoryFix(this); new MemoryFix(this);

View File

@ -110,7 +110,7 @@ public class GameCycle extends GameManager
cancel(); cancel();
} }
} }
}, 10, 10); }, 20, 10);
} }
} }

View File

@ -17,7 +17,6 @@ import mineplex.game.nano.game.games.jumprope.JumpRope;
import mineplex.game.nano.game.games.kingslime.KingSlime; import mineplex.game.nano.game.games.kingslime.KingSlime;
import mineplex.game.nano.game.games.microbattle.MicroBattle; import mineplex.game.nano.game.games.microbattle.MicroBattle;
import mineplex.game.nano.game.games.minekart.MineKart; import mineplex.game.nano.game.games.minekart.MineKart;
import mineplex.game.nano.game.games.mobfarm.MobFarm;
import mineplex.game.nano.game.games.musicminecart.MusicMinecarts; import mineplex.game.nano.game.games.musicminecart.MusicMinecarts;
import mineplex.game.nano.game.games.oits.SnowballTrouble; import mineplex.game.nano.game.games.oits.SnowballTrouble;
import mineplex.game.nano.game.games.parkour.Parkour; import mineplex.game.nano.game.games.parkour.Parkour;
@ -45,8 +44,8 @@ public enum GameType
JUMP_ROPE(JumpRope.class, NanoDisplay.JUMP_ROPE), JUMP_ROPE(JumpRope.class, NanoDisplay.JUMP_ROPE),
FIND_ORES(FindOres.class, NanoDisplay.FIND_ORES), FIND_ORES(FindOres.class, NanoDisplay.FIND_ORES),
MUSIC_MINECARTS(MusicMinecarts.class, NanoDisplay.MUSIC_MINECARTS), MUSIC_MINECARTS(MusicMinecarts.class, NanoDisplay.MUSIC_MINECARTS),
MOB_FARM(MobFarm.class, NanoDisplay.MOB_FARM), // MOB_FARM(MobFarm.class, NanoDisplay.MOB_FARM),
CHICKEN_SHOOT(ChickenShoot.class, NanoDisplay.CHICKEN_SHOOT, mapsFromNano(NanoDisplay.MOB_FARM)), CHICKEN_SHOOT(ChickenShoot.class, NanoDisplay.CHICKEN_SHOOT),
SLIME_CYCLES(SlimeCycles.class, NanoDisplay.SLIME_CYCLES), SLIME_CYCLES(SlimeCycles.class, NanoDisplay.SLIME_CYCLES),
TERRITORY(Territory.class, NanoDisplay.TERRITORY), TERRITORY(Territory.class, NanoDisplay.TERRITORY),
COPY_CAT(CopyCat.class, NanoDisplay.COPY_CAT), COPY_CAT(CopyCat.class, NanoDisplay.COPY_CAT),

View File

@ -7,13 +7,16 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerToggleFlightEvent; import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.nano.game.Game; import mineplex.game.nano.game.Game;
import mineplex.game.nano.game.Game.GameState; import mineplex.game.nano.game.Game.GameState;
import mineplex.game.nano.game.GameComponent; import mineplex.game.nano.game.GameComponent;
import mineplex.game.nano.game.event.GameStateChangeEvent;
public class DoubleJumpComponent extends GameComponent<Game> public class DoubleJumpComponent extends GameComponent<Game>
{ {
@ -44,6 +47,32 @@ public class DoubleJumpComponent extends GameComponent<Game>
return this; return this;
} }
@EventHandler
public void live(GameStateChangeEvent event)
{
if (event.getState() != GameState.Live)
{
return;
}
getGame().getManager().runSyncLater(() ->
{
if (!getGame().isLive())
{
return;
}
Player[] players = getGame().getAllPlayers().toArray(new Player[0]);
for (Player player : players)
{
player.playEffect(player.getLocation(), Effect.BLAZE_SHOOT, 8);
}
UtilTextMiddle.display(C.cYellow + "Double Jump", "Double Tap Jump to Leap!", 0, 30, 20, players);
}, 5);
}
@EventHandler(priority = EventPriority.HIGH) @EventHandler(priority = EventPriority.HIGH)
public void updateJump(UpdateEvent event) public void updateJump(UpdateEvent event)
{ {

View File

@ -17,6 +17,8 @@ import mineplex.core.account.permissions.Permission;
import mineplex.core.account.permissions.PermissionGroup; import mineplex.core.account.permissions.PermissionGroup;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.gadget.event.GadgetEnableEvent;
import mineplex.core.gadget.persistence.UserGadgetPersistence;
import mineplex.core.teleport.event.MineplexTeleportEvent; import mineplex.core.teleport.event.MineplexTeleportEvent;
import mineplex.game.nano.GameManager; import mineplex.game.nano.GameManager;
import mineplex.game.nano.game.Game.GameState; import mineplex.game.nano.game.Game.GameState;
@ -154,7 +156,38 @@ public class GamePlayerManager extends GameManager implements ComponentHook<Game
} }
_manager.getCosmeticManager().setHideParticles(_hook.isHideParticles()); _manager.getCosmeticManager().setHideParticles(_hook.isHideParticles());
_manager.getCosmeticManager().getGadgetManager().disableAll(); _manager.getCosmeticManager().disableItemsForGame();
}
@EventHandler
public void enableCosmetics(GameStateChangeEvent event)
{
if (event.getState() != GameState.Loading)
{
return;
}
UserGadgetPersistence gadgetPersistence = _manager.getCosmeticManager().getGadgetManager().getUserGadgetPersistence();
gadgetPersistence.setEnabled(true);
for (Player player : UtilServer.getPlayersCollection())
{
gadgetPersistence.load(player);
}
}
@EventHandler
public void gadgetEnable(GadgetEnableEvent event)
{
if (_hook == null)
{
return;
}
if (event.getGadget().getGadgetType().disableForGame())
{
event.setCancelled(true);
}
} }
@EventHandler @EventHandler

View File

@ -41,8 +41,11 @@ public class GiveItemComponent extends GameComponent<Game>
@EventHandler @EventHandler
public void respawn(PlayerGameRespawnEvent event) public void respawn(PlayerGameRespawnEvent event)
{ {
Player player = event.getPlayer(); giveItems(event.getPlayer());
}
public void giveItems(Player player)
{
if (_items != null) if (_items != null)
{ {
player.getInventory().clear(); player.getInventory().clear();

View File

@ -12,6 +12,7 @@ import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import mineplex.core.achievement.Achievement; import mineplex.core.achievement.Achievement;
import mineplex.core.achievement.AchievementCategory; import mineplex.core.achievement.AchievementCategory;
@ -82,6 +83,12 @@ public class GameStatsComponent extends GameComponent<Game> implements StatsComp
_statsManager.incrementStat(player, stat, amount); _statsManager.incrementStat(player, stat, amount);
} }
@EventHandler
public void playerJoin(PlayerJoinEvent event)
{
getGame().getManager().getAchievementManager().clearLog(event.getPlayer());
}
/* /*
Copied from AchievementSummaryComponent Copied from AchievementSummaryComponent
// TODO Replace and reinvent when reimplementing achievements // TODO Replace and reinvent when reimplementing achievements
@ -99,6 +106,11 @@ public class GameStatsComponent extends GameComponent<Game> implements StatsComp
for (Player player : UtilServer.getPlayersCollection()) for (Player player : UtilServer.getPlayersCollection())
{ {
if (_statsManager.Get(player).isTemporary())
{
continue;
}
Map<Achievement, AchievementLog> logs = manager.getLog(player); Map<Achievement, AchievementLog> logs = manager.getLog(player);
if (logs == null) if (logs == null)

View File

@ -64,6 +64,12 @@ public class GeneralStatsTracker extends StatTracker<Game>
} }
GamePlacements placements = _game.getGamePlacements(); GamePlacements placements = _game.getGamePlacements();
if (placements == null)
{
return;
}
List<Player> allPlayers = _game.getAllPlayers(); List<Player> allPlayers = _game.getAllPlayers();
List<Player> winners = placements.getWinners(); List<Player> winners = placements.getWinners();
@ -76,7 +82,7 @@ public class GeneralStatsTracker extends StatTracker<Game>
// Wins & Losses // Wins & Losses
winners.forEach(player -> addStat(player, "Wins", 1, true, false)); winners.forEach(player -> addStat(player, "Wins", 1, true, false));
if (_game.getTeams().size() > 1 && winners.size() > 1) if (_game.getTeams().size() == 1 && winners.size() > 1)
{ {
winners.forEach(player -> addStat(player, "ShareFirst", 1, true, false)); winners.forEach(player -> addStat(player, "ShareFirst", 1, true, false));
} }

View File

@ -19,10 +19,13 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockDamageEvent; import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilTextMiddle; import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
@ -30,7 +33,6 @@ import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.nano.NanoManager; import mineplex.game.nano.NanoManager;
import mineplex.game.nano.game.GameType; import mineplex.game.nano.game.GameType;
import mineplex.game.nano.game.components.player.NightVisionComponent; import mineplex.game.nano.game.components.player.NightVisionComponent;
import mineplex.game.nano.game.event.PlayerGameRespawnEvent;
import mineplex.game.nano.game.games.copycat.CopyCat.SealBreakerRoom; import mineplex.game.nano.game.games.copycat.CopyCat.SealBreakerRoom;
import mineplex.game.nano.game.roomed.Room; import mineplex.game.nano.game.roomed.Room;
import mineplex.game.nano.game.roomed.RoomedSoloGame; import mineplex.game.nano.game.roomed.RoomedSoloGame;
@ -90,16 +92,7 @@ public class CopyCat extends RoomedSoloGame<SealBreakerRoom>
} }
@EventHandler @EventHandler
public void respawn(PlayerGameRespawnEvent event) public void updateLevels(UpdateEvent event)
{
Player player = event.getPlayer();
player.setAllowFlight(true);
player.setFlying(true);
}
@EventHandler
public void update(UpdateEvent event)
{ {
if (event.getType() != UpdateType.FAST || !isLive()) if (event.getType() != UpdateType.FAST || !isLive())
{ {
@ -108,11 +101,6 @@ public class CopyCat extends RoomedSoloGame<SealBreakerRoom>
_rooms.forEach((player, room) -> _rooms.forEach((player, room) ->
{ {
if (!player.isFlying())
{
player.setFlying(true);
}
if (room.next()) if (room.next())
{ {
UtilTextMiddle.display(C.cYellowB + "Level " + room.Level, C.cRed + room.Blocks + " Blocks", 0, 40, 0, player); UtilTextMiddle.display(C.cYellowB + "Level " + room.Level, C.cRed + room.Blocks + " Blocks", 0, 40, 0, player);
@ -130,6 +118,26 @@ public class CopyCat extends RoomedSoloGame<SealBreakerRoom>
}); });
} }
@EventHandler
public void updateFlight(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
for (Player player : getAllPlayers())
{
player.setAllowFlight(true);
player.setFlying(true);
if (UtilEnt.isGrounded(player))
{
UtilAction.velocity(player, new Vector(0, 0.3, 0));
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void blockPlace(BlockPlaceEvent event) public void blockPlace(BlockPlaceEvent event)
{ {

View File

@ -212,6 +212,7 @@ public class DeathTag extends SoloGame
{ {
announce(F.main(getManager().getName(), F.elem(_runners.getChatColour() + player.getName()) + " has become an " + F.elem(_chasers.getChatColour() + "Alpha Zombie") + ".")); announce(F.main(getManager().getName(), F.elem(_runners.getChatColour() + player.getName()) + " has become an " + F.elem(_chasers.getChatColour() + "Alpha Zombie") + "."));
player.getWorld().strikeLightningEffect(player.getLocation()); player.getWorld().strikeLightningEffect(player.getLocation());
_itemComponent.giveItems(player);
player.getInventory().setArmorContents(new ItemStack[] player.getInventory().setArmorContents(new ItemStack[]
{ {
null, null,

View File

@ -7,7 +7,6 @@ import java.util.concurrent.TimeUnit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
@ -17,12 +16,10 @@ import com.mineplex.anticheat.checks.move.Glide;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.MapUtil; import mineplex.core.common.util.MapUtil;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilTextMiddle; import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime;
import mineplex.core.newnpc.NPC; import mineplex.core.updater.UpdateType;
import mineplex.core.newnpc.SimpleNPC; import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.newnpc.event.NPCInteractEvent;
import mineplex.game.nano.NanoManager; import mineplex.game.nano.NanoManager;
import mineplex.game.nano.game.GamePlacements; import mineplex.game.nano.game.GamePlacements;
import mineplex.game.nano.game.GameType; import mineplex.game.nano.game.GameType;
@ -37,8 +34,9 @@ public class Dropper extends SoloGame
{ {
private List<Location> _floor; private List<Location> _floor;
private int _goalY, _goalDelay;
private final List<Player> _completed; private final List<Player> _completed, _delayed;
public Dropper(NanoManager manager) public Dropper(NanoManager manager)
{ {
@ -49,6 +47,7 @@ public class Dropper extends SoloGame
}); });
_completed = new ArrayList<>(); _completed = new ArrayList<>();
_delayed = new ArrayList<>();
_prepareComponent.setPrepareFreeze(false); _prepareComponent.setPrepareFreeze(false);
@ -90,19 +89,16 @@ public class Dropper extends SoloGame
@Override @Override
protected void parseData() protected void parseData()
{ {
Location goal = _mineplexWorld.getIronLocation("YELLOW"); _mineplexWorld.getSpongeLocations().forEach((key, locations) ->
goal.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(goal, getSpectatorLocation()))); {
if (!key.startsWith("END"))
{
return;
}
_worldComponent.setCreatureAllowOverride(true); _goalY = locations.get(0).getBlockY();
_goalDelay = Integer.parseInt(key.split(" ")[1]);
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 = _mineplexWorld.getSpongeLocations(String.valueOf(Material.GLASS.getId()));
_floor.forEach(location -> MapUtil.QuickChangeBlockAt(location, Material.STAINED_GLASS, (byte) 5)); _floor.forEach(location -> MapUtil.QuickChangeBlockAt(location, Material.STAINED_GLASS, (byte) 5));
@ -129,7 +125,10 @@ public class Dropper extends SoloGame
@EventHandler @EventHandler
public void respawn(PlayerGameRespawnEvent event) public void respawn(PlayerGameRespawnEvent event)
{ {
event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 0, false, false)); Player player = event.getPlayer();
_delayed.remove(player);
player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 0, false, false));
} }
@EventHandler @EventHandler
@ -144,28 +143,35 @@ public class Dropper extends SoloGame
} }
@EventHandler @EventHandler
public void npcInteract(NPCInteractEvent event) public void update(UpdateEvent event)
{ {
if (!isLive()) if (event.getType() != UpdateType.TICK)
{ {
return; return;
} }
Player player = event.getPlayer(); for (Player player : getAlivePlayers())
if (!event.getNpc().getMetadata().equals(getGameType().getName()) || !isAlive(player))
{ {
return; if (_delayed.contains(player) || player.getLocation().getY() > _goalY)
{
continue;
}
_delayed.add(player);
getManager().runSyncLater(() ->
{
if (!isLive() || !isAlive(player))
{
return;
}
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(player, false, true);
}, _goalDelay);
} }
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 @Override

View File

@ -7,6 +7,7 @@ import org.bukkit.entity.Sheep;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime;
import mineplex.game.nano.game.games.minekart.KartController.DriftDirection; import mineplex.game.nano.game.games.minekart.KartController.DriftDirection;
@ -45,7 +46,14 @@ public class Kart
UtilEnt.ghost(_vehicle, true, false); UtilEnt.ghost(_vehicle, true, false);
UtilEnt.setFakeHead(_vehicle, true); UtilEnt.setFakeHead(_vehicle, true);
_vehicle.setColor(DyeColor.RED); if (driver.isOp())
{
_vehicle.setCustomName("jeb_");
}
else
{
_vehicle.setColor(UtilMath.randomElement(DyeColor.values()));
}
_vehicle.setPassenger(driver); _vehicle.setPassenger(driver);

View File

@ -79,12 +79,12 @@ public class KartController
if (length > 0.4) if (length > 0.4)
{ {
velocity.multiply(-0.6); velocity.multiply(-0.6);
velocity.setY(0.4); velocity.setY(0.3);
} }
else else
{ {
velocity = UtilAlg.getTrajectory(kart.getYaw(), 0).multiply(-0.4); velocity = UtilAlg.getTrajectory(kart.getYaw(), 0).multiply(-0.4);
velocity.setY(0.4); velocity.setY(0.3);
kart.setVelocity(velocity); kart.setVelocity(velocity);
} }
@ -158,13 +158,13 @@ public class KartController
} }
float velocityInverse = (float) (2 - speed); float velocityInverse = (float) (2 - speed);
float newYaw = kart.getYaw() - (3 * kart.getSidewaysInput() * velocityInverse); float newYaw = kart.getYaw() - (4 * kart.getSidewaysInput() * velocityInverse);
kart.setYaw(newYaw); kart.setYaw(newYaw);
Vector turn = UtilAlg.getTrajectory(newYaw, 0); Vector turn = UtilAlg.getTrajectory(newYaw, 0);
turn.subtract(new Vector(velocity.getX(), 0, velocity.getZ()).normalize()).multiply(0.033); turn.subtract(new Vector(velocity.getX(), 0, velocity.getZ()).normalize()).multiply(0.05);
velocity.add(turn); velocity.add(turn);
@ -185,7 +185,7 @@ public class KartController
return; return;
} }
if (kart.getDriftDirection() != null && kart.getVelocity().length() > 0.1) if (kart.getDriftDirection() != null && kart.getVelocity().length() > 0.25)
{ {
float power = kart.getDriftPower() + (0.05F * (kart.getDriftDirection() == DriftDirection.LEFT ? kart.getSidewaysInput() : -kart.getSidewaysInput())); float power = kart.getDriftPower() + (0.05F * (kart.getDriftDirection() == DriftDirection.LEFT ? kart.getSidewaysInput() : -kart.getSidewaysInput()));

View File

@ -91,16 +91,16 @@ public class MineKart extends SoloGame implements IPacketHandler
return 1; return 1;
} }
if (o1.getLapKeyCheckpoint() != o2.getLapKeyCheckpoint())
{
return Integer.compare(o2.getLapKeyCheckpoint(), o1.getLapKeyCheckpoint());
}
if (o1.getLap() != o2.getLap()) if (o1.getLap() != o2.getLap())
{ {
return Integer.compare(o2.getLap(), o1.getLap()); return Integer.compare(o2.getLap(), o1.getLap());
} }
if (o1.getLapKeyCheckpoint() != o2.getLapKeyCheckpoint())
{
return Integer.compare(o2.getLapKeyCheckpoint(), o1.getLapKeyCheckpoint());
}
return Integer.compare(o2.getLapCheckpoint(), o1.getLapCheckpoint()); return Integer.compare(o2.getLapCheckpoint(), o1.getLapCheckpoint());
}; };
@ -491,6 +491,7 @@ public class MineKart extends SoloGame implements IPacketHandler
if (points.isEmpty()) if (points.isEmpty())
{ {
kart.setVelocity(new Vector()); kart.setVelocity(new Vector());
kart.getVehicle().setFallDistance(0);
kart.setResetting(false); kart.setResetting(false);
cancel(); cancel();
return; return;

View File

@ -1,241 +0,0 @@
package mineplex.game.nano.game.games.mobfarm;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.nano.NanoManager;
import mineplex.game.nano.game.GameType;
import mineplex.game.nano.game.ScoredSoloGame;
import mineplex.game.nano.game.components.player.GiveItemComponent;
import mineplex.game.nano.game.event.GameStateChangeEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class MobFarm extends ScoredSoloGame
{
private static final int MAX_MOBS = 30;
private static final int MAX_MINUS_TICKS = 400;
private enum MobType
{
CHICKEN(EntityType.CHICKEN, 1, ChatColor.WHITE, 1),
PIG(EntityType.PIG, 3, ChatColor.LIGHT_PURPLE, 6),
COW(EntityType.COW, 5, ChatColor.GOLD, 10),
;
final EntityType Type;
final int Points;
final ChatColor Colour;
final int Health;
MobType(EntityType type, int points, ChatColor colour, int health)
{
Type = type;
Points = points;
Colour = colour;
Health = health;
}
}
private final Map<LivingEntity, Boolean> _mobs;
private List<Location> _mobSpawns;
public MobFarm(NanoManager manager)
{
super(manager, GameType.MOB_FARM, new String[]
{
"Kill " + C.cYellow + "Mobs" + C.Reset + " to earn points.",
C.cGreen + "Bigger" + C.Reset + " mobs give more points.",
"Watch out for " + C.cRed + "Minus" + C.Reset + " mobs. They will reduce your score.",
C.cYellow + "Most points" + C.Reset + " wins!"
});
_mobs = new HashMap<>();
_prepareComponent.setPrepareFreeze(false);
_damageComponent.setPvp(false);
_damageComponent.setFall(false);
_endComponent.setTimeout(TimeUnit.SECONDS.toMillis(75));
new GiveItemComponent(this)
.setItems(new ItemStack[]
{
new ItemBuilder(Material.WOOD_SWORD)
.setUnbreakable(true)
.build()
});
}
@Override
protected void parseData()
{
_mobSpawns = _mineplexWorld.getIronLocations("LIME");
}
@Override
public void disable()
{
super.disable();
_mobSpawns.clear();
}
@EventHandler
public void updateMobs(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST || !isLive())
{
return;
}
_mobs.entrySet().removeIf(entry ->
{
LivingEntity entity = entry.getKey();
if (entry.getValue() && entity.getTicksLived() > MAX_MINUS_TICKS)
{
entity.setHealth(0);
return true;
}
return false;
});
while (_mobs.size() < MAX_MOBS)
{
MobType mobType = getRandomMob();
Location location = UtilAlg.Random(_mobSpawns);
if (location == null)
{
return;
}
_worldComponent.setCreatureAllowOverride(true);
location.setYaw(UtilMath.r(360));
LivingEntity entity = (LivingEntity) location.getWorld().spawnEntity(location, mobType.Type);
if (Math.random() < 0.1)
{
entity.setCustomName(C.cRedB + "MINUS 50%");
entity.setMaxHealth(1);
_mobs.put(entity, true);
}
else
{
entity.setCustomName(mobType.Colour + C.Bold + "+" + mobType.Points + " Point" + (mobType.Points == 1 ? "" : "s"));
entity.setMaxHealth(mobType.Health);
_mobs.put(entity, false);
}
entity.setCustomNameVisible(true);
entity.setHealth(entity.getMaxHealth());
}
}
@EventHandler(ignoreCancelled = true)
public void damage(CustomDamageEvent event)
{
if (_mobs.containsKey(event.GetDamageeEntity()))
{
event.GetDamageeEntity().addPotionEffect(new PotionEffect(PotionEffectType.SPEED, Integer.MAX_VALUE, 1, false, false));
}
}
@EventHandler
public void entityDeath(EntityDeathEvent event)
{
LivingEntity entity = event.getEntity();
Boolean minus = _mobs.remove(entity);
if (minus != null)
{
event.getDrops().clear();
event.setDroppedExp(0);
Player killer = entity.getKiller();
if (killer == null)
{
return;
}
if (minus)
{
getScores().put(killer, getScores().getOrDefault(killer, 0) / 2);
killer.playSound(entity.getLocation(), Sound.SILVERFISH_KILL, 1, 1);
}
else
{
incrementScore(killer, getPointsFor(entity));
}
}
}
@EventHandler
public void end(GameStateChangeEvent event)
{
if (event.getState() != GameState.End)
{
return;
}
_mobs.keySet().forEach(entity -> entity.setHealth(0));
}
private MobType getRandomMob()
{
double random = Math.random();
if (random > 0.5)
{
return MobType.CHICKEN;
}
else if (random > 0.1)
{
return MobType.PIG;
}
return MobType.COW;
}
private int getPointsFor(LivingEntity entity)
{
for (MobType type : MobType.values())
{
if (type.Type == entity.getType())
{
return type.Points;
}
}
return 0;
}
}

View File

@ -128,14 +128,14 @@ public abstract class Challenge extends ListenerComponent implements Lifetimed,
{ {
_playerWon = true; _playerWon = true;
_game.announce(F.main(_game.getManager().getName(), "A player has completed the challenge. " + F.time("3 Seconds") + " left."), Sound.NOTE_STICKS); _game.announce(F.main(_game.getManager().getName(), "A player has completed the challenge. " + F.time(_winConditions.getTimeout() + " Second" + (_winConditions.getTimeout() == 1 ? "" : "s")) + " left."), Sound.NOTE_STICKS);
_game.getManager().runSyncLater(() -> _game.getManager().runSyncLater(() ->
{ {
if (isRunning()) if (isRunning())
{ {
end(); end();
} }
}, 3 * 20); }, _winConditions.getTimeout() * 20);
} }
} }
} }

View File

@ -48,7 +48,7 @@ public enum ChallengeType
SLIME_JUMP(ChallengeSlimeJump.class, "Get on the emerald blocks!"), SLIME_JUMP(ChallengeSlimeJump.class, "Get on the emerald blocks!"),
PUNCH_A_PIG(ChallengePunchAPig.class, "Punch 5 Pigs!"), PUNCH_A_PIG(ChallengePunchAPig.class, "Punch 5 Pigs!"),
IGNITE_TNT(ChallengeIgniteTNT.class, "Ignite the TNT!"), IGNITE_TNT(ChallengeIgniteTNT.class, "Ignite the TNT!"),
SPIN(ChallengeSpin.class, "Spin around has fast as you can!"), SPIN(ChallengeSpin.class, "Spin around as fast as you can!"),
PLAY_MUSIC(ChallengePlayMusic.class, "Play a song on the noteblocks!"), PLAY_MUSIC(ChallengePlayMusic.class, "Play a song on the noteblocks!"),
MATHS_QUESTION(ChallengeMaths.class, "Get ready! Solve this math equation..."), MATHS_QUESTION(ChallengeMaths.class, "Get ready! Solve this math equation..."),
MILK_A_COW(ChallengeMilkCow.class, "Drink the milk from one of the cows!"), MILK_A_COW(ChallengeMilkCow.class, "Drink the milk from one of the cows!"),

View File

@ -5,6 +5,7 @@ public class ChallengeWinConditions
private boolean _lastOne, _lastThree, _timeoutWin; private boolean _lastOne, _lastThree, _timeoutWin;
private boolean _timeoutAfterFirst; private boolean _timeoutAfterFirst;
private int _timeout = 3;
public ChallengeWinConditions setLastOne(boolean lastOne) public ChallengeWinConditions setLastOne(boolean lastOne)
{ {
@ -47,8 +48,20 @@ public class ChallengeWinConditions
return this; return this;
} }
public ChallengeWinConditions setTimeoutAfterFirst(boolean firstHalfWin, int timeout)
{
_timeoutAfterFirst = firstHalfWin;
_timeout = timeout;
return this;
}
public boolean isTimeoutAfterFirst() public boolean isTimeoutAfterFirst()
{ {
return _timeoutAfterFirst; return _timeoutAfterFirst;
} }
public int getTimeout()
{
return _timeout;
}
} }

View File

@ -80,13 +80,13 @@ public class ChallengeIgniteTNT extends Challenge
} }
ItemStack itemStack = player.getItemInHand(); ItemStack itemStack = player.getItemInHand();
Block block = event.getClickedBlock();
if (itemStack == null || itemStack.getType() != Material.FLINT_AND_STEEL || event.getClickedBlock().getType() != Material.TNT) if (itemStack == null || itemStack.getType() != Material.FLINT_AND_STEEL || block.getType() != Material.TNT || !inArena(block))
{ {
return; return;
} }
_game.getManager().runSyncLater(() -> _game.getManager().runSyncLater(() ->
{ {
completePlayer(player, true); completePlayer(player, true);

View File

@ -16,7 +16,7 @@ public class ChallengeIntoVoid extends Challenge
{ {
super(game, ChallengeType.INTO_VOID); super(game, ChallengeType.INTO_VOID);
_winConditions.setTimeoutAfterFirst(true); _winConditions.setTimeoutAfterFirst(true, 1);
} }
@Override @Override

View File

@ -21,7 +21,7 @@ public class ChallengeMilkCow extends Challenge
{ {
super(game, ChallengeType.MILK_A_COW); super(game, ChallengeType.MILK_A_COW);
_winConditions.setTimeoutAfterFirst(true); _timeout = 2500;
} }
@Override @Override

View File

@ -51,6 +51,8 @@ public class ChallengePlayMusic extends Challenge
_song = song; _song = song;
_songTick = new HashMap<>(); _songTick = new HashMap<>();
_timeout = 2500;
} }
@Override @Override

View File

@ -25,7 +25,7 @@ public class ChallengePole extends Challenge
super(game, ChallengeType.POLE); super(game, ChallengeType.POLE);
_timeout = TimeUnit.SECONDS.toMillis(25); _timeout = TimeUnit.SECONDS.toMillis(25);
_winConditions.setTimeoutAfterFirst(true); _winConditions.setTimeoutAfterFirst(true, 1);
} }
@Override @Override

View File

@ -27,6 +27,7 @@ import mineplex.game.nano.NanoManager;
import mineplex.game.nano.game.GameType; import mineplex.game.nano.game.GameType;
import mineplex.game.nano.game.ScoredSoloGame; import mineplex.game.nano.game.ScoredSoloGame;
import mineplex.game.nano.game.event.GameStateChangeEvent; import mineplex.game.nano.game.event.GameStateChangeEvent;
import mineplex.game.nano.game.event.PlayerStateChangeEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class ReverseTag extends ScoredSoloGame public class ReverseTag extends ScoredSoloGame
@ -184,4 +185,13 @@ public class ReverseTag extends ScoredSoloGame
event.setCancelled(true); event.setCancelled(true);
} }
} }
@EventHandler
public void playerQut(PlayerStateChangeEvent event)
{
if (!event.isAlive())
{
_holders.remove(event.getPlayer());
}
}
} }

View File

@ -154,7 +154,7 @@ public class SlimeCycles extends SoloGame
_trailSize++; _trailSize++;
if (_trailSize == 60) if (_trailSize == 100)
{ {
getAlivePlayers().forEach(player -> addStat(player, "SlimeCyclesTail", 1, true, false)); getAlivePlayers().forEach(player -> addStat(player, "SlimeCyclesTail", 1, true, false));
} }

View File

@ -11,19 +11,13 @@ import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.account.permissions.Permission;
import mineplex.core.account.permissions.PermissionGroup;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle; import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.powerplayclub.PowerPlayClubRepository;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.world.MineplexWorld; import mineplex.core.world.MineplexWorld;
@ -34,48 +28,24 @@ import mineplex.game.nano.NanoPlayer;
public class LobbyManager extends GameManager public class LobbyManager extends GameManager
{ {
public enum Perm implements Permission
{
BETA_WHITELIST,
}
private final PowerPlayClubRepository _powerPlayClub;
private final MineplexWorld _mineplexWorld; private final MineplexWorld _mineplexWorld;
private final Location _spawn; private final Location _spawn;
private boolean _infoTick; private final String[] _info =
{
"This game goes on forever! If you ever want to cash out on your rewards, you can do so at any time using the " + C.cGreen + "Cash Out Clock" + C.cPurple + " or " + C.cYellow + "/hub" + C.cPurple + "!",
"Suggest new " + C.cGreen + "Nano Games" + C.cPurple + "! We're open to hearing your ideas and changes! Click " + C.cYellowB + "HERE" + C.cPurple + " to go to the forums and suggest them!",
};
private int _infoTick;
private LobbyManager() private LobbyManager()
{ {
super("Lobby"); super("Lobby");
_powerPlayClub = new PowerPlayClubRepository(_plugin, _manager.getClientManager(), _manager.getDonationManager());
_mineplexWorld = new MineplexWorld(Bukkit.getWorlds().get(0)); _mineplexWorld = new MineplexWorld(Bukkit.getWorlds().get(0));
_spawn = _mineplexWorld.getSpongeLocation("SPAWN"); _spawn = _mineplexWorld.getSpongeLocation("SPAWN");
_mineplexWorld.getWorld().setSpawnLocation(_spawn.getBlockX(), _spawn.getBlockY(), _spawn.getBlockZ()); _mineplexWorld.getWorld().setSpawnLocation(_spawn.getBlockX(), _spawn.getBlockY(), _spawn.getBlockZ());
generatePermissions();
}
private void generatePermissions()
{
PermissionGroup.TITAN.setPermission(Perm.BETA_WHITELIST, true, true);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void playerLogin(PlayerLoginEvent event)
{
Player player = event.getPlayer();
if (_manager.getClientManager().Get(player).hasPermission(Perm.BETA_WHITELIST) || _powerPlayClub.getCachedData(player).isSubscribed())
{
return;
}
event.disallow(Result.KICK_WHITELIST, "Only players with Eternal or PPC can participate in the BETA.");
} }
@EventHandler @EventHandler
@ -86,24 +56,14 @@ public class LobbyManager extends GameManager
return; return;
} }
String info = C.cPurpleB + "INFO" + C.cDGrayB + "> " + C.cPurple; String info = C.cPurpleB + "INFO" + C.cDGrayB + "> " + C.cPurple + _info[_infoTick];
_infoTick = (_infoTick + 1) % _info.length;
if (_infoTick)
{
info += C.cGreen + "Nano Games" + C.cPurple + " are still in development and do not represent a finished product. You can leave feedback and report bugs " + C.cYellowB + "HERE" + C.cPurple + ".";
}
else
{
info += "This game goes on forever! If you ever want to cash out on your rewards, you can do so at any time using the " + C.cGreen + "Cash Out Clock" + C.cPurple + " or " + C.cYellow + "/hub" + C.cPurple + "!";
}
_infoTick = !_infoTick;
BaseComponent[] components = TextComponent.fromLegacyText(info); BaseComponent[] components = TextComponent.fromLegacyText(info);
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Click here to visit the forums.") HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Click here to visit the forums.")
.color(ChatColor.YELLOW) .color(ChatColor.YELLOW)
.create()); .create());
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.mineplex.com/forums/m/11929946/viewforum/3983713"); ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.OPEN_URL, "https://mineplex.com/forums/nano-games.388/");
for (BaseComponent component : components) for (BaseComponent component : components)
{ {

View File

@ -68,7 +68,7 @@ public class ReturnToHubManager extends GameManager
sendToHub(caller); sendToHub(caller);
} }
}); });
addCommand(new CommandBase<ReturnToHubManager>(this, Perm.COMMANDS, "favorite", "favoritegames") addCommand(new CommandBase<ReturnToHubManager>(this, Perm.COMMANDS, "favorite", "fav")
{ {
@Override @Override
public void Execute(Player caller, String[] args) public void Execute(Player caller, String[] args)
@ -151,7 +151,8 @@ public class ReturnToHubManager extends GameManager
PlayerInventory inventory = player.getInventory(); PlayerInventory inventory = player.getInventory();
inventory.setItem(8, HUB_CLOCK); inventory.setItem(8, HUB_CLOCK);
inventory.setItem(7, FAVOURITE_STAR); _manager.getCosmeticManager().giveInterfaceItem(player);
inventory.setItem(6, FAVOURITE_STAR);
} }
private void sendToHub(Player player) private void sendToHub(Player player)

View File

@ -138,7 +138,7 @@ public class GameWorld
MapUtil.UnloadWorld(_game.getManager().getPlugin(), _world); MapUtil.UnloadWorld(_game.getManager().getPlugin(), _world);
MapUtil.ClearWorldReferences(_world.getName()); MapUtil.ClearWorldReferences(_world.getName());
FileUtil.DeleteFolder(_world.getWorldFolder()); FileUtil.DeleteFolder(new File(_world.getName()));
_world = null; _world = null;
} }

View File

@ -330,7 +330,7 @@ public class ServerGameMenu extends ShopPageBase<ServerManager, QuickShop>
"", "",
C.cWhite + "Perfect for Solo or Parties of any size." C.cWhite + "Perfect for Solo or Parties of any size."
}, null); }, null);
add(13, new ItemBuilder(Material.EGG), "Nano Games", C.cYellow + C.Scramble + "ABC" + C.cGreenB + " Nano Games " + C.cYellow + C.Scramble + "DEF" + C.cGray + " Limited Beta Game", new String[] add(13, new ItemBuilder(Material.EGG), "Nano Games", C.cYellow + C.Scramble + "ABC" + C.cGreenB + " Nano Games " + C.cYellow + C.Scramble + "DEF" + C.cGray + " Beta Game", new String[]
{ {
"Game Over? Straight into the next!", "Game Over? Straight into the next!",
"Want to enjoy constant action with no", "Want to enjoy constant action with no",
@ -339,8 +339,6 @@ public class ServerGameMenu extends ShopPageBase<ServerManager, QuickShop>
"you're down hit the Cash Out Clock and", "you're down hit the Cash Out Clock and",
"claim your rewards.", "claim your rewards.",
"", "",
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." C.cWhite + "Perfect for Solo or Parties up to 16."
}, "Nano_Games", true); }, "Nano_Games", true);