Added /GivePet and tweaked pet protections.

This commit is contained in:
ryanhamshire 2014-12-17 21:19:47 -08:00
parent 14b0129c3e
commit 4a426f6469
7 changed files with 126 additions and 66 deletions

View File

@ -137,6 +137,9 @@ commands:
description: Reloads Grief Prevention's configuration settings. Does NOT totally reload the entire plugin. description: Reloads Grief Prevention's configuration settings. Does NOT totally reload the entire plugin.
usage: /gpreload usage: /gpreload
permission: griefprevention.reload permission: griefprevention.reload
givepet:
description: Allows a player to give away a pet he or she tamed.
usage: /GivePet <player>
permissions: permissions:
griefprevention.createclaims: griefprevention.createclaims:
description: Grants permission to create claims. description: Grants permission to create claims.

View File

@ -1176,6 +1176,10 @@ public abstract class DataStore
this.addDefault(defaults, Messages.AdvertiseACandACB, "You may use /ACB to give yourself more claim blocks, or /AdminClaims to create a free administrative claim.", null); this.addDefault(defaults, Messages.AdvertiseACandACB, "You may use /ACB to give yourself more claim blocks, or /AdminClaims to create a free administrative claim.", null);
this.addDefault(defaults, Messages.AdvertiseAdminClaims, "You could create an administrative land claim instead using /AdminClaims, which you'd share with other administrators.", null); this.addDefault(defaults, Messages.AdvertiseAdminClaims, "You could create an administrative land claim instead using /AdminClaims, which you'd share with other administrators.", null);
this.addDefault(defaults, Messages.AdvertiseACB, "You may use /ACB to give yourself more claim blocks.", null); this.addDefault(defaults, Messages.AdvertiseACB, "You may use /ACB to give yourself more claim blocks.", null);
this.addDefault(defaults, Messages.NotYourPet, "That belongs to {0} until it's given to you with /GivePet.", "0: owner name");
this.addDefault(defaults, Messages.PetGiveawayConfirmation, "Pet transferred.", null);
this.addDefault(defaults, Messages.PetTransferCancellation, "Pet giveaway cancelled.", null);
this.addDefault(defaults, Messages.ReadyToTransferPet, "Ready to transfer! Right-click the pet you'd like to give away, or cancel with /GivePet cancel.", null);
//load the config file //load the config file
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath)); FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath));

View File

@ -430,12 +430,33 @@ class EntityEventHandler implements Listener
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onEntityDamage (EntityDamageEvent event) public void onEntityDamage (EntityDamageEvent event)
{ {
//only actually interested in entities damaging entities (ignoring environmental damage)
if(!(event instanceof EntityDamageByEntityEvent)) return;
//monsters are never protected //monsters are never protected
if(event.getEntity() instanceof Monster) return; if(event.getEntity() instanceof Monster) return;
//protect pets from environmental damage types which could be easily caused by griefers
if(event.getEntity() instanceof Tameable && !GriefPrevention.instance.config_pvp_enabledWorlds.contains(event.getEntity().getWorld()))
{
Tameable tameable = (Tameable)event.getEntity();
if(tameable.isTamed())
{
DamageCause cause = event.getCause();
if( cause != null && (
cause == DamageCause.ENTITY_EXPLOSION ||
cause == DamageCause.FALLING_BLOCK ||
cause == DamageCause.FIRE ||
cause == DamageCause.FIRE_TICK ||
cause == DamageCause.LAVA ||
cause == DamageCause.SUFFOCATION))
{
event.setCancelled(true);
return;
}
}
}
//the rest is only interested in entities damaging entities (ignoring environmental damage)
if(!(event instanceof EntityDamageByEntityEvent)) return;
EntityDamageByEntityEvent subEvent = (EntityDamageByEntityEvent) event; EntityDamageByEntityEvent subEvent = (EntityDamageByEntityEvent) event;
//determine which player is attacking, if any //determine which player is attacking, if any
@ -578,7 +599,7 @@ class EntityEventHandler implements Listener
if ((subEvent.getEntity() instanceof Creature && GriefPrevention.instance.config_claims_protectCreatures)) if ((subEvent.getEntity() instanceof Creature && GriefPrevention.instance.config_claims_protectCreatures))
{ {
//if entity is tameable and has an owner, apply special rules //if entity is tameable and has an owner, apply special rules
if(subEvent.getEntity() instanceof Tameable) if(subEvent.getEntity() instanceof Tameable && !GriefPrevention.instance.config_pvp_enabledWorlds.contains(subEvent.getEntity().getWorld()))
{ {
Tameable tameable = (Tameable)subEvent.getEntity(); Tameable tameable = (Tameable)subEvent.getEntity();
if(tameable.isTamed() && tameable.getOwner() != null) if(tameable.isTamed() && tameable.getOwner() != null)
@ -609,23 +630,6 @@ class EntityEventHandler implements Listener
return; return;
} }
} }
//also limit damage sources to prevent grief of pets by build (flint/steel, lava buckets, sand...)
else
{
DamageCause cause = event.getCause();
if(cause != null && (
cause == DamageCause.ENTITY_EXPLOSION ||
cause == DamageCause.FALLING_BLOCK ||
cause == DamageCause.FIRE ||
cause == DamageCause.FIRE_TICK ||
cause == DamageCause.LAVA ||
cause == DamageCause.SUFFOCATION))
{
event.setCancelled(true);
return;
}
}
} }
} }

View File

@ -1919,6 +1919,39 @@ public class GriefPrevention extends JavaPlugin
return true; return true;
} }
//givepet
else if(cmd.getName().equalsIgnoreCase("givepet") && player != null)
{
//requires one parameter
if(args.length < 1) return false;
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
//special case: cancellation
if(args[0].equalsIgnoreCase("cancel"))
{
playerData.petGiveawayRecipient = null;
GriefPrevention.sendMessage(player, TextMode.Success, Messages.PetTransferCancellation);
return true;
}
//find the specified player
OfflinePlayer targetPlayer = this.resolvePlayerByName(args[0]);
if(targetPlayer == null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound2);
return true;
}
//remember the player's ID for later pet transfer
playerData.petGiveawayRecipient = targetPlayer;
//send instructions
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.ReadyToTransferPet);
return true;
}
return false; return false;
} }

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, SubdivisionVideo, 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, CreativeBasicsVideo, SurvivalBasicsVideo, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeClaimTooSmall, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooSmall, 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, UntrustOwnerOnly, 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 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, SubdivisionVideo, 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, CreativeBasicsVideo, SurvivalBasicsVideo, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeClaimTooSmall, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooSmall, 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, UntrustOwnerOnly, 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
} }

View File

@ -30,6 +30,7 @@ import me.ryanhamshire.GriefPrevention.SiegeData;
import me.ryanhamshire.GriefPrevention.Visualization; import me.ryanhamshire.GriefPrevention.Visualization;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
//holds all of GriefPrevention's player-tied data //holds all of GriefPrevention's player-tied data
public class PlayerData public class PlayerData
@ -118,6 +119,9 @@ public class PlayerData
//message to send to player after he respawns //message to send to player after he respawns
String messageOnRespawn = null; String messageOnRespawn = null;
//player which a pet will be given to when it's right-clicked
OfflinePlayer petGiveawayRecipient = null;
//whether or not this player is "in" pvp combat //whether or not this player is "in" pvp combat
public boolean inPvpCombat() public boolean inPvpCombat()
{ {

View File

@ -825,15 +825,48 @@ class PlayerEventHandler implements Listener
if(!GriefPrevention.instance.claimsEnabledForWorld(entity.getWorld())) return; if(!GriefPrevention.instance.claimsEnabledForWorld(entity.getWorld())) return;
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
//always allow interactions when player is in ignore claims mode
if(playerData.ignoreClaims) return;
//allow horse protection to be overridden to allow management from other plugins //allow horse protection to be overridden to allow management from other plugins
if (!GriefPrevention.instance.config_claims_protectHorses && entity instanceof Horse) return; if (!GriefPrevention.instance.config_claims_protectHorses && entity instanceof Horse) return;
//don't allow interaction with item frames or armor stands in claimed areas without build permission PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
//if entity is tameable and has an owner, apply special rules
if(entity instanceof Tameable && !GriefPrevention.instance.config_pvp_enabledWorlds.contains(entity.getLocation().getWorld()))
{
Tameable tameable = (Tameable)entity;
if(tameable.isTamed() && tameable.getOwner() != null)
{
UUID ownerID = tameable.getOwner().getUniqueId();
//if the player interacting is the owner or an admin in ignore claims mode, always allow
if(player.getUniqueId().equals(ownerID) || playerData.ignoreClaims)
{
//if giving away pet, do that instead
if(playerData.petGiveawayRecipient != null)
{
tameable.setOwner(playerData.petGiveawayRecipient);
playerData.petGiveawayRecipient = null;
GriefPrevention.sendMessage(player, TextMode.Success, Messages.PetGiveawayConfirmation);
event.setCancelled(true);
}
return;
}
//otherwise disallow
OfflinePlayer owner = GriefPrevention.instance.getServer().getOfflinePlayer(ownerID);
String ownerName = owner.getName();
if(ownerName == null) ownerName = "someone";
String message = GriefPrevention.instance.dataStore.getMessage(Messages.NotYourPet, ownerName);
if(player.hasPermission("griefprevention.ignoreclaims"))
message += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
GriefPrevention.sendMessage(player, TextMode.Err, message);
event.setCancelled(true);
return;
}
}
//don't allow interaction with item frames or armor stands in claimed areas without build permission
if(entity.getType() == EntityType.ARMOR_STAND || entity instanceof Hanging) if(entity.getType() == EntityType.ARMOR_STAND || entity instanceof Hanging)
{ {
String noBuildReason = GriefPrevention.instance.allowBuild(player, entity.getLocation(), Material.ITEM_FRAME); String noBuildReason = GriefPrevention.instance.allowBuild(player, entity.getLocation(), Material.ITEM_FRAME);
@ -845,45 +878,24 @@ class PlayerEventHandler implements Listener
} }
} }
//don't allow container access during pvp combat //always allow interactions when player is in ignore claims mode
if((entity instanceof StorageMinecart || entity instanceof PoweredMinecart)) if(playerData.ignoreClaims) return;
{
if(playerData.siegeData != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoContainers);
event.setCancelled(true);
return;
}
if(playerData.inPvpCombat()) //don't allow container access during pvp combat
{ if((entity instanceof StorageMinecart || entity instanceof PoweredMinecart))
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoContainers);
event.setCancelled(true);
return;
}
}
//if entity is tameable and has an owner, apply special rules
if(entity instanceof Tameable && !GriefPrevention.instance.config_pvp_enabledWorlds.contains(entity.getLocation().getWorld()))
{ {
Tameable tameable = (Tameable)entity; if(playerData.siegeData != null)
if(tameable.isTamed() && tameable.getOwner() != null)
{ {
UUID ownerID = tameable.getOwner().getUniqueId(); GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoContainers);
event.setCancelled(true);
return;
}
//if the player interacting is the owner, always allow if(playerData.inPvpCombat())
if(player.getUniqueId().equals(ownerID)) return; {
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoContainers);
//otherwise disallow event.setCancelled(true);
OfflinePlayer owner = GriefPrevention.instance.getServer().getOfflinePlayer(ownerID); return;
String ownerName = owner.getName();
if(ownerName == null) ownerName = "someone";
String message = GriefPrevention.instance.dataStore.getMessage(Messages.NoDamageClaimedEntity, ownerName);
if(player.hasPermission("griefprevention.ignoreclaims"))
message += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
GriefPrevention.sendMessage(player, TextMode.Err, message);
event.setCancelled(true);
return;
} }
} }