Added /Claim and /ExtendClaim

This commit is contained in:
ryanhamshire 2015-12-17 21:09:08 -08:00
parent 6db3e11ab1
commit 3ca069e3bd
6 changed files with 422 additions and 176 deletions

View File

@ -92,6 +92,16 @@ commands:
usage: /BasicClaims usage: /BasicClaims
aliases: bc aliases: bc
permission: griefprevention.claims permission: griefprevention.claims
extendclaim:
description: Resizes the land claim you're standing in by pushing or pulling its boundary in the direction you're facing.
usage: /ExtendClaim <numberOfBlocks>
aliases: [expandclaim, resizeclaim]
permission: griefprevention.claims
claim:
description: Creates a land claim centered at your current location.
usage: /Claim
aliases: [createclaim, makeclaim, newclaim]
permission: griefprevention.claims
buyclaimblocks: buyclaimblocks:
description: Purchases additional claim blocks with server money. Doesn't work on servers without a Vault-compatible economy plugin. description: Purchases additional claim blocks with server money. Doesn't work on servers without a Vault-compatible economy plugin.
usage: /BuyClaimBlocks <numberOfBlocks> usage: /BuyClaimBlocks <numberOfBlocks>

View File

@ -1193,6 +1193,164 @@ public abstract class DataStore
return result; return result;
} }
void resizeClaimWithChecks(Player player, PlayerData playerData, int newx1, int newx2, int newy1, int newy2, int newz1, int newz2)
{
//for top level claims, apply size rules and claim blocks requirement
if(playerData.claimResizing.parent == null)
{
//measure new claim, apply size rules
int newWidth = (Math.abs(newx1 - newx2) + 1);
int newHeight = (Math.abs(newz1 - newz2) + 1);
boolean smaller = newWidth < playerData.claimResizing.getWidth() || newHeight < playerData.claimResizing.getHeight();
if(!player.hasPermission("griefprevention.adminclaims") && !playerData.claimResizing.isAdminClaim() && smaller)
{
if(newWidth < GriefPrevention.instance.config_claims_minWidth || newHeight < GriefPrevention.instance.config_claims_minWidth)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeClaimTooNarrow, String.valueOf(GriefPrevention.instance.config_claims_minWidth));
return;
}
int newArea = newWidth * newHeight;
if(newArea < GriefPrevention.instance.config_claims_minArea)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeClaimInsufficientArea, String.valueOf(GriefPrevention.instance.config_claims_minArea));
return;
}
}
//make sure player has enough blocks to make up the difference
if(!playerData.claimResizing.isAdminClaim() && player.getName().equals(playerData.claimResizing.getOwnerName()))
{
int newArea = newWidth * newHeight;
int blocksRemainingAfter = playerData.getRemainingClaimBlocks() + playerData.claimResizing.getArea() - newArea;
if(blocksRemainingAfter < 0)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeNeedMoreBlocks, String.valueOf(Math.abs(blocksRemainingAfter)));
this.tryAdvertiseAdminAlternatives(player);
return;
}
}
}
//special rule for making a top-level claim smaller. to check this, verifying the old claim's corners are inside the new claim's boundaries.
//rule: in any mode, shrinking a claim removes any surface fluids
Claim oldClaim = playerData.claimResizing;
boolean smaller = false;
if(oldClaim.parent == null)
{
//temporary claim instance, just for checking contains()
Claim newClaim = new Claim(
new Location(oldClaim.getLesserBoundaryCorner().getWorld(), newx1, newy1, newz1),
new Location(oldClaim.getLesserBoundaryCorner().getWorld(), newx2, newy2, newz2),
null, new ArrayList<String>(), new ArrayList<String>(), new ArrayList<String>(), new ArrayList<String>(), null);
//if the new claim is smaller
if(!newClaim.contains(oldClaim.getLesserBoundaryCorner(), true, false) || !newClaim.contains(oldClaim.getGreaterBoundaryCorner(), true, false))
{
smaller = true;
//remove surface fluids about to be unclaimed
oldClaim.removeSurfaceFluids(newClaim);
}
}
//ask the datastore to try and resize the claim, this checks for conflicts with other claims
CreateClaimResult result = GriefPrevention.instance.dataStore.resizeClaim(playerData.claimResizing, newx1, newx2, newy1, newy2, newz1, newz2, player);
if(result.succeeded)
{
//decide how many claim blocks are available for more resizing
int claimBlocksRemaining = 0;
if(!playerData.claimResizing.isAdminClaim())
{
UUID ownerID = playerData.claimResizing.ownerID;
if(playerData.claimResizing.parent != null)
{
ownerID = playerData.claimResizing.parent.ownerID;
}
if(ownerID == player.getUniqueId())
{
claimBlocksRemaining = playerData.getRemainingClaimBlocks();
}
else
{
PlayerData ownerData = this.getPlayerData(ownerID);
claimBlocksRemaining = ownerData.getRemainingClaimBlocks();
OfflinePlayer owner = GriefPrevention.instance.getServer().getOfflinePlayer(ownerID);
if(!owner.isOnline())
{
this.clearCachedPlayerData(ownerID);
}
}
}
//inform about success, visualize, communicate remaining blocks available
GriefPrevention.sendMessage(player, TextMode.Success, Messages.ClaimResizeSuccess, String.valueOf(claimBlocksRemaining));
Visualization visualization = Visualization.FromClaim(result.claim, player.getEyeLocation().getBlockY(), VisualizationType.Claim, player.getLocation());
Visualization.Apply(player, visualization);
//if resizing someone else's claim, make a log entry
if(!player.getUniqueId().equals(playerData.claimResizing.ownerID) && playerData.claimResizing.parent == null)
{
GriefPrevention.AddLogEntry(player.getName() + " resized " + playerData.claimResizing.getOwnerName() + "'s claim at " + GriefPrevention.getfriendlyLocationString(playerData.claimResizing.lesserBoundaryCorner) + ".");
}
//if increased to a sufficiently large size and no subdivisions yet, send subdivision instructions
if(oldClaim.getArea() < 1000 && result.claim.getArea() >= 1000 && result.claim.children.size() == 0 && !player.hasPermission("griefprevention.adminclaims"))
{
GriefPrevention.sendMessage(player, TextMode.Info, Messages.BecomeMayor, 200L);
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SubdivisionVideo2, 201L, DataStore.SUBDIVISION_VIDEO_URL);
}
//if in a creative mode world and shrinking an existing claim, restore any unclaimed area
if(smaller && GriefPrevention.instance.creativeRulesApply(oldClaim.getLesserBoundaryCorner()))
{
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.UnclaimCleanupWarning);
GriefPrevention.instance.restoreClaim(oldClaim, 20L * 60 * 2); //2 minutes
GriefPrevention.AddLogEntry(player.getName() + " shrank a claim @ " + GriefPrevention.getfriendlyLocationString(playerData.claimResizing.getLesserBoundaryCorner()));
}
//clean up
playerData.claimResizing = null;
playerData.lastShovelLocation = null;
}
else
{
if(result.claim != null)
{
//inform player
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeFailOverlap);
//show the player the conflicting claim
Visualization visualization = Visualization.FromClaim(result.claim, player.getEyeLocation().getBlockY(), VisualizationType.ErrorClaim, player.getLocation());
Visualization.Apply(player, visualization);
}
else
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeFailOverlapRegion);
}
}
}
//educates a player about /adminclaims and /acb, if he can use them
void tryAdvertiseAdminAlternatives(Player player)
{
if(player.hasPermission("griefprevention.adminclaims") && player.hasPermission("griefprevention.adjustclaimblocks"))
{
GriefPrevention.sendMessage(player, TextMode.Info, Messages.AdvertiseACandACB);
}
else if(player.hasPermission("griefprevention.adminclaims"))
{
GriefPrevention.sendMessage(player, TextMode.Info, Messages.AdvertiseAdminClaims);
}
else if(player.hasPermission("griefprevention.adjustclaimblocks"))
{
GriefPrevention.sendMessage(player, TextMode.Info, Messages.AdvertiseACB);
}
}
private void loadMessages() private void loadMessages()
{ {
Messages [] messageIDs = Messages.values(); Messages [] messageIDs = Messages.values();
@ -1406,6 +1564,10 @@ public abstract class DataStore
this.addDefault(defaults, Messages.ManagersDontUntrustManagers, "Only the claim owner can demote a manager.", null); this.addDefault(defaults, Messages.ManagersDontUntrustManagers, "Only the claim owner can demote a manager.", null);
this.addDefault(defaults, Messages.PlayerNotIgnorable, "You can't ignore that player.", null); this.addDefault(defaults, Messages.PlayerNotIgnorable, "You can't ignore that player.", null);
this.addDefault(defaults, Messages.NoEnoughBlocksForChestClaim, "Because you don't have any claim blocks available, no automatic land claim was created for you. You can use /ClaimsList to monitor your available claim block total.", null); this.addDefault(defaults, Messages.NoEnoughBlocksForChestClaim, "Because you don't have any claim blocks available, no automatic land claim was created for you. You can use /ClaimsList to monitor your available claim block total.", null);
this.addDefault(defaults, Messages.MustHoldModificationToolForThat, "You must be holding a golden shovel to do that.", null);
this.addDefault(defaults, Messages.StandInClaimToResize, "Stand inside the land claim you want to resize.", null);
this.addDefault(defaults, Messages.ClaimsExtendToSky, "Land claims always extend to max build height.", null);
this.addDefault(defaults, Messages.ClaimsAutoExtendDownward, "Land claims auto-extend deeper into the ground when you place blocks under them.", null);
this.addDefault(defaults, Messages.BookAuthor, "BigScary", null); this.addDefault(defaults, Messages.BookAuthor, "BigScary", null);
this.addDefault(defaults, Messages.BookTitle, "How to Claim Land", null); this.addDefault(defaults, Messages.BookTitle, "How to Claim Land", null);
@ -1561,7 +1723,7 @@ public abstract class DataStore
{ {
for(Claim claim : claimsInChunk) for(Claim claim : claimsInChunk)
{ {
if(claim.getLesserBoundaryCorner().getWorld().equals(location.getWorld())) if(claim.inDataStore && claim.getLesserBoundaryCorner().getWorld().equals(location.getWorld()))
{ {
claims.add(claim); claims.add(claim);
} }

View File

@ -40,6 +40,7 @@ import org.bukkit.BanList;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -924,6 +925,227 @@ public class GriefPrevention extends JavaPlugin
player = (Player) sender; player = (Player) sender;
} }
//claim
if(cmd.getName().equalsIgnoreCase("claim") && player != null)
{
if(!GriefPrevention.instance.claimsEnabledForWorld(player.getWorld()))
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ClaimsDisabledWorld);
return true;
}
//if player already has a land claim, this requires the claim modification tool to be in hand
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
int radius = GriefPrevention.instance.config_claims_automaticClaimsForNewPlayersRadius;
if(radius < 0) radius = 0;
if(playerData.getClaims().size() > 0)
{
if(player.getGameMode() != GameMode.CREATIVE && player.getItemInHand().getType() != GriefPrevention.instance.config_claims_modificationTool)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.MustHoldModificationToolForThat);
return true;
}
radius = (int)Math.ceil(Math.sqrt(GriefPrevention.instance.config_claims_minArea) / 2);
}
Location lc = player.getLocation().add(-radius, 0, -radius);
Location gc = player.getLocation().add(radius, 0, radius);
//player must have sufficient unused claim blocks
if(playerData.getClaims().size() > 0)
{
int area = Math.abs((gc.getBlockX() - lc.getBlockX() + 1) * (gc.getBlockZ() - lc.getBlockZ() + 1));
int remaining = playerData.getRemainingClaimBlocks();
if(remaining < area)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimInsufficientBlocks, String.valueOf(area - remaining));
GriefPrevention.instance.dataStore.tryAdvertiseAdminAlternatives(player);
return true;
}
}
CreateClaimResult result = this.dataStore.createClaim(lc.getWorld(),
lc.getBlockX(), gc.getBlockX(),
lc.getBlockY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance - 1,
gc.getWorld().getHighestBlockYAt(gc) - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance - 1,
lc.getBlockZ(), gc.getBlockZ(),
player.getUniqueId(), null, null, player);
if(!result.succeeded)
{
if(result.claim != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimFailOverlapShort);
Visualization visualization = Visualization.FromClaim(result.claim, player.getEyeLocation().getBlockY(), VisualizationType.ErrorClaim, player.getLocation());
Visualization.Apply(player, visualization);
}
else
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimFailOverlapRegion);
}
}
else
{
GriefPrevention.sendMessage(player, TextMode.Success, Messages.CreateClaimSuccess);
//link to a video demo of land claiming, based on world type
if(GriefPrevention.instance.creativeRulesApply(player.getLocation()))
{
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.CreativeBasicsVideo2, DataStore.CREATIVE_VIDEO_URL);
}
else if(GriefPrevention.instance.claimsEnabledForWorld(player.getLocation().getWorld()))
{
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SurvivalBasicsVideo2, DataStore.SURVIVAL_VIDEO_URL);
}
Visualization visualization = Visualization.FromClaim(result.claim, player.getEyeLocation().getBlockY(), VisualizationType.Claim, player.getLocation());
Visualization.Apply(player, visualization);
playerData.lastShovelLocation = null;
this.autoExtendClaim(result.claim);
}
return true;
}
//extendclaim
if(cmd.getName().equalsIgnoreCase("extendclaim") && player != null)
{
if(args.length < 1)
{
//link to a video demo of land claiming, based on world type
if(GriefPrevention.instance.creativeRulesApply(player.getLocation()))
{
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.CreativeBasicsVideo2, DataStore.CREATIVE_VIDEO_URL);
}
else if(GriefPrevention.instance.claimsEnabledForWorld(player.getLocation().getWorld()))
{
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SurvivalBasicsVideo2, DataStore.SURVIVAL_VIDEO_URL);
}
return false;
}
int amount;
try
{
amount = Integer.parseInt(args[0]);
}
catch(NumberFormatException e)
{
//link to a video demo of land claiming, based on world type
if(GriefPrevention.instance.creativeRulesApply(player.getLocation()))
{
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.CreativeBasicsVideo2, DataStore.CREATIVE_VIDEO_URL);
}
else if(GriefPrevention.instance.claimsEnabledForWorld(player.getLocation().getWorld()))
{
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SurvivalBasicsVideo2, DataStore.SURVIVAL_VIDEO_URL);
}
return false;
}
//requires claim modification tool in hand
if(player.getGameMode() != GameMode.CREATIVE && player.getItemInHand().getType() != GriefPrevention.instance.config_claims_modificationTool)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.MustHoldModificationToolForThat);
return true;
}
//must be standing in a land claim
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
Claim claim = this.dataStore.getClaimAt(player.getLocation(), true, playerData.lastClaim);
if(claim == null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.StandInClaimToResize);
return true;
}
//must have permission to edit the land claim you're in
String errorMessage = claim.allowEdit(player);
if(errorMessage != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NotYourClaim);
return true;
}
//determine new corner coordinates
org.bukkit.util.Vector direction = player.getLocation().getDirection();
GriefPrevention.AddLogEntry(direction.toString());
if(direction.getY() > .75)
{
GriefPrevention.sendMessage(player, TextMode.Info, Messages.ClaimsExtendToSky);
return true;
}
if(direction.getY() < -.75)
{
GriefPrevention.sendMessage(player, TextMode.Info, Messages.ClaimsAutoExtendDownward);
return true;
}
Location lc = claim.getLesserBoundaryCorner();
Location gc = claim.getGreaterBoundaryCorner();
int newx1 = lc.getBlockX();
int newx2 = gc.getBlockX();
int newy1 = lc.getBlockY();
int newy2 = gc.getBlockY();
int newz1 = lc.getBlockZ();
int newz2 = gc.getBlockZ();
//if changing Z only
if(Math.abs(direction.getX()) < .3)
{
if(direction.getZ() > 0)
{
newz2 += amount; //north
}
else
{
newz1 -= amount; //south
}
}
//if changing X only
else if(Math.abs(direction.getZ()) < .3)
{
if(direction.getX() > 0)
{
newx2 += amount; //east
}
else
{
newx1 -= amount; //west
}
}
//diagonals
else
{
if(direction.getX() > 0)
{
newx2 += amount;
}
else
{
newx1 -= amount;
}
if(direction.getZ() > 0)
{
newz2 += amount;
}
else
{
newz1 -= amount;
}
}
//attempt resize
playerData.claimResizing = claim;
this.dataStore.resizeClaimWithChecks(player, playerData, newx1, newx2, newy1, newy2, newz1, newz2);
return true;
}
//abandonclaim //abandonclaim
if(cmd.getName().equalsIgnoreCase("abandonclaim") && player != null) if(cmd.getName().equalsIgnoreCase("abandonclaim") && player != null)
{ {
@ -3062,6 +3284,27 @@ public class GriefPrevention extends JavaPlugin
return false; return false;
} }
void autoExtendClaim(Claim newClaim)
{
//auto-extend it downward to cover anything already built underground
Location lesserCorner = newClaim.getLesserBoundaryCorner();
Location greaterCorner = newClaim.getGreaterBoundaryCorner();
World world = lesserCorner.getWorld();
ArrayList<ChunkSnapshot> snapshots = new ArrayList<ChunkSnapshot>();
for(int chunkx = lesserCorner.getBlockX() / 16; chunkx <= greaterCorner.getBlockX() / 16; chunkx++)
{
for(int chunkz = lesserCorner.getBlockZ() / 16; chunkz <= greaterCorner.getBlockZ() / 16; chunkz++)
{
if(world.isChunkLoaded(chunkx, chunkz))
{
snapshots.add(world.getChunkAt(chunkx, chunkz).getChunkSnapshot(true, true, true));
}
}
}
Bukkit.getScheduler().runTaskAsynchronously(GriefPrevention.instance, new AutoExtendClaimTask(newClaim, snapshots, world.getEnvironment()));
}
public boolean pvpRulesApply(World world) public boolean pvpRulesApply(World world)
{ {
Boolean configSetting = this.config_pvp_specifiedWorlds.get(world); Boolean configSetting = this.config_pvp_specifiedWorlds.get(world);

View File

@ -20,5 +20,5 @@ package me.ryanhamshire.GriefPrevention;
public enum Messages public enum Messages
{ {
RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound2, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionVideo2, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, RescuePending, NonSiegeWorld, AlreadySieging, NotSiegableThere, SiegeTooFarAway, NoSiegeDefenseless, AlreadyUnderSiegePlayer, AlreadyUnderSiegeArea, NoSiegeAdminClaim, SiegeOnCooldown, SiegeAlert, SiegeConfirmed, AbandonClaimMissing, NotYourClaim, DeleteTopLevelClaim, AbandonSuccess, CantGrantThatPermission, GrantPermissionNoClaim, GrantPermissionConfirmation, ManageUniversalPermissionsInstruction, ManageOneClaimPermissionsInstruction, CollectivePublic, BuildPermission, ContainersPermission, AccessPermission, PermissionsPermission, LocationCurrentClaim, LocationAllClaims, PvPImmunityStart, SiegeNoDrop, DonateItemsInstruction, ChestFull, DonationSuccess, PlayerTooCloseForFire, TooDeepToClaim, ChestClaimConfirmation, AutomaticClaimNotification, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsVideo2, SurvivalBasicsVideo2, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooNarrow, CreateClaimInsufficientBlocks, AbandonClaimAdvertisement, CreateClaimFailOverlapShort, CreateClaimSuccess, SiegeWinDoorsOpen, RescueAbortedMoved, SiegeDoorsLockedEjection, NoModifyDuringSiege, OnlyOwnersModifyClaims, NoBuildUnderSiege, NoBuildPvP, NoBuildPermission, NonSiegeMaterial, NoOwnerBuildUnderSiege, NoAccessPermission, NoContainersSiege, NoContainersPermission, OwnerNameForAdminClaims, ClaimTooSmallForEntities, TooManyEntitiesInClaim, YouHaveNoClaims, ConfirmFluidRemoval, AutoBanNotify, AdjustGroupBlocksSuccess, InvalidPermissionID, HowToClaimRegex, NoBuildOutsideClaims, PlayerOfflineTime, BuildingOutsideClaims, TrappedWontWorkHere, CommandBannedInPvP, UnclaimCleanupWarning, BuySellNotConfigured, NoTeleportPvPCombat, NoTNTDamageAboveSeaLevel, NoTNTDamageClaims, IgnoreClaimsAdvertisement, NoPermissionForCommand, ClaimsListNoPermission, ExplosivesDisabled, ExplosivesEnabled, ClaimExplosivesAdvertisement, PlayerInPvPSafeZone, NoPistonsOutsideClaims, SoftMuted, UnSoftMuted, DropUnlockAdvertisement, PickupBlockedExplanation, DropUnlockConfirmation, AdvertiseACandACB, AdvertiseAdminClaims, AdvertiseACB, NotYourPet, PetGiveawayConfirmation, PetTransferCancellation, ReadyToTransferPet, AvoidGriefClaimLand, BecomeMayor, ClaimCreationFailedOverClaimCountLimit, CreateClaimFailOverlapRegion, ResizeFailOverlapRegion, NoBuildPortalPermission, ShowNearbyClaims, NoChatUntilMove, SiegeImmune, SetClaimBlocksSuccess, IgnoreConfirmation, NotIgnoringPlayer, UnIgnoreConfirmation, SeparateConfirmation, UnSeparateConfirmation, NotIgnoringAnyone, TrustListHeader, Manage, Build, Containers, Access, StartBlockMath, ClaimsListHeader, ContinueBlockMath, EndBlockMath, NoClaimDuringPvP, UntrustAllOwnerOnly, ManagersDontUntrustManagers, BookAuthor, BookTitle, BookIntro, BookDisabledChestClaims, BookUsefulCommands, BookLink, BookTools, ResizeClaimTooNarrow, ResizeClaimInsufficientArea, NoProfanity, PlayerNotIgnorable, NoEnoughBlocksForChestClaim, IsIgnoringYou RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound2, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionVideo2, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, RescuePending, NonSiegeWorld, AlreadySieging, NotSiegableThere, SiegeTooFarAway, NoSiegeDefenseless, AlreadyUnderSiegePlayer, AlreadyUnderSiegeArea, NoSiegeAdminClaim, SiegeOnCooldown, SiegeAlert, SiegeConfirmed, AbandonClaimMissing, NotYourClaim, DeleteTopLevelClaim, AbandonSuccess, CantGrantThatPermission, GrantPermissionNoClaim, GrantPermissionConfirmation, ManageUniversalPermissionsInstruction, ManageOneClaimPermissionsInstruction, CollectivePublic, BuildPermission, ContainersPermission, AccessPermission, PermissionsPermission, LocationCurrentClaim, LocationAllClaims, PvPImmunityStart, SiegeNoDrop, DonateItemsInstruction, ChestFull, DonationSuccess, PlayerTooCloseForFire, TooDeepToClaim, ChestClaimConfirmation, AutomaticClaimNotification, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsVideo2, SurvivalBasicsVideo2, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooNarrow, CreateClaimInsufficientBlocks, AbandonClaimAdvertisement, CreateClaimFailOverlapShort, CreateClaimSuccess, SiegeWinDoorsOpen, RescueAbortedMoved, SiegeDoorsLockedEjection, NoModifyDuringSiege, OnlyOwnersModifyClaims, NoBuildUnderSiege, NoBuildPvP, NoBuildPermission, NonSiegeMaterial, NoOwnerBuildUnderSiege, NoAccessPermission, NoContainersSiege, NoContainersPermission, OwnerNameForAdminClaims, ClaimTooSmallForEntities, TooManyEntitiesInClaim, YouHaveNoClaims, ConfirmFluidRemoval, AutoBanNotify, AdjustGroupBlocksSuccess, InvalidPermissionID, HowToClaimRegex, NoBuildOutsideClaims, PlayerOfflineTime, BuildingOutsideClaims, TrappedWontWorkHere, CommandBannedInPvP, UnclaimCleanupWarning, BuySellNotConfigured, NoTeleportPvPCombat, NoTNTDamageAboveSeaLevel, NoTNTDamageClaims, IgnoreClaimsAdvertisement, NoPermissionForCommand, ClaimsListNoPermission, ExplosivesDisabled, ExplosivesEnabled, ClaimExplosivesAdvertisement, PlayerInPvPSafeZone, NoPistonsOutsideClaims, SoftMuted, UnSoftMuted, DropUnlockAdvertisement, PickupBlockedExplanation, DropUnlockConfirmation, AdvertiseACandACB, AdvertiseAdminClaims, AdvertiseACB, NotYourPet, PetGiveawayConfirmation, PetTransferCancellation, ReadyToTransferPet, AvoidGriefClaimLand, BecomeMayor, ClaimCreationFailedOverClaimCountLimit, CreateClaimFailOverlapRegion, ResizeFailOverlapRegion, NoBuildPortalPermission, ShowNearbyClaims, NoChatUntilMove, SiegeImmune, SetClaimBlocksSuccess, IgnoreConfirmation, NotIgnoringPlayer, UnIgnoreConfirmation, SeparateConfirmation, UnSeparateConfirmation, NotIgnoringAnyone, TrustListHeader, Manage, Build, Containers, Access, StartBlockMath, ClaimsListHeader, ContinueBlockMath, EndBlockMath, NoClaimDuringPvP, UntrustAllOwnerOnly, ManagersDontUntrustManagers, BookAuthor, BookTitle, BookIntro, BookDisabledChestClaims, BookUsefulCommands, BookLink, BookTools, ResizeClaimTooNarrow, ResizeClaimInsufficientArea, NoProfanity, PlayerNotIgnorable, NoEnoughBlocksForChestClaim, IsIgnoringYou, MustHoldModificationToolForThat, StandInClaimToResize, ClaimsExtendToSky, ClaimsAutoExtendDownward
} }

View File

@ -2211,143 +2211,7 @@ class PlayerEventHandler implements Listener
newy1 = playerData.claimResizing.getLesserBoundaryCorner().getBlockY(); newy1 = playerData.claimResizing.getLesserBoundaryCorner().getBlockY();
newy2 = clickedBlock.getY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance; newy2 = clickedBlock.getY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance;
//for top level claims, apply size rules and claim blocks requirement this.dataStore.resizeClaimWithChecks(player, playerData, newx1, newx2, newy1, newy2, newz1, newz2);
if(playerData.claimResizing.parent == null)
{
//measure new claim, apply size rules
int newWidth = (Math.abs(newx1 - newx2) + 1);
int newHeight = (Math.abs(newz1 - newz2) + 1);
boolean smaller = newWidth < playerData.claimResizing.getWidth() || newHeight < playerData.claimResizing.getHeight();
if(!player.hasPermission("griefprevention.adminclaims") && !playerData.claimResizing.isAdminClaim() && smaller)
{
if(newWidth < GriefPrevention.instance.config_claims_minWidth || newHeight < GriefPrevention.instance.config_claims_minWidth)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeClaimTooNarrow, String.valueOf(GriefPrevention.instance.config_claims_minWidth));
return;
}
int newArea = newWidth * newHeight;
if(newArea < GriefPrevention.instance.config_claims_minArea)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeClaimInsufficientArea, String.valueOf(GriefPrevention.instance.config_claims_minArea));
return;
}
}
//make sure player has enough blocks to make up the difference
if(!playerData.claimResizing.isAdminClaim() && player.getName().equals(playerData.claimResizing.getOwnerName()))
{
int newArea = newWidth * newHeight;
int blocksRemainingAfter = playerData.getRemainingClaimBlocks() + playerData.claimResizing.getArea() - newArea;
if(blocksRemainingAfter < 0)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeNeedMoreBlocks, String.valueOf(Math.abs(blocksRemainingAfter)));
this.tryAdvertiseAdminAlternatives(player);
return;
}
}
}
//special rule for making a top-level claim smaller. to check this, verifying the old claim's corners are inside the new claim's boundaries.
//rule: in any mode, shrinking a claim removes any surface fluids
Claim oldClaim = playerData.claimResizing;
boolean smaller = false;
if(oldClaim.parent == null)
{
//temporary claim instance, just for checking contains()
Claim newClaim = new Claim(
new Location(oldClaim.getLesserBoundaryCorner().getWorld(), newx1, newy1, newz1),
new Location(oldClaim.getLesserBoundaryCorner().getWorld(), newx2, newy2, newz2),
null, new ArrayList<String>(), new ArrayList<String>(), new ArrayList<String>(), new ArrayList<String>(), null);
//if the new claim is smaller
if(!newClaim.contains(oldClaim.getLesserBoundaryCorner(), true, false) || !newClaim.contains(oldClaim.getGreaterBoundaryCorner(), true, false))
{
smaller = true;
//remove surface fluids about to be unclaimed
oldClaim.removeSurfaceFluids(newClaim);
}
}
//ask the datastore to try and resize the claim, this checks for conflicts with other claims
CreateClaimResult result = GriefPrevention.instance.dataStore.resizeClaim(playerData.claimResizing, newx1, newx2, newy1, newy2, newz1, newz2, player);
if(result.succeeded)
{
//decide how many claim blocks are available for more resizing
int claimBlocksRemaining = 0;
if(!playerData.claimResizing.isAdminClaim())
{
UUID ownerID = playerData.claimResizing.ownerID;
if(playerData.claimResizing.parent != null)
{
ownerID = playerData.claimResizing.parent.ownerID;
}
if(ownerID == player.getUniqueId())
{
claimBlocksRemaining = playerData.getRemainingClaimBlocks();
}
else
{
PlayerData ownerData = this.dataStore.getPlayerData(ownerID);
claimBlocksRemaining = ownerData.getRemainingClaimBlocks();
OfflinePlayer owner = GriefPrevention.instance.getServer().getOfflinePlayer(ownerID);
if(!owner.isOnline())
{
this.dataStore.clearCachedPlayerData(ownerID);
}
}
}
//inform about success, visualize, communicate remaining blocks available
GriefPrevention.sendMessage(player, TextMode.Success, Messages.ClaimResizeSuccess, String.valueOf(claimBlocksRemaining));
Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.Claim, player.getLocation());
Visualization.Apply(player, visualization);
//if resizing someone else's claim, make a log entry
if(!playerID.equals(playerData.claimResizing.ownerID) && playerData.claimResizing.parent == null)
{
GriefPrevention.AddLogEntry(player.getName() + " resized " + playerData.claimResizing.getOwnerName() + "'s claim at " + GriefPrevention.getfriendlyLocationString(playerData.claimResizing.lesserBoundaryCorner) + ".");
}
//if increased to a sufficiently large size and no subdivisions yet, send subdivision instructions
if(oldClaim.getArea() < 1000 && result.claim.getArea() >= 1000 && result.claim.children.size() == 0 && !player.hasPermission("griefprevention.adminclaims"))
{
GriefPrevention.sendMessage(player, TextMode.Info, Messages.BecomeMayor, 200L);
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SubdivisionVideo2, 201L, DataStore.SUBDIVISION_VIDEO_URL);
}
//if in a creative mode world and shrinking an existing claim, restore any unclaimed area
if(smaller && GriefPrevention.instance.creativeRulesApply(oldClaim.getLesserBoundaryCorner()))
{
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.UnclaimCleanupWarning);
GriefPrevention.instance.restoreClaim(oldClaim, 20L * 60 * 2); //2 minutes
GriefPrevention.AddLogEntry(player.getName() + " shrank a claim @ " + GriefPrevention.getfriendlyLocationString(playerData.claimResizing.getLesserBoundaryCorner()));
}
//clean up
playerData.claimResizing = null;
playerData.lastShovelLocation = null;
}
else
{
if(result.claim != null)
{
//inform player
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeFailOverlap);
//show the player the conflicting claim
Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.ErrorClaim, player.getLocation());
Visualization.Apply(player, visualization);
}
else
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeFailOverlapRegion);
}
}
return; return;
} }
@ -2541,7 +2405,7 @@ class PlayerEventHandler implements Listener
if(newClaimArea > remainingBlocks) if(newClaimArea > remainingBlocks)
{ {
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimInsufficientBlocks, String.valueOf(newClaimArea - remainingBlocks)); GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimInsufficientBlocks, String.valueOf(newClaimArea - remainingBlocks));
this.tryAdvertiseAdminAlternatives(player); GriefPrevention.instance.dataStore.tryAdvertiseAdminAlternatives(player);
return; return;
} }
} }
@ -2593,44 +2457,10 @@ class PlayerEventHandler implements Listener
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SubdivisionVideo2, 201L, DataStore.SUBDIVISION_VIDEO_URL); GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SubdivisionVideo2, 201L, DataStore.SUBDIVISION_VIDEO_URL);
} }
//auto-extend it downward to cover anything already built underground GriefPrevention.instance.autoExtendClaim(result.claim);
Claim newClaim = result.claim;
Location lesserCorner = newClaim.getLesserBoundaryCorner();
Location greaterCorner = newClaim.getGreaterBoundaryCorner();
World world = lesserCorner.getWorld();
ArrayList<ChunkSnapshot> snapshots = new ArrayList<ChunkSnapshot>();
for(int chunkx = lesserCorner.getBlockX() / 16; chunkx <= greaterCorner.getBlockX() / 16; chunkx++)
{
for(int chunkz = lesserCorner.getBlockZ() / 16; chunkz <= greaterCorner.getBlockZ() / 16; chunkz++)
{
if(world.isChunkLoaded(chunkx, chunkz))
{
snapshots.add(world.getChunkAt(chunkx, chunkz).getChunkSnapshot(true, true, true));
} }
} }
} }
Bukkit.getScheduler().runTaskAsynchronously(GriefPrevention.instance, new AutoExtendClaimTask(newClaim, snapshots, world.getEnvironment()));
}
}
}
}
//educates a player about /adminclaims and /acb, if he can use them
private void tryAdvertiseAdminAlternatives(Player player)
{
if(player.hasPermission("griefprevention.adminclaims") && player.hasPermission("griefprevention.adjustclaimblocks"))
{
GriefPrevention.sendMessage(player, TextMode.Info, Messages.AdvertiseACandACB);
}
else if(player.hasPermission("griefprevention.adminclaims"))
{
GriefPrevention.sendMessage(player, TextMode.Info, Messages.AdvertiseAdminClaims);
}
else if(player.hasPermission("griefprevention.adjustclaimblocks"))
{
GriefPrevention.sendMessage(player, TextMode.Info, Messages.AdvertiseACB);
}
} }
//determines whether a block type is an inventory holder. uses a caching strategy to save cpu time //determines whether a block type is an inventory holder. uses a caching strategy to save cpu time

View File

@ -55,6 +55,7 @@ public class WelcomeTask implements Runnable
page2.append("/Trust /UnTrust /TrustList\n"); page2.append("/Trust /UnTrust /TrustList\n");
page2.append("/ClaimsList\n"); page2.append("/ClaimsList\n");
page2.append("/AbandonClaim\n\n"); page2.append("/AbandonClaim\n\n");
page2.append("/Claim /ExtendClaim\n");
page2.append("/IgnorePlayer\n\n"); page2.append("/IgnorePlayer\n\n");