package me.desht.chesscraft.chess.pieces; import chesspresso.Chess; import chesspresso.position.Position; import com.google.common.base.Joiner; import me.desht.chesscraft.ChessPersistence; import me.desht.chesscraft.ChessValidate; import me.desht.chesscraft.chess.ChessBoard; import me.desht.chesscraft.enums.BoardRotation; import me.desht.chesscraft.exceptions.ChessException; import org.bukkit.Location; import org.bukkit.configuration.Configuration; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.EntityType; import java.util.HashMap; import java.util.Map; /** * @author des * */ public class EntityChessSet extends ChessSet { private static final String[] CHESS_SET_HEADER_LINES = new String[] { "ChessCraft entity piece style definition file", "See http://dev.bukkit.org/server-mods/chesscraft/pages/piece-styles", "", "'name' is the name for this set, and should match the filename", "", "'comment' is a freeform comment about the set (can be multi-line)", "", "'pieces.<colour>.<X>' defines the NPC used for a chess piece," + " where <colour> is one of black, white and <X> is one of P,R,N,B,Q,K", "", "The piece definition is a compound structure with a mandatory 'entity'", "field, which must be a Bukkit EntityType for a living entity - see", "http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/EntityType.html", "", "Other fields are optional and modify the appearance of the piece.", "Different entities understand different fields - see", "http://dev.bukkit.org/server-mods/chesscraft/pages/piece-styles for", "full information.", }; // stores which piece is standing on which chess square private final EntityChessStone[] stones; // map piece name to NPC entity type private Map<Integer,ConfigurationSection> stoneTypeMap; public EntityChessSet(Configuration c, boolean isCustom) { super(c, isCustom); ChessPersistence.requireSection(c, "pieces.white"); ChessPersistence.requireSection(c, "pieces.black"); this.stones = new EntityChessStone[Chess.NUM_OF_SQUARES]; try { this.stoneTypeMap = loadPieces(c.getConfigurationSection("pieces")); } catch (Exception e) { throw new ChessException(e.getMessage()); } } private Map<Integer, ConfigurationSection> loadPieces(ConfigurationSection cs) { Map<Integer,ConfigurationSection> map = new HashMap<Integer, ConfigurationSection>(); loadPieces(map, Chess.WHITE, cs.getConfigurationSection("white")); loadPieces(map, Chess.BLACK, cs.getConfigurationSection("black")); return map; } private void loadPieces(Map<Integer, ConfigurationSection> map, int colour, ConfigurationSection cs) { for (int piece = Chess.MIN_PIECE + 1; piece <= Chess.MAX_PIECE; piece++) { String s = Character.toString(Chess.pieceToChar(piece)); ConfigurationSection details = cs.getConfigurationSection(s); ChessValidate.notNull(details, "missing definition for chess piece: " + s); ChessPersistence.requireSection(details, "entity"); details.set("_entity", EntityType.valueOf(details.getString("entity").toUpperCase())); map.put(Chess.pieceToStone(piece, colour), details); } } @Override protected String getHeaderText() { return Joiner.on("\n").join(CHESS_SET_HEADER_LINES); } @Override protected String getType() { return "entity"; } @Override protected void addSaveData(Configuration c) { for (int piece = 1; piece <= Chess.MAX_PIECE; piece++) { char pc = Chess.pieceToChar(piece); c.set("pieces.white." + pc, stoneTypeMap.get(Chess.pieceToStone(piece, Chess.WHITE))); c.set("pieces.black." + pc, stoneTypeMap.get(Chess.pieceToStone(piece, Chess.BLACK))); } } @Override public ChessStone getStone(int stone, BoardRotation direction) { throw new UnsupportedOperationException("Entity chess sets don't track pieces by stone ID"); } @Override public ChessStone getStoneAt(int sqi) { return stones[sqi]; } @Override public boolean canRide() { return false; } @Override public boolean hasMovablePieces() { return true; } @Override public void movePiece(int fromSqi, int toSqi, int captureSqi, Location to, int promoteStone) { EntityChessStone stone = (EntityChessStone) getStoneAt(fromSqi); EntityChessStone captured = (EntityChessStone) getStoneAt(captureSqi); if (stone != null) { if (promoteStone != Chess.NO_STONE) { Location loc = stone.getBukkitEntity().getLocation(); stone.cleanup(); stone = new EntityChessStone(promoteStone, stoneTypeMap.get(promoteStone), loc, loc.getYaw()); } stone.move(fromSqi, toSqi, to, captured); stones[fromSqi] = null; stones[toSqi] = stone; } } @Override public void syncToPosition(Position pos, final ChessBoard board) { for (int sqi = 0; sqi < Chess.NUM_OF_SQUARES; sqi++) { if (stones[sqi] != null) { stones[sqi].cleanup(); stones[sqi] = null; } if (pos != null && pos.getStone(sqi) != Chess.NO_STONE) { int stone = pos.getStone(sqi); Location loc = board.getSquare(Chess.sqiToRow(sqi), Chess.sqiToCol(sqi)).getCenter().add(0, 0.5, 0); float yaw = board.getRotation().getYaw(); if (Chess.stoneToColor(stone) == Chess.BLACK) { yaw = (yaw + 180) % 360; } stones[sqi] = new EntityChessStone(stone, stoneTypeMap.get(stone), loc, yaw); } } } }