38a20f98c2
These two directories contain code that was removed from the src and dependencies of the compiled files. They were removed due to being either a. unnecessary or b. a royal pain in my booty.
432 lines
10 KiB
Java
432 lines
10 KiB
Java
package mineplex.core.gadget.gadgets.item;
|
|
|
|
import java.time.Month;
|
|
import java.time.YearMonth;
|
|
import java.util.Arrays;
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.Sound;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.entity.ArmorStand;
|
|
import org.bukkit.entity.Entity;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
|
|
|
import mineplex.core.common.util.C;
|
|
import mineplex.core.common.util.F;
|
|
import mineplex.core.common.util.UtilBlock;
|
|
import mineplex.core.common.util.UtilEnt;
|
|
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.UtilTextMiddle;
|
|
import mineplex.core.common.util.UtilTime;
|
|
import mineplex.core.gadget.GadgetManager;
|
|
import mineplex.core.gadget.util.CostConstants;
|
|
import mineplex.core.itemstack.ItemBuilder;
|
|
import mineplex.core.recharge.Recharge;
|
|
import mineplex.core.updater.UpdateType;
|
|
import mineplex.core.updater.event.UpdateEvent;
|
|
|
|
public class ItemOAndX extends GameItemGadget
|
|
{
|
|
|
|
private static final long COOLDOWN_USE = TimeUnit.SECONDS.toMillis(15);
|
|
private static final int BOARD_SIZE = 9;
|
|
private static final int[][] TILE_LOCATIONS =
|
|
{
|
|
{
|
|
-1, -1,
|
|
},
|
|
{
|
|
-1, 0,
|
|
},
|
|
{
|
|
-1, 1
|
|
},
|
|
{
|
|
0, -1
|
|
},
|
|
{
|
|
0, 0
|
|
},
|
|
{
|
|
0, 1,
|
|
},
|
|
{
|
|
1, -1
|
|
},
|
|
{
|
|
1, 0
|
|
},
|
|
{
|
|
1, 1
|
|
}
|
|
};
|
|
private static final ItemStack FLOOR = new ItemStack(Material.WOOL);
|
|
private static final ItemStack DEFAULT_TILE = new ItemStack(Material.WOOL, 1, (short) 0, (byte) 15);
|
|
private static final long TIMEOUT = TimeUnit.MINUTES.toMillis(2);
|
|
|
|
private final Set<GameBoard> _gameBoards;
|
|
|
|
public ItemOAndX(GadgetManager manager)
|
|
{
|
|
super(manager, "Tic Tac Toe", new String[]
|
|
{
|
|
C.cGray + "Play Tic Tac Toe",
|
|
C.cGray + "with other players!",
|
|
C.blankLine,
|
|
C.cWhite + "Left click the block",
|
|
C.cWhite + "to claim it.",
|
|
C.cWhite + "First person to get 3",
|
|
C.cWhite + "in a row"
|
|
}, CostConstants.POWERPLAY_BONUS, Material.CARPET, (byte) 14, null);
|
|
|
|
_gameBoards = new HashSet<>(3);
|
|
|
|
Free = false;
|
|
setPPCYearMonth(YearMonth.of(2017, Month.NOVEMBER));
|
|
}
|
|
|
|
@Override
|
|
public boolean activatePreprocess(Player player)
|
|
{
|
|
for (GameBoard board : _gameBoards)
|
|
{
|
|
if (board.PlayerA.equals(player) || board.PlayerB.equals(player))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
protected void startGame(Player invitee, Player inviter)
|
|
{
|
|
Location location = inviter.getLocation();
|
|
|
|
if (!UtilEnt.isGrounded(inviter))
|
|
{
|
|
inviter.sendMessage(F.main(Manager.getName(), "You must be on the ground to play."));
|
|
invitee.sendMessage(F.main(Manager.getName(), "Sorry, " + F.name(inviter.getName()) + " needs to be on the ground to play."));
|
|
return;
|
|
}
|
|
|
|
for (Block block : UtilBlock.getInBoundingBox(location.clone().add(2, 1, 2), location.clone().subtract(2, 0, 2)))
|
|
{
|
|
if (UtilBlock.airFoliage(block))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
inviter.sendMessage(F.main(Manager.getName(), "You cannot play in such a small area."));
|
|
invitee.sendMessage(F.main(Manager.getName(), "Sorry, " + F.name(inviter.getName()) + " needs to find a more open area to play."));
|
|
return;
|
|
}
|
|
|
|
invitee.sendMessage(F.main(Manager.getName(), F.name(inviter.getName()) + " challenged you to a game of " + F.name(getName()) + "!"));
|
|
inviter.sendMessage(F.main(Manager.getName(), "You challenged " + F.name(invitee.getName()) + " to a game of " + F.name(getName()) + "!"));
|
|
|
|
location.setYaw(0);
|
|
|
|
{
|
|
Location teleport = location.clone().add(0, 0, 2);
|
|
teleport.setYaw(180);
|
|
inviter.teleport(teleport);
|
|
}
|
|
{
|
|
Location teleport = location.clone().subtract(0, 0, 2);
|
|
teleport.setYaw(0);
|
|
invitee.teleport(teleport);
|
|
}
|
|
|
|
String title = C.cYellowB + getName();
|
|
UtilTextMiddle.display(title, "You are " + C.cGreenB + "Green", 0, 20, 5, invitee);
|
|
UtilTextMiddle.display(title, "You are " + C.cRedB + "Red", 0, 20, 5, inviter);
|
|
location.getWorld().playSound(location, Sound.LEVEL_UP, 1, 1);
|
|
|
|
_gameBoards.add(new GameBoard(inviter, invitee, location.subtract(0, 1.4, 0)));
|
|
}
|
|
|
|
@EventHandler
|
|
public void armorStandInteract(EntityDamageByEntityEvent event)
|
|
{
|
|
if (!(event.getDamager() instanceof Player))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Entity entity = event.getEntity();
|
|
Player player = (Player) event.getDamager();
|
|
|
|
for (GameBoard board : _gameBoards)
|
|
{
|
|
boolean playerA = board.PlayerA.equals(player);
|
|
boolean playerB = board.PlayerB.equals(player);
|
|
boolean playerATurn = board.Turn % 2 == 0;
|
|
|
|
if (!playerA && !playerB)
|
|
{
|
|
continue;
|
|
}
|
|
else if (playerA && !playerATurn || playerB && playerATurn)
|
|
{
|
|
player.sendMessage(F.main(Manager.getName(), "It's not your turn."));
|
|
continue;
|
|
}
|
|
|
|
for (int i = 0; i < board.Pieces.length; i++)
|
|
{
|
|
ArmorStand piece = board.Pieces[i];
|
|
|
|
if (!piece.equals(entity))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
int ownership = board.OwnedPieces[i];
|
|
|
|
if (ownership != 0)
|
|
{
|
|
player.sendMessage(F.main(Manager.getName(), "That piece has already been claimed."));
|
|
}
|
|
else
|
|
{
|
|
board.OwnedPieces[i] = playerATurn ? 1 : 2;
|
|
piece.setHelmet(new ItemBuilder(Material.WOOL, (byte) (playerATurn ? 14 : 5)).build());
|
|
piece.getWorld().playSound(piece.getLocation(), Sound.NOTE_STICKS, 1, 1);
|
|
UtilParticle.PlayParticleToAll(ParticleType.CRIT, piece.getLocation().add(0, 1.5, 0), 0.25F, 0.25F, 0.25F, 0.05F, 5, ViewDist.NORMAL);
|
|
|
|
board.nextTurn();
|
|
|
|
Manager.runSyncTimer(new BukkitRunnable()
|
|
{
|
|
int iterations = 0;
|
|
|
|
@Override
|
|
public void run()
|
|
{
|
|
if (++iterations == 10)
|
|
{
|
|
cancel();
|
|
return;
|
|
}
|
|
|
|
piece.teleport(piece.getLocation().subtract(0, 0.025, 0));
|
|
}
|
|
}, 1, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void disableCustom(Player player, boolean message)
|
|
{
|
|
super.disableCustom(player, message);
|
|
|
|
remove(player);
|
|
}
|
|
|
|
private void remove(Player player)
|
|
{
|
|
_gameBoards.removeIf(board ->
|
|
{
|
|
if (board.PlayerA.equals(player) || board.PlayerB.equals(player))
|
|
{
|
|
cleanupBoard(board, false);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
_invites.remove(player.getName());
|
|
}
|
|
|
|
@EventHandler
|
|
public void updateTimeout(UpdateEvent event)
|
|
{
|
|
if (event.getType() != UpdateType.SLOWER)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_gameBoards.removeIf(board ->
|
|
{
|
|
if (UtilTime.elapsed(board.StartTime, TIMEOUT))
|
|
{
|
|
cleanupBoard(board, false);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
}
|
|
|
|
private void cleanupBoard(GameBoard board, boolean remove)
|
|
{
|
|
Recharge.Instance.use(board.PlayerA, getName(), COOLDOWN_USE, true, true);
|
|
board.cleanup();
|
|
|
|
if (remove)
|
|
{
|
|
_gameBoards.remove(board);
|
|
}
|
|
}
|
|
|
|
private class GameBoard
|
|
{
|
|
|
|
final Player PlayerA;
|
|
final Player PlayerB;
|
|
final int[] OwnedPieces;
|
|
final ArmorStand[] Floor;
|
|
final ArmorStand[] Pieces;
|
|
final long StartTime;
|
|
int Turn;
|
|
boolean First = true;
|
|
|
|
GameBoard(Player playerA, Player playerB, Location center)
|
|
{
|
|
PlayerA = playerA;
|
|
PlayerB = playerB;
|
|
|
|
OwnedPieces = new int[BOARD_SIZE];
|
|
Arrays.fill(OwnedPieces, 0);
|
|
|
|
Floor = new ArmorStand[BOARD_SIZE];
|
|
Pieces = new ArmorStand[BOARD_SIZE];
|
|
|
|
for (int i = 0; i < Floor.length; i++)
|
|
{
|
|
int[] cords = TILE_LOCATIONS[i];
|
|
Location location = center.clone().add(cords[0], 0, cords[1]);
|
|
|
|
{
|
|
ArmorStand stand = location.getWorld().spawn(location, ArmorStand.class);
|
|
|
|
prepareStand(stand);
|
|
stand.setHelmet(FLOOR);
|
|
|
|
Floor[i] = stand;
|
|
}
|
|
{
|
|
ArmorStand stand = location.getWorld().spawn(location.add(0, 1.25, 0), ArmorStand.class);
|
|
|
|
prepareStand(stand);
|
|
stand.setSmall(true);
|
|
stand.setHelmet(DEFAULT_TILE);
|
|
|
|
Pieces[i] = stand;
|
|
}
|
|
}
|
|
|
|
StartTime = System.currentTimeMillis();
|
|
|
|
// Starting on turn 1 will make player B go first
|
|
if (Math.random() > 0.5)
|
|
{
|
|
Turn = 1;
|
|
}
|
|
|
|
nextTurn();
|
|
}
|
|
|
|
void nextTurn()
|
|
{
|
|
boolean playerATurn = Turn % 2 == 0;
|
|
|
|
if (hasDrawn())
|
|
{
|
|
drawGame(PlayerA, PlayerB);
|
|
cleanupBoard(this, true);
|
|
return;
|
|
}
|
|
else if (hasWon(playerATurn ? 1 : 2))
|
|
{
|
|
Player winner = playerATurn ? PlayerA : PlayerB;
|
|
Player loser = playerATurn ? PlayerB : PlayerA;
|
|
|
|
endGame(winner, loser);
|
|
cleanupBoard(this, true);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
Turn++;
|
|
playerATurn = !playerATurn;
|
|
}
|
|
|
|
if (First)
|
|
{
|
|
boolean finalPlayerATurn = playerATurn;
|
|
|
|
Manager.runSyncLater(() -> informTurn(finalPlayerATurn), 20);
|
|
}
|
|
else
|
|
{
|
|
informTurn(playerATurn);
|
|
}
|
|
}
|
|
|
|
private void informTurn(boolean playerATurn)
|
|
{
|
|
UtilTextMiddle.display("", C.cYellowB + "Your Turn", 5, 15, 5, playerATurn ? PlayerA : PlayerB);
|
|
}
|
|
|
|
void cleanup()
|
|
{
|
|
for (ArmorStand piece : Pieces)
|
|
{
|
|
piece.remove();
|
|
}
|
|
|
|
for (ArmorStand floor : Floor)
|
|
{
|
|
floor.remove();
|
|
}
|
|
}
|
|
|
|
boolean hasWon(int valueToCheck)
|
|
{
|
|
return (OwnedPieces[0] == valueToCheck && OwnedPieces[1] == valueToCheck && OwnedPieces[2] == valueToCheck) ||
|
|
(OwnedPieces[3] == valueToCheck && OwnedPieces[4] == valueToCheck && OwnedPieces[5] == valueToCheck) ||
|
|
(OwnedPieces[6] == valueToCheck && OwnedPieces[7] == valueToCheck && OwnedPieces[8] == valueToCheck) ||
|
|
(OwnedPieces[0] == valueToCheck && OwnedPieces[4] == valueToCheck && OwnedPieces[8] == valueToCheck) ||
|
|
(OwnedPieces[2] == valueToCheck && OwnedPieces[4] == valueToCheck && OwnedPieces[6] == valueToCheck) ||
|
|
(OwnedPieces[0] == valueToCheck && OwnedPieces[3] == valueToCheck && OwnedPieces[6] == valueToCheck) ||
|
|
(OwnedPieces[1] == valueToCheck && OwnedPieces[4] == valueToCheck && OwnedPieces[7] == valueToCheck) ||
|
|
(OwnedPieces[2] == valueToCheck && OwnedPieces[5] == valueToCheck && OwnedPieces[8] == valueToCheck);
|
|
}
|
|
|
|
boolean hasDrawn()
|
|
{
|
|
for (int piece : OwnedPieces)
|
|
{
|
|
if (piece == 0)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private void prepareStand(ArmorStand stand)
|
|
{
|
|
stand.setGravity(false);
|
|
stand.setVisible(false);
|
|
}
|
|
}
|
|
}
|