/******************************************************************************* * Copyright (C) 2014 Travis Ralston (turt2live) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package com.turt2live.antishare.engine; import com.turt2live.antishare.APermission; import com.turt2live.antishare.ASGameMode; import com.turt2live.antishare.object.APlayer; import com.turt2live.antishare.object.ASLocation; /** * Represents a world split for players. A world split is a axis * split in the world which has two sides, each being a different * gamemode. When a player crosses the axis line, they will be * switched from gamemodes. * * @author turt2live */ public class WorldSplit { /** * The possible axises to use for splitting */ public static enum Axis { X, Z } private Axis axis; private ASGameMode positive, negative; private int value; /** * Creates a new world split * * @param axis the axis to split on, cannot be null * @param value the axis coordinate value to split on * @param positive the positive side of the split, cannot be null * @param negative the negative side of the split, cannot be null */ public WorldSplit(Axis axis, int value, ASGameMode positive, ASGameMode negative) { if (axis == null || positive == null || negative == null) throw new IllegalArgumentException(); this.axis = axis; this.value = value; this.positive = positive; this.negative = negative; } /** * Determines if a specified player is affected by this world split * * @param player the player to check, cannot be null * * @return true if the player is affected by this split, false otherwise */ public boolean isAffected(APlayer player) { if (player == null) throw new IllegalArgumentException(); return !player.hasPermission(APermission.FREE_ROAM); } /** * Processes a player's movement, handling the gamemode changeover * * @param player the player that is moving, cannot be null * @param from the start location, cannot be null * @param to the end location, cannot be null * * @return returns the distance the player is to the world split, returning -1 * for 'crossed' and -2 for 'not applicable to this player' */ public int processMovement(APlayer player, ASLocation from, ASLocation to) { if (player == null || from == null || to == null) throw new IllegalArgumentException(); int distance = getDistance(to); if (isAffected(player)) { int axisValue = axis == Axis.X ? to.X : to.Z; ASGameMode expectedGamemode = axisValue < value ? negative : positive; if (player.getGameMode() != expectedGamemode) { player.setGameMode(expectedGamemode); distance = -1; } } else distance = -2; return distance; } /** * Gets the absolute distance a location is away from the axis. * * @param location the location, cannot be null * * @return the absolute distance, always positive or zero */ public int getDistance(ASLocation location) { if (location == null) throw new IllegalArgumentException(); int axisValue = axis == Axis.X ? location.X : location.Z; return Math.abs(value - axisValue); } /** * Determines if the specified location range is 'approaching' this world split * * @param from the start location, cannot be null * @param to the end location, cannot be null * * @return true if approaching, false otherwise */ public boolean isApproaching(ASLocation from, ASLocation to) { if (from == null || to == null) throw new IllegalArgumentException(); return getDistance(to) < getDistance(from); } }