2014-10-08 06:38:26 +02:00
|
|
|
package com.massivecraft.factions.engine;
|
2013-04-10 12:25:46 +02:00
|
|
|
|
2013-04-18 21:00:46 +02:00
|
|
|
import java.text.MessageFormat;
|
2013-04-18 16:35:45 +02:00
|
|
|
import java.util.Collection;
|
2013-09-22 11:34:21 +02:00
|
|
|
import java.util.HashMap;
|
2013-04-18 15:59:20 +02:00
|
|
|
import java.util.Iterator;
|
2013-04-23 12:31:07 +02:00
|
|
|
import java.util.List;
|
2013-09-22 11:34:21 +02:00
|
|
|
import java.util.Map;
|
2013-04-18 15:59:20 +02:00
|
|
|
|
2013-04-10 12:25:46 +02:00
|
|
|
import org.bukkit.Bukkit;
|
2013-04-26 10:32:02 +02:00
|
|
|
import org.bukkit.Location;
|
2013-04-24 15:35:46 +02:00
|
|
|
import org.bukkit.Material;
|
2013-04-17 16:21:25 +02:00
|
|
|
import org.bukkit.block.Block;
|
2014-10-06 13:08:34 +02:00
|
|
|
import org.bukkit.command.CommandSender;
|
2013-04-18 15:59:20 +02:00
|
|
|
import org.bukkit.entity.Enderman;
|
2013-04-10 12:25:46 +02:00
|
|
|
import org.bukkit.entity.Entity;
|
2013-04-18 16:11:45 +02:00
|
|
|
import org.bukkit.entity.EntityType;
|
2014-01-05 12:20:41 +01:00
|
|
|
import org.bukkit.entity.ItemFrame;
|
2013-04-18 21:00:46 +02:00
|
|
|
import org.bukkit.entity.LivingEntity;
|
2013-04-10 12:25:46 +02:00
|
|
|
import org.bukkit.entity.Player;
|
2013-04-18 15:59:20 +02:00
|
|
|
import org.bukkit.entity.Wither;
|
2013-04-17 16:21:25 +02:00
|
|
|
import org.bukkit.event.Cancellable;
|
2013-04-10 12:25:46 +02:00
|
|
|
import org.bukkit.event.EventHandler;
|
|
|
|
import org.bukkit.event.EventPriority;
|
2013-04-24 15:35:46 +02:00
|
|
|
import org.bukkit.event.block.Action;
|
2013-04-17 16:21:25 +02:00
|
|
|
import org.bukkit.event.block.BlockBreakEvent;
|
|
|
|
import org.bukkit.event.block.BlockBurnEvent;
|
|
|
|
import org.bukkit.event.block.BlockDamageEvent;
|
|
|
|
import org.bukkit.event.block.BlockIgniteEvent;
|
|
|
|
import org.bukkit.event.block.BlockPistonExtendEvent;
|
|
|
|
import org.bukkit.event.block.BlockPistonRetractEvent;
|
|
|
|
import org.bukkit.event.block.BlockPlaceEvent;
|
|
|
|
import org.bukkit.event.block.BlockSpreadEvent;
|
|
|
|
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
|
2013-04-18 16:11:45 +02:00
|
|
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
2013-04-18 15:59:20 +02:00
|
|
|
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
2013-04-18 21:00:46 +02:00
|
|
|
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
|
|
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
2013-04-10 12:25:46 +02:00
|
|
|
import org.bukkit.event.entity.EntityDamageEvent;
|
2013-04-18 15:59:20 +02:00
|
|
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
2013-04-18 16:11:45 +02:00
|
|
|
import org.bukkit.event.entity.EntityTargetEvent;
|
2013-04-19 12:27:39 +02:00
|
|
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
2013-04-18 21:00:46 +02:00
|
|
|
import org.bukkit.event.entity.PotionSplashEvent;
|
2014-10-03 18:01:40 +02:00
|
|
|
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
2013-04-17 16:21:25 +02:00
|
|
|
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
|
|
|
import org.bukkit.event.hanging.HangingBreakEvent;
|
|
|
|
import org.bukkit.event.hanging.HangingPlaceEvent;
|
|
|
|
import org.bukkit.event.hanging.HangingBreakEvent.RemoveCause;
|
2013-04-24 15:35:46 +02:00
|
|
|
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
|
|
|
import org.bukkit.event.player.PlayerBucketFillEvent;
|
2013-04-18 16:35:45 +02:00
|
|
|
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
2014-10-03 13:16:07 +02:00
|
|
|
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
2013-04-24 15:35:46 +02:00
|
|
|
import org.bukkit.event.player.PlayerInteractEvent;
|
2014-10-02 16:12:16 +02:00
|
|
|
import org.bukkit.event.player.PlayerJoinEvent;
|
2013-04-18 17:20:42 +02:00
|
|
|
import org.bukkit.event.player.PlayerKickEvent;
|
|
|
|
import org.bukkit.event.player.PlayerMoveEvent;
|
2013-07-24 18:29:55 +02:00
|
|
|
import org.bukkit.event.player.PlayerRespawnEvent;
|
2014-10-08 06:24:37 +02:00
|
|
|
import org.bukkit.plugin.Plugin;
|
2014-03-27 00:13:41 +01:00
|
|
|
import org.bukkit.projectiles.ProjectileSource;
|
2013-04-10 12:25:46 +02:00
|
|
|
|
2013-04-18 14:02:39 +02:00
|
|
|
import com.massivecraft.factions.Factions;
|
2013-04-18 16:35:45 +02:00
|
|
|
import com.massivecraft.factions.Rel;
|
2013-04-24 15:19:49 +02:00
|
|
|
import com.massivecraft.factions.TerritoryAccess;
|
2014-09-17 13:17:33 +02:00
|
|
|
import com.massivecraft.factions.entity.BoardColl;
|
2014-10-02 11:45:06 +02:00
|
|
|
import com.massivecraft.factions.entity.MFlag;
|
2014-10-02 14:02:07 +02:00
|
|
|
import com.massivecraft.factions.entity.MPerm;
|
2014-09-17 13:17:33 +02:00
|
|
|
import com.massivecraft.factions.entity.MPlayer;
|
2013-04-22 09:37:53 +02:00
|
|
|
import com.massivecraft.factions.entity.Faction;
|
2013-04-22 10:43:40 +02:00
|
|
|
import com.massivecraft.factions.entity.MConf;
|
2014-09-17 13:17:33 +02:00
|
|
|
import com.massivecraft.factions.entity.MPlayerColl;
|
2014-06-04 16:47:01 +02:00
|
|
|
import com.massivecraft.factions.event.EventFactionsPvpDisallowed;
|
|
|
|
import com.massivecraft.factions.event.EventFactionsPowerChange;
|
|
|
|
import com.massivecraft.factions.event.EventFactionsPowerChange.PowerChangeReason;
|
2013-04-18 17:20:42 +02:00
|
|
|
import com.massivecraft.factions.util.VisualizeUtil;
|
2014-10-08 06:24:37 +02:00
|
|
|
import com.massivecraft.massivecore.EngineAbstract;
|
2014-10-06 13:08:34 +02:00
|
|
|
import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave;
|
2014-10-02 16:12:16 +02:00
|
|
|
import com.massivecraft.massivecore.mixin.Mixin;
|
2014-06-04 14:02:23 +02:00
|
|
|
import com.massivecraft.massivecore.ps.PS;
|
|
|
|
import com.massivecraft.massivecore.util.MUtil;
|
|
|
|
import com.massivecraft.massivecore.util.PlayerUtil;
|
|
|
|
import com.massivecraft.massivecore.util.Txt;
|
2013-04-10 12:25:46 +02:00
|
|
|
|
2014-10-08 06:38:26 +02:00
|
|
|
public class EngineMain extends EngineAbstract
|
2013-04-10 12:25:46 +02:00
|
|
|
{
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// INSTANCE & CONSTRUCT
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
2014-10-08 06:38:26 +02:00
|
|
|
private static EngineMain i = new EngineMain();
|
|
|
|
public static EngineMain get() { return i; }
|
|
|
|
public EngineMain() {}
|
2013-04-10 12:25:46 +02:00
|
|
|
|
|
|
|
// -------------------------------------------- //
|
2014-10-08 06:24:37 +02:00
|
|
|
// OVERRIDE
|
2013-04-10 12:25:46 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
|
2014-10-08 06:24:37 +02:00
|
|
|
@Override
|
|
|
|
public Plugin getPlugin()
|
2013-04-10 12:25:46 +02:00
|
|
|
{
|
2014-10-08 06:24:37 +02:00
|
|
|
return Factions.get();
|
2013-04-10 12:25:46 +02:00
|
|
|
}
|
2014-10-06 13:08:34 +02:00
|
|
|
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// UPDATE LAST ACTIVITY
|
|
|
|
// -------------------------------------------- //
|
2013-04-18 21:00:46 +02:00
|
|
|
|
2014-10-06 13:08:34 +02:00
|
|
|
public static void updateLastActivity(CommandSender sender)
|
|
|
|
{
|
|
|
|
if (sender == null) throw new RuntimeException("sender");
|
|
|
|
MPlayer mplayer = MPlayer.get(sender);
|
|
|
|
mplayer.setLastActivityMillis();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void updateLastActivitySoon(final CommandSender sender)
|
|
|
|
{
|
|
|
|
if (sender == null) throw new RuntimeException("sender");
|
|
|
|
Bukkit.getScheduler().scheduleSyncDelayedTask(Factions.get(), new Runnable()
|
|
|
|
{
|
|
|
|
@Override
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
updateLastActivity(sender);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can't be cancelled
|
|
|
|
@EventHandler(priority = EventPriority.LOWEST)
|
|
|
|
public void updateLastActivity(PlayerJoinEvent event)
|
|
|
|
{
|
|
|
|
// During the join event itself we want to be able to reach the old data.
|
|
|
|
// That is also the way the underlying fallback Mixin system does it and we do it that way for the sake of symmetry.
|
|
|
|
// For that reason we wait till the next tick with updating the value.
|
|
|
|
updateLastActivitySoon(event.getPlayer());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can't be cancelled
|
|
|
|
@EventHandler(priority = EventPriority.LOWEST)
|
|
|
|
public void updateLastActivity(EventMassiveCorePlayerLeave event)
|
|
|
|
{
|
|
|
|
// Here we do however update immediately.
|
|
|
|
// The player data should be fully updated before leaving the server.
|
|
|
|
updateLastActivity(event.getPlayer());
|
|
|
|
}
|
|
|
|
|
2014-10-02 16:12:16 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
// MOTD
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
public static void motd(PlayerJoinEvent event, EventPriority currentPriority)
|
|
|
|
{
|
|
|
|
// Gather info ...
|
|
|
|
final Player player = event.getPlayer();
|
|
|
|
final MPlayer mplayer = MPlayer.get(player);
|
|
|
|
final Faction faction = mplayer.getFaction();
|
|
|
|
|
|
|
|
// ... if there is a motd ...
|
|
|
|
if ( ! faction.hasMotd()) return;
|
|
|
|
|
|
|
|
// ... and this is the priority we are supposed to act on ...
|
|
|
|
if (currentPriority != MConf.get().motdPriority) return;
|
|
|
|
|
|
|
|
// ... and this is an actual join ...
|
|
|
|
if (!Mixin.isActualJoin(event)) return;
|
|
|
|
|
|
|
|
// ... then prepare the messages ...
|
|
|
|
final List<String> messages = faction.getMotdMessages();
|
|
|
|
|
|
|
|
// ... and send to the player.
|
|
|
|
if (MConf.get().motdDelayTicks < 0)
|
|
|
|
{
|
|
|
|
Mixin.messageOne(player, messages);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Bukkit.getScheduler().scheduleSyncDelayedTask(Factions.get(), new Runnable()
|
|
|
|
{
|
|
|
|
@Override
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
Mixin.messageOne(player, messages);
|
|
|
|
}
|
|
|
|
}, MConf.get().motdDelayTicks);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can't be cancelled
|
|
|
|
@EventHandler(priority = EventPriority.LOWEST)
|
|
|
|
public void motdLowest(PlayerJoinEvent event)
|
|
|
|
{
|
|
|
|
motd(event, EventPriority.LOWEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can't be cancelled
|
|
|
|
@EventHandler(priority = EventPriority.LOW)
|
|
|
|
public void motdLow(PlayerJoinEvent event)
|
|
|
|
{
|
|
|
|
motd(event, EventPriority.LOW);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can't be cancelled
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL)
|
|
|
|
public void motdNormal(PlayerJoinEvent event)
|
|
|
|
{
|
|
|
|
motd(event, EventPriority.NORMAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can't be cancelled
|
|
|
|
@EventHandler(priority = EventPriority.HIGH)
|
|
|
|
public void motdHigh(PlayerJoinEvent event)
|
|
|
|
{
|
|
|
|
motd(event, EventPriority.HIGH);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can't be cancelled
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST)
|
|
|
|
public void motdHighest(PlayerJoinEvent event)
|
|
|
|
{
|
|
|
|
motd(event, EventPriority.HIGHEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can't be cancelled
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR)
|
|
|
|
public void motdMonitor(PlayerJoinEvent event)
|
|
|
|
{
|
|
|
|
motd(event, EventPriority.MONITOR);
|
|
|
|
}
|
|
|
|
|
2013-04-24 15:19:49 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
// CHUNK CHANGE: DETECT
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
|
|
public void chunkChangeDetect(PlayerMoveEvent event)
|
|
|
|
{
|
|
|
|
// If the player is moving from one chunk to another ...
|
|
|
|
if (MUtil.isSameChunk(event)) return;
|
2013-04-25 13:25:15 +02:00
|
|
|
Player player = event.getPlayer();
|
|
|
|
|
2013-04-24 15:19:49 +02:00
|
|
|
// ... gather info on the player and the move ...
|
2014-09-17 13:17:33 +02:00
|
|
|
MPlayer mplayer = MPlayer.get(player);
|
2013-04-24 15:19:49 +02:00
|
|
|
|
|
|
|
PS chunkFrom = PS.valueOf(event.getFrom()).getChunk(true);
|
|
|
|
PS chunkTo = PS.valueOf(event.getTo()).getChunk(true);
|
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction factionFrom = BoardColl.get().getFactionAt(chunkFrom);
|
|
|
|
Faction factionTo = BoardColl.get().getFactionAt(chunkTo);
|
2013-04-24 15:19:49 +02:00
|
|
|
|
|
|
|
// ... and send info onwards.
|
2014-09-17 13:17:33 +02:00
|
|
|
this.chunkChangeTerritoryInfo(mplayer, player, chunkFrom, chunkTo, factionFrom, factionTo);
|
|
|
|
this.chunkChangeAutoClaim(mplayer, chunkTo);
|
2013-04-24 15:19:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// CHUNK CHANGE: TERRITORY INFO
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
2014-09-17 13:29:58 +02:00
|
|
|
public void chunkChangeTerritoryInfo(MPlayer mplayer, Player player, PS chunkFrom, PS chunkTo, Faction factionFrom, Faction factionTo)
|
2013-04-24 15:19:49 +02:00
|
|
|
{
|
|
|
|
// send host faction info updates
|
2014-09-17 13:29:58 +02:00
|
|
|
if (mplayer.isMapAutoUpdating())
|
2013-04-24 15:19:49 +02:00
|
|
|
{
|
2014-09-17 13:29:58 +02:00
|
|
|
mplayer.sendMessage(BoardColl.get().getMap(mplayer, chunkTo, player.getLocation().getYaw()));
|
2013-04-24 15:19:49 +02:00
|
|
|
}
|
|
|
|
else if (factionFrom != factionTo)
|
|
|
|
{
|
2014-09-17 13:29:58 +02:00
|
|
|
String msg = Txt.parse("<i>") + " ~ " + factionTo.getName(mplayer);
|
2013-04-24 15:19:49 +02:00
|
|
|
if (factionTo.hasDescription())
|
|
|
|
{
|
|
|
|
msg += " - " + factionTo.getDescription();
|
|
|
|
}
|
|
|
|
player.sendMessage(msg);
|
|
|
|
}
|
|
|
|
|
2013-04-29 12:48:11 +02:00
|
|
|
// Show access level message if it changed.
|
2014-09-17 13:17:33 +02:00
|
|
|
TerritoryAccess accessFrom = BoardColl.get().getTerritoryAccessAt(chunkFrom);
|
2014-09-17 13:29:58 +02:00
|
|
|
Boolean hasTerritoryAccessFrom = accessFrom.hasTerritoryAccess(mplayer);
|
2013-04-29 12:48:11 +02:00
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
TerritoryAccess accessTo = BoardColl.get().getTerritoryAccessAt(chunkTo);
|
2014-09-17 13:29:58 +02:00
|
|
|
Boolean hasTerritoryAccessTo = accessTo.hasTerritoryAccess(mplayer);
|
2013-04-29 12:48:11 +02:00
|
|
|
|
|
|
|
if (!MUtil.equals(hasTerritoryAccessFrom, hasTerritoryAccessTo))
|
2013-04-24 15:19:49 +02:00
|
|
|
{
|
2013-04-29 12:48:11 +02:00
|
|
|
if (hasTerritoryAccessTo == null)
|
|
|
|
{
|
2014-09-17 13:29:58 +02:00
|
|
|
mplayer.msg("<i>You have standard access to this area.");
|
2013-04-29 12:48:11 +02:00
|
|
|
}
|
|
|
|
else if (hasTerritoryAccessTo)
|
2013-04-24 15:19:49 +02:00
|
|
|
{
|
2014-09-17 13:29:58 +02:00
|
|
|
mplayer.msg("<g>You have elevated access to this area.");
|
2013-04-24 15:19:49 +02:00
|
|
|
}
|
2013-04-29 12:48:11 +02:00
|
|
|
else
|
2013-04-24 15:19:49 +02:00
|
|
|
{
|
2014-09-17 13:29:58 +02:00
|
|
|
mplayer.msg("<b>You have decreased access to this area.");
|
2013-04-24 15:19:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// CHUNK CHANGE: AUTO CLAIM
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
2014-09-17 13:29:58 +02:00
|
|
|
public void chunkChangeAutoClaim(MPlayer mplayer, PS chunkTo)
|
2013-04-24 15:19:49 +02:00
|
|
|
{
|
|
|
|
// If the player is auto claiming ...
|
2014-09-17 13:29:58 +02:00
|
|
|
Faction autoClaimFaction = mplayer.getAutoClaimFaction();
|
2013-04-24 15:19:49 +02:00
|
|
|
if (autoClaimFaction == null) return;
|
|
|
|
|
|
|
|
// ... try claim.
|
2014-09-17 13:29:58 +02:00
|
|
|
mplayer.tryClaim(autoClaimFaction, chunkTo, true, true);
|
2013-04-24 15:19:49 +02:00
|
|
|
}
|
|
|
|
|
2013-04-19 12:27:39 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
// POWER LOSS ON DEATH
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL)
|
|
|
|
public void powerLossOnDeath(PlayerDeathEvent event)
|
|
|
|
{
|
|
|
|
// If a player dies ...
|
|
|
|
Player player = event.getEntity();
|
2013-04-25 13:25:15 +02:00
|
|
|
|
2013-08-27 10:56:47 +02:00
|
|
|
// ... and this is the first death event this tick ...
|
|
|
|
// (yeah other plugins can case death event to fire twice the same tick)
|
|
|
|
if (PlayerUtil.isDuplicateDeathEvent(event)) return;
|
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
MPlayer mplayer = MPlayer.get(player);
|
2013-04-19 12:27:39 +02:00
|
|
|
|
|
|
|
// ... and powerloss can happen here ...
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction faction = BoardColl.get().getFactionAt(PS.valueOf(player));
|
2013-04-19 12:27:39 +02:00
|
|
|
|
2014-10-07 12:30:44 +02:00
|
|
|
if (!faction.getFlag(MFlag.getFlagPowerloss()))
|
2013-04-19 12:27:39 +02:00
|
|
|
{
|
2014-09-17 13:17:33 +02:00
|
|
|
mplayer.msg("<i>You didn't lose any power since the territory you died in works that way.");
|
2013-04-19 12:27:39 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-09-17 22:29:33 +02:00
|
|
|
if (!MConf.get().worldsPowerLossEnabled.contains(player.getWorld()))
|
2013-04-19 12:27:39 +02:00
|
|
|
{
|
2014-09-17 13:17:33 +02:00
|
|
|
mplayer.msg("<i>You didn't lose any power due to the world you died in.");
|
2013-04-19 12:27:39 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:14:36 +02:00
|
|
|
// ... alter the power ...
|
2014-09-17 13:17:33 +02:00
|
|
|
double newPower = mplayer.getPower() + mplayer.getPowerPerDeath();
|
2013-04-23 12:14:36 +02:00
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
EventFactionsPowerChange powerChangeEvent = new EventFactionsPowerChange(null, mplayer, PowerChangeReason.DEATH, newPower);
|
2013-04-19 14:39:44 +02:00
|
|
|
powerChangeEvent.run();
|
|
|
|
if (powerChangeEvent.isCancelled()) return;
|
|
|
|
newPower = powerChangeEvent.getNewPower();
|
2013-04-19 12:27:39 +02:00
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
mplayer.setPower(newPower);
|
2013-04-19 12:27:39 +02:00
|
|
|
|
|
|
|
// ... and inform the player.
|
2013-04-23 12:14:36 +02:00
|
|
|
// TODO: A progress bar here would be epic :)
|
2014-09-17 13:17:33 +02:00
|
|
|
mplayer.msg("<i>Your power is now <h>%.2f / %.2f", newPower, mplayer.getPowerMax());
|
2013-04-19 12:27:39 +02:00
|
|
|
}
|
|
|
|
|
2013-04-18 21:00:46 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
// CAN COMBAT DAMAGE HAPPEN
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void canCombatDamageHappen(EntityDamageEvent event)
|
|
|
|
{
|
|
|
|
// TODO: Can't we just listen to the class type the sub is of?
|
|
|
|
if (!(event instanceof EntityDamageByEntityEvent)) return;
|
|
|
|
EntityDamageByEntityEvent sub = (EntityDamageByEntityEvent)event;
|
|
|
|
|
|
|
|
if (this.canCombatDamageHappen(sub, true)) return;
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// mainly for flaming arrows; don't want allies or people in safe zones to be ignited even after damage event is cancelled
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void canCombatDamageHappen(EntityCombustByEntityEvent event)
|
|
|
|
{
|
2013-07-02 10:44:03 +02:00
|
|
|
EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(event.getCombuster(), event.getEntity(), EntityDamageEvent.DamageCause.FIRE, 0D);
|
2013-04-18 21:00:46 +02:00
|
|
|
if (this.canCombatDamageHappen(sub, false)) return;
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void canCombatDamageHappen(PotionSplashEvent event)
|
|
|
|
{
|
|
|
|
// If a harmful potion is splashing ...
|
|
|
|
if (!MUtil.isHarmfulPotion(event.getPotion())) return;
|
|
|
|
|
2014-03-27 00:13:41 +01:00
|
|
|
ProjectileSource projectileSource = event.getPotion().getShooter();
|
|
|
|
if (! (projectileSource instanceof Entity)) return;
|
|
|
|
|
|
|
|
Entity thrower = (Entity)projectileSource;
|
2013-04-18 21:00:46 +02:00
|
|
|
|
|
|
|
// ... scan through affected entities to make sure they're all valid targets.
|
|
|
|
for (LivingEntity affectedEntity : event.getAffectedEntities())
|
|
|
|
{
|
2013-07-02 10:44:03 +02:00
|
|
|
EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(thrower, affectedEntity, EntityDamageEvent.DamageCause.CUSTOM, 0D);
|
2013-04-18 21:00:46 +02:00
|
|
|
if (this.canCombatDamageHappen(sub, true)) continue;
|
|
|
|
|
|
|
|
// affected entity list doesn't accept modification (iter.remove() is a no-go), but this works
|
|
|
|
event.setIntensity(affectedEntity, 0.0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-21 11:32:39 +02:00
|
|
|
// Utility method used in "canCombatDamageHappen" below.
|
|
|
|
public static boolean falseUnlessDisallowedPvpEventCancelled(Player attacker, Player defender, EntityDamageByEntityEvent event)
|
|
|
|
{
|
2014-06-04 16:47:01 +02:00
|
|
|
EventFactionsPvpDisallowed dpe = new EventFactionsPvpDisallowed(attacker, defender, event);
|
2013-09-21 11:32:39 +02:00
|
|
|
dpe.run();
|
|
|
|
return dpe.isCancelled();
|
|
|
|
}
|
|
|
|
|
2013-04-18 21:00:46 +02:00
|
|
|
public boolean canCombatDamageHappen(EntityDamageByEntityEvent event, boolean notify)
|
2013-09-21 11:32:39 +02:00
|
|
|
{
|
|
|
|
boolean ret = true;
|
|
|
|
|
2013-04-18 21:00:46 +02:00
|
|
|
// If the defender is a player ...
|
|
|
|
Entity edefender = event.getEntity();
|
|
|
|
if (!(edefender instanceof Player)) return true;
|
|
|
|
Player defender = (Player)edefender;
|
2014-09-17 13:17:33 +02:00
|
|
|
MPlayer udefender = MPlayer.get(edefender);
|
2013-04-25 13:25:15 +02:00
|
|
|
|
2013-04-18 21:00:46 +02:00
|
|
|
// ... and the attacker is someone else ...
|
2014-03-27 00:13:41 +01:00
|
|
|
Entity eattacker = MUtil.getLiableDamager(event);
|
|
|
|
|
2013-08-07 07:52:26 +02:00
|
|
|
// (we check null here since there may not be an attacker)
|
|
|
|
// (lack of attacker situations can be caused by other bukkit plugins)
|
|
|
|
if (eattacker != null && eattacker.equals(edefender)) return true;
|
2013-04-18 21:00:46 +02:00
|
|
|
|
|
|
|
// ... gather defender PS and faction information ...
|
|
|
|
PS defenderPs = PS.valueOf(defender);
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction defenderPsFaction = BoardColl.get().getFactionAt(defenderPs);
|
2013-04-18 21:00:46 +02:00
|
|
|
|
|
|
|
// ... PVP flag may cause a damage block ...
|
2014-10-07 12:30:44 +02:00
|
|
|
if (defenderPsFaction.getFlag(MFlag.getFlagPvp()) == false)
|
2013-04-18 21:00:46 +02:00
|
|
|
{
|
2013-08-07 07:52:26 +02:00
|
|
|
if (eattacker == null)
|
|
|
|
{
|
|
|
|
// No attacker?
|
|
|
|
// Let's behave as if it were a player
|
2013-09-21 11:32:39 +02:00
|
|
|
return falseUnlessDisallowedPvpEventCancelled(null, defender, event);
|
2013-08-07 07:52:26 +02:00
|
|
|
}
|
2013-04-18 21:00:46 +02:00
|
|
|
if (eattacker instanceof Player)
|
|
|
|
{
|
2013-09-21 11:32:39 +02:00
|
|
|
ret = falseUnlessDisallowedPvpEventCancelled((Player)eattacker, defender, event);
|
|
|
|
if (!ret && notify)
|
2013-04-18 21:00:46 +02:00
|
|
|
{
|
2014-09-17 13:17:33 +02:00
|
|
|
MPlayer attacker = MPlayer.get(eattacker);
|
2013-04-18 21:00:46 +02:00
|
|
|
attacker.msg("<i>PVP is disabled in %s.", defenderPsFaction.describeTo(attacker));
|
|
|
|
}
|
2013-09-21 11:32:39 +02:00
|
|
|
return ret;
|
2013-04-18 21:00:46 +02:00
|
|
|
}
|
2014-10-07 12:30:44 +02:00
|
|
|
return defenderPsFaction.getFlag(MFlag.getFlagMonsters());
|
2013-04-18 21:00:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// ... and if the attacker is a player ...
|
|
|
|
if (!(eattacker instanceof Player)) return true;
|
|
|
|
Player attacker = (Player)eattacker;
|
2014-09-17 13:17:33 +02:00
|
|
|
MPlayer uattacker = MPlayer.get(attacker);
|
2013-04-18 21:00:46 +02:00
|
|
|
|
|
|
|
// ... does this player bypass all protection? ...
|
2013-04-22 10:43:40 +02:00
|
|
|
if (MConf.get().playersWhoBypassAllProtection.contains(attacker.getName())) return true;
|
2013-04-18 21:00:46 +02:00
|
|
|
|
|
|
|
// ... gather attacker PS and faction information ...
|
|
|
|
PS attackerPs = PS.valueOf(attacker);
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction attackerPsFaction = BoardColl.get().getFactionAt(attackerPs);
|
2013-04-18 21:00:46 +02:00
|
|
|
|
|
|
|
// ... PVP flag may cause a damage block ...
|
|
|
|
// (just checking the defender as above isn't enough. What about the attacker? It could be in a no-pvp area)
|
|
|
|
// NOTE: This check is probably not that important but we could keep it anyways.
|
2014-10-07 12:30:44 +02:00
|
|
|
if (attackerPsFaction.getFlag(MFlag.getFlagPvp()) == false)
|
2013-04-18 21:00:46 +02:00
|
|
|
{
|
2013-09-21 11:39:08 +02:00
|
|
|
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, event);
|
2013-09-21 11:32:39 +02:00
|
|
|
if (!ret && notify) uattacker.msg("<i>PVP is disabled in %s.", attackerPsFaction.describeTo(uattacker));
|
|
|
|
return ret;
|
2013-04-18 21:00:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// ... are PVP rules completely ignored in this world? ...
|
2014-09-17 22:29:33 +02:00
|
|
|
if (!MConf.get().worldsPvpRulesEnabled.contains(defenderPs.getWorld())) return true;
|
2013-04-18 21:00:46 +02:00
|
|
|
|
2013-07-31 14:50:28 +02:00
|
|
|
Faction defendFaction = udefender.getFaction();
|
|
|
|
Faction attackFaction = uattacker.getFaction();
|
2013-04-18 21:00:46 +02:00
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
if (attackFaction.isNone() && MConf.get().disablePVPForFactionlessPlayers)
|
2013-04-18 21:00:46 +02:00
|
|
|
{
|
2013-09-21 11:39:08 +02:00
|
|
|
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, event);
|
2013-09-21 11:32:39 +02:00
|
|
|
if (!ret && notify) uattacker.msg("<i>You can't hurt other players until you join a faction.");
|
|
|
|
return ret;
|
2013-04-18 21:00:46 +02:00
|
|
|
}
|
|
|
|
else if (defendFaction.isNone())
|
|
|
|
{
|
2014-09-17 13:17:33 +02:00
|
|
|
if (defenderPsFaction == attackFaction && MConf.get().enablePVPAgainstFactionlessInAttackersLand)
|
2013-04-18 21:00:46 +02:00
|
|
|
{
|
|
|
|
// Allow PVP vs. Factionless in attacker's faction territory
|
|
|
|
return true;
|
|
|
|
}
|
2014-09-17 13:17:33 +02:00
|
|
|
else if (MConf.get().disablePVPForFactionlessPlayers)
|
2013-04-18 21:00:46 +02:00
|
|
|
{
|
2013-09-21 11:39:08 +02:00
|
|
|
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, event);
|
2013-09-21 11:32:39 +02:00
|
|
|
if (!ret && notify) uattacker.msg("<i>You can't hurt players who are not currently in a faction.");
|
|
|
|
return ret;
|
2013-04-18 21:00:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Rel relation = defendFaction.getRelationTo(attackFaction);
|
|
|
|
|
|
|
|
// Check the relation
|
2014-10-07 12:30:44 +02:00
|
|
|
if (udefender.hasFaction() && relation.isFriend() && defenderPsFaction.getFlag(MFlag.getFlagFriendlyire()) == false)
|
2013-04-18 21:00:46 +02:00
|
|
|
{
|
2013-09-21 11:39:08 +02:00
|
|
|
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, event);
|
2013-09-21 11:32:39 +02:00
|
|
|
if (!ret && notify) uattacker.msg("<i>You can't hurt %s<i>.", relation.getDescPlayerMany());
|
|
|
|
return ret;
|
2013-04-18 21:00:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// You can not hurt neutrals in their own territory.
|
2013-07-31 14:50:28 +02:00
|
|
|
boolean ownTerritory = udefender.isInOwnTerritory();
|
|
|
|
|
|
|
|
if (udefender.hasFaction() && ownTerritory && relation == Rel.NEUTRAL)
|
2013-04-18 21:00:46 +02:00
|
|
|
{
|
2013-09-21 11:39:08 +02:00
|
|
|
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, event);
|
2013-09-21 11:32:39 +02:00
|
|
|
if (!ret && notify)
|
2013-04-18 21:00:46 +02:00
|
|
|
{
|
2013-07-31 14:50:28 +02:00
|
|
|
uattacker.msg("<i>You can't hurt %s<i> in their own territory unless you declare them as an enemy.", udefender.describeTo(uattacker));
|
|
|
|
udefender.msg("%s<i> tried to hurt you.", uattacker.describeTo(udefender, true));
|
2013-04-18 21:00:46 +02:00
|
|
|
}
|
2013-09-21 11:32:39 +02:00
|
|
|
return ret;
|
2013-04-18 21:00:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Damage will be dealt. However check if the damage should be reduced.
|
2013-07-02 10:44:03 +02:00
|
|
|
double damage = event.getDamage();
|
2014-09-17 13:17:33 +02:00
|
|
|
if (damage > 0.0 && udefender.hasFaction() && ownTerritory && MConf.get().territoryShieldFactor > 0)
|
2013-04-18 21:00:46 +02:00
|
|
|
{
|
2014-09-17 13:17:33 +02:00
|
|
|
double newDamage = damage * (1D - MConf.get().territoryShieldFactor);
|
2013-04-18 21:00:46 +02:00
|
|
|
event.setDamage(newDamage);
|
|
|
|
|
|
|
|
// Send message
|
|
|
|
if (notify)
|
|
|
|
{
|
2014-09-17 13:17:33 +02:00
|
|
|
String perc = MessageFormat.format("{0,number,#%}", (MConf.get().territoryShieldFactor)); // TODO does this display correctly??
|
2013-07-31 14:50:28 +02:00
|
|
|
udefender.msg("<i>Enemy damage reduced by <rose>%s<i>.", perc);
|
2013-04-18 21:00:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2013-04-10 12:25:46 +02:00
|
|
|
|
2013-04-18 17:20:42 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
// REMOVE PLAYER DATA WHEN BANNED
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
|
|
public void onPlayerKick(PlayerKickEvent event)
|
|
|
|
{
|
|
|
|
// If a player was kicked from the server ...
|
|
|
|
Player player = event.getPlayer();
|
|
|
|
|
|
|
|
// ... and if the if player was banned (not just kicked) ...
|
2014-07-08 16:02:37 +02:00
|
|
|
//if (!event.getReason().equals("Banned by admin.")) return;
|
|
|
|
if (!player.isBanned()) return;
|
2013-04-18 17:20:42 +02:00
|
|
|
|
|
|
|
// ... and we remove player data when banned ...
|
2014-10-06 13:08:34 +02:00
|
|
|
if (!MConf.get().removePlayerWhenBanned) return;
|
2013-04-18 17:20:42 +02:00
|
|
|
|
|
|
|
// ... get rid of their stored info.
|
2014-09-17 13:17:33 +02:00
|
|
|
MPlayer mplayer = MPlayerColl.get().get(player, false);
|
|
|
|
if (mplayer == null) return;
|
|
|
|
|
|
|
|
if (mplayer.getRole() == Rel.LEADER)
|
2013-04-18 17:20:42 +02:00
|
|
|
{
|
2014-09-17 13:17:33 +02:00
|
|
|
mplayer.getFaction().promoteNewLeader();
|
2013-04-18 17:20:42 +02:00
|
|
|
}
|
2014-09-17 13:17:33 +02:00
|
|
|
|
|
|
|
mplayer.leave();
|
|
|
|
mplayer.detach();
|
2013-04-18 17:20:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// VISUALIZE UTIL
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
|
|
public void onPlayerMoveClearVisualizations(PlayerMoveEvent event)
|
|
|
|
{
|
|
|
|
if (MUtil.isSameBlock(event)) return;
|
|
|
|
|
|
|
|
VisualizeUtil.clear(event.getPlayer());
|
|
|
|
}
|
|
|
|
|
2013-04-18 16:35:45 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
// DENY COMMANDS
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
|
|
public void denyCommands(PlayerCommandPreprocessEvent event)
|
|
|
|
{
|
|
|
|
// If a player is trying to run a command ...
|
|
|
|
Player player = event.getPlayer();
|
2013-04-25 13:25:15 +02:00
|
|
|
|
2014-09-17 13:29:58 +02:00
|
|
|
MPlayer mplayer = MPlayer.get(player);
|
2013-04-18 16:35:45 +02:00
|
|
|
|
|
|
|
// ... and the player does not have adminmode ...
|
2014-09-17 13:29:58 +02:00
|
|
|
if (mplayer.isUsingAdminMode()) return;
|
2013-04-18 16:35:45 +02:00
|
|
|
|
|
|
|
// ... clean up the command ...
|
|
|
|
String command = event.getMessage();
|
|
|
|
command = Txt.removeLeadingCommandDust(command);
|
|
|
|
command = command.toLowerCase();
|
|
|
|
command = command.trim();
|
|
|
|
|
2013-04-23 12:31:07 +02:00
|
|
|
// ... the command may be denied for members of permanent factions ...
|
2014-10-07 12:30:44 +02:00
|
|
|
if (mplayer.hasFaction() && mplayer.getFaction().getFlag(MFlag.getFlagPermanent()) && containsCommand(command, MConf.get().denyCommandsPermanentFactionMember))
|
2013-04-18 16:35:45 +02:00
|
|
|
{
|
2014-09-17 13:29:58 +02:00
|
|
|
mplayer.msg("<b>You can't use \"<h>/%s<b>\" as member of a permanent faction.", command);
|
2013-04-18 16:35:45 +02:00
|
|
|
event.setCancelled(true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-04-26 11:06:07 +02:00
|
|
|
// ... if there is a faction at the players location ...
|
2013-04-22 21:00:00 +02:00
|
|
|
PS ps = PS.valueOf(player).getChunk(true);
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction factionAtPs = BoardColl.get().getFactionAt(ps);
|
2013-08-08 09:28:39 +02:00
|
|
|
if (factionAtPs.isNone()) return; // TODO: An NPE can arise here? Why?
|
2013-04-26 11:06:07 +02:00
|
|
|
|
|
|
|
// ... the command may be denied in the territory of this relation type ...
|
2014-09-17 13:29:58 +02:00
|
|
|
Rel rel = factionAtPs.getRelationTo(mplayer);
|
2013-04-18 16:35:45 +02:00
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
List<String> deniedCommands = MConf.get().denyCommandsTerritoryRelation.get(rel);
|
2013-04-23 12:54:34 +02:00
|
|
|
if (deniedCommands == null) return;
|
2013-04-23 12:31:07 +02:00
|
|
|
if (!containsCommand(command, deniedCommands)) return;
|
|
|
|
|
2014-09-17 13:29:58 +02:00
|
|
|
mplayer.msg("<b>You can't use \"<h>/%s<b>\" in %s territory.", command, Txt.getNicedEnum(rel));
|
2013-04-23 12:31:07 +02:00
|
|
|
event.setCancelled(true);
|
2013-04-18 16:35:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static boolean containsCommand(String needle, Collection<String> haystack)
|
|
|
|
{
|
|
|
|
if (needle == null) return false;
|
|
|
|
needle = Txt.removeLeadingCommandDust(needle);
|
|
|
|
needle = needle.toLowerCase();
|
|
|
|
|
2013-04-18 17:42:49 +02:00
|
|
|
for (String straw : haystack)
|
2013-04-18 16:35:45 +02:00
|
|
|
{
|
2013-04-18 17:42:49 +02:00
|
|
|
if (straw == null) continue;
|
|
|
|
straw = Txt.removeLeadingCommandDust(straw);
|
|
|
|
straw = straw.toLowerCase();
|
2013-04-18 16:35:45 +02:00
|
|
|
|
2013-04-18 17:42:49 +02:00
|
|
|
if (needle.startsWith(straw)) return true;
|
2013-04-18 16:35:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-04-18 16:11:45 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
// FLAG: MONSTERS
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockMonsters(CreatureSpawnEvent event)
|
|
|
|
{
|
2014-10-03 18:01:40 +02:00
|
|
|
// If a creature is spawning ...
|
|
|
|
EntityType type = event.getEntityType();
|
2013-04-18 16:11:45 +02:00
|
|
|
|
2014-10-03 18:01:40 +02:00
|
|
|
// ... and that creature is a monster ...
|
|
|
|
if ( ! MConf.get().entityTypesMonsters.contains(type)) return;
|
|
|
|
|
|
|
|
// ... and the reason for the spawn is natural ...
|
|
|
|
SpawnReason reason = event.getSpawnReason();
|
|
|
|
if (reason != SpawnReason.NATURAL && reason != SpawnReason.JOCKEY) return;
|
|
|
|
|
|
|
|
// ... and monsters are forbidden at the location ...
|
2014-10-06 13:24:52 +02:00
|
|
|
Location location = event.getLocation();
|
|
|
|
if (location == null) return;
|
|
|
|
|
|
|
|
PS ps = PS.valueOf(location);
|
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction faction = BoardColl.get().getFactionAt(ps);
|
2014-10-06 13:24:52 +02:00
|
|
|
if (faction == null) return;
|
|
|
|
|
2014-10-07 12:30:44 +02:00
|
|
|
if (faction.getFlag(MFlag.getFlagMonsters())) return;
|
2013-04-18 16:11:45 +02:00
|
|
|
|
|
|
|
// ... block the spawn.
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockMonsters(EntityTargetEvent event)
|
|
|
|
{
|
2013-04-25 12:04:01 +02:00
|
|
|
// If a monster ...
|
2013-08-29 10:48:17 +02:00
|
|
|
if ( ! MConf.get().entityTypesMonsters.contains(event.getEntityType())) return;
|
2013-04-18 16:11:45 +02:00
|
|
|
|
2013-04-25 12:04:01 +02:00
|
|
|
// ... is targeting something ...
|
|
|
|
Entity target = event.getTarget();
|
|
|
|
if (target == null) return;
|
|
|
|
|
2013-04-18 16:11:45 +02:00
|
|
|
// ... at a place where monsters are forbidden ...
|
2013-04-25 12:04:01 +02:00
|
|
|
PS ps = PS.valueOf(target);
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction faction = BoardColl.get().getFactionAt(ps);
|
2014-10-07 12:30:44 +02:00
|
|
|
if (faction.getFlag(MFlag.getFlagMonsters())) return;
|
2013-04-18 16:11:45 +02:00
|
|
|
|
|
|
|
// ... then if ghast target nothing ...
|
|
|
|
if (event.getEntityType() == EntityType.GHAST)
|
|
|
|
{
|
|
|
|
event.setTarget(null);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ... otherwise simply cancel.
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
2013-04-17 16:21:25 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
// FLAG: EXPLOSIONS
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockExplosion(HangingBreakEvent event)
|
|
|
|
{
|
|
|
|
// If a hanging entity was broken by an explosion ...
|
|
|
|
if (event.getCause() != RemoveCause.EXPLOSION) return;
|
2013-04-25 13:25:15 +02:00
|
|
|
Entity entity = event.getEntity();
|
2013-04-17 16:21:25 +02:00
|
|
|
|
|
|
|
// ... and the faction there has explosions disabled ...
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction faction = BoardColl.get().getFactionAt(PS.valueOf(entity));
|
2013-08-23 10:45:27 +02:00
|
|
|
if (faction.isExplosionsAllowed()) return;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
|
|
|
// ... then cancel.
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
2013-04-18 15:59:20 +02:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockExplosion(EntityExplodeEvent event)
|
|
|
|
{
|
2013-09-22 11:34:21 +02:00
|
|
|
// Prepare some variables:
|
|
|
|
// Current faction
|
|
|
|
Faction faction = null;
|
|
|
|
// Current allowed
|
|
|
|
Boolean allowed = true;
|
|
|
|
// Caching to speed things up.
|
|
|
|
Map<Faction, Boolean> faction2allowed = new HashMap<Faction, Boolean>();
|
|
|
|
|
2013-04-26 10:32:02 +02:00
|
|
|
// If an explosion occurs at a location ...
|
|
|
|
Location location = event.getLocation();
|
2013-04-25 13:25:15 +02:00
|
|
|
|
|
|
|
// Check the entity. Are explosions disabled there?
|
2014-09-17 13:17:33 +02:00
|
|
|
faction = BoardColl.get().getFactionAt(PS.valueOf(location));
|
2013-09-22 11:34:21 +02:00
|
|
|
allowed = faction.isExplosionsAllowed();
|
|
|
|
if (allowed == false)
|
2013-04-25 13:25:15 +02:00
|
|
|
{
|
|
|
|
event.setCancelled(true);
|
|
|
|
return;
|
|
|
|
}
|
2013-09-22 11:34:21 +02:00
|
|
|
faction2allowed.put(faction, allowed);
|
2013-04-25 13:25:15 +02:00
|
|
|
|
2013-04-18 15:59:20 +02:00
|
|
|
// Individually check the flag state for each block
|
|
|
|
Iterator<Block> iter = event.blockList().iterator();
|
|
|
|
while (iter.hasNext())
|
|
|
|
{
|
|
|
|
Block block = iter.next();
|
2014-09-17 13:17:33 +02:00
|
|
|
faction = BoardColl.get().getFactionAt(PS.valueOf(block));
|
2013-09-22 11:34:21 +02:00
|
|
|
allowed = faction2allowed.get(faction);
|
|
|
|
if (allowed == null)
|
|
|
|
{
|
|
|
|
allowed = faction.isExplosionsAllowed();
|
|
|
|
faction2allowed.put(faction, allowed);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (allowed == false) iter.remove();
|
2013-04-18 15:59:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockExplosion(EntityChangeBlockEvent event)
|
|
|
|
{
|
|
|
|
// If a wither is changing a block ...
|
|
|
|
Entity entity = event.getEntity();
|
|
|
|
if (!(entity instanceof Wither)) return;
|
|
|
|
|
|
|
|
// ... and the faction there has explosions disabled ...
|
|
|
|
PS ps = PS.valueOf(event.getBlock());
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction faction = BoardColl.get().getFactionAt(ps);
|
2013-08-23 10:45:27 +02:00
|
|
|
|
|
|
|
if (faction.isExplosionsAllowed()) return;
|
2013-04-18 15:59:20 +02:00
|
|
|
|
|
|
|
// ... stop the block alteration.
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// FLAG: ENDERGRIEF
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockEndergrief(EntityChangeBlockEvent event)
|
|
|
|
{
|
|
|
|
// If an enderman is changing a block ...
|
|
|
|
Entity entity = event.getEntity();
|
|
|
|
if (!(entity instanceof Enderman)) return;
|
|
|
|
|
|
|
|
// ... and the faction there has endergrief disabled ...
|
|
|
|
PS ps = PS.valueOf(event.getBlock());
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction faction = BoardColl.get().getFactionAt(ps);
|
2014-10-07 12:30:44 +02:00
|
|
|
if (faction.getFlag(MFlag.getFlagEndergrief())) return;
|
2013-04-18 15:59:20 +02:00
|
|
|
|
|
|
|
// ... stop the block alteration.
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
2013-04-24 15:35:46 +02:00
|
|
|
|
|
|
|
// -------------------------------------------- //
|
|
|
|
// FLAG: FIRE SPREAD
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
public void blockFireSpread(Block block, Cancellable cancellable)
|
|
|
|
{
|
|
|
|
// If the faction at the block has firespread disabled ...
|
|
|
|
PS ps = PS.valueOf(block);
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction faction = BoardColl.get().getFactionAt(ps);
|
2013-04-26 10:32:02 +02:00
|
|
|
|
2014-10-07 12:30:44 +02:00
|
|
|
if (faction.getFlag(MFlag.getFlagFirespread())) return;
|
2013-04-24 15:35:46 +02:00
|
|
|
|
|
|
|
// then cancel the event.
|
|
|
|
cancellable.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockFireSpread(BlockIgniteEvent event)
|
|
|
|
{
|
|
|
|
// If fire is spreading ...
|
|
|
|
if (event.getCause() != IgniteCause.SPREAD && event.getCause() != IgniteCause.LAVA) return;
|
|
|
|
|
|
|
|
// ... consider blocking it.
|
|
|
|
blockFireSpread(event.getBlock(), event);
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Is use of this event deprecated?
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockFireSpread(BlockSpreadEvent event)
|
|
|
|
{
|
|
|
|
// If fire is spreading ...
|
2013-09-20 12:50:32 +02:00
|
|
|
if (event.getNewState().getType() != Material.FIRE) return;
|
2013-04-24 15:35:46 +02:00
|
|
|
|
|
|
|
// ... consider blocking it.
|
|
|
|
blockFireSpread(event.getBlock(), event);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockFireSpread(BlockBurnEvent event)
|
|
|
|
{
|
|
|
|
// If a block is burning ...
|
|
|
|
|
|
|
|
// ... consider blocking it.
|
|
|
|
blockFireSpread(event.getBlock(), event);
|
|
|
|
}
|
2013-04-18 15:59:20 +02:00
|
|
|
|
2013-04-17 16:21:25 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
// FLAG: BUILD
|
|
|
|
// -------------------------------------------- //
|
2014-09-19 09:30:08 +02:00
|
|
|
|
|
|
|
public static boolean canPlayerBuildAt(Object senderObject, PS ps, boolean verboose)
|
2013-04-17 16:21:25 +02:00
|
|
|
{
|
2014-09-19 09:30:08 +02:00
|
|
|
MPlayer mplayer = MPlayer.get(senderObject);
|
|
|
|
if (mplayer == null) return false;
|
|
|
|
|
|
|
|
String name = mplayer.getName();
|
2013-04-22 10:43:40 +02:00
|
|
|
if (MConf.get().playersWhoBypassAllProtection.contains(name)) return true;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
2014-09-17 13:29:58 +02:00
|
|
|
if (mplayer.isUsingAdminMode()) return true;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
2014-10-03 09:01:36 +02:00
|
|
|
if (!MPerm.getPermBuild().has(mplayer, ps, false) && MPerm.getPermPainbuild().has(mplayer, ps, false))
|
2013-04-17 16:21:25 +02:00
|
|
|
{
|
2013-04-29 12:48:11 +02:00
|
|
|
if (verboose)
|
2013-04-17 16:21:25 +02:00
|
|
|
{
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction hostFaction = BoardColl.get().getFactionAt(ps);
|
2014-09-17 13:29:58 +02:00
|
|
|
mplayer.msg("<b>It is painful to build in the territory of %s<b>.", hostFaction.describeTo(mplayer));
|
2014-09-19 09:30:08 +02:00
|
|
|
Player player = mplayer.getPlayer();
|
|
|
|
if (player != null)
|
|
|
|
{
|
|
|
|
player.damage(MConf.get().actionDeniedPainAmount);
|
|
|
|
}
|
2013-04-17 16:21:25 +02:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-10-03 09:01:36 +02:00
|
|
|
return MPerm.getPermBuild().has(mplayer, ps, verboose);
|
2013-04-17 16:21:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockBuild(HangingPlaceEvent event)
|
|
|
|
{
|
2013-04-29 12:48:11 +02:00
|
|
|
if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getEntity()), true)) return;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockBuild(HangingBreakEvent event)
|
|
|
|
{
|
|
|
|
if (! (event instanceof HangingBreakByEntityEvent)) return;
|
|
|
|
HangingBreakByEntityEvent entityEvent = (HangingBreakByEntityEvent)event;
|
|
|
|
|
|
|
|
Entity breaker = entityEvent.getRemover();
|
|
|
|
if (! (breaker instanceof Player)) return;
|
|
|
|
|
2014-09-19 09:30:08 +02:00
|
|
|
if ( ! canPlayerBuildAt(breaker, PS.valueOf(event.getEntity()), true))
|
2013-04-17 16:21:25 +02:00
|
|
|
{
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-05 12:20:41 +01:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void itemFrameDamage(EntityDamageByEntityEvent event)
|
|
|
|
{
|
|
|
|
// If the damagee is an ItemFrame ...
|
|
|
|
Entity edamagee = event.getEntity();
|
|
|
|
if (!(edamagee instanceof ItemFrame)) return;
|
|
|
|
ItemFrame itemFrame = (ItemFrame)edamagee;
|
|
|
|
|
|
|
|
// ... and the liable damager is a player ...
|
|
|
|
Entity edamager = MUtil.getLiableDamager(event);
|
|
|
|
if (!(edamager instanceof Player)) return;
|
|
|
|
Player player = (Player)edamager;
|
|
|
|
|
|
|
|
// ... and the player can't build there ...
|
|
|
|
if (canPlayerBuildAt(player, PS.valueOf(itemFrame), true)) return;
|
|
|
|
|
|
|
|
// ... then cancel the event.
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
2013-04-17 16:21:25 +02:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL)
|
|
|
|
public void blockBuild(BlockPlaceEvent event)
|
|
|
|
{
|
|
|
|
if (!event.canBuild()) return;
|
|
|
|
|
2013-04-29 12:48:11 +02:00
|
|
|
if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), true)) return;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
|
|
|
event.setBuild(false);
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockBuild(BlockBreakEvent event)
|
|
|
|
{
|
2013-04-29 12:48:11 +02:00
|
|
|
if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), true)) return;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockBuild(BlockDamageEvent event)
|
|
|
|
{
|
|
|
|
if (!event.getInstaBreak()) return;
|
|
|
|
|
2013-04-29 12:48:11 +02:00
|
|
|
if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), true)) return;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockBuild(BlockPistonExtendEvent event)
|
|
|
|
{
|
2013-04-24 07:51:48 +02:00
|
|
|
Block block = event.getBlock();
|
2013-04-17 16:21:25 +02:00
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction pistonFaction = BoardColl.get().getFactionAt(PS.valueOf(block));
|
2013-04-17 16:21:25 +02:00
|
|
|
|
|
|
|
// target end-of-the-line empty (air) block which is being pushed into, including if piston itself would extend into air
|
2013-04-24 07:51:48 +02:00
|
|
|
Block targetBlock = block.getRelative(event.getDirection(), event.getLength() + 1);
|
2013-04-17 16:21:25 +02:00
|
|
|
|
|
|
|
// members of faction might not have build rights in their own territory, but pistons should still work regardless; so, address that corner case
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction targetFaction = BoardColl.get().getFactionAt(PS.valueOf(targetBlock));
|
2013-04-17 16:21:25 +02:00
|
|
|
if (targetFaction == pistonFaction) return;
|
|
|
|
|
|
|
|
// if potentially pushing into air/water/lava in another territory, we need to check it out
|
2014-10-03 09:01:36 +02:00
|
|
|
if ((targetBlock.isEmpty() || targetBlock.isLiquid()) && ! MPerm.getPermBuild().has(pistonFaction, targetFaction))
|
2013-04-17 16:21:25 +02:00
|
|
|
{
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* note that I originally was testing the territory of each affected block, but since I found that pistons can only push
|
|
|
|
* up to 12 blocks and the width of any territory is 16 blocks, it should be safe (and much more lightweight) to test
|
|
|
|
* only the final target block as done above
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void blockBuild(BlockPistonRetractEvent event)
|
2013-04-24 07:51:48 +02:00
|
|
|
{
|
2013-04-17 16:21:25 +02:00
|
|
|
// if not a sticky piston, retraction should be fine
|
|
|
|
if (!event.isSticky()) return;
|
|
|
|
|
2013-04-22 14:16:07 +02:00
|
|
|
Block retractBlock = event.getRetractLocation().getBlock();
|
|
|
|
PS retractPs = PS.valueOf(retractBlock);
|
2013-04-17 16:21:25 +02:00
|
|
|
|
|
|
|
// if potentially retracted block is just air/water/lava, no worries
|
2013-04-22 14:16:07 +02:00
|
|
|
if (retractBlock.isEmpty() || retractBlock.isLiquid()) return;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction pistonFaction = BoardColl.get().getFactionAt(PS.valueOf(event.getBlock()));
|
2013-04-17 16:21:25 +02:00
|
|
|
|
|
|
|
// members of faction might not have build rights in their own territory, but pistons should still work regardless; so, address that corner case
|
2014-09-17 13:17:33 +02:00
|
|
|
Faction targetFaction = BoardColl.get().getFactionAt(retractPs);
|
2013-04-17 16:21:25 +02:00
|
|
|
if (targetFaction == pistonFaction) return;
|
|
|
|
|
2014-10-03 09:01:36 +02:00
|
|
|
if (!MPerm.getPermBuild().has(pistonFaction, targetFaction))
|
2013-04-17 16:21:25 +02:00
|
|
|
{
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------- //
|
2013-04-24 15:35:46 +02:00
|
|
|
// ASSORTED BUILD AND INTERACT
|
2013-04-17 16:21:25 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
|
2013-04-24 15:35:46 +02:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void onPlayerInteract(PlayerInteractEvent event)
|
2013-04-17 16:21:25 +02:00
|
|
|
{
|
2013-04-24 15:35:46 +02:00
|
|
|
// only need to check right-clicks and physical as of MC 1.4+; good performance boost
|
|
|
|
if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.PHYSICAL) return;
|
2014-10-03 13:16:07 +02:00
|
|
|
|
2013-04-24 15:35:46 +02:00
|
|
|
Block block = event.getClickedBlock();
|
|
|
|
Player player = event.getPlayer();
|
|
|
|
|
|
|
|
if (block == null) return; // clicked in air, apparently
|
|
|
|
|
2014-10-03 13:16:07 +02:00
|
|
|
if ( ! canPlayerUseBlock(player, block, true))
|
2013-04-24 15:35:46 +02:00
|
|
|
{
|
|
|
|
event.setCancelled(true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; // only interested on right-clicks for below
|
|
|
|
|
2014-10-03 13:16:07 +02:00
|
|
|
if ( ! playerCanUseItemHere(player, PS.valueOf(block), event.getMaterial(), true))
|
2013-04-24 15:35:46 +02:00
|
|
|
{
|
|
|
|
event.setCancelled(true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-03 13:16:07 +02:00
|
|
|
public static boolean playerCanUseItemHere(Player player, PS ps, Material material, boolean verboose)
|
2013-04-24 15:35:46 +02:00
|
|
|
{
|
2014-10-03 12:52:46 +02:00
|
|
|
if ( ! MConf.get().materialsEditTools.contains(material) && ! MConf.get().materialsEditToolsDupeBug.contains(material)) return true;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
2013-04-24 15:35:46 +02:00
|
|
|
String name = player.getName();
|
|
|
|
if (MConf.get().playersWhoBypassAllProtection.contains(name)) return true;
|
|
|
|
|
2014-09-17 13:29:58 +02:00
|
|
|
MPlayer mplayer = MPlayer.get(player);
|
|
|
|
if (mplayer.isUsingAdminMode()) return true;
|
2013-04-24 15:35:46 +02:00
|
|
|
|
2014-10-03 13:16:07 +02:00
|
|
|
return MPerm.getPermBuild().has(mplayer, ps, verboose);
|
2013-04-17 16:21:25 +02:00
|
|
|
}
|
|
|
|
|
2014-10-03 13:16:07 +02:00
|
|
|
public static boolean canPlayerUseBlock(Player player, Block block, boolean verboose)
|
2013-04-17 16:21:25 +02:00
|
|
|
{
|
2013-04-24 15:35:46 +02:00
|
|
|
String name = player.getName();
|
|
|
|
if (MConf.get().playersWhoBypassAllProtection.contains(name)) return true;
|
|
|
|
|
2014-09-17 13:17:33 +02:00
|
|
|
MPlayer me = MPlayer.get(player);
|
2013-04-24 15:35:46 +02:00
|
|
|
if (me.isUsingAdminMode()) return true;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
2013-04-24 15:35:46 +02:00
|
|
|
PS ps = PS.valueOf(block);
|
|
|
|
Material material = block.getType();
|
|
|
|
|
2014-10-03 13:16:07 +02:00
|
|
|
if (MConf.get().materialsEditOnInteract.contains(material) && ! MPerm.getPermBuild().has(me, ps, verboose)) return false;
|
|
|
|
if (MConf.get().materialsContainer.contains(material) && ! MPerm.getPermContainer().has(me, ps, verboose)) return false;
|
|
|
|
if (MConf.get().materialsDoor.contains(material) && ! MPerm.getPermDoor().has(me, ps, verboose)) return false;
|
|
|
|
if (material == Material.STONE_BUTTON && ! MPerm.getPermButton().has(me, ps, verboose)) return false;
|
|
|
|
if (material == Material.LEVER && ! MPerm.getPermLever().has(me, ps, verboose)) return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
|
|
public void onPlayerInteractEntity(PlayerInteractEntityEvent event)
|
|
|
|
{
|
|
|
|
// If a player ...
|
|
|
|
final Player player = event.getPlayer();
|
|
|
|
|
|
|
|
// ... right clicked an entity ...
|
|
|
|
final Entity entity = event.getRightClicked();
|
|
|
|
if (entity == null) return;
|
|
|
|
|
|
|
|
// ... and using that entity is forbidden ...
|
|
|
|
if (canPlayerUseEntity(player, entity, true)) return;
|
|
|
|
|
|
|
|
// ... then cancel the event.
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean canPlayerUseEntity(Player player, Entity entity, boolean verboose)
|
|
|
|
{
|
|
|
|
String name = player.getName();
|
|
|
|
if (MConf.get().playersWhoBypassAllProtection.contains(name)) return true;
|
|
|
|
|
|
|
|
MPlayer me = MPlayer.get(player);
|
|
|
|
if (me.isUsingAdminMode()) return true;
|
|
|
|
|
|
|
|
PS ps = PS.valueOf(entity);
|
|
|
|
EntityType type = entity.getType();
|
|
|
|
|
|
|
|
if (MConf.get().entityTypesContainer.contains(type) && ! MPerm.getPermContainer().has(me, ps, verboose)) return false;
|
|
|
|
|
2013-04-24 15:35:46 +02:00
|
|
|
return true;
|
2013-04-17 16:21:25 +02:00
|
|
|
}
|
2013-04-24 15:35:46 +02:00
|
|
|
|
|
|
|
// For some reason onPlayerInteract() sometimes misses bucket events depending on distance (something like 2-3 blocks away isn't detected),
|
|
|
|
// but these separate bucket events below always fire without fail
|
2013-04-17 16:21:25 +02:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
2013-04-24 15:35:46 +02:00
|
|
|
public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event)
|
2013-04-17 16:21:25 +02:00
|
|
|
{
|
2013-04-24 15:35:46 +02:00
|
|
|
Block block = event.getBlockClicked();
|
|
|
|
Player player = event.getPlayer();
|
2013-04-17 16:21:25 +02:00
|
|
|
|
2014-10-03 13:16:07 +02:00
|
|
|
if (playerCanUseItemHere(player, PS.valueOf(block), event.getBucket(), true)) return;
|
2013-04-24 15:35:46 +02:00
|
|
|
|
|
|
|
event.setCancelled(true);
|
2013-04-17 16:21:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
2013-04-24 15:35:46 +02:00
|
|
|
public void onPlayerBucketFill(PlayerBucketFillEvent event)
|
2013-04-17 16:21:25 +02:00
|
|
|
{
|
2013-04-24 15:35:46 +02:00
|
|
|
Block block = event.getBlockClicked();
|
|
|
|
Player player = event.getPlayer();
|
|
|
|
|
2014-10-03 13:16:07 +02:00
|
|
|
if (playerCanUseItemHere(player, PS.valueOf(block), event.getBucket(), true)) return;
|
2013-04-17 16:21:25 +02:00
|
|
|
|
2013-04-24 15:35:46 +02:00
|
|
|
event.setCancelled(true);
|
2013-04-17 16:21:25 +02:00
|
|
|
}
|
|
|
|
|
2013-07-24 18:29:55 +02:00
|
|
|
// -------------------------------------------- //
|
|
|
|
// TELEPORT TO HOME ON DEATH
|
|
|
|
// -------------------------------------------- //
|
|
|
|
|
|
|
|
public void teleportToHomeOnDeath(PlayerRespawnEvent event, EventPriority priority)
|
|
|
|
{
|
|
|
|
// If a player is respawning ...
|
|
|
|
final Player player = event.getPlayer();
|
2014-09-17 13:29:58 +02:00
|
|
|
final MPlayer mplayer = MPlayer.get(player);
|
2013-07-24 18:29:55 +02:00
|
|
|
|
|
|
|
// ... homes are enabled, active and at this priority ...
|
2014-09-17 13:17:33 +02:00
|
|
|
if (!MConf.get().homesEnabled) return;
|
|
|
|
if (!MConf.get().homesTeleportToOnDeathActive) return;
|
|
|
|
if (MConf.get().homesTeleportToOnDeathPriority != priority) return;
|
2013-07-24 18:29:55 +02:00
|
|
|
|
|
|
|
// ... and the player has a faction ...
|
2014-09-17 13:29:58 +02:00
|
|
|
final Faction faction = mplayer.getFaction();
|
2013-07-24 18:29:55 +02:00
|
|
|
if (faction.isNone()) return;
|
|
|
|
|
|
|
|
// ... and the faction has a home ...
|
|
|
|
PS home = faction.getHome();
|
|
|
|
if (home == null) return;
|
|
|
|
|
|
|
|
// ... and the home is translatable ...
|
|
|
|
Location respawnLocation = null;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
respawnLocation = home.asBukkitLocation(true);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
// The home location map may have been deleted
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ... then use it for the respawn location.
|
|
|
|
event.setRespawnLocation(respawnLocation);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.LOWEST)
|
|
|
|
public void teleportToHomeOnDeathLowest(PlayerRespawnEvent event)
|
|
|
|
{
|
|
|
|
this.teleportToHomeOnDeath(event, EventPriority.LOWEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.LOW)
|
|
|
|
public void teleportToHomeOnDeathLow(PlayerRespawnEvent event)
|
|
|
|
{
|
|
|
|
this.teleportToHomeOnDeath(event, EventPriority.LOW);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL)
|
|
|
|
public void teleportToHomeOnDeathNormal(PlayerRespawnEvent event)
|
|
|
|
{
|
|
|
|
this.teleportToHomeOnDeath(event, EventPriority.NORMAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.HIGH)
|
|
|
|
public void teleportToHomeOnDeathHigh(PlayerRespawnEvent event)
|
|
|
|
{
|
|
|
|
this.teleportToHomeOnDeath(event, EventPriority.HIGH);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST)
|
|
|
|
public void teleportToHomeOnDeathHighest(PlayerRespawnEvent event)
|
|
|
|
{
|
|
|
|
this.teleportToHomeOnDeath(event, EventPriority.HIGHEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR)
|
|
|
|
public void teleportToHomeOnDeathMonitor(PlayerRespawnEvent event)
|
|
|
|
{
|
|
|
|
this.teleportToHomeOnDeath(event, EventPriority.MONITOR);
|
|
|
|
}
|
|
|
|
|
2013-04-10 12:25:46 +02:00
|
|
|
}
|