New game block system; resolves #125

This commit is contained in:
Daniel Saukel 2016-07-31 23:52:33 +02:00
parent 5704a6987a
commit f90d3ad5c7
24 changed files with 884 additions and 168 deletions

View File

@ -22,7 +22,9 @@ import io.github.dre2n.dungeonsxl.DungeonsXL;
import io.github.dre2n.dungeonsxl.config.DMessages;
import io.github.dre2n.dungeonsxl.event.dplayer.DPlayerLeaveDGroupEvent;
import io.github.dre2n.dungeonsxl.event.dplayer.instance.edit.DEditPlayerEscapeEvent;
import io.github.dre2n.dungeonsxl.event.dplayer.instance.game.DGamePlayerEscapeEvent;
import io.github.dre2n.dungeonsxl.player.DEditPlayer;
import io.github.dre2n.dungeonsxl.player.DGamePlayer;
import io.github.dre2n.dungeonsxl.player.DGlobalPlayer;
import io.github.dre2n.dungeonsxl.player.DGroup;
import io.github.dre2n.dungeonsxl.player.DInstancePlayer;
@ -67,12 +69,17 @@ public class LeaveCommand extends BRCommand {
return;
}
DEditPlayerEscapeEvent dPlayerEscapeEvent = new DEditPlayerEscapeEvent((DEditPlayer) dPlayer);
if (dPlayer instanceof DGamePlayer) {
DGamePlayerEscapeEvent dPlayerEscapeEvent = new DGamePlayerEscapeEvent((DGamePlayer) dPlayer);
plugin.getServer().getPluginManager().callEvent(dPlayerEscapeEvent);
if (dPlayerEscapeEvent.isCancelled()) {
return;
}
}
DPlayerLeaveDGroupEvent dPlayerLeaveDGroupEvent = new DPlayerLeaveDGroupEvent(dPlayer, dGroup);
plugin.getServer().getPluginManager().callEvent(dPlayerLeaveDGroupEvent);
if (dPlayerEscapeEvent.isCancelled() || dPlayerLeaveDGroupEvent.isCancelled()) {
if (dPlayerLeaveDGroupEvent.isCancelled()) {
return;
}

View File

@ -86,6 +86,7 @@ public enum DMessages implements Messages {
ERROR_NOT_IN_GROUP("Error_NotInGroup", "&4The player &6&v1&4 is not member of the group &6&v2&v4."),
ERROR_NOT_INVITED("Error_NotInvited", "&4You are not invited to the group &6&v1&4."),
ERROR_NOT_SAVED("Error_NotSaved", "&4The map &6&v1&4 has not been saved to the &6DungeonsXL/maps/ &4folder yet!"),
ERROR_BLOCK_OWN_TEAM("Error_BlockOwnTeam", "&4This block belongs to your own group."),
ERROR_READY("Error_Ready", "&4Choose your class first!"),
ERROR_REQUIREMENTS("Error_Requirements", "&4You don't fulfill the requirements for this dungeon!"),
ERROR_SIGN_WRONG_FORMAT("Error_SignWrongFormat", "&4The sign is not written correctly!"),
@ -126,8 +127,11 @@ public enum DMessages implements Messages {
HELP_CMD_SETTINGS("Help_Cmd_Settings", "/dxl settings ([edit|global|player])- Opens the settings menu"),
HELP_CMD_TEST("Help_Cmd_Test", "/dxl test - Starts the game in test mode"),
HELP_CMD_UNINVITE("Help_Cmd_Uninvite", "/dxl uninvite [player] [dungeon] - Uninvite a player to edit a dungeon"),
GROUP_BED_DESTROYED("Group_BedDestroyed", "&6The bed of the group &4&v1 &6has been destroyed by &4&v2&6!"),
GROUP_CREATED("Group_Created", "&4&v1&6 created the group &4&v2&6!"),
GROUP_DISBANDED("Group_Disbanded", "&4&v1&6 disbanded the group &4&v2&6."),
GROUP_FLAG_CAPTURED("Group_FlagCaptured", "&4&v1&6 has captured the flag of the group &4&v2&6!"),
GROUP_FLAG_STEALING("Group_FlagStealing", "&4&v1&6 is stealing the flag of the group &4&v2&6!"),
GROUP_INVITED_PLAYER("Group_InvitedPlayer", "&4&v1&6 invited the player &4&v2&6 to the group &4&v3&6."),
GROUP_JOINED_GAME("Group_JoinedGame", "&6Your group successfully joined the game."),
GROUP_UNINVITED_PLAYER("Group_UninvitedPlayer", "&4&v1&6 took back the invitation for &4&v2&6 to the group &4&v3&6."),

View File

@ -91,7 +91,7 @@ public class BlockListener implements Listener {
// Deny DGameWorld block breaking
DGameWorld gameWorld = DGameWorld.getByWorld(block.getWorld());
if (gameWorld != null) {
if (gameWorld.onBreak(player, block)) {
if (gameWorld.onBreak(event)) {
event.setCancelled(true);
}
}

View File

@ -36,13 +36,13 @@ import io.github.dre2n.dungeonsxl.player.DInstancePlayer;
import io.github.dre2n.dungeonsxl.player.DPermissions;
import io.github.dre2n.dungeonsxl.player.DPlayers;
import io.github.dre2n.dungeonsxl.reward.DLootInventory;
import io.github.dre2n.dungeonsxl.world.block.RewardChest;
import io.github.dre2n.dungeonsxl.sign.OpenDoorSign;
import io.github.dre2n.dungeonsxl.task.RespawnTask;
import io.github.dre2n.dungeonsxl.trigger.InteractTrigger;
import io.github.dre2n.dungeonsxl.trigger.UseItemTrigger;
import io.github.dre2n.dungeonsxl.world.DEditWorld;
import io.github.dre2n.dungeonsxl.world.DGameWorld;
import io.github.dre2n.dungeonsxl.world.block.LockedDoor;
import io.github.dre2n.dungeonsxl.world.block.RewardChest;
import java.util.ArrayList;
import org.bukkit.ChatColor;
import org.bukkit.Location;
@ -117,9 +117,8 @@ public class PlayerListener implements Listener {
return;
}
dPlayer.setLives(dPlayer.getLives() - dPlayerDeathEvent.getLostLives());
if (dPlayer.getLives() != -1) {
dPlayer.setLives(dPlayer.getLives() - dPlayerDeathEvent.getLostLives());
MessageUtil.sendMessage(player, DMessages.PLAYER_DEATH.getMessage(String.valueOf(dPlayer.getLives())));
if (game.getRules().getKeepInventoryOnDeath()) {
@ -142,6 +141,7 @@ public class PlayerListener implements Listener {
Player player = event.getPlayer();
DGlobalPlayer dGlobalPlayer = dPlayers.getByPlayer(player);
Block clickedBlock = event.getClickedBlock();
DGameWorld dGameWorld = DGameWorld.getByWorld(player.getWorld());
if (dGlobalPlayer.isInBreakMode()) {
return;
@ -149,7 +149,7 @@ public class PlayerListener implements Listener {
if (clickedBlock != null) {
// Block Enderchests
if (DGameWorld.getByWorld(player.getWorld()) != null || DEditWorld.getByWorld(player.getWorld()) != null) {
if (dGameWorld != null || DEditWorld.getByWorld(player.getWorld()) != null) {
if (event.getAction() != Action.LEFT_CLICK_BLOCK) {
if (clickedBlock.getType() == Material.ENDER_CHEST) {
if (!DPermissions.hasPermission(player, DPermissions.BYPASS)) {
@ -167,7 +167,7 @@ public class PlayerListener implements Listener {
}
// Block Dispensers
if (DGameWorld.getByWorld(player.getWorld()) != null) {
if (dGameWorld != null) {
if (event.getAction() != Action.LEFT_CLICK_BLOCK) {
if (clickedBlock.getType() == Material.DISPENSER) {
if (!DPermissions.hasPermission(player, DPermissions.BYPASS)) {
@ -177,6 +177,13 @@ public class PlayerListener implements Listener {
}
}
}
for (LockedDoor door : dGameWorld.getLockedDoors()) {
if (clickedBlock.equals(door.getBlock()) || clickedBlock.equals(door.getAttachedBlock())) {
event.setCancelled(true);
return;
}
}
}
// Check Portals
@ -298,9 +305,6 @@ public class PlayerListener implements Listener {
}
}
}
} else if (OpenDoorSign.isProtected(clickedBlock)) {
event.setCancelled(true);
}
}
}

View File

@ -74,6 +74,8 @@ public class DGamePlayer extends DInstancePlayer {
private int initialLives = -1;
private int lives;
private DGroup stealing;
public DGamePlayer(Player player, DGameWorld world) {
super(player, world.getWorld());
@ -365,6 +367,28 @@ public class DGamePlayer extends DInstancePlayer {
this.lives = lives;
}
/**
* @return if the player is stealing a flag
*/
public boolean isStealing() {
return stealing != null;
}
/**
* @return the group whose flag is stolen
*/
public DGroup getRobbedGroup() {
return stealing;
}
/**
* @param dGroup
* the group whose flag is stolen
*/
public void setRobbedGroup(DGroup dGroup) {
stealing = dGroup;
}
/* Actions */
@Override
public void leave() {

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2012-2016 Frank Baumann
*
* 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 io.github.dre2n.dungeonsxl.sign;
import io.github.dre2n.commons.util.BlockUtil;
import io.github.dre2n.commons.util.NumberUtil;
import io.github.dre2n.dungeonsxl.world.DGameWorld;
import io.github.dre2n.dungeonsxl.world.block.TeamBed;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
/**
* @author Daniel Saukel
*/
public class BedSign extends DSign {
private DSignType type = DSignTypeDefault.BED;
private int team;
public BedSign(Sign sign, String[] lines, DGameWorld gameWorld) {
super(sign, lines, gameWorld);
}
/* Getters and setters */
@Override
public DSignType getType() {
return type;
}
/* Actions */
@Override
public boolean check() {
return NumberUtil.parseInt(lines[1], -1) != -1;
}
@Override
public void onInit() {
this.team = NumberUtil.parseInt(lines[1]);
Block block = BlockUtil.getAttachedBlock(getSign().getBlock());
if (block.getType() == Material.BED_BLOCK) {
getGameWorld().addGameBlock(new TeamBed(block, getGame().getDGroups().get(team)));
getSign().getBlock().setType(Material.AIR);
} else {
markAsErroneous();
}
}
}

View File

@ -18,8 +18,8 @@ package io.github.dre2n.dungeonsxl.sign;
import io.github.dre2n.commons.util.NumberUtil;
import io.github.dre2n.dungeonsxl.loottable.DLootTable;
import io.github.dre2n.dungeonsxl.reward.RewardChest;
import io.github.dre2n.dungeonsxl.world.DGameWorld;
import io.github.dre2n.dungeonsxl.world.block.RewardChest;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
@ -181,7 +181,7 @@ public class ChestSign extends DSign {
itemReward = list.toArray(new ItemStack[list.size()]);
}
new RewardChest(chest, getGameWorld(), moneyReward, levelReward, itemReward);
getGameWorld().addGameBlock(new RewardChest(chest, moneyReward, levelReward, itemReward));
getSign().getBlock().setType(Material.AIR);
} else {

View File

@ -32,10 +32,15 @@ public interface DSignType {
public String getBuildPermission();
/**
* @return the onDungeonInit
* @return if the sign gets initialized when the dungeon is loaded instead of when the game starts
*/
public boolean isOnDungeonInit();
/**
* @return if the sign block should be destroyable after the initialization
*/
public boolean isProtected();
/**
* @return the handler
*/

View File

@ -23,45 +23,50 @@ import io.github.dre2n.dungeonsxl.player.DPermissions;
*/
public enum DSignTypeDefault implements DSignType {
BLOCK("Block", "block", false, BlockSign.class),
CHECKPOINT("Checkpoint", "checkpoint", false, CheckpointSign.class),
CHEST("Chest", "chest", false, ChestSign.class),
CHUNK_UPDATER("ChunkUpdater", "chunkupdater", true, ChunkUpdaterSign.class),
CLASSES("Classes", "classes", true, ClassesSign.class),
COMMAND("CMD", "cmd", false, CommandSign.class),
DROP("Drop", "drop", false, DropSign.class),
END("End", "end", false, EndSign.class),
EXTERNAL_MOB("ExternalMob", "mob", false, ExternalMobSign.class),
FLOOR("Floor", "floor", false, FloorSign.class),
HOLOGRAM("Hologram", "hologram", true, HologramSign.class),
INTERACT("Interact", "interact", true, InteractSign.class),
LEAVE("Leave", "leave", true, LeaveSign.class),
LIVES_MODIFIER("Lives", "lives", false, LivesModifierSign.class),
LOBBY("Lobby", "lobby", true, LobbySign.class),
MOB("Mob", "mob", false, DMobSign.class),
MESSAGE("MSG", "msg", false, MessageSign.class),
BED("Bed", "bed", false, false, BedSign.class),
BLOCK("Block", "block", false, true, BlockSign.class),
CHECKPOINT("Checkpoint", "checkpoint", false, false, CheckpointSign.class),
CHEST("Chest", "chest", false, false, ChestSign.class),
CHUNK_UPDATER("ChunkUpdater", "chunkupdater", true, false, ChunkUpdaterSign.class),
CLASSES("Classes", "classes", true, true, ClassesSign.class),
COMMAND("CMD", "cmd", false, false, CommandSign.class),
DROP("Drop", "drop", false, false, DropSign.class),
END("End", "end", false, true, EndSign.class),
EXTERNAL_MOB("ExternalMob", "mob", false, false, ExternalMobSign.class),
FLAG("Flag", "flag", false, false, FlagSign.class),
FLOOR("Floor", "floor", false, true, FloorSign.class),
HOLOGRAM("Hologram", "hologram", true, false, HologramSign.class),
INTERACT("Interact", "interact", true, true, InteractSign.class),
LEAVE("Leave", "leave", true, true, LeaveSign.class),
LIVES_MODIFIER("Lives", "lives", false, false, LivesModifierSign.class),
LOBBY("Lobby", "lobby", true, false, LobbySign.class),
MOB("Mob", "mob", false, false, DMobSign.class),
MESSAGE("MSG", "msg", false, false, MessageSign.class),
@Deprecated
MYTHIC_MOBS("MythicMobs", "mob", false, ExternalMobSign.class),
OPEN_DOOR("Door", "door", false, OpenDoorSign.class),
PLACE("Place", "place", false, PlaceSign.class),
READY("Ready", "ready", true, ReadySign.class),
REDSTONE("Redstone", "redstone", false, RedstoneSign.class),
SCRIPT("Script", "script", false, ScriptSign.class),
SOUND_MESSAGE("SoundMSG", "soundmsg", false, SoundMessageSign.class),
START("Start", "start", true, StartSign.class),
TELEPORT("Teleport", "teleport", false, TeleportSign.class),
TRIGGER("Trigger", "trigger", true, TriggerSign.class),
WAVE("Wave", "wave", false, WaveSign.class);
MYTHIC_MOBS("MythicMobs", "mob", false, false, ExternalMobSign.class),
OPEN_DOOR("Door", "door", false, false, OpenDoorSign.class),
PLACE("Place", "place", false, false, PlaceSign.class),
PROTECTION("Protection", "protection", false, false, ProtectionSign.class),
READY("Ready", "ready", true, true, ReadySign.class),
REDSTONE("Redstone", "redstone", false, false, RedstoneSign.class),
SCRIPT("Script", "script", false, false, ScriptSign.class),
SOUND_MESSAGE("SoundMSG", "soundmsg", false, false, SoundMessageSign.class),
START("Start", "start", true, false, StartSign.class),
TELEPORT("Teleport", "teleport", false, false, TeleportSign.class),
TRIGGER("Trigger", "trigger", true, false, TriggerSign.class),
WAVE("Wave", "wave", false, false, WaveSign.class);
private String name;
private String buildPermission;
private boolean onDungeonInit;
private boolean isProtected;
private Class<? extends DSign> handler;
DSignTypeDefault(String name, String buildPermission, boolean onDungeonInit, Class<? extends DSign> handler) {
DSignTypeDefault(String name, String buildPermission, boolean onDungeonInit, boolean isProtected, Class<? extends DSign> handler) {
this.name = name;
this.buildPermission = buildPermission;
this.onDungeonInit = onDungeonInit;
this.isProtected = isProtected;
this.handler = handler;
}
@ -80,6 +85,11 @@ public enum DSignTypeDefault implements DSignType {
return onDungeonInit;
}
@Override
public boolean isProtected() {
return isProtected;
}
@Override
public Class<? extends DSign> getHandler() {
return handler;

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2012-2016 Frank Baumann
*
* 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 io.github.dre2n.dungeonsxl.sign;
import io.github.dre2n.commons.util.NumberUtil;
import io.github.dre2n.dungeonsxl.world.DGameWorld;
import io.github.dre2n.dungeonsxl.world.block.TeamFlag;
import org.bukkit.block.Sign;
/**
* @author Daniel Saukel
*/
public class FlagSign extends DSign {
private DSignType type = DSignTypeDefault.FLAG;
private int team;
public FlagSign(Sign sign, String[] lines, DGameWorld gameWorld) {
super(sign, lines, gameWorld);
}
/* Getters and setters */
@Override
public DSignType getType() {
return type;
}
/* Actions */
@Override
public boolean check() {
return NumberUtil.parseInt(lines[1], -1) != -1;
}
@Override
public void onInit() {
this.team = NumberUtil.parseInt(lines[1]);
getGameWorld().addGameBlock(new TeamFlag(getSign().getBlock(), team, getGame().getDGroups().get(team)));
}
}

View File

@ -18,6 +18,7 @@ package io.github.dre2n.dungeonsxl.sign;
import io.github.dre2n.commons.util.BlockUtil;
import io.github.dre2n.dungeonsxl.world.DGameWorld;
import io.github.dre2n.dungeonsxl.world.block.LockedDoor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
@ -31,7 +32,7 @@ public class OpenDoorSign extends DSign {
private DSignType type = DSignTypeDefault.OPEN_DOOR;
private Block block;
private LockedDoor door;
public OpenDoorSign(Sign sign, String[] lines, DGameWorld gameWorld) {
super(sign, lines, gameWorld);
@ -41,16 +42,16 @@ public class OpenDoorSign extends DSign {
/**
* @return the door to open;
*/
public Block getBlock() {
return block;
public LockedDoor getDoor() {
return door;
}
/**
* @param block
* @param door
* the door to open
*/
public void setBlock(Block block) {
this.block = block;
public void setDoor(LockedDoor door) {
this.door = door;
}
@Override
@ -69,44 +70,24 @@ public class OpenDoorSign extends DSign {
Block block = BlockUtil.getAttachedBlock(getSign().getBlock());
if (block.getState().getData() instanceof Door) {
if (block.getRelative(BlockFace.DOWN).getType() == block.getType()) {
this.block = block.getRelative(BlockFace.DOWN);
door = new LockedDoor(block.getRelative(BlockFace.DOWN));
} else {
this.block = block;
}
door = new LockedDoor(block);
}
getGameWorld().addGameBlock(door);
getSign().getBlock().setType(Material.AIR);
} else {
markAsErroneous();
}
}
@Override
public void onTrigger() {
if (block != null) {
((Door) block.getState().getData()).setOpen(true);
block.getState().update(true);
if (door != null) {
door.open();
}
}
/* Statics */
/**
* @param block
* the block to check
* @return
* true if the block is openable only with a sign
*/
public static boolean isProtected(Block block) {
DGameWorld gameWorld = DGameWorld.getByWorld(block.getWorld());
if (gameWorld != null) {
for (DSign dSign : gameWorld.getDSigns(DSignTypeDefault.OPEN_DOOR)) {
Block signBlock1 = ((OpenDoorSign) dSign).getBlock();
Block signBlock2 = signBlock1.getRelative(BlockFace.UP);
if (block.equals(signBlock1) || block.equals(signBlock2)) {
return true;
}
}
}
return false;
}
}

View File

@ -39,7 +39,7 @@ public class PlaceSign extends DSign {
@Override
public void onInit() {
getGameWorld().getPlaceableBlocks().add(new PlaceableBlock(getSign().getBlock(), lines[1], lines[2]));
getGameWorld().addGameBlock(new PlaceableBlock(getSign().getBlock(), lines[1], lines[2]));
getSign().getBlock().setType(Material.AIR);
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2012-2016 Frank Baumann
*
* 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 io.github.dre2n.dungeonsxl.sign;
import io.github.dre2n.commons.util.BlockUtil;
import io.github.dre2n.dungeonsxl.world.DGameWorld;
import io.github.dre2n.dungeonsxl.world.block.ProtectedBlock;
import org.bukkit.Material;
import org.bukkit.block.Sign;
/**
* @author Daniel Saukel
*/
public class ProtectionSign extends DSign {
private DSignType type = DSignTypeDefault.PROTECTION;
public ProtectionSign(Sign sign, String[] lines, DGameWorld gameWorld) {
super(sign, lines, gameWorld);
}
/* Getters and setters */
@Override
public DSignType getType() {
return type;
}
/* Actions */
@Override
public boolean check() {
return true;
}
@Override
public void onInit() {
getGameWorld().addGameBlock(new ProtectedBlock(BlockUtil.getAttachedBlock(getSign().getBlock())));
getSign().getBlock().setType(Material.AIR);
}
}

View File

@ -24,7 +24,6 @@ import io.github.dre2n.dungeonsxl.game.Game;
import io.github.dre2n.dungeonsxl.game.GameRules;
import io.github.dre2n.dungeonsxl.mob.DMob;
import io.github.dre2n.dungeonsxl.player.DGroup;
import io.github.dre2n.dungeonsxl.reward.RewardChest;
import io.github.dre2n.dungeonsxl.sign.DSign;
import io.github.dre2n.dungeonsxl.sign.DSignType;
import io.github.dre2n.dungeonsxl.sign.DSignTypeDefault;
@ -36,6 +35,13 @@ import io.github.dre2n.dungeonsxl.trigger.RedstoneTrigger;
import io.github.dre2n.dungeonsxl.trigger.Trigger;
import io.github.dre2n.dungeonsxl.trigger.TriggerType;
import io.github.dre2n.dungeonsxl.trigger.TriggerTypeDefault;
import io.github.dre2n.dungeonsxl.world.block.GameBlock;
import io.github.dre2n.dungeonsxl.world.block.LockedDoor;
import io.github.dre2n.dungeonsxl.world.block.MultiBlock;
import io.github.dre2n.dungeonsxl.world.block.PlaceableBlock;
import io.github.dre2n.dungeonsxl.world.block.RewardChest;
import io.github.dre2n.dungeonsxl.world.block.TeamBed;
import io.github.dre2n.dungeonsxl.world.block.TeamFlag;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
@ -55,6 +61,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Spider;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
@ -69,12 +76,18 @@ public class DGameWorld extends DInstanceWorld {
// TO DO: Which lists actually need to be CopyOnWriteArrayLists?
private List<Block> placedBlocks = new LinkedList<>();
private CopyOnWriteArrayList<GamePlaceableBlock> placeableBlocks = new CopyOnWriteArrayList<>();
private Set<GameBlock> gameBlocks = new HashSet<>();
private Set<LockedDoor> lockedDoors = new HashSet<>();
private Set<PlaceableBlock> placeableBlocks = new HashSet<>();
private Set<RewardChest> rewardChests = new HashSet<>();
private Set<TeamBed> teamBeds = new HashSet<>();
private Set<TeamFlag> teamFlags = new HashSet<>();
private List<ItemStack> secureObjects = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<Chunk> loadedChunks = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<Sign> classesSigns = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<DMob> dMobs = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<RewardChest> rewardChests = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<DSign> dSigns = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<Trigger> triggers = new CopyOnWriteArrayList<>();
@ -163,16 +176,83 @@ public class DGameWorld extends DInstanceWorld {
/**
* @return the placeableBlocks
*/
public CopyOnWriteArrayList<GamePlaceableBlock> getPlaceableBlocks() {
public Set<GameBlock> getGameBlocks() {
return gameBlocks;
}
/**
* @param gameBlock
* the gameBlock to add
*/
public void addGameBlock(GameBlock gameBlock) {
gameBlocks.add(gameBlock);
if (gameBlock instanceof LockedDoor) {
lockedDoors.add((LockedDoor) gameBlock);
} else if (gameBlock instanceof PlaceableBlock) {
placeableBlocks.add((PlaceableBlock) gameBlock);
} else if (gameBlock instanceof RewardChest) {
rewardChests.add((RewardChest) gameBlock);
} else if (gameBlock instanceof TeamBed) {
teamBeds.add((TeamBed) gameBlock);
} else if (gameBlock instanceof TeamFlag) {
teamFlags.add((TeamFlag) gameBlock);
}
}
/**
* @param gameBlock
* the gameBlock to remove
*/
public void removeGameBlock(GameBlock gameBlock) {
gameBlocks.remove(gameBlock);
if (gameBlock instanceof LockedDoor) {
lockedDoors.remove((LockedDoor) gameBlock);
} else if (gameBlock instanceof PlaceableBlock) {
placeableBlocks.remove((PlaceableBlock) gameBlock);
} else if (gameBlock instanceof RewardChest) {
rewardChests.remove((RewardChest) gameBlock);
} else if (gameBlock instanceof TeamBed) {
teamBeds.remove((TeamBed) gameBlock);
} else if (gameBlock instanceof TeamFlag) {
teamFlags.remove((TeamFlag) gameBlock);
}
}
/**
* @return the rewardChests
*/
public Set<RewardChest> getRewardChests() {
return rewardChests;
}
/**
* @return the locked doors
*/
public Set<LockedDoor> getLockedDoors() {
return lockedDoors;
}
/**
* @return the placeable blocks
*/
public Set<PlaceableBlock> getPlaceableBlocks() {
return placeableBlocks;
}
/**
* @param placeableBlocks
* the placeableBlocks to set
* @return the team beds
*/
public void setPlaceableBlocks(CopyOnWriteArrayList<GamePlaceableBlock> placeableBlocks) {
this.placeableBlocks = placeableBlocks;
public Set<TeamBed> getTeamBeds() {
return teamBeds;
}
/**
* @return the team flags
*/
public Set<TeamFlag> getTeamFlags() {
return teamFlags;
}
/**
@ -243,21 +323,6 @@ public class DGameWorld extends DInstanceWorld {
dMobs.remove(dMob);
}
/**
* @return the rewardChests
*/
public CopyOnWriteArrayList<RewardChest> getRewardChests() {
return rewardChests;
}
/**
* @param rewardChests
* the rewardChests to set
*/
public void setRewardChests(CopyOnWriteArrayList<RewardChest> rewardChests) {
this.rewardChests = rewardChests;
}
/**
* @return the dSigns
*/
@ -460,17 +525,35 @@ public class DGameWorld extends DInstanceWorld {
}
}
public boolean onBreak(Player player, Block block) {
/**
* Handles what happens when a player breaks a block.
*
* @param event
* the passed Bukkit event
* @return if the event is cancelled
*/
public boolean onBreak(BlockBreakEvent event) {
Player player = event.getPlayer();
Block block = event.getBlock();
for (DSign dSign : dSigns) {
if (dSign.getSign().getBlock().equals(block)) {
if (block.equals(dSign.getSign().getBlock()) && dSign.getType().isProtected()) {
return true;
}
}
for (RewardChest rChest : rewardChests) {
if (rChest.getChest().getBlock().equals(block)) {
for (GameBlock gameBlock : gameBlocks) {
if (block.equals(gameBlock.getBlock())) {
if (gameBlock.onBreak(event)) {
return true;
}
} else if (gameBlock instanceof MultiBlock) {
if (block.equals(((MultiBlock) gameBlock).getAttachedBlock())) {
if (gameBlock.onBreak(event)) {
return true;
}
}
}
}
Game game = getGame();
@ -505,6 +588,16 @@ public class DGameWorld extends DInstanceWorld {
return true;
}
/**
* Handles what happens when a player places a block.
*
* @param player
* @param block
* @param against
* @param hand
* the event parameters.
* @return if the event is cancelled
*/
public boolean onPlace(Player player, Block block, Block against, ItemStack hand) {
// Workaround for a bug that would allow 3-Block-high jumping
Location loc = player.getLocation();
@ -525,7 +618,7 @@ public class DGameWorld extends DInstanceWorld {
}
GameRules rules = game.getRules();
if (!rules.canPlaceBlocks() && !GamePlaceableBlock.canBuildHere(block, block.getFace(against), hand.getType(), this)) {
if (!rules.canPlaceBlocks() && !PlaceableBlock.canBuildHere(block, block.getFace(against), hand.getType(), this)) {
return true;
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2012-2016 Frank Baumann
*
* 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 io.github.dre2n.dungeonsxl.world.block;
import org.bukkit.block.Block;
import org.bukkit.event.block.BlockBreakEvent;
/**
* @author Daniel Saukel
*/
public abstract class GameBlock {
protected Block block;
public GameBlock(Block block) {
this.block = block;
}
/* Getters and setters */
/**
* @return the block
*/
public Block getBlock() {
return block;
}
/**
* @param block
* the block to set
*/
public void setBlock(Block block) {
this.block = block;
}
/* Abstracts */
/**
* Handles what happens when a player breaks the block.
*
* @param event
* the passed Bukkit event
* @return if the event is cancelled
*/
public abstract boolean onBreak(BlockBreakEvent event);
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2012-2016 Frank Baumann
*
* 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 io.github.dre2n.dungeonsxl.world.block;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.material.Door;
/**
* @author Daniel Saukel
*/
public class LockedDoor extends GameBlock implements MultiBlock {
private Block attachedBlock;
public LockedDoor(Block block) {
super(block);
attachedBlock = getAttachedBlock();
}
/* Getters and setters */
@Override
public Block getAttachedBlock() {
if (attachedBlock != null) {
return attachedBlock;
} else {
return block.getRelative(BlockFace.UP);
}
}
/* Actions */
@Override
public boolean onBreak(BlockBreakEvent event) {
return true;
}
/**
* Opens the door.
*/
public void open() {
((Door) block.getState().getData()).setOpen(true);
block.getState().update(true);
}
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2012-2016 Frank Baumann
*
* 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 io.github.dre2n.dungeonsxl.world.block;
import org.bukkit.block.Block;
/**
* In some cases, a "game block" might actually be a structure with multiple blocks,
* like a bed or a door with two halfs. These GameBlocks implement MultiBlock.
*
* @author Daniel Saukel
*/
public interface MultiBlock {
public Block getAttachedBlock();
}

View File

@ -14,22 +14,23 @@
* 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 io.github.dre2n.dungeonsxl.world;
package io.github.dre2n.dungeonsxl.world.block;
import io.github.dre2n.commons.util.NumberUtil;
import io.github.dre2n.dungeonsxl.world.DGameWorld;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.event.block.BlockBreakEvent;
/**
* @author Frank Baumann, Daniel Saukel
*/
public class GamePlaceableBlock {
public class PlaceableBlock extends GameBlock {
// Variables
private Block block;
private Set<Material> materials = new HashSet<>();
private boolean onTop = false;
@ -39,8 +40,8 @@ public class GamePlaceableBlock {
private boolean onEast = false;
private boolean onWest = false;
public GamePlaceableBlock(Block block, String ids, String directions) {
this.block = block;
public PlaceableBlock(Block block, String ids, String directions) {
super(block);
// Split ids
if (!ids.isEmpty()) {
@ -252,9 +253,15 @@ public class GamePlaceableBlock {
}
}
/* Actions */
@Override
public boolean onBreak(BlockBreakEvent event) {
return false;
}
// Can build
public static boolean canBuildHere(Block block, BlockFace blockFace, Material mat, DGameWorld gameWorld) {
for (GamePlaceableBlock gamePlacableBlock : gameWorld.getPlaceableBlocks()) {
for (PlaceableBlock gamePlacableBlock : gameWorld.getPlaceableBlocks()) {
if (gamePlacableBlock.block.getFace(block) != BlockFace.SELF) {
continue;
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2012-2016 Frank Baumann
*
* 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 io.github.dre2n.dungeonsxl.world.block;
import org.bukkit.block.Block;
import org.bukkit.event.block.BlockBreakEvent;
/**
* @author Daniel Saukel
*/
public class ProtectedBlock extends GameBlock {
public ProtectedBlock(Block block) {
super(block);
}
/* Actions */
@Override
public boolean onBreak(BlockBreakEvent event) {
return true;
}
}

View File

@ -14,14 +14,18 @@
* 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 io.github.dre2n.dungeonsxl.reward;
package io.github.dre2n.dungeonsxl.world.block;
import io.github.dre2n.commons.util.messageutil.MessageUtil;
import io.github.dre2n.dungeonsxl.DungeonsXL;
import io.github.dre2n.dungeonsxl.config.DMessages;
import io.github.dre2n.dungeonsxl.player.DGamePlayer;
import io.github.dre2n.dungeonsxl.player.DGroup;
import io.github.dre2n.dungeonsxl.world.DGameWorld;
import io.github.dre2n.dungeonsxl.reward.ItemReward;
import io.github.dre2n.dungeonsxl.reward.LevelReward;
import io.github.dre2n.dungeonsxl.reward.MoneyReward;
import io.github.dre2n.dungeonsxl.reward.Reward;
import io.github.dre2n.dungeonsxl.reward.RewardTypeDefault;
import net.milkbowl.vault.item.ItemInfo;
import net.milkbowl.vault.item.Items;
import org.bukkit.Bukkit;
@ -29,35 +33,34 @@ import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
/**
* @author Frank Baumann, Daniel Saukel
*/
public class RewardChest {
public class RewardChest extends GameBlock {
static DungeonsXL plugin = DungeonsXL.getInstance();
// Variables
private boolean used = false;
private Chest chest;
private DGameWorld gameWorld;
private double moneyReward;
private int levelReward;
private ItemStack[] itemReward;
public RewardChest(Block chest, DGameWorld gameWorld, double moneyReward, int levelReward, ItemStack[] itemReward) {
public RewardChest(Block chest, double moneyReward, int levelReward, ItemStack[] itemReward) {
super(chest);
if (!(chest.getState() instanceof Chest)) {
return;
}
this.chest = (Chest) chest.getState();
this.gameWorld = gameWorld;
this.moneyReward = moneyReward;
this.levelReward = levelReward;
this.itemReward = itemReward;
gameWorld.getRewardChests().add(this);
}
/**
@ -90,21 +93,6 @@ public class RewardChest {
this.chest = chest;
}
/**
* @return the gameWorld
*/
public DGameWorld getGameWorld() {
return gameWorld;
}
/**
* @param gameWorld
* the gameWorld to set
*/
public void setGameWorld(DGameWorld gameWorld) {
this.gameWorld = gameWorld;
}
/**
* @return the moneyReward
*/
@ -136,6 +124,11 @@ public class RewardChest {
}
/* Actions */
@Override
public boolean onBreak(BlockBreakEvent event) {
return true;
}
/**
* @param opener
* the player who opens the chest

View File

@ -0,0 +1,96 @@
/*
* Copyright (C) 2012-2016 Frank Baumann
*
* 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 io.github.dre2n.dungeonsxl.world.block;
import io.github.dre2n.commons.util.messageutil.MessageUtil;
import io.github.dre2n.dungeonsxl.config.DMessages;
import io.github.dre2n.dungeonsxl.player.DGamePlayer;
import io.github.dre2n.dungeonsxl.player.DGroup;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.material.Bed;
/**
* @author Daniel Saukel
*/
public class TeamBed extends TeamBlock implements MultiBlock {
private Block attachedBlock;
public TeamBed(Block block, DGroup owner) {
super(block, owner);
attachedBlock = getAttachedBlock();
}
/* Getters and setters */
public Block getAttachedBlock(Block block) {
if (block.getRelative(BlockFace.EAST).getType() == Material.BED_BLOCK) {
return block.getRelative(BlockFace.EAST);
} else if (block.getRelative(BlockFace.NORTH).getType() == Material.BED_BLOCK) {
return block.getRelative(BlockFace.NORTH);
} else if (block.getRelative(BlockFace.WEST).getType() == Material.BED_BLOCK) {
return block.getRelative(BlockFace.WEST);
} else if (block.getRelative(BlockFace.SOUTH).getType() == Material.BED_BLOCK) {
return block.getRelative(BlockFace.SOUTH);
} else {
return null;
}
}
@Override
public Block getAttachedBlock() {
if (attachedBlock != null) {
return attachedBlock;
} else {
return getAttachedBlock(block);
}
}
/* Actions */
@Override
public boolean onBreak(BlockBreakEvent event) {
Player breaker = event.getPlayer();
if (owner.getPlayers().contains(breaker)) {
MessageUtil.sendMessage(breaker, DMessages.ERROR_BLOCK_OWN_TEAM.getMessage());
return true;
}
for (DGamePlayer player : owner.getDGamePlayers()) {
player.setLives(1);
}
owner.getGameWorld().sendMessage(DMessages.GROUP_BED_DESTROYED.getMessage(owner.getName(), breaker.getName()));
Block block1 = event.getBlock();
if (((Bed) block1.getState().getData()).isHeadOfBed()) {
Block block2 = getAttachedBlock(block1);
if (block2 != null) {
block2.setType(Material.AIR);
}
}
block1.setType(Material.AIR);
return true;
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2012-2016 Frank Baumann
*
* 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 io.github.dre2n.dungeonsxl.world.block;
import io.github.dre2n.dungeonsxl.player.DGroup;
import org.bukkit.block.Block;
/**
* @author Daniel Saukel
*/
public abstract class TeamBlock extends GameBlock {
protected DGroup owner;
public TeamBlock(Block block, DGroup owner) {
super(block);
this.owner = owner;
}
/* Getters and setters */
/**
* @return the group that owns the flag
*/
public DGroup getOwner() {
return owner;
}
/**
* @param owner
* the owner group to set
*/
public void setOwner(DGroup owner) {
this.owner = owner;
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2012-2016 Frank Baumann
*
* 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 io.github.dre2n.dungeonsxl.world.block;
import io.github.dre2n.commons.util.messageutil.MessageUtil;
import io.github.dre2n.dungeonsxl.DungeonsXL;
import io.github.dre2n.dungeonsxl.config.DMessages;
import io.github.dre2n.dungeonsxl.player.DGamePlayer;
import io.github.dre2n.dungeonsxl.player.DGroup;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
/**
* @author Daniel Saukel
*/
public class TeamFlag extends TeamBlock {
DungeonsXL plugin = DungeonsXL.getInstance();
public static final int WOOL = 35;
private byte teamId;
public TeamFlag(Block block, int teamId, DGroup owner) {
super(block, owner);
this.teamId = plugin.getMainConfig().getGroupColorPriority().get(teamId).byteValue();
reset();
}
/* Actions */
/**
* Reset a team flag when the capturer dies.
*/
public void reset() {
block.setTypeIdAndData(WOOL, teamId, false);
}
@Override
public boolean onBreak(BlockBreakEvent event) {
Player breaker = event.getPlayer();
DGamePlayer gamePlayer = DGamePlayer.getByPlayer(breaker);
if (gamePlayer == null) {
return true;
}
if (owner.getPlayers().contains(breaker)) {
MessageUtil.sendMessage(breaker, DMessages.ERROR_BLOCK_OWN_TEAM.getMessage());
return true;
}
owner.getGameWorld().sendMessage(DMessages.GROUP_FLAG_STEALING.getMessage(breaker.getName(), owner.getName()));
gamePlayer.setRobbedGroup(owner);
event.getBlock().setType(Material.AIR);
return true;
}
}

View File

@ -23,17 +23,19 @@ import io.github.dre2n.dungeonsxl.player.DPermissions;
*/
public enum DSignTypeCustom implements DSignType {
CUSTOM("Custom", "custom", false, CustomSign.class);
CUSTOM("Custom", "custom", false, false, CustomSign.class);
private String name;
private String buildPermission;
private boolean onDungeonInit;
private boolean isProtected;
private Class<? extends DSign> handler;
DSignTypeCustom(String name, String buildPermission, boolean onDungeonInit, Class<? extends DSign> handler) {
DSignTypeCustom(String name, String buildPermission, boolean onDungeonInit, boolean isProtected, Class<? extends DSign> handler) {
this.name = name;
this.buildPermission = buildPermission;
this.onDungeonInit = onDungeonInit;
this.isProtected = isProtected;
this.handler = handler;
}
@ -52,6 +54,11 @@ public enum DSignTypeCustom implements DSignType {
return onDungeonInit;
}
@Override
public boolean isProtected() {
return isProtected;
}
@Override
public Class<? extends DSign> getHandler() {
return handler;